UNPKG

@crossed/ui

Version:

A universal & performant styling library for React Native, Next.js & React

151 lines (150 loc) 4.22 kB
import { jsx } from "react/jsx-runtime"; import { composeEventHandlers, withStaticProperties } from "@crossed/core"; import { useCallback, useEffect, useRef } from "react"; import { composeStyles, isWeb, useInteraction } from "@crossed/styled"; import { withTiming } from "react-native-reanimated"; import { focusStyles, tabTitleStyles, triggerStyles } from "./styles"; import { Button } from "../../buttons/Button"; import { useMedia } from "../../useMedia"; const createTab = ({ useTriggerContext, useTabsContext, TriggerProvider }) => { const TabImpl = ({ value: valueProps, children, disabled, style, ...props }) => { const { setValue, value, id, variant, listTabRef, indicator, scroll, shouldShow, widthLayout, size } = useTabsContext(); const media = useMedia(); const selected = valueProps === value; const { state, props: interaction } = useInteraction(props); const measure = () => { var _a; if (listTabRef.current) { (_a = ref.current) == null ? void 0 : _a.measureLayout( listTabRef.current, (left, _top, width) => { var _a2, _b; const offset = shouldShow ? 30 : 0; const positionLeft = isWeb ? left + scroll.value : left; indicator.left.value = withTiming(positionLeft); indicator.width.value = withTiming(width); if (widthLayout.value + scroll.value < positionLeft + width + offset) { (_a2 = listTabRef.current) == null ? void 0 : _a2.scrollTo({ x: positionLeft + width - widthLayout.value + offset }); } else if (positionLeft <= offset || positionLeft < scroll.value) { (_b = listTabRef.current) == null ? void 0 : _b.scrollTo({ x: positionLeft - offset }); } } ); } }; const onPress = useCallback( composeEventHandlers(() => { setValue(valueProps); measure(); }, props.onPress), [props.onPress, setValue] ); useEffect(() => { if (shouldShow && selected) { measure(); } }, [shouldShow]); useEffect(() => { selected && measure(); }, [...Object.values(media), selected]); const onLayout = useCallback( composeEventHandlers(({ nativeEvent: { layout } }) => { if (selected) { indicator.left.value = layout.x + scroll.value; indicator.width.value = layout.width; } }, props.onLayout), [props.onLayout, setValue, selected, shouldShow] ); const ref = useRef(); return /* @__PURE__ */ jsx( TriggerProvider, { ...state, disabled, selected, hover: selected || state.hover, children: /* @__PURE__ */ jsx( Button, { role: "tab", ref, disabled, variant: "tertiary", "aria-selected": selected, "aria-control": `${id}-panel-${valueProps}`, id: `${id}-tab-${valueProps}`, ...props, style: composeStyles( triggerStyles.trigger, triggerStyles[size], focusStyles[variant], disabled && triggerStyles.disabled, style ), ...interaction, onPress, onLayout, children: (e) => typeof children === "function" ? children(e) : children } ) } ); }; const Text = ({ style, ...props }) => { const { size } = useTabsContext(); const state = useTriggerContext(); return /* @__PURE__ */ jsx( Button.Text, { style: composeStyles( tabTitleStyles.default, state.selected && tabTitleStyles.active, !state.selected && !state.disabled && state.hover && tabTitleStyles.hover, style ), size: size === "sm" ? "md" : "default", ...state, ...props } ); }; return withStaticProperties(TabImpl, { Text }); }; export { createTab }; //# sourceMappingURL=Tab.js.map