@fountain-ui/core 3.0.0-alpha.40 → 3.0.0-alpha.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commonjs/Tabs/Tabs.js +9 -4
- package/build/commonjs/Tabs/Tabs.js.map +1 -1
- package/build/commonjs/hooks/useCollapsibleAppBar.js +10 -0
- package/build/commonjs/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/module/Tabs/Tabs.js +10 -5
- package/build/module/Tabs/Tabs.js.map +1 -1
- package/build/module/hooks/useCollapsibleAppBar.js +10 -0
- package/build/module/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/typescript/Accordion/Accordion.d.ts +0 -1
- package/build/typescript/AspectRatio/AspectRatioNative.d.ts +0 -1
- package/build/typescript/AspectRatio/AspectRatioWeb.d.ts +0 -1
- package/build/typescript/Avatar/Avatar.d.ts +0 -1
- package/build/typescript/Badge/Badge.d.ts +0 -1
- package/build/typescript/BottomSheetActions/BottomSheetActions.d.ts +0 -1
- package/build/typescript/BottomSheetContent/BottomSheetContent.d.ts +0 -1
- package/build/typescript/BottomSheetTitle/BottomSheetTitle.d.ts +0 -1
- package/build/typescript/Button/Button.d.ts +0 -1
- package/build/typescript/ButtonBase/ButtonBase.d.ts +0 -1
- package/build/typescript/ButtonSet/ButtonSet.d.ts +0 -1
- package/build/typescript/Card/Card.d.ts +0 -1
- package/build/typescript/CardActions/CardActions.d.ts +0 -1
- package/build/typescript/CardContent/CardContent.d.ts +0 -1
- package/build/typescript/CardMedia/CardMedia.d.ts +0 -1
- package/build/typescript/Checkbox/Checkbox.d.ts +0 -1
- package/build/typescript/Chip/Chip.d.ts +0 -1
- package/build/typescript/CircularProgress/CircularProgress.d.ts +0 -1
- package/build/typescript/Column/Column.d.ts +0 -1
- package/build/typescript/Dialog/Dialog.d.ts +0 -1
- package/build/typescript/DialogActions/DialogActions.d.ts +0 -1
- package/build/typescript/DialogContent/DialogContent.d.ts +0 -1
- package/build/typescript/DialogMedia/DialogMedia.d.ts +0 -1
- package/build/typescript/DialogTitle/DialogLargeTitle.d.ts +0 -1
- package/build/typescript/DialogTitle/DialogTitle.d.ts +0 -1
- package/build/typescript/Divider/Divider.d.ts +0 -1
- package/build/typescript/Empty/Empty.d.ts +0 -1
- package/build/typescript/Fab/Fab.d.ts +0 -1
- package/build/typescript/Flexbox/Flexbox.d.ts +0 -1
- package/build/typescript/IconButton/IconButton.d.ts +0 -1
- package/build/typescript/Image/Image.d.ts +0 -1
- package/build/typescript/ImageCore/ImageCoreNative.d.ts +0 -1
- package/build/typescript/ImageCore/ImageCoreWeb.d.ts +0 -1
- package/build/typescript/Link/Link.d.ts +0 -1
- package/build/typescript/List/List.d.ts +0 -1
- package/build/typescript/ListItem/ListItem.d.ts +0 -1
- package/build/typescript/ListItemIcon/ListItemIcon.d.ts +0 -1
- package/build/typescript/ListItemSecondaryAction/ListItemSecondaryAction.d.ts +0 -1
- package/build/typescript/ListItemText/ListItemText.d.ts +0 -1
- package/build/typescript/ListSubheader/ListSubheader.d.ts +0 -1
- package/build/typescript/Menu/Menu.d.ts +0 -1
- package/build/typescript/MenuItem/MenuItem.d.ts +0 -1
- package/build/typescript/Modal/AnimatedContainer/index.d.ts +0 -1
- package/build/typescript/Modal/Modal.d.ts +0 -1
- package/build/typescript/Pagination/NumberPagination.d.ts +0 -1
- package/build/typescript/Pagination/Pagination.d.ts +0 -1
- package/build/typescript/Portal/Portal.d.ts +0 -1
- package/build/typescript/Radio/Radio.d.ts +0 -1
- package/build/typescript/RadioGroup/RadioGroup.d.ts +0 -1
- package/build/typescript/Row/Row.d.ts +0 -1
- package/build/typescript/Section/Section.d.ts +0 -1
- package/build/typescript/ShadowView/ShadowView.d.ts +0 -1
- package/build/typescript/ShadowView/ShadowView.native.d.ts +0 -1
- package/build/typescript/Slide/Slide.d.ts +0 -1
- package/build/typescript/Snackbar/Snackbar.d.ts +0 -1
- package/build/typescript/SnackbarContent/SnackbarContent.d.ts +0 -1
- package/build/typescript/SnackbarContent/StatusIcon.d.ts +0 -1
- package/build/typescript/Spacer/Spacer.d.ts +0 -1
- package/build/typescript/SvgIcon/SvgIcon.d.ts +0 -1
- package/build/typescript/Switch/Switch.d.ts +0 -1
- package/build/typescript/Tab/Tab.d.ts +0 -1
- package/build/typescript/TabBase/TabBase.d.ts +0 -1
- package/build/typescript/Tabs/ScrollableTabsView.d.ts +0 -1
- package/build/typescript/Tabs/TabIndicator.d.ts +0 -1
- package/build/typescript/Toggle/Toggle.d.ts +0 -1
- package/build/typescript/Toolbar/BackButton/BackButton.d.ts +0 -1
- package/build/typescript/Toolbar/Toolbar.d.ts +0 -1
- package/build/typescript/Tooltip/Beaks/Beak.d.ts +0 -1
- package/build/typescript/Tooltip/Beaks/HorizontalLargeBeak.d.ts +0 -1
- package/build/typescript/Tooltip/Beaks/HorizontalSmallBeak.d.ts +0 -1
- package/build/typescript/Tooltip/Beaks/VerticalLargeBeak.d.ts +0 -1
- package/build/typescript/Tooltip/Beaks/VerticalSmallBeak.d.ts +0 -1
- package/build/typescript/Tooltip/Tooltip.d.ts +0 -1
- package/build/typescript/hooks/useCollapsibleAppBar.d.ts +1 -0
- package/build/typescript/internal/icons/CircularProgress.d.ts +0 -1
- package/build/typescript/internal/icons/LoadingSpinner/index.d.ts +0 -1
- package/build/typescript/internal/icons/LoadingSpinner/index.native.d.ts +0 -1
- package/package.json +2 -2
- package/src/Tabs/Tabs.tsx +14 -5
- package/src/hooks/useCollapsibleAppBar.ts +17 -0
|
@@ -42,14 +42,16 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
42
42
|
const useStyles = function () {
|
|
43
43
|
const theme = (0, _styles.useTheme)();
|
|
44
44
|
return {
|
|
45
|
-
root: {
|
|
45
|
+
root: {
|
|
46
|
+
position: 'relative'
|
|
47
|
+
},
|
|
46
48
|
fixedRoot: {
|
|
47
49
|
flexDirection: 'row'
|
|
48
50
|
},
|
|
49
51
|
fixedTab: {
|
|
50
52
|
flex: 1
|
|
51
53
|
},
|
|
52
|
-
|
|
54
|
+
borderContainer: { ..._reactNative.StyleSheet.absoluteFillObject,
|
|
53
55
|
borderBottomColor: theme.palette.border.base,
|
|
54
56
|
borderBottomWidth: 0.5
|
|
55
57
|
}
|
|
@@ -213,7 +215,7 @@ const Tabs = /*#__PURE__*/(0, _react.forwardRef)(function Tabs(props, ref) {
|
|
|
213
215
|
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
214
216
|
style: (0, _styles.css)([styles.root, containerStyle, {
|
|
215
217
|
backgroundColor: backgroundColorMap[color]
|
|
216
|
-
},
|
|
218
|
+
}, scrollable ? undefined : styles.fixedRoot, style])
|
|
217
219
|
}, scrollable ? /*#__PURE__*/_react.default.createElement(_ScrollableTabsView.default, {
|
|
218
220
|
automaticallyAdjustContentInsets: false,
|
|
219
221
|
bounces: false,
|
|
@@ -227,7 +229,10 @@ const Tabs = /*#__PURE__*/(0, _react.forwardRef)(function Tabs(props, ref) {
|
|
|
227
229
|
showsVerticalScrollIndicator: false,
|
|
228
230
|
keyboardDismissMode: keyboardDismissMode,
|
|
229
231
|
keyboardShouldPersistTaps: keyboardShouldPersistTaps
|
|
230
|
-
}, tabElements, tabIndicator) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, tabElements, tabIndicator)
|
|
232
|
+
}, tabElements, tabIndicator) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, tabElements, tabIndicator), showDivider ? /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
233
|
+
pointerEvents: 'none',
|
|
234
|
+
style: styles.borderContainer
|
|
235
|
+
}) : null));
|
|
231
236
|
});
|
|
232
237
|
var _default = Tabs;
|
|
233
238
|
exports.default = _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useStyles","theme","useTheme","root","fixedRoot","flexDirection","fixedTab","flex","bottomDivider","borderBottomColor","palette","border","base","borderBottomWidth","Tabs","forwardRef","props","ref","children","color","initialIndex","disableIndicator","indicatorSize","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","scrollViewContentContainerStyle","showDivider","size","style","variant","UNSTABLE_sharedIndex","onTabSelected","fallbackSharedIndex","useSyncAnimatedValue","initialValue","sharedIndex","realInitialIndex","currentIndexRef","useRef","container","containerStyle","contentContainer","contentContainerStyle","useTabsStyle","setTab","newIndex","currentIndex","current","animatedValue","setValue","useImperativeHandle","styles","outerCoordinates","updateCoordinate","useTabCoordinates","innerContentsWidthList","updateInnerContentsWidth","useTabInnerContentsWidth","canRenderIndicator","isEveryTabCoordinatesDefined","indexStore","useIndexStore","coordinates","useMemo","length","map","innerContentWidth","idx","outerCoordinate","defaultCoordinate","x1","outerX1","x2","outerX2","tabWidth","distanceFromParent","indicatorStartCoordinate","useEffect","subscribe","tabElements","React","Children","child","index","onTabInnerLayout","event","width","nativeEvent","layout","onLayout","x","onMouseDown","e","preventDefault","onPress","tabStyle","tabElement","cloneElement","enableIndicator","parentColor","css","undefined","filter","Boolean","tabIndicator","backgroundColorMap","default","background","alt","backgroundColor"],"sources":["Tabs.tsx"],"sourcesContent":["import React, { cloneElement, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';\nimport type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';\nimport { View } from 'react-native';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { css, useTheme } from '../styles';\nimport { useSyncAnimatedValue } from '../hooks';\nimport type { TabSize, TabVariant } from '../Tab';\nimport type TabsProps from './TabsProps';\nimport type { TabsColor } from './TabsProps';\nimport type { TabsInstance } from './types';\nimport TabIndicator from './TabIndicator';\nimport ScrollableTabsView from './ScrollableTabsView';\nimport IndexAwareTab from './IndexAwareTab';\nimport useTabCoordinates from './useTabCoordinates';\nimport useTabInnerContentsWidth from './useTabInnerContentsWidth';\nimport useIndexStore from './useIndexStore';\nimport InternalContext from './InternalContext';\nimport { isEveryTabCoordinatesDefined } from './utils';\nimport { defaultCoordinate } from './TabCoordinate';\nimport useTabsStyle from './useTabsStyle';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'bottomDivider';\n\ntype TabsStyles = NamedStylesStringUnion<TabsStyleKeys>;\n\nconst useStyles: UseStyles<TabsStyles> = function (): TabsStyles {\n const theme = useTheme();\n\n return {\n root: {},\n fixedRoot: {\n flexDirection: 'row',\n },\n fixedTab: {\n flex: 1,\n },\n bottomDivider: {\n borderBottomColor: theme.palette.border.base,\n borderBottomWidth: 0.5,\n },\n };\n};\n\nconst Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {\n const {\n children,\n color = 'default',\n initialIndex = 0,\n disableIndicator = false,\n indicatorSize = 'fit-content',\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n scrollViewContentContainerStyle,\n showDivider = false,\n size = 'medium' as TabSize,\n style,\n variant = 'default' as TabVariant,\n UNSTABLE_sharedIndex,\n onTabSelected,\n } = props;\n\n const fallbackSharedIndex = useSyncAnimatedValue({ initialValue: initialIndex });\n const sharedIndex = UNSTABLE_sharedIndex ?? fallbackSharedIndex;\n const realInitialIndex = sharedIndex.initialValue;\n\n const currentIndexRef = useRef(initialIndex);\n\n const {\n container: containerStyle,\n contentContainer: contentContainerStyle,\n } = useTabsStyle(variant, size, scrollable);\n\n const setTab = (newIndex: number) => {\n const currentIndex = currentIndexRef.current;\n onTabSelected?.(newIndex, currentIndex);\n\n sharedIndex.animatedValue.setValue(newIndex);\n };\n\n useImperativeHandle(\n ref,\n () => ({\n setTab,\n }),\n [sharedIndex],\n );\n\n const styles = useStyles();\n\n const theme = useTheme();\n\n const [outerCoordinates, updateCoordinate] = useTabCoordinates(children);\n const [innerContentsWidthList, updateInnerContentsWidth] = useTabInnerContentsWidth(children);\n\n const canRenderIndicator = indicatorSize === 'fit-content'\n ? isEveryTabCoordinatesDefined(innerContentsWidthList, children)\n : isEveryTabCoordinatesDefined(outerCoordinates, children);\n\n const indexStore = useIndexStore(sharedIndex);\n\n const coordinates = useMemo(() => {\n if (outerCoordinates.length === 0) {\n return [];\n }\n\n if (indicatorSize !== 'fit-content') {\n return outerCoordinates;\n }\n\n return innerContentsWidthList.map((innerContentWidth, idx) => {\n const outerCoordinate = outerCoordinates[idx];\n if (!outerCoordinate) {\n return defaultCoordinate;\n }\n\n const { x1: outerX1, x2: outerX2 } = outerCoordinate;\n\n const tabWidth = outerX2 - outerX1;\n const distanceFromParent = (tabWidth - innerContentWidth) / 2;\n const indicatorStartCoordinate = outerX1 + distanceFromParent;\n\n return {\n x1: indicatorStartCoordinate,\n x2: indicatorStartCoordinate + innerContentWidth,\n };\n });\n }, [outerCoordinates, innerContentsWidthList]);\n\n useEffect(() => {\n return indexStore.subscribe(newIndex => {\n onChange?.(newIndex);\n currentIndexRef.current = newIndex;\n });\n }, [indexStore, onChange]);\n\n const tabElements = React.Children.map(children, (child, index) => {\n if (!child) {\n return null;\n }\n\n const onTabInnerLayout = (event: LayoutChangeEvent) => {\n const { width } = event.nativeEvent.layout;\n\n updateInnerContentsWidth(index, width);\n };\n\n const onLayout = (event: LayoutChangeEvent) => {\n const { x, width } = event.nativeEvent.layout;\n\n updateCoordinate(index, x, width);\n\n // @ts-ignore\n child.props.onLayout?.(event);\n };\n\n const onMouseDown = (e: GestureResponderEvent) => {\n if (keyboardShouldPersistTaps === 'always') {\n e.preventDefault();\n }\n };\n\n const onPress = () => {\n setTab(index);\n\n // @ts-ignore\n child.props.onPress?.();\n };\n\n // @ts-ignore\n const tabStyle = child.props.style;\n\n // @ts-ignore\n const tabElement = cloneElement(child, {\n enableIndicator: !disableIndicator && !canRenderIndicator,\n onTabInnerLayout,\n onLayout,\n onPress,\n onMouseDown,\n parentColor: color,\n size,\n variant,\n indicatorSize,\n style: css([\n scrollable ? undefined : styles.fixedTab,\n tabStyle,\n ]),\n });\n\n return (\n <IndexAwareTab\n children={tabElement}\n index={index}\n initialIndex={realInitialIndex}\n />\n );\n })?.filter(Boolean);\n\n const tabIndicator = canRenderIndicator ? (\n <TabIndicator\n coordinates={coordinates}\n disabled={disableIndicator}\n initialIndex={realInitialIndex}\n />\n ) : null;\n\n const backgroundColorMap: Record<TabsColor, string> = {\n default: theme.palette.background.base,\n alt: theme.palette.background.alt,\n };\n\n return (\n <InternalContext.Provider value={{ indexStore }}>\n <View\n style={css([\n styles.root,\n containerStyle,\n { backgroundColor: backgroundColorMap[color] },\n showDivider ? styles.bottomDivider : undefined,\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n >\n {scrollable ? (\n <ScrollableTabsView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={css([\n contentContainerStyle,\n scrollViewContentContainerStyle,\n ])}\n coordinates={coordinates}\n directionalLockEnabled={true}\n horizontal={true}\n initialIndex={realInitialIndex}\n scrollsToTop={false}\n showsHorizontalScrollIndicator={false}\n showsVerticalScrollIndicator={false}\n keyboardDismissMode={keyboardDismissMode}\n keyboardShouldPersistTaps={keyboardShouldPersistTaps}\n >\n {tabElements}\n {tabIndicator}\n </ScrollableTabsView>\n ) : (\n <React.Fragment>\n {tabElements}\n {tabIndicator}\n </React.Fragment>\n )}\n </View>\n </InternalContext.Provider>\n );\n});\n\nexport default Tabs;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["useStyles","theme","useTheme","root","position","fixedRoot","flexDirection","fixedTab","flex","borderContainer","StyleSheet","absoluteFillObject","borderBottomColor","palette","border","base","borderBottomWidth","Tabs","forwardRef","props","ref","children","color","initialIndex","disableIndicator","indicatorSize","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","scrollViewContentContainerStyle","showDivider","size","style","variant","UNSTABLE_sharedIndex","onTabSelected","fallbackSharedIndex","useSyncAnimatedValue","initialValue","sharedIndex","realInitialIndex","currentIndexRef","useRef","container","containerStyle","contentContainer","contentContainerStyle","useTabsStyle","setTab","newIndex","currentIndex","current","animatedValue","setValue","useImperativeHandle","styles","outerCoordinates","updateCoordinate","useTabCoordinates","innerContentsWidthList","updateInnerContentsWidth","useTabInnerContentsWidth","canRenderIndicator","isEveryTabCoordinatesDefined","indexStore","useIndexStore","coordinates","useMemo","length","map","innerContentWidth","idx","outerCoordinate","defaultCoordinate","x1","outerX1","x2","outerX2","tabWidth","distanceFromParent","indicatorStartCoordinate","useEffect","subscribe","tabElements","React","Children","child","index","onTabInnerLayout","event","width","nativeEvent","layout","onLayout","x","onMouseDown","e","preventDefault","onPress","tabStyle","tabElement","cloneElement","enableIndicator","parentColor","css","undefined","filter","Boolean","tabIndicator","backgroundColorMap","default","background","alt","backgroundColor"],"sources":["Tabs.tsx"],"sourcesContent":["import React, { cloneElement, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';\nimport type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';\nimport { StyleSheet, View } from 'react-native';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { css, useTheme } from '../styles';\nimport { useSyncAnimatedValue } from '../hooks';\nimport type { TabSize, TabVariant } from '../Tab';\nimport type TabsProps from './TabsProps';\nimport type { TabsColor } from './TabsProps';\nimport type { TabsInstance } from './types';\nimport TabIndicator from './TabIndicator';\nimport ScrollableTabsView from './ScrollableTabsView';\nimport IndexAwareTab from './IndexAwareTab';\nimport useTabCoordinates from './useTabCoordinates';\nimport useTabInnerContentsWidth from './useTabInnerContentsWidth';\nimport useIndexStore from './useIndexStore';\nimport InternalContext from './InternalContext';\nimport { isEveryTabCoordinatesDefined } from './utils';\nimport { defaultCoordinate } from './TabCoordinate';\nimport useTabsStyle from './useTabsStyle';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'borderContainer';\n\ntype TabsStyles = NamedStylesStringUnion<TabsStyleKeys>;\n\nconst useStyles: UseStyles<TabsStyles> = function (): TabsStyles {\n const theme = useTheme();\n\n return {\n root: {\n position: 'relative',\n },\n fixedRoot: {\n flexDirection: 'row',\n },\n fixedTab: {\n flex: 1,\n },\n borderContainer: {\n ...StyleSheet.absoluteFillObject,\n borderBottomColor: theme.palette.border.base,\n borderBottomWidth: 0.5,\n },\n };\n};\n\nconst Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {\n const {\n children,\n color = 'default',\n initialIndex = 0,\n disableIndicator = false,\n indicatorSize = 'fit-content',\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n scrollViewContentContainerStyle,\n showDivider = false,\n size = 'medium' as TabSize,\n style,\n variant = 'default' as TabVariant,\n UNSTABLE_sharedIndex,\n onTabSelected,\n } = props;\n\n const fallbackSharedIndex = useSyncAnimatedValue({ initialValue: initialIndex });\n const sharedIndex = UNSTABLE_sharedIndex ?? fallbackSharedIndex;\n const realInitialIndex = sharedIndex.initialValue;\n\n const currentIndexRef = useRef(initialIndex);\n\n const {\n container: containerStyle,\n contentContainer: contentContainerStyle,\n } = useTabsStyle(variant, size, scrollable);\n\n const setTab = (newIndex: number) => {\n const currentIndex = currentIndexRef.current;\n onTabSelected?.(newIndex, currentIndex);\n\n sharedIndex.animatedValue.setValue(newIndex);\n };\n\n useImperativeHandle(\n ref,\n () => ({\n setTab,\n }),\n [sharedIndex],\n );\n\n const styles = useStyles();\n\n const theme = useTheme();\n\n const [outerCoordinates, updateCoordinate] = useTabCoordinates(children);\n const [innerContentsWidthList, updateInnerContentsWidth] = useTabInnerContentsWidth(children);\n\n const canRenderIndicator = indicatorSize === 'fit-content'\n ? isEveryTabCoordinatesDefined(innerContentsWidthList, children)\n : isEveryTabCoordinatesDefined(outerCoordinates, children);\n\n const indexStore = useIndexStore(sharedIndex);\n\n const coordinates = useMemo(() => {\n if (outerCoordinates.length === 0) {\n return [];\n }\n\n if (indicatorSize !== 'fit-content') {\n return outerCoordinates;\n }\n\n return innerContentsWidthList.map((innerContentWidth, idx) => {\n const outerCoordinate = outerCoordinates[idx];\n if (!outerCoordinate) {\n return defaultCoordinate;\n }\n\n const { x1: outerX1, x2: outerX2 } = outerCoordinate;\n\n const tabWidth = outerX2 - outerX1;\n const distanceFromParent = (tabWidth - innerContentWidth) / 2;\n const indicatorStartCoordinate = outerX1 + distanceFromParent;\n\n return {\n x1: indicatorStartCoordinate,\n x2: indicatorStartCoordinate + innerContentWidth,\n };\n });\n }, [outerCoordinates, innerContentsWidthList]);\n\n useEffect(() => {\n return indexStore.subscribe(newIndex => {\n onChange?.(newIndex);\n currentIndexRef.current = newIndex;\n });\n }, [indexStore, onChange]);\n\n const tabElements = React.Children.map(children, (child, index) => {\n if (!child) {\n return null;\n }\n\n const onTabInnerLayout = (event: LayoutChangeEvent) => {\n const { width } = event.nativeEvent.layout;\n\n updateInnerContentsWidth(index, width);\n };\n\n const onLayout = (event: LayoutChangeEvent) => {\n const { x, width } = event.nativeEvent.layout;\n\n updateCoordinate(index, x, width);\n\n // @ts-ignore\n child.props.onLayout?.(event);\n };\n\n const onMouseDown = (e: GestureResponderEvent) => {\n if (keyboardShouldPersistTaps === 'always') {\n e.preventDefault();\n }\n };\n\n const onPress = () => {\n setTab(index);\n\n // @ts-ignore\n child.props.onPress?.();\n };\n\n // @ts-ignore\n const tabStyle = child.props.style;\n\n // @ts-ignore\n const tabElement = cloneElement(child, {\n enableIndicator: !disableIndicator && !canRenderIndicator,\n onTabInnerLayout,\n onLayout,\n onPress,\n onMouseDown,\n parentColor: color,\n size,\n variant,\n indicatorSize,\n style: css([\n scrollable ? undefined : styles.fixedTab,\n tabStyle,\n ]),\n });\n\n return (\n <IndexAwareTab\n children={tabElement}\n index={index}\n initialIndex={realInitialIndex}\n />\n );\n })?.filter(Boolean);\n\n const tabIndicator = canRenderIndicator ? (\n <TabIndicator\n coordinates={coordinates}\n disabled={disableIndicator}\n initialIndex={realInitialIndex}\n />\n ) : null;\n\n const backgroundColorMap: Record<TabsColor, string> = {\n default: theme.palette.background.base,\n alt: theme.palette.background.alt,\n };\n\n return (\n <InternalContext.Provider value={{ indexStore }}>\n <View\n style={css([\n styles.root,\n containerStyle,\n { backgroundColor: backgroundColorMap[color] },\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n >\n {scrollable ? (\n <ScrollableTabsView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={css([\n contentContainerStyle,\n scrollViewContentContainerStyle,\n ])}\n coordinates={coordinates}\n directionalLockEnabled={true}\n horizontal={true}\n initialIndex={realInitialIndex}\n scrollsToTop={false}\n showsHorizontalScrollIndicator={false}\n showsVerticalScrollIndicator={false}\n keyboardDismissMode={keyboardDismissMode}\n keyboardShouldPersistTaps={keyboardShouldPersistTaps}\n >\n {tabElements}\n {tabIndicator}\n </ScrollableTabsView>\n ) : (\n <React.Fragment>\n {tabElements}\n {tabIndicator}\n </React.Fragment>\n )}\n\n {showDivider ? (\n <View\n pointerEvents={'none'}\n style={styles.borderContainer}\n />\n ) : null}\n </View>\n </InternalContext.Provider>\n );\n});\n\nexport default Tabs;\n"],"mappings":"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"}
|
|
@@ -82,6 +82,15 @@ function useCollapsibleAppBar() {
|
|
|
82
82
|
translateY.value = (0, _reactNativeReanimated.withTiming)(0, ANIMATION_CONFIG);
|
|
83
83
|
}
|
|
84
84
|
}, [appBarHeight]);
|
|
85
|
+
const recoverAppBar = (0, _react.useCallback)(() => {
|
|
86
|
+
const currentIndex = indexRef.current;
|
|
87
|
+
offsetsRef.current[currentIndex] = 0;
|
|
88
|
+
lastOffsetY.value = 0;
|
|
89
|
+
translateY.value = (0, _reactNativeReanimated.withTiming)(0, ANIMATION_CONFIG);
|
|
90
|
+
lastTranslateY.value = 0;
|
|
91
|
+
overlapped.value = false;
|
|
92
|
+
setIsScrolled(false);
|
|
93
|
+
}, []);
|
|
85
94
|
const scrollHandler = (0, _reactNativeReanimated.useAnimatedScrollHandler)({
|
|
86
95
|
onBeginDrag: () => {
|
|
87
96
|
if (keyboardDismissMode === 'on-drag') {
|
|
@@ -150,6 +159,7 @@ function useCollapsibleAppBar() {
|
|
|
150
159
|
onCollapsibleToolbarLayout,
|
|
151
160
|
onScroll: scrollHandler,
|
|
152
161
|
onScrollViewChanged,
|
|
162
|
+
recoverAppBar,
|
|
153
163
|
scrollContentInsets: {
|
|
154
164
|
top: hasCollapsible ? appBarHeight : 0
|
|
155
165
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["defaultOptions","keyboardDismissMode","supportsReverseScroll","minVisibleHeight","ANIMATION_CONFIG","duration","TRANSPARENT","SUPPORTS_DRAG_DETECTION","Platform","OS","dismissKeyboard","Keyboard","dismiss","useCollapsibleAppBar","userOptions","styles","useAppbarStyles","safeAreaInsets","useSafeAreaInsets","appBarHeight","onAppBarLayout","useHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","useDerivedValue","safeMinVisibleHeight","Math","min","translateY","useSharedValue","lastTranslateY","lastOffsetY","overlapped","isScrolled","setIsScrolled","useState","animatedStyle","useAnimatedStyle","transform","value","indexRef","useRef","offsetsRef","onScrollViewChanged","useCallback","nextIndex","prevIndex","current","savedOffsetY","withTiming","scrollHandler","useAnimatedScrollHandler","onBeginDrag","runOnJS","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","maxTy","dy","max","minOffsetY","maxOffsetY","contentSize","height","layoutMeasurement","safeOffsetY","safeLastOffsetY","newTranslateY","onEndDrag","onMomentumEnd","ty","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n supportsReverseScroll?: boolean;\n minVisibleHeight?: number;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n isScrolled: boolean;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n supportsReverseScroll: true,\n minVisibleHeight: 0,\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\nconst TRANSPARENT = '#FFFFFF00';\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\nconst dismissKeyboard = () => Keyboard.dismiss();\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode, supportsReverseScroll, minVisibleHeight }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => {\n const safeMinVisibleHeight = Math.min(minVisibleHeight, collapsibleToolbarHeight);\n return -(collapsibleToolbarHeight - safeMinVisibleHeight);\n }, [collapsibleToolbarHeight, minVisibleHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const [isScrolled, setIsScrolled] = useState<boolean>(false);\n\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n return {\n transform,\n };\n }, [translateY]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }, [appBarHeight]);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(dismissKeyboard)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n if (!isScrolled && offsetY > 0) {\n runOnJS(setIsScrolled)(true);\n } else if (isScrolled && offsetY <= 0) {\n runOnJS(setIsScrolled)(false);\n }\n\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n const minOffsetY = -maxTy;\n const maxOffsetY = event.contentSize.height - event.layoutMeasurement.height;\n\n const safeOffsetY = Math.min(Math.max(offsetY, minOffsetY), maxOffsetY);\n const safeLastOffsetY = Math.min(Math.max(lastOffsetY.value, minOffsetY), maxOffsetY);\n const dy = safeOffsetY - safeLastOffsetY;\n\n const newTranslateY = safeOffsetY <= minOffsetY\n ? 0\n : supportsReverseScroll\n ? dy === 0\n ? lastTranslateY.value\n : dy > 0\n ? maxTy\n : 0\n : maxTy;\n\n translateY.value = withTiming(newTranslateY, ANIMATION_CONFIG);\n lastTranslateY.value = newTranslateY;\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n });\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n isScrolled,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["defaultOptions","keyboardDismissMode","supportsReverseScroll","minVisibleHeight","ANIMATION_CONFIG","duration","TRANSPARENT","SUPPORTS_DRAG_DETECTION","Platform","OS","dismissKeyboard","Keyboard","dismiss","useCollapsibleAppBar","userOptions","styles","useAppbarStyles","safeAreaInsets","useSafeAreaInsets","appBarHeight","onAppBarLayout","useHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","useDerivedValue","safeMinVisibleHeight","Math","min","translateY","useSharedValue","lastTranslateY","lastOffsetY","overlapped","isScrolled","setIsScrolled","useState","animatedStyle","useAnimatedStyle","transform","value","indexRef","useRef","offsetsRef","onScrollViewChanged","useCallback","nextIndex","prevIndex","current","savedOffsetY","withTiming","recoverAppBar","currentIndex","scrollHandler","useAnimatedScrollHandler","onBeginDrag","runOnJS","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","maxTy","dy","max","minOffsetY","maxOffsetY","contentSize","height","layoutMeasurement","safeOffsetY","safeLastOffsetY","newTranslateY","onEndDrag","onMomentumEnd","ty","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n supportsReverseScroll?: boolean;\n minVisibleHeight?: number;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n recoverAppBar: () => void;\n scrollContentInsets: ContentInsets;\n isScrolled: boolean;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n supportsReverseScroll: true,\n minVisibleHeight: 0,\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\nconst TRANSPARENT = '#FFFFFF00';\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\nconst dismissKeyboard = () => Keyboard.dismiss();\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode, supportsReverseScroll, minVisibleHeight }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => {\n const safeMinVisibleHeight = Math.min(minVisibleHeight, collapsibleToolbarHeight);\n return -(collapsibleToolbarHeight - safeMinVisibleHeight);\n }, [collapsibleToolbarHeight, minVisibleHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const [isScrolled, setIsScrolled] = useState<boolean>(false);\n\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n return {\n transform,\n };\n }, [translateY]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }, [appBarHeight]);\n\n const recoverAppBar = useCallback(() => {\n const currentIndex = indexRef.current;\n\n offsetsRef.current[currentIndex] = 0;\n\n lastOffsetY.value = 0;\n\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n lastTranslateY.value = 0;\n\n overlapped.value = false;\n\n setIsScrolled(false);\n }, []);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(dismissKeyboard)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n if (!isScrolled && offsetY > 0) {\n runOnJS(setIsScrolled)(true);\n } else if (isScrolled && offsetY <= 0) {\n runOnJS(setIsScrolled)(false);\n }\n\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n const minOffsetY = -maxTy;\n const maxOffsetY = event.contentSize.height - event.layoutMeasurement.height;\n\n const safeOffsetY = Math.min(Math.max(offsetY, minOffsetY), maxOffsetY);\n const safeLastOffsetY = Math.min(Math.max(lastOffsetY.value, minOffsetY), maxOffsetY);\n const dy = safeOffsetY - safeLastOffsetY;\n\n const newTranslateY = safeOffsetY <= minOffsetY\n ? 0\n : supportsReverseScroll\n ? dy === 0\n ? lastTranslateY.value\n : dy > 0\n ? maxTy\n : 0\n : maxTy;\n\n translateY.value = withTiming(newTranslateY, ANIMATION_CONFIG);\n lastTranslateY.value = newTranslateY;\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n });\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n recoverAppBar,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n isScrolled,\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { cloneElement, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
|
2
|
-
import { View } from 'react-native';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import { css, useTheme } from '../styles';
|
|
4
4
|
import { useSyncAnimatedValue } from '../hooks';
|
|
5
5
|
import TabIndicator from './TabIndicator';
|
|
@@ -16,14 +16,16 @@ import useTabsStyle from './useTabsStyle';
|
|
|
16
16
|
const useStyles = function () {
|
|
17
17
|
const theme = useTheme();
|
|
18
18
|
return {
|
|
19
|
-
root: {
|
|
19
|
+
root: {
|
|
20
|
+
position: 'relative'
|
|
21
|
+
},
|
|
20
22
|
fixedRoot: {
|
|
21
23
|
flexDirection: 'row'
|
|
22
24
|
},
|
|
23
25
|
fixedTab: {
|
|
24
26
|
flex: 1
|
|
25
27
|
},
|
|
26
|
-
|
|
28
|
+
borderContainer: { ...StyleSheet.absoluteFillObject,
|
|
27
29
|
borderBottomColor: theme.palette.border.base,
|
|
28
30
|
borderBottomWidth: 0.5
|
|
29
31
|
}
|
|
@@ -187,7 +189,7 @@ const Tabs = /*#__PURE__*/forwardRef(function Tabs(props, ref) {
|
|
|
187
189
|
}, /*#__PURE__*/React.createElement(View, {
|
|
188
190
|
style: css([styles.root, containerStyle, {
|
|
189
191
|
backgroundColor: backgroundColorMap[color]
|
|
190
|
-
},
|
|
192
|
+
}, scrollable ? undefined : styles.fixedRoot, style])
|
|
191
193
|
}, scrollable ? /*#__PURE__*/React.createElement(ScrollableTabsView, {
|
|
192
194
|
automaticallyAdjustContentInsets: false,
|
|
193
195
|
bounces: false,
|
|
@@ -201,7 +203,10 @@ const Tabs = /*#__PURE__*/forwardRef(function Tabs(props, ref) {
|
|
|
201
203
|
showsVerticalScrollIndicator: false,
|
|
202
204
|
keyboardDismissMode: keyboardDismissMode,
|
|
203
205
|
keyboardShouldPersistTaps: keyboardShouldPersistTaps
|
|
204
|
-
}, tabElements, tabIndicator) : /*#__PURE__*/React.createElement(React.Fragment, null, tabElements, tabIndicator)
|
|
206
|
+
}, tabElements, tabIndicator) : /*#__PURE__*/React.createElement(React.Fragment, null, tabElements, tabIndicator), showDivider ? /*#__PURE__*/React.createElement(View, {
|
|
207
|
+
pointerEvents: 'none',
|
|
208
|
+
style: styles.borderContainer
|
|
209
|
+
}) : null));
|
|
205
210
|
});
|
|
206
211
|
export default Tabs;
|
|
207
212
|
//# sourceMappingURL=Tabs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","cloneElement","forwardRef","useEffect","useImperativeHandle","useMemo","useRef","View","css","useTheme","useSyncAnimatedValue","TabIndicator","ScrollableTabsView","IndexAwareTab","useTabCoordinates","useTabInnerContentsWidth","useIndexStore","InternalContext","isEveryTabCoordinatesDefined","defaultCoordinate","useTabsStyle","useStyles","theme","root","fixedRoot","flexDirection","fixedTab","flex","bottomDivider","borderBottomColor","palette","border","base","borderBottomWidth","Tabs","props","ref","children","color","initialIndex","disableIndicator","indicatorSize","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","scrollViewContentContainerStyle","showDivider","size","style","variant","UNSTABLE_sharedIndex","onTabSelected","fallbackSharedIndex","initialValue","sharedIndex","realInitialIndex","currentIndexRef","container","containerStyle","contentContainer","contentContainerStyle","setTab","newIndex","currentIndex","current","animatedValue","setValue","styles","outerCoordinates","updateCoordinate","innerContentsWidthList","updateInnerContentsWidth","canRenderIndicator","indexStore","coordinates","length","map","innerContentWidth","idx","outerCoordinate","x1","outerX1","x2","outerX2","tabWidth","distanceFromParent","indicatorStartCoordinate","subscribe","tabElements","Children","child","index","onTabInnerLayout","event","width","nativeEvent","layout","onLayout","x","onMouseDown","e","preventDefault","onPress","tabStyle","tabElement","enableIndicator","parentColor","undefined","filter","Boolean","tabIndicator","backgroundColorMap","default","background","alt","backgroundColor"],"sources":["Tabs.tsx"],"sourcesContent":["import React, { cloneElement, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';\nimport type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';\nimport { View } from 'react-native';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { css, useTheme } from '../styles';\nimport { useSyncAnimatedValue } from '../hooks';\nimport type { TabSize, TabVariant } from '../Tab';\nimport type TabsProps from './TabsProps';\nimport type { TabsColor } from './TabsProps';\nimport type { TabsInstance } from './types';\nimport TabIndicator from './TabIndicator';\nimport ScrollableTabsView from './ScrollableTabsView';\nimport IndexAwareTab from './IndexAwareTab';\nimport useTabCoordinates from './useTabCoordinates';\nimport useTabInnerContentsWidth from './useTabInnerContentsWidth';\nimport useIndexStore from './useIndexStore';\nimport InternalContext from './InternalContext';\nimport { isEveryTabCoordinatesDefined } from './utils';\nimport { defaultCoordinate } from './TabCoordinate';\nimport useTabsStyle from './useTabsStyle';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'bottomDivider';\n\ntype TabsStyles = NamedStylesStringUnion<TabsStyleKeys>;\n\nconst useStyles: UseStyles<TabsStyles> = function (): TabsStyles {\n const theme = useTheme();\n\n return {\n root: {},\n fixedRoot: {\n flexDirection: 'row',\n },\n fixedTab: {\n flex: 1,\n },\n bottomDivider: {\n borderBottomColor: theme.palette.border.base,\n borderBottomWidth: 0.5,\n },\n };\n};\n\nconst Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {\n const {\n children,\n color = 'default',\n initialIndex = 0,\n disableIndicator = false,\n indicatorSize = 'fit-content',\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n scrollViewContentContainerStyle,\n showDivider = false,\n size = 'medium' as TabSize,\n style,\n variant = 'default' as TabVariant,\n UNSTABLE_sharedIndex,\n onTabSelected,\n } = props;\n\n const fallbackSharedIndex = useSyncAnimatedValue({ initialValue: initialIndex });\n const sharedIndex = UNSTABLE_sharedIndex ?? fallbackSharedIndex;\n const realInitialIndex = sharedIndex.initialValue;\n\n const currentIndexRef = useRef(initialIndex);\n\n const {\n container: containerStyle,\n contentContainer: contentContainerStyle,\n } = useTabsStyle(variant, size, scrollable);\n\n const setTab = (newIndex: number) => {\n const currentIndex = currentIndexRef.current;\n onTabSelected?.(newIndex, currentIndex);\n\n sharedIndex.animatedValue.setValue(newIndex);\n };\n\n useImperativeHandle(\n ref,\n () => ({\n setTab,\n }),\n [sharedIndex],\n );\n\n const styles = useStyles();\n\n const theme = useTheme();\n\n const [outerCoordinates, updateCoordinate] = useTabCoordinates(children);\n const [innerContentsWidthList, updateInnerContentsWidth] = useTabInnerContentsWidth(children);\n\n const canRenderIndicator = indicatorSize === 'fit-content'\n ? isEveryTabCoordinatesDefined(innerContentsWidthList, children)\n : isEveryTabCoordinatesDefined(outerCoordinates, children);\n\n const indexStore = useIndexStore(sharedIndex);\n\n const coordinates = useMemo(() => {\n if (outerCoordinates.length === 0) {\n return [];\n }\n\n if (indicatorSize !== 'fit-content') {\n return outerCoordinates;\n }\n\n return innerContentsWidthList.map((innerContentWidth, idx) => {\n const outerCoordinate = outerCoordinates[idx];\n if (!outerCoordinate) {\n return defaultCoordinate;\n }\n\n const { x1: outerX1, x2: outerX2 } = outerCoordinate;\n\n const tabWidth = outerX2 - outerX1;\n const distanceFromParent = (tabWidth - innerContentWidth) / 2;\n const indicatorStartCoordinate = outerX1 + distanceFromParent;\n\n return {\n x1: indicatorStartCoordinate,\n x2: indicatorStartCoordinate + innerContentWidth,\n };\n });\n }, [outerCoordinates, innerContentsWidthList]);\n\n useEffect(() => {\n return indexStore.subscribe(newIndex => {\n onChange?.(newIndex);\n currentIndexRef.current = newIndex;\n });\n }, [indexStore, onChange]);\n\n const tabElements = React.Children.map(children, (child, index) => {\n if (!child) {\n return null;\n }\n\n const onTabInnerLayout = (event: LayoutChangeEvent) => {\n const { width } = event.nativeEvent.layout;\n\n updateInnerContentsWidth(index, width);\n };\n\n const onLayout = (event: LayoutChangeEvent) => {\n const { x, width } = event.nativeEvent.layout;\n\n updateCoordinate(index, x, width);\n\n // @ts-ignore\n child.props.onLayout?.(event);\n };\n\n const onMouseDown = (e: GestureResponderEvent) => {\n if (keyboardShouldPersistTaps === 'always') {\n e.preventDefault();\n }\n };\n\n const onPress = () => {\n setTab(index);\n\n // @ts-ignore\n child.props.onPress?.();\n };\n\n // @ts-ignore\n const tabStyle = child.props.style;\n\n // @ts-ignore\n const tabElement = cloneElement(child, {\n enableIndicator: !disableIndicator && !canRenderIndicator,\n onTabInnerLayout,\n onLayout,\n onPress,\n onMouseDown,\n parentColor: color,\n size,\n variant,\n indicatorSize,\n style: css([\n scrollable ? undefined : styles.fixedTab,\n tabStyle,\n ]),\n });\n\n return (\n <IndexAwareTab\n children={tabElement}\n index={index}\n initialIndex={realInitialIndex}\n />\n );\n })?.filter(Boolean);\n\n const tabIndicator = canRenderIndicator ? (\n <TabIndicator\n coordinates={coordinates}\n disabled={disableIndicator}\n initialIndex={realInitialIndex}\n />\n ) : null;\n\n const backgroundColorMap: Record<TabsColor, string> = {\n default: theme.palette.background.base,\n alt: theme.palette.background.alt,\n };\n\n return (\n <InternalContext.Provider value={{ indexStore }}>\n <View\n style={css([\n styles.root,\n containerStyle,\n { backgroundColor: backgroundColorMap[color] },\n showDivider ? styles.bottomDivider : undefined,\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n >\n {scrollable ? (\n <ScrollableTabsView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={css([\n contentContainerStyle,\n scrollViewContentContainerStyle,\n ])}\n coordinates={coordinates}\n directionalLockEnabled={true}\n horizontal={true}\n initialIndex={realInitialIndex}\n scrollsToTop={false}\n showsHorizontalScrollIndicator={false}\n showsVerticalScrollIndicator={false}\n keyboardDismissMode={keyboardDismissMode}\n keyboardShouldPersistTaps={keyboardShouldPersistTaps}\n >\n {tabElements}\n {tabIndicator}\n </ScrollableTabsView>\n ) : (\n <React.Fragment>\n {tabElements}\n {tabIndicator}\n </React.Fragment>\n )}\n </View>\n </InternalContext.Provider>\n );\n});\n\nexport default Tabs;\n"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,YAAhB,EAA8BC,UAA9B,EAA0CC,SAA1C,EAAqDC,mBAArD,EAA0EC,OAA1E,EAAmFC,MAAnF,QAAiG,OAAjG;AAEA,SAASC,IAAT,QAAqB,cAArB;AAEA,SAASC,GAAT,EAAcC,QAAd,QAA8B,WAA9B;AACA,SAASC,oBAAT,QAAqC,UAArC;AAKA,OAAOC,YAAP,MAAyB,gBAAzB;AACA,OAAOC,kBAAP,MAA+B,sBAA/B;AACA,OAAOC,aAAP,MAA0B,iBAA1B;AACA,OAAOC,iBAAP,MAA8B,qBAA9B;AACA,OAAOC,wBAAP,MAAqC,4BAArC;AACA,OAAOC,aAAP,MAA0B,iBAA1B;AACA,OAAOC,eAAP,MAA4B,mBAA5B;AACA,SAASC,4BAAT,QAA6C,SAA7C;AACA,SAASC,iBAAT,QAAkC,iBAAlC;AACA,OAAOC,YAAP,MAAyB,gBAAzB;;AAUA,MAAMC,SAAgC,GAAG,YAAwB;EAC7D,MAAMC,KAAK,GAAGb,QAAQ,EAAtB;EAEA,OAAO;IACHc,IAAI,EAAE,EADH;IAEHC,SAAS,EAAE;MACPC,aAAa,EAAE;IADR,CAFR;IAKHC,QAAQ,EAAE;MACNC,IAAI,EAAE;IADA,CALP;IAQHC,aAAa,EAAE;MACXC,iBAAiB,EAAEP,KAAK,CAACQ,OAAN,CAAcC,MAAd,CAAqBC,IAD7B;MAEXC,iBAAiB,EAAE;IAFR;EARZ,CAAP;AAaH,CAhBD;;AAkBA,MAAMC,IAAI,gBAAGhC,UAAU,CAA0B,SAASgC,IAAT,CAAcC,KAAd,EAAqBC,GAArB,EAA0B;EAAA;;EACvE,MAAM;IACFC,QADE;IAEFC,KAAK,GAAG,SAFN;IAGFC,YAAY,GAAG,CAHb;IAIFC,gBAAgB,GAAG,KAJjB;IAKFC,aAAa,GAAG,aALd;IAMFC,mBAAmB,GAAG,MANpB;IAOFC,yBAAyB,GAAG,OAP1B;IAQFC,QARE;IASFC,UAAU,GAAG,KATX;IAUFC,+BAVE;IAWFC,WAAW,GAAG,KAXZ;IAYFC,IAAI,GAAG,QAZL;IAaFC,KAbE;IAcFC,OAAO,GAAG,SAdR;IAeFC,oBAfE;IAgBFC;EAhBE,IAiBFjB,KAjBJ;EAmBA,MAAMkB,mBAAmB,GAAG3C,oBAAoB,CAAC;IAAE4C,YAAY,EAAEf;EAAhB,CAAD,CAAhD;EACA,MAAMgB,WAAW,GAAGJ,oBAAoB,IAAIE,mBAA5C;EACA,MAAMG,gBAAgB,GAAGD,WAAW,CAACD,YAArC;EAEA,MAAMG,eAAe,GAAGnD,MAAM,CAACiC,YAAD,CAA9B;EAEA,MAAM;IACFmB,SAAS,EAAEC,cADT;IAEFC,gBAAgB,EAAEC;EAFhB,IAGFzC,YAAY,CAAC8B,OAAD,EAAUF,IAAV,EAAgBH,UAAhB,CAHhB;;EAKA,MAAMiB,MAAM,GAAIC,QAAD,IAAsB;IACjC,MAAMC,YAAY,GAAGP,eAAe,CAACQ,OAArC;IACAb,aAAa,SAAb,IAAAA,aAAa,WAAb,YAAAA,aAAa,CAAGW,QAAH,EAAaC,YAAb,CAAb;IAEAT,WAAW,CAACW,aAAZ,CAA0BC,QAA1B,CAAmCJ,QAAnC;EACH,CALD;;EAOA3D,mBAAmB,CACfgC,GADe,EAEf,OAAO;IACH0B;EADG,CAAP,CAFe,EAKf,CAACP,WAAD,CALe,CAAnB;EAQA,MAAMa,MAAM,GAAG/C,SAAS,EAAxB;EAEA,MAAMC,KAAK,GAAGb,QAAQ,EAAtB;EAEA,MAAM,CAAC4D,gBAAD,EAAmBC,gBAAnB,IAAuCxD,iBAAiB,CAACuB,QAAD,CAA9D;EACA,MAAM,CAACkC,sBAAD,EAAyBC,wBAAzB,IAAqDzD,wBAAwB,CAACsB,QAAD,CAAnF;EAEA,MAAMoC,kBAAkB,GAAGhC,aAAa,KAAK,aAAlB,GACrBvB,4BAA4B,CAACqD,sBAAD,EAAyBlC,QAAzB,CADP,GAErBnB,4BAA4B,CAACmD,gBAAD,EAAmBhC,QAAnB,CAFlC;EAIA,MAAMqC,UAAU,GAAG1D,aAAa,CAACuC,WAAD,CAAhC;EAEA,MAAMoB,WAAW,GAAGtE,OAAO,CAAC,MAAM;IAC9B,IAAIgE,gBAAgB,CAACO,MAAjB,KAA4B,CAAhC,EAAmC;MAC/B,OAAO,EAAP;IACH;;IAED,IAAInC,aAAa,KAAK,aAAtB,EAAqC;MACjC,OAAO4B,gBAAP;IACH;;IAED,OAAOE,sBAAsB,CAACM,GAAvB,CAA2B,CAACC,iBAAD,EAAoBC,GAApB,KAA4B;MAC1D,MAAMC,eAAe,GAAGX,gBAAgB,CAACU,GAAD,CAAxC;;MACA,IAAI,CAACC,eAAL,EAAsB;QAClB,OAAO7D,iBAAP;MACH;;MAED,MAAM;QAAE8D,EAAE,EAAEC,OAAN;QAAeC,EAAE,EAAEC;MAAnB,IAA+BJ,eAArC;MAEA,MAAMK,QAAQ,GAAGD,OAAO,GAAGF,OAA3B;MACA,MAAMI,kBAAkB,GAAG,CAACD,QAAQ,GAAGP,iBAAZ,IAAiC,CAA5D;MACA,MAAMS,wBAAwB,GAAGL,OAAO,GAAGI,kBAA3C;MAEA,OAAO;QACHL,EAAE,EAAEM,wBADD;QAEHJ,EAAE,EAAEI,wBAAwB,GAAGT;MAF5B,CAAP;IAIH,CAhBM,CAAP;EAiBH,CA1B0B,EA0BxB,CAACT,gBAAD,EAAmBE,sBAAnB,CA1BwB,CAA3B;EA4BApE,SAAS,CAAC,MAAM;IACZ,OAAOuE,UAAU,CAACc,SAAX,CAAqBzB,QAAQ,IAAI;MACpCnB,QAAQ,SAAR,IAAAA,QAAQ,WAAR,YAAAA,QAAQ,CAAGmB,QAAH,CAAR;MACAN,eAAe,CAACQ,OAAhB,GAA0BF,QAA1B;IACH,CAHM,CAAP;EAIH,CALQ,EAKN,CAACW,UAAD,EAAa9B,QAAb,CALM,CAAT;EAOA,MAAM6C,WAAW,0BAAGzF,KAAK,CAAC0F,QAAN,CAAeb,GAAf,CAAmBxC,QAAnB,EAA6B,CAACsD,KAAD,EAAQC,KAAR,KAAkB;IAC/D,IAAI,CAACD,KAAL,EAAY;MACR,OAAO,IAAP;IACH;;IAED,MAAME,gBAAgB,GAAIC,KAAD,IAA8B;MACnD,MAAM;QAAEC;MAAF,IAAYD,KAAK,CAACE,WAAN,CAAkBC,MAApC;MAEAzB,wBAAwB,CAACoB,KAAD,EAAQG,KAAR,CAAxB;IACH,CAJD;;IAMA,MAAMG,QAAQ,GAAIJ,KAAD,IAA8B;MAAA;;MAC3C,MAAM;QAAEK,CAAF;QAAKJ;MAAL,IAAeD,KAAK,CAACE,WAAN,CAAkBC,MAAvC;MAEA3B,gBAAgB,CAACsB,KAAD,EAAQO,CAAR,EAAWJ,KAAX,CAAhB,CAH2C,CAK3C;;MACA,yCAAAJ,KAAK,CAACxD,KAAN,EAAY+D,QAAZ,mGAAuBJ,KAAvB;IACH,CAPD;;IASA,MAAMM,WAAW,GAAIC,CAAD,IAA8B;MAC9C,IAAI1D,yBAAyB,KAAK,QAAlC,EAA4C;QACxC0D,CAAC,CAACC,cAAF;MACH;IACJ,CAJD;;IAMA,MAAMC,OAAO,GAAG,MAAM;MAAA;;MAClBzC,MAAM,CAAC8B,KAAD,CAAN,CADkB,CAGlB;;MACA,yCAAAD,KAAK,CAACxD,KAAN,EAAYoE,OAAZ;IACH,CALD,CA1B+D,CAiC/D;;;IACA,MAAMC,QAAQ,GAAGb,KAAK,CAACxD,KAAN,CAAYc,KAA7B,CAlC+D,CAoC/D;;IACA,MAAMwD,UAAU,gBAAGxG,YAAY,CAAC0F,KAAD,EAAQ;MACnCe,eAAe,EAAE,CAAClE,gBAAD,IAAqB,CAACiC,kBADJ;MAEnCoB,gBAFmC;MAGnCK,QAHmC;MAInCK,OAJmC;MAKnCH,WALmC;MAMnCO,WAAW,EAAErE,KANsB;MAOnCU,IAPmC;MAQnCE,OARmC;MASnCT,aATmC;MAUnCQ,KAAK,EAAEzC,GAAG,CAAC,CACPqC,UAAU,GAAG+D,SAAH,GAAexC,MAAM,CAAC1C,QADzB,EAEP8E,QAFO,CAAD;IAVyB,CAAR,CAA/B;IAgBA,oBACI,oBAAC,aAAD;MACI,QAAQ,EAAEC,UADd;MAEI,KAAK,EAAEb,KAFX;MAGI,YAAY,EAAEpC;IAHlB,EADJ;EAOH,CA5DmB,CAAH,wDAAG,oBA4DhBqD,MA5DgB,CA4DTC,OA5DS,CAApB;EA8DA,MAAMC,YAAY,GAAGtC,kBAAkB,gBACnC,oBAAC,YAAD;IACI,WAAW,EAAEE,WADjB;IAEI,QAAQ,EAAEnC,gBAFd;IAGI,YAAY,EAAEgB;EAHlB,EADmC,GAMnC,IANJ;EAQA,MAAMwD,kBAA6C,GAAG;IAClDC,OAAO,EAAE3F,KAAK,CAACQ,OAAN,CAAcoF,UAAd,CAAyBlF,IADgB;IAElDmF,GAAG,EAAE7F,KAAK,CAACQ,OAAN,CAAcoF,UAAd,CAAyBC;EAFoB,CAAtD;EAKA,oBACI,oBAAC,eAAD,CAAiB,QAAjB;IAA0B,KAAK,EAAE;MAAEzC;IAAF;EAAjC,gBACI,oBAAC,IAAD;IACI,KAAK,EAAElE,GAAG,CAAC,CACP4D,MAAM,CAAC7C,IADA,EAEPoC,cAFO,EAGP;MAAEyD,eAAe,EAAEJ,kBAAkB,CAAC1E,KAAD;IAArC,CAHO,EAIPS,WAAW,GAAGqB,MAAM,CAACxC,aAAV,GAA0BgF,SAJ9B,EAKP/D,UAAU,GAAG+D,SAAH,GAAexC,MAAM,CAAC5C,SALzB,EAMPyB,KANO,CAAD;EADd,GAUKJ,UAAU,gBACP,oBAAC,kBAAD;IACI,gCAAgC,EAAE,KADtC;IAEI,OAAO,EAAE,KAFb;IAGI,qBAAqB,EAAErC,GAAG,CAAC,CACvBqD,qBADuB,EAEvBf,+BAFuB,CAAD,CAH9B;IAOI,WAAW,EAAE6B,WAPjB;IAQI,sBAAsB,EAAE,IAR5B;IASI,UAAU,EAAE,IAThB;IAUI,YAAY,EAAEnB,gBAVlB;IAWI,YAAY,EAAE,KAXlB;IAYI,8BAA8B,EAAE,KAZpC;IAaI,4BAA4B,EAAE,KAblC;IAcI,mBAAmB,EAAEd,mBAdzB;IAeI,yBAAyB,EAAEC;EAf/B,GAiBK8C,WAjBL,EAkBKsB,YAlBL,CADO,gBAsBP,oBAAC,KAAD,CAAO,QAAP,QACKtB,WADL,EAEKsB,YAFL,CAhCR,CADJ,CADJ;AA0CH,CAnNsB,CAAvB;AAqNA,eAAe7E,IAAf"}
|
|
1
|
+
{"version":3,"names":["React","cloneElement","forwardRef","useEffect","useImperativeHandle","useMemo","useRef","StyleSheet","View","css","useTheme","useSyncAnimatedValue","TabIndicator","ScrollableTabsView","IndexAwareTab","useTabCoordinates","useTabInnerContentsWidth","useIndexStore","InternalContext","isEveryTabCoordinatesDefined","defaultCoordinate","useTabsStyle","useStyles","theme","root","position","fixedRoot","flexDirection","fixedTab","flex","borderContainer","absoluteFillObject","borderBottomColor","palette","border","base","borderBottomWidth","Tabs","props","ref","children","color","initialIndex","disableIndicator","indicatorSize","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","scrollViewContentContainerStyle","showDivider","size","style","variant","UNSTABLE_sharedIndex","onTabSelected","fallbackSharedIndex","initialValue","sharedIndex","realInitialIndex","currentIndexRef","container","containerStyle","contentContainer","contentContainerStyle","setTab","newIndex","currentIndex","current","animatedValue","setValue","styles","outerCoordinates","updateCoordinate","innerContentsWidthList","updateInnerContentsWidth","canRenderIndicator","indexStore","coordinates","length","map","innerContentWidth","idx","outerCoordinate","x1","outerX1","x2","outerX2","tabWidth","distanceFromParent","indicatorStartCoordinate","subscribe","tabElements","Children","child","index","onTabInnerLayout","event","width","nativeEvent","layout","onLayout","x","onMouseDown","e","preventDefault","onPress","tabStyle","tabElement","enableIndicator","parentColor","undefined","filter","Boolean","tabIndicator","backgroundColorMap","default","background","alt","backgroundColor"],"sources":["Tabs.tsx"],"sourcesContent":["import React, { cloneElement, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';\nimport type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';\nimport { StyleSheet, View } from 'react-native';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { css, useTheme } from '../styles';\nimport { useSyncAnimatedValue } from '../hooks';\nimport type { TabSize, TabVariant } from '../Tab';\nimport type TabsProps from './TabsProps';\nimport type { TabsColor } from './TabsProps';\nimport type { TabsInstance } from './types';\nimport TabIndicator from './TabIndicator';\nimport ScrollableTabsView from './ScrollableTabsView';\nimport IndexAwareTab from './IndexAwareTab';\nimport useTabCoordinates from './useTabCoordinates';\nimport useTabInnerContentsWidth from './useTabInnerContentsWidth';\nimport useIndexStore from './useIndexStore';\nimport InternalContext from './InternalContext';\nimport { isEveryTabCoordinatesDefined } from './utils';\nimport { defaultCoordinate } from './TabCoordinate';\nimport useTabsStyle from './useTabsStyle';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'borderContainer';\n\ntype TabsStyles = NamedStylesStringUnion<TabsStyleKeys>;\n\nconst useStyles: UseStyles<TabsStyles> = function (): TabsStyles {\n const theme = useTheme();\n\n return {\n root: {\n position: 'relative',\n },\n fixedRoot: {\n flexDirection: 'row',\n },\n fixedTab: {\n flex: 1,\n },\n borderContainer: {\n ...StyleSheet.absoluteFillObject,\n borderBottomColor: theme.palette.border.base,\n borderBottomWidth: 0.5,\n },\n };\n};\n\nconst Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {\n const {\n children,\n color = 'default',\n initialIndex = 0,\n disableIndicator = false,\n indicatorSize = 'fit-content',\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n scrollViewContentContainerStyle,\n showDivider = false,\n size = 'medium' as TabSize,\n style,\n variant = 'default' as TabVariant,\n UNSTABLE_sharedIndex,\n onTabSelected,\n } = props;\n\n const fallbackSharedIndex = useSyncAnimatedValue({ initialValue: initialIndex });\n const sharedIndex = UNSTABLE_sharedIndex ?? fallbackSharedIndex;\n const realInitialIndex = sharedIndex.initialValue;\n\n const currentIndexRef = useRef(initialIndex);\n\n const {\n container: containerStyle,\n contentContainer: contentContainerStyle,\n } = useTabsStyle(variant, size, scrollable);\n\n const setTab = (newIndex: number) => {\n const currentIndex = currentIndexRef.current;\n onTabSelected?.(newIndex, currentIndex);\n\n sharedIndex.animatedValue.setValue(newIndex);\n };\n\n useImperativeHandle(\n ref,\n () => ({\n setTab,\n }),\n [sharedIndex],\n );\n\n const styles = useStyles();\n\n const theme = useTheme();\n\n const [outerCoordinates, updateCoordinate] = useTabCoordinates(children);\n const [innerContentsWidthList, updateInnerContentsWidth] = useTabInnerContentsWidth(children);\n\n const canRenderIndicator = indicatorSize === 'fit-content'\n ? isEveryTabCoordinatesDefined(innerContentsWidthList, children)\n : isEveryTabCoordinatesDefined(outerCoordinates, children);\n\n const indexStore = useIndexStore(sharedIndex);\n\n const coordinates = useMemo(() => {\n if (outerCoordinates.length === 0) {\n return [];\n }\n\n if (indicatorSize !== 'fit-content') {\n return outerCoordinates;\n }\n\n return innerContentsWidthList.map((innerContentWidth, idx) => {\n const outerCoordinate = outerCoordinates[idx];\n if (!outerCoordinate) {\n return defaultCoordinate;\n }\n\n const { x1: outerX1, x2: outerX2 } = outerCoordinate;\n\n const tabWidth = outerX2 - outerX1;\n const distanceFromParent = (tabWidth - innerContentWidth) / 2;\n const indicatorStartCoordinate = outerX1 + distanceFromParent;\n\n return {\n x1: indicatorStartCoordinate,\n x2: indicatorStartCoordinate + innerContentWidth,\n };\n });\n }, [outerCoordinates, innerContentsWidthList]);\n\n useEffect(() => {\n return indexStore.subscribe(newIndex => {\n onChange?.(newIndex);\n currentIndexRef.current = newIndex;\n });\n }, [indexStore, onChange]);\n\n const tabElements = React.Children.map(children, (child, index) => {\n if (!child) {\n return null;\n }\n\n const onTabInnerLayout = (event: LayoutChangeEvent) => {\n const { width } = event.nativeEvent.layout;\n\n updateInnerContentsWidth(index, width);\n };\n\n const onLayout = (event: LayoutChangeEvent) => {\n const { x, width } = event.nativeEvent.layout;\n\n updateCoordinate(index, x, width);\n\n // @ts-ignore\n child.props.onLayout?.(event);\n };\n\n const onMouseDown = (e: GestureResponderEvent) => {\n if (keyboardShouldPersistTaps === 'always') {\n e.preventDefault();\n }\n };\n\n const onPress = () => {\n setTab(index);\n\n // @ts-ignore\n child.props.onPress?.();\n };\n\n // @ts-ignore\n const tabStyle = child.props.style;\n\n // @ts-ignore\n const tabElement = cloneElement(child, {\n enableIndicator: !disableIndicator && !canRenderIndicator,\n onTabInnerLayout,\n onLayout,\n onPress,\n onMouseDown,\n parentColor: color,\n size,\n variant,\n indicatorSize,\n style: css([\n scrollable ? undefined : styles.fixedTab,\n tabStyle,\n ]),\n });\n\n return (\n <IndexAwareTab\n children={tabElement}\n index={index}\n initialIndex={realInitialIndex}\n />\n );\n })?.filter(Boolean);\n\n const tabIndicator = canRenderIndicator ? (\n <TabIndicator\n coordinates={coordinates}\n disabled={disableIndicator}\n initialIndex={realInitialIndex}\n />\n ) : null;\n\n const backgroundColorMap: Record<TabsColor, string> = {\n default: theme.palette.background.base,\n alt: theme.palette.background.alt,\n };\n\n return (\n <InternalContext.Provider value={{ indexStore }}>\n <View\n style={css([\n styles.root,\n containerStyle,\n { backgroundColor: backgroundColorMap[color] },\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n >\n {scrollable ? (\n <ScrollableTabsView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={css([\n contentContainerStyle,\n scrollViewContentContainerStyle,\n ])}\n coordinates={coordinates}\n directionalLockEnabled={true}\n horizontal={true}\n initialIndex={realInitialIndex}\n scrollsToTop={false}\n showsHorizontalScrollIndicator={false}\n showsVerticalScrollIndicator={false}\n keyboardDismissMode={keyboardDismissMode}\n keyboardShouldPersistTaps={keyboardShouldPersistTaps}\n >\n {tabElements}\n {tabIndicator}\n </ScrollableTabsView>\n ) : (\n <React.Fragment>\n {tabElements}\n {tabIndicator}\n </React.Fragment>\n )}\n\n {showDivider ? (\n <View\n pointerEvents={'none'}\n style={styles.borderContainer}\n />\n ) : null}\n </View>\n </InternalContext.Provider>\n );\n});\n\nexport default Tabs;\n"],"mappings":"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"}
|
|
@@ -67,6 +67,15 @@ export default function useCollapsibleAppBar() {
|
|
|
67
67
|
translateY.value = withTiming(0, ANIMATION_CONFIG);
|
|
68
68
|
}
|
|
69
69
|
}, [appBarHeight]);
|
|
70
|
+
const recoverAppBar = useCallback(() => {
|
|
71
|
+
const currentIndex = indexRef.current;
|
|
72
|
+
offsetsRef.current[currentIndex] = 0;
|
|
73
|
+
lastOffsetY.value = 0;
|
|
74
|
+
translateY.value = withTiming(0, ANIMATION_CONFIG);
|
|
75
|
+
lastTranslateY.value = 0;
|
|
76
|
+
overlapped.value = false;
|
|
77
|
+
setIsScrolled(false);
|
|
78
|
+
}, []);
|
|
70
79
|
const scrollHandler = useAnimatedScrollHandler({
|
|
71
80
|
onBeginDrag: () => {
|
|
72
81
|
if (keyboardDismissMode === 'on-drag') {
|
|
@@ -135,6 +144,7 @@ export default function useCollapsibleAppBar() {
|
|
|
135
144
|
onCollapsibleToolbarLayout,
|
|
136
145
|
onScroll: scrollHandler,
|
|
137
146
|
onScrollViewChanged,
|
|
147
|
+
recoverAppBar,
|
|
138
148
|
scrollContentInsets: {
|
|
139
149
|
top: hasCollapsible ? appBarHeight : 0
|
|
140
150
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useRef","useState","Keyboard","Platform","runOnJS","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useHeight","useAppbarStyles","defaultOptions","keyboardDismissMode","supportsReverseScroll","minVisibleHeight","ANIMATION_CONFIG","duration","TRANSPARENT","SUPPORTS_DRAG_DETECTION","OS","dismissKeyboard","dismiss","useCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","safeMinVisibleHeight","Math","min","translateY","lastTranslateY","lastOffsetY","overlapped","isScrolled","setIsScrolled","animatedStyle","transform","value","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","current","savedOffsetY","scrollHandler","onBeginDrag","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","maxTy","dy","max","minOffsetY","maxOffsetY","contentSize","height","layoutMeasurement","safeOffsetY","safeLastOffsetY","newTranslateY","onEndDrag","onMomentumEnd","ty","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n supportsReverseScroll?: boolean;\n minVisibleHeight?: number;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n isScrolled: boolean;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n supportsReverseScroll: true,\n minVisibleHeight: 0,\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\nconst TRANSPARENT = '#FFFFFF00';\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\nconst dismissKeyboard = () => Keyboard.dismiss();\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode, supportsReverseScroll, minVisibleHeight }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => {\n const safeMinVisibleHeight = Math.min(minVisibleHeight, collapsibleToolbarHeight);\n return -(collapsibleToolbarHeight - safeMinVisibleHeight);\n }, [collapsibleToolbarHeight, minVisibleHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const [isScrolled, setIsScrolled] = useState<boolean>(false);\n\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n return {\n transform,\n };\n }, [translateY]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }, [appBarHeight]);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(dismissKeyboard)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n if (!isScrolled && offsetY > 0) {\n runOnJS(setIsScrolled)(true);\n } else if (isScrolled && offsetY <= 0) {\n runOnJS(setIsScrolled)(false);\n }\n\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n const minOffsetY = -maxTy;\n const maxOffsetY = event.contentSize.height - event.layoutMeasurement.height;\n\n const safeOffsetY = Math.min(Math.max(offsetY, minOffsetY), maxOffsetY);\n const safeLastOffsetY = Math.min(Math.max(lastOffsetY.value, minOffsetY), maxOffsetY);\n const dy = safeOffsetY - safeLastOffsetY;\n\n const newTranslateY = safeOffsetY <= minOffsetY\n ? 0\n : supportsReverseScroll\n ? dy === 0\n ? lastTranslateY.value\n : dy > 0\n ? maxTy\n : 0\n : maxTy;\n\n translateY.value = withTiming(newTranslateY, ANIMATION_CONFIG);\n lastTranslateY.value = newTranslateY;\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n });\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n isScrolled,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["useCallback","useRef","useState","Keyboard","Platform","runOnJS","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useHeight","useAppbarStyles","defaultOptions","keyboardDismissMode","supportsReverseScroll","minVisibleHeight","ANIMATION_CONFIG","duration","TRANSPARENT","SUPPORTS_DRAG_DETECTION","OS","dismissKeyboard","dismiss","useCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","safeMinVisibleHeight","Math","min","translateY","lastTranslateY","lastOffsetY","overlapped","isScrolled","setIsScrolled","animatedStyle","transform","value","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","current","savedOffsetY","recoverAppBar","currentIndex","scrollHandler","onBeginDrag","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","maxTy","dy","max","minOffsetY","maxOffsetY","contentSize","height","layoutMeasurement","safeOffsetY","safeLastOffsetY","newTranslateY","onEndDrag","onMomentumEnd","ty","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n supportsReverseScroll?: boolean;\n minVisibleHeight?: number;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n recoverAppBar: () => void;\n scrollContentInsets: ContentInsets;\n isScrolled: boolean;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n supportsReverseScroll: true,\n minVisibleHeight: 0,\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\nconst TRANSPARENT = '#FFFFFF00';\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\nconst dismissKeyboard = () => Keyboard.dismiss();\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode, supportsReverseScroll, minVisibleHeight }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => {\n const safeMinVisibleHeight = Math.min(minVisibleHeight, collapsibleToolbarHeight);\n return -(collapsibleToolbarHeight - safeMinVisibleHeight);\n }, [collapsibleToolbarHeight, minVisibleHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const [isScrolled, setIsScrolled] = useState<boolean>(false);\n\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n return {\n transform,\n };\n }, [translateY]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }, [appBarHeight]);\n\n const recoverAppBar = useCallback(() => {\n const currentIndex = indexRef.current;\n\n offsetsRef.current[currentIndex] = 0;\n\n lastOffsetY.value = 0;\n\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n lastTranslateY.value = 0;\n\n overlapped.value = false;\n\n setIsScrolled(false);\n }, []);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(dismissKeyboard)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n if (!isScrolled && offsetY > 0) {\n runOnJS(setIsScrolled)(true);\n } else if (isScrolled && offsetY <= 0) {\n runOnJS(setIsScrolled)(false);\n }\n\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n const minOffsetY = -maxTy;\n const maxOffsetY = event.contentSize.height - event.layoutMeasurement.height;\n\n const safeOffsetY = Math.min(Math.max(offsetY, minOffsetY), maxOffsetY);\n const safeLastOffsetY = Math.min(Math.max(lastOffsetY.value, minOffsetY), maxOffsetY);\n const dy = safeOffsetY - safeLastOffsetY;\n\n const newTranslateY = safeOffsetY <= minOffsetY\n ? 0\n : supportsReverseScroll\n ? dy === 0\n ? lastTranslateY.value\n : dy > 0\n ? maxTy\n : 0\n : maxTy;\n\n translateY.value = withTiming(newTranslateY, ANIMATION_CONFIG);\n lastTranslateY.value = newTranslateY;\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n });\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n recoverAppBar,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n isScrolled,\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import type ModalProps from '../ModalProps';
|
|
3
2
|
declare type AnimatedContainerProps = Pick<ModalProps, 'children' | 'closeAnimation' | 'initialOpacity' | 'initialTranslateY' | 'onEnter' | 'onEntered' | 'onExit' | 'onExited' | 'openAnimation' | 'offsetAnimation' | 'style' | 'visible'>;
|
|
4
3
|
export default function AnimatedContainer(props: AnimatedContainerProps): JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.42",
|
|
4
4
|
"author": "Fountain-UI Team",
|
|
5
5
|
"description": "React components that implement Tappytoon's Fountain Design.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"publishConfig": {
|
|
68
68
|
"access": "public"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "4a7de3f29299eb5f7ea9b6b874f232263756f854"
|
|
71
71
|
}
|
package/src/Tabs/Tabs.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { cloneElement, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
|
2
2
|
import type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';
|
|
3
|
-
import { View } from 'react-native';
|
|
3
|
+
import { StyleSheet, View } from 'react-native';
|
|
4
4
|
import { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';
|
|
5
5
|
import { css, useTheme } from '../styles';
|
|
6
6
|
import { useSyncAnimatedValue } from '../hooks';
|
|
@@ -23,7 +23,7 @@ type TabsStyleKeys =
|
|
|
23
23
|
| 'root'
|
|
24
24
|
| 'fixedRoot'
|
|
25
25
|
| 'fixedTab'
|
|
26
|
-
| '
|
|
26
|
+
| 'borderContainer';
|
|
27
27
|
|
|
28
28
|
type TabsStyles = NamedStylesStringUnion<TabsStyleKeys>;
|
|
29
29
|
|
|
@@ -31,14 +31,17 @@ const useStyles: UseStyles<TabsStyles> = function (): TabsStyles {
|
|
|
31
31
|
const theme = useTheme();
|
|
32
32
|
|
|
33
33
|
return {
|
|
34
|
-
root: {
|
|
34
|
+
root: {
|
|
35
|
+
position: 'relative',
|
|
36
|
+
},
|
|
35
37
|
fixedRoot: {
|
|
36
38
|
flexDirection: 'row',
|
|
37
39
|
},
|
|
38
40
|
fixedTab: {
|
|
39
41
|
flex: 1,
|
|
40
42
|
},
|
|
41
|
-
|
|
43
|
+
borderContainer: {
|
|
44
|
+
...StyleSheet.absoluteFillObject,
|
|
42
45
|
borderBottomColor: theme.palette.border.base,
|
|
43
46
|
borderBottomWidth: 0.5,
|
|
44
47
|
},
|
|
@@ -221,7 +224,6 @@ const Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {
|
|
|
221
224
|
styles.root,
|
|
222
225
|
containerStyle,
|
|
223
226
|
{ backgroundColor: backgroundColorMap[color] },
|
|
224
|
-
showDivider ? styles.bottomDivider : undefined,
|
|
225
227
|
scrollable ? undefined : styles.fixedRoot,
|
|
226
228
|
style,
|
|
227
229
|
])}
|
|
@@ -253,6 +255,13 @@ const Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {
|
|
|
253
255
|
{tabIndicator}
|
|
254
256
|
</React.Fragment>
|
|
255
257
|
)}
|
|
258
|
+
|
|
259
|
+
{showDivider ? (
|
|
260
|
+
<View
|
|
261
|
+
pointerEvents={'none'}
|
|
262
|
+
style={styles.borderContainer}
|
|
263
|
+
/>
|
|
264
|
+
) : null}
|
|
256
265
|
</View>
|
|
257
266
|
</InternalContext.Provider>
|
|
258
267
|
);
|
|
@@ -40,6 +40,7 @@ export interface CollapsibleAppBar {
|
|
|
40
40
|
onCollapsibleToolbarLayout: OnLayoutCallback;
|
|
41
41
|
onScroll: OnScroll;
|
|
42
42
|
onScrollViewChanged: (index: number) => void;
|
|
43
|
+
recoverAppBar: () => void;
|
|
43
44
|
scrollContentInsets: ContentInsets;
|
|
44
45
|
isScrolled: boolean;
|
|
45
46
|
}
|
|
@@ -114,6 +115,21 @@ export default function useCollapsibleAppBar(userOptions: Options = defaultOptio
|
|
|
114
115
|
}
|
|
115
116
|
}, [appBarHeight]);
|
|
116
117
|
|
|
118
|
+
const recoverAppBar = useCallback(() => {
|
|
119
|
+
const currentIndex = indexRef.current;
|
|
120
|
+
|
|
121
|
+
offsetsRef.current[currentIndex] = 0;
|
|
122
|
+
|
|
123
|
+
lastOffsetY.value = 0;
|
|
124
|
+
|
|
125
|
+
translateY.value = withTiming(0, ANIMATION_CONFIG);
|
|
126
|
+
lastTranslateY.value = 0;
|
|
127
|
+
|
|
128
|
+
overlapped.value = false;
|
|
129
|
+
|
|
130
|
+
setIsScrolled(false);
|
|
131
|
+
}, []);
|
|
132
|
+
|
|
117
133
|
const scrollHandler = useAnimatedScrollHandler({
|
|
118
134
|
onBeginDrag: () => {
|
|
119
135
|
if (keyboardDismissMode === 'on-drag') {
|
|
@@ -207,6 +223,7 @@ export default function useCollapsibleAppBar(userOptions: Options = defaultOptio
|
|
|
207
223
|
onCollapsibleToolbarLayout,
|
|
208
224
|
onScroll: scrollHandler,
|
|
209
225
|
onScrollViewChanged,
|
|
226
|
+
recoverAppBar,
|
|
210
227
|
scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },
|
|
211
228
|
isScrolled,
|
|
212
229
|
};
|