@crossed/ui
Version:
A universal & performant styling library for React Native, Next.js & React
221 lines (220 loc) • 6.54 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import Animated, {
FadeIn,
FadeOut,
useAnimatedReaction,
useSharedValue
} from "react-native-reanimated";
import {
composeStyles,
createStyles,
inlineStyle,
isTouchable
} from "@crossed/styled";
import { XBox } from "../../layout/XBox";
import { ScrollView } from "react-native-gesture-handler";
import { Box } from "../../layout/Box";
import { Button } from "../../buttons/Button";
import { useState } from "react";
import {
heightStyles,
linearGradientRounded,
linearGradientUnderline
} from "./styles";
import { ChevronLeft, ChevronRight } from "@crossed/unicons";
const styles = createStyles(() => ({
default: { base: { zIndex: 1 } }
}));
const ButtonScroll = ({
children,
style,
...rest
}) => {
return /* @__PURE__ */ jsx(
Animated.View,
{
entering: FadeIn,
exiting: FadeOut,
style,
...composeStyles(
inlineStyle(() => ({
base: {
position: "absolute",
top: 0,
bottom: 0,
zIndex: 100
}
})),
style
).style(),
children: /* @__PURE__ */ jsx(
Button,
{
variant: "tertiary",
style: composeStyles(
inlineStyle(() => ({
base: { paddingHorizontal: 0, height: "100%", width: 30 }
})),
rest.disabled && inlineStyle(() => ({ base: { opacity: 0.5 } }))
),
...rest,
children: /* @__PURE__ */ jsx(
Button.Icon,
{
style: inlineStyle(({ colors }) => ({
"base": { color: colors.text.secondary, flexShrink: 0 },
":hover": { color: colors.text.primary }
})),
children
}
)
}
)
}
);
};
const createList = (useTabsContext) => {
const PrevButton = ({
widthLayout
}) => {
const { listTabRef, scroll, variant } = useTabsContext();
const [disabled, setDisabled] = useState(false);
useAnimatedReaction(
() => {
return scroll.value;
},
(currentValue, previousValue) => {
if (currentValue !== previousValue) {
setDisabled(currentValue === 0);
}
},
[widthLayout, scroll]
);
const style = variant === "rounded" ? linearGradientRounded : linearGradientUnderline;
return /* @__PURE__ */ jsx(
ButtonScroll,
{
variant: "tertiary",
disabled,
testID: "toLeft",
"aria-label": "Slide to left",
style: style.prev,
onPress: () => {
var _a;
(_a = listTabRef.current) == null ? void 0 : _a.scrollTo({
x: scroll.value >= widthLayout.value ? scroll.value - widthLayout.value : 0
});
},
children: /* @__PURE__ */ jsx(ChevronLeft, {})
}
);
};
const NextButton = ({
widthLayout,
widthContent
}) => {
const { listTabRef, scroll, variant } = useTabsContext();
const [disabled, setDisabled] = useState(false);
useAnimatedReaction(
() => {
return scroll.value;
},
(currentValue, previousValue) => {
if (currentValue !== previousValue) {
setDisabled(currentValue + widthLayout.value >= widthContent.value);
}
},
[widthLayout, scroll, widthContent]
);
const style = variant === "rounded" ? linearGradientRounded : linearGradientUnderline;
return /* @__PURE__ */ jsx(
ButtonScroll,
{
variant: "tertiary",
disabled,
style: style.next,
testID: "toRight",
"aria-label": "Slide to right",
onPress: () => {
var _a, _b;
scroll.value <= widthLayout.value ? (_a = listTabRef.current) == null ? void 0 : _a.scrollTo({
x: scroll.value + widthLayout.value
}) : (_b = listTabRef.current) == null ? void 0 : _b.scrollToEnd();
},
children: /* @__PURE__ */ jsx(ChevronRight, {})
}
);
};
return ({ children, ...props }) => {
const { listTabRef, scroll, shouldShow, setShow, widthLayout, size } = useTabsContext();
const widthContent = useSharedValue(0);
useAnimatedReaction(
() => {
return widthLayout.value;
},
(currentValue, previousValue) => {
if (currentValue !== previousValue && !isTouchable) {
setShow(currentValue < widthContent.value);
}
},
[widthLayout, widthContent, setShow]
);
return /* @__PURE__ */ jsxs(
XBox,
{
justifyContent: "between",
style: composeStyles(styles.default, heightStyles[size]),
children: [
shouldShow && /* @__PURE__ */ jsx(PrevButton, { widthLayout }),
shouldShow && /* @__PURE__ */ jsx(NextButton, { widthLayout, widthContent }),
/* @__PURE__ */ jsxs(
ScrollView,
{
space: "md",
role: "tablist",
ref: listTabRef,
horizontal: true,
showsHorizontalScrollIndicator: false,
scrollEventThrottle: 16,
onScroll: ({ nativeEvent }) => {
scroll.value = nativeEvent.contentOffset.x;
},
onContentSizeChange: (width) => {
widthContent.value = width - (shouldShow ? 60 : 0);
},
onLayout: ({ nativeEvent: { layout } }) => {
widthLayout.value = layout.width;
},
stickyHeaderIndices: shouldShow ? [0] : [],
...props,
contentContainerStyle: composeStyles(
inlineStyle(() => ({ base: { alignItems: "center" } }))
).rnw().style,
...composeStyles(
shouldShow && inlineStyle(() => ({
base: {
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0,
zIndex: 30
}
}))
).rnw(),
children: [
shouldShow && /* @__PURE__ */ jsx(Box, { style: inlineStyle(() => ({ base: { width: 30 } })) }),
children,
shouldShow && /* @__PURE__ */ jsx(Box, { style: inlineStyle(() => ({ base: { width: 30 } })) })
]
}
)
]
}
);
};
};
export {
createList
};
//# sourceMappingURL=List.js.map