@fountain-ui/core 2.0.0-beta.75 → 2.0.0-beta.77

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.
Files changed (59) hide show
  1. package/build/commonjs/Dialog/Dialog.js +30 -2
  2. package/build/commonjs/Dialog/Dialog.js.map +1 -1
  3. package/build/commonjs/Modal/Modal.js +7 -1
  4. package/build/commonjs/Modal/Modal.js.map +1 -1
  5. package/build/commonjs/Modal/ModalProps.js.map +1 -1
  6. package/build/commonjs/Snackbar/Snackbar.js +30 -7
  7. package/build/commonjs/Snackbar/Snackbar.js.map +1 -1
  8. package/build/commonjs/Tab/Tab.js +23 -14
  9. package/build/commonjs/Tab/Tab.js.map +1 -1
  10. package/build/commonjs/Tab/TabIndicator.js +5 -4
  11. package/build/commonjs/Tab/TabIndicator.js.map +1 -1
  12. package/build/commonjs/Tab/TabProps.js.map +1 -1
  13. package/build/commonjs/Tab/index.js.map +1 -1
  14. package/build/commonjs/Tabs/Tabs.js +47 -6
  15. package/build/commonjs/Tabs/Tabs.js.map +1 -1
  16. package/build/commonjs/Tabs/TabsProps.js.map +1 -1
  17. package/build/commonjs/Tabs/useTabInnerContentsWidth.js +30 -0
  18. package/build/commonjs/Tabs/useTabInnerContentsWidth.js.map +1 -0
  19. package/build/commonjs/Tabs/utils.js.map +1 -1
  20. package/build/module/Dialog/Dialog.js +25 -3
  21. package/build/module/Dialog/Dialog.js.map +1 -1
  22. package/build/module/Modal/Modal.js +6 -1
  23. package/build/module/Modal/Modal.js.map +1 -1
  24. package/build/module/Modal/ModalProps.js.map +1 -1
  25. package/build/module/Snackbar/Snackbar.js +21 -5
  26. package/build/module/Snackbar/Snackbar.js.map +1 -1
  27. package/build/module/Tab/Tab.js +24 -15
  28. package/build/module/Tab/Tab.js.map +1 -1
  29. package/build/module/Tab/TabIndicator.js +5 -4
  30. package/build/module/Tab/TabIndicator.js.map +1 -1
  31. package/build/module/Tab/TabProps.js.map +1 -1
  32. package/build/module/Tab/index.js.map +1 -1
  33. package/build/module/Tabs/Tabs.js +48 -6
  34. package/build/module/Tabs/Tabs.js.map +1 -1
  35. package/build/module/Tabs/TabsProps.js.map +1 -1
  36. package/build/module/Tabs/useTabInnerContentsWidth.js +21 -0
  37. package/build/module/Tabs/useTabInnerContentsWidth.js.map +1 -0
  38. package/build/module/Tabs/utils.js.map +1 -1
  39. package/build/typescript/Modal/ModalProps.d.ts +10 -0
  40. package/build/typescript/Tab/TabIndicator.d.ts +3 -2
  41. package/build/typescript/Tab/TabProps.d.ts +14 -1
  42. package/build/typescript/Tab/index.d.ts +1 -1
  43. package/build/typescript/Tabs/Tabs.d.ts +1 -1
  44. package/build/typescript/Tabs/TabsProps.d.ts +14 -1
  45. package/build/typescript/Tabs/useTabInnerContentsWidth.d.ts +6 -0
  46. package/build/typescript/Tabs/utils.d.ts +1 -1
  47. package/package.json +2 -2
  48. package/src/Dialog/Dialog.tsx +26 -4
  49. package/src/Modal/Modal.tsx +7 -1
  50. package/src/Modal/ModalProps.ts +12 -0
  51. package/src/Snackbar/Snackbar.tsx +29 -7
  52. package/src/Tab/Tab.tsx +43 -17
  53. package/src/Tab/TabIndicator.tsx +7 -7
  54. package/src/Tab/TabProps.ts +16 -1
  55. package/src/Tab/index.ts +1 -1
  56. package/src/Tabs/Tabs.tsx +47 -4
  57. package/src/Tabs/TabsProps.ts +16 -1
  58. package/src/Tabs/useTabInnerContentsWidth.ts +26 -0
  59. package/src/Tabs/utils.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"names":["React","cloneElement","forwardRef","useEffect","useImperativeHandle","View","css","useTheme","useSyncAnimatedValue","TabIndicator","ScrollableTabsView","IndexAwareTab","useTabCoordinates","useIndexStore","InternalContext","isEveryTabCoordinatesDefined","useStyles","theme","root","fixedRoot","flexDirection","fixedTab","flex","scrollableContainer","paddingHorizontal","spacing","Tabs","props","ref","children","indicatorColor","initialIndex","disableIndicator","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","style","variant","UNSTABLE_sharedIndex","fallbackSharedIndex","initialValue","sharedIndex","realInitialIndex","setTab","newIndex","animatedValue","setValue","styles","coordinates","updateCoordinate","canRenderIndicator","indexStore","subscribe","tabElements","Children","map","child","index","onLayout","event","x","width","nativeEvent","layout","onMouseDown","e","preventDefault","onPress","tabElement","enableIndicator","undefined","tabIndicator"],"sources":["Tabs.tsx"],"sourcesContent":["import React, { cloneElement, forwardRef, useEffect, useImperativeHandle } 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 TabsProps from './TabsProps';\nimport type { TabsInstance } from './types';\nimport TabIndicator from './TabIndicator';\nimport ScrollableTabsView from './ScrollableTabsView';\nimport IndexAwareTab from './IndexAwareTab';\nimport useTabCoordinates from './useTabCoordinates';\nimport useIndexStore from './useIndexStore';\nimport InternalContext from './InternalContext';\nimport { isEveryTabCoordinatesDefined } from './utils';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'scrollableContainer';\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 scrollableContainer: {\n paddingHorizontal: theme.spacing(1),\n },\n };\n};\n\nconst Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {\n const {\n children,\n indicatorColor = 'primary',\n initialIndex = 0,\n disableIndicator = false,\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n style,\n variant = 'primary',\n UNSTABLE_sharedIndex,\n } = props;\n\n const fallbackSharedIndex = useSyncAnimatedValue({ initialValue: initialIndex });\n const sharedIndex = UNSTABLE_sharedIndex ?? fallbackSharedIndex;\n const realInitialIndex = sharedIndex.initialValue;\n\n const setTab = (newIndex: number) => {\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 [coordinates, updateCoordinate] = useTabCoordinates(children);\n\n const canRenderIndicator = isEveryTabCoordinatesDefined(coordinates, children);\n\n const indexStore = useIndexStore(sharedIndex);\n\n useEffect(() => {\n return indexStore.subscribe(newIndex => {\n onChange?.(newIndex);\n });\n }, [indexStore, onChange]);\n\n const tabElements = React.Children.map(children, (child, index) => {\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 tabElement = cloneElement(child, {\n enableIndicator: !disableIndicator && !canRenderIndicator,\n indicatorColor,\n onLayout,\n onPress,\n onMouseDown,\n variant,\n style: scrollable ? undefined : styles.fixedTab,\n });\n\n return (\n <IndexAwareTab\n children={tabElement}\n index={index}\n initialIndex={realInitialIndex}\n />\n );\n });\n\n const tabIndicator = canRenderIndicator ? (\n <TabIndicator\n color={indicatorColor}\n coordinates={coordinates}\n disabled={disableIndicator}\n initialIndex={realInitialIndex}\n scrollable={scrollable}\n />\n ) : null;\n\n return (\n <InternalContext.Provider value={{ indexStore }}>\n <View\n style={css([\n styles.root,\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n >\n {scrollable ? (\n <ScrollableTabsView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={styles.scrollableContainer}\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":["React","cloneElement","forwardRef","useEffect","useImperativeHandle","useMemo","useRef","View","css","useTheme","useSyncAnimatedValue","TabIndicator","ScrollableTabsView","IndexAwareTab","useTabCoordinates","useTabInnerContentsWidth","useIndexStore","InternalContext","isEveryTabCoordinatesDefined","useStyles","theme","root","fixedRoot","flexDirection","fixedTab","flex","scrollableContainer","paddingHorizontal","spacing","Tabs","props","ref","children","indicatorColor","initialIndex","disableIndicator","indicatorSize","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","style","variant","UNSTABLE_sharedIndex","onTabSelected","fallbackSharedIndex","initialValue","sharedIndex","realInitialIndex","currentIndexRef","setTab","newIndex","currentIndex","current","animatedValue","setValue","styles","outerCoordinates","updateCoordinate","innerContentsWidthList","updateInnerContentsWidth","canRenderIndicator","indexStore","coordinates","map","innerContentWidth","idx","x1","outerX1","x2","outerX2","tabWidth","distanceFromParent","indicatorStartCoordinate","subscribe","tabElements","Children","child","index","onTabInnerLayout","event","width","nativeEvent","layout","onLayout","x","onMouseDown","e","preventDefault","onPress","tabElement","enableIndicator","undefined","filter","Boolean","tabIndicator"],"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 TabsProps 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';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'scrollableContainer';\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 scrollableContainer: {\n paddingHorizontal: theme.spacing(1),\n },\n };\n};\n\nconst Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {\n const {\n children,\n indicatorColor = 'primary',\n initialIndex = 0,\n disableIndicator = false,\n indicatorSize = 'full',\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n style,\n variant = 'primary',\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 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 [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 (indicatorSize !== 'fit-content') {\n return outerCoordinates;\n }\n\n return innerContentsWidthList.map((innerContentWidth, idx) => {\n const { x1: outerX1, x2: outerX2 } = outerCoordinates[idx];\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, variant]);\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 tabElement = cloneElement(child, {\n enableIndicator: !disableIndicator && !canRenderIndicator,\n indicatorColor,\n onTabInnerLayout,\n onLayout,\n onPress,\n onMouseDown,\n variant,\n indicatorSize,\n style: scrollable ? undefined : styles.fixedTab,\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 color={indicatorColor}\n coordinates={coordinates}\n disabled={disableIndicator}\n initialIndex={realInitialIndex}\n scrollable={scrollable}\n />\n ) : null;\n\n return (\n <InternalContext.Provider value={{ indexStore }}>\n <View\n style={css([\n styles.root,\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n >\n {scrollable ? (\n <ScrollableTabsView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={styles.scrollableContainer}\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 +1 @@
1
- {"version":3,"names":[],"sources":["TabsProps.ts"],"sourcesContent":["import type { ReactNode, Ref } from 'react';\nimport type { ViewProps } from 'react-native';\nimport type { TabIndicatorColor } from './TabIndicatorProps';\nimport type { TabVariant } from '../Tab';\nimport type { OverridableComponentProps, SyncAnimatedValue } from '../types';\nimport type { KeyboardDismissMode, KeyboardShouldPersistTaps, TabsInstance } from './types';\n\nexport default interface TabsProps extends OverridableComponentProps<ViewProps, {\n ref?: Ref<TabsInstance>;\n\n /**\n * Collection of Tab components.\n */\n children: ReactNode;\n\n /**\n * If `true`, the indicator is disabled.\n * @default false\n */\n disableIndicator?: boolean;\n\n /**\n * The color of tab indicator\n * @default 'primary'\n */\n indicatorColor?: TabIndicatorColor;\n\n /**\n * Index of initial tab that should be selected.\n * @default 0\n */\n initialIndex?: number;\n\n /**\n * keyboard dismissing condition of dragging.\n * @default 'none'\n */\n keyboardDismissMode?: KeyboardDismissMode,\n\n /**\n * keyboard persisting condition of tapping.\n * @default 'never'\n */\n keyboardShouldPersistTaps?: KeyboardShouldPersistTaps,\n\n /**\n * Callback fired when a tab is selected.\n */\n onChange?: (newIndex: number) => void;\n\n /**\n * If `true`, the component will be able to scroll.\n * @default false\n */\n scrollable?: boolean;\n\n /**\n * Unstable API.\n */\n UNSTABLE_sharedIndex?: SyncAnimatedValue;\n\n /**\n * The variant to use.\n * @default 'primary'\n */\n variant?: TabVariant;\n}> {}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["TabsProps.ts"],"sourcesContent":["import type { ReactNode, Ref } from 'react';\nimport type { ViewProps } from 'react-native';\nimport type { TabIndicatorColor } from './TabIndicatorProps';\nimport type { TabVariant, TabIndicatorSize } from '../Tab';\nimport type { OverridableComponentProps, SyncAnimatedValue } from '../types';\nimport type { KeyboardDismissMode, KeyboardShouldPersistTaps, TabsInstance } from './types';\n\nexport default interface TabsProps extends OverridableComponentProps<ViewProps, {\n ref?: Ref<TabsInstance>;\n\n /**\n * Collection of Tab components.\n */\n children: ReactNode;\n\n /**\n * If `true`, the indicator is disabled.\n * @default false\n */\n disableIndicator?: boolean;\n\n /**\n * The color of tab indicator\n * @default 'primary'\n */\n indicatorColor?: TabIndicatorColor;\n\n /**\n * The size of tab indicator.\n * 'full' adjusts the indicator to the size of the Tab,\n * while 'fit-content' adjusts the indicator to the size of the content inside the Tab.\n * @default 'full'\n */\n indicatorSize?: TabIndicatorSize;\n\n /**\n * Index of initial tab that should be selected.\n * @default 0\n */\n initialIndex?: number;\n\n /**\n * keyboard dismissing condition of dragging.\n * @default 'none'\n */\n keyboardDismissMode?: KeyboardDismissMode,\n\n /**\n * keyboard persisting condition of tapping.\n * @default 'never'\n */\n keyboardShouldPersistTaps?: KeyboardShouldPersistTaps,\n\n /**\n * Callback fired when a tab is selected.\n */\n onChange?: (newIndex: number) => void;\n\n /**\n * If `true`, the component will be able to scroll.\n * @default false\n */\n scrollable?: boolean;\n\n /**\n * Unstable API.\n */\n UNSTABLE_sharedIndex?: SyncAnimatedValue;\n\n /**\n * The variant to use.\n * @default 'primary'\n */\n variant?: TabVariant;\n\n /**\n * Callback function executed when a Tab is selected.\n * Executed even if the index does not change when a Tab is pressed.\n * Receives the next tab index and the current tab index as parameters.\n */\n onTabSelected?: (newIndex: number, currentIndex: number) => void;\n}> {}\n"],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { useRef, useState } from 'react';
2
+ import { isEveryTabCoordinatesDefined } from './utils';
3
+
4
+ const useTabInnerContentsWidth = tabElements => {
5
+ const [innerContentsWidthList, setInnerContentsWidth] = useState([]);
6
+ const cacheRef = useRef([]);
7
+
8
+ const updateInnerContentsWidth = (index, width) => {
9
+ cacheRef.current[index] = width;
10
+
11
+ if (isEveryTabCoordinatesDefined(cacheRef.current, tabElements)) {
12
+ setInnerContentsWidth([...cacheRef.current]);
13
+ cacheRef.current = [];
14
+ }
15
+ };
16
+
17
+ return [innerContentsWidthList, updateInnerContentsWidth];
18
+ };
19
+
20
+ export default useTabInnerContentsWidth;
21
+ //# sourceMappingURL=useTabInnerContentsWidth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useRef","useState","isEveryTabCoordinatesDefined","useTabInnerContentsWidth","tabElements","innerContentsWidthList","setInnerContentsWidth","cacheRef","updateInnerContentsWidth","index","width","current"],"sources":["useTabInnerContentsWidth.ts"],"sourcesContent":["import React, { useRef, useState } from 'react';\nimport { isEveryTabCoordinatesDefined } from './utils';\n\nexport interface UpdateInnerContentsWidth {\n (index: number, width: number): void;\n}\n\nconst useTabInnerContentsWidth = (tabElements: React.ReactNode): [number[], UpdateInnerContentsWidth] => {\n const [innerContentsWidthList, setInnerContentsWidth] = useState<number[]>([]);\n\n const cacheRef = useRef<number[]>([]);\n\n const updateInnerContentsWidth: UpdateInnerContentsWidth = (index, width) => {\n cacheRef.current[index] = width;\n\n if (isEveryTabCoordinatesDefined(cacheRef.current, tabElements)) {\n setInnerContentsWidth([...cacheRef.current]);\n\n cacheRef.current = [];\n }\n };\n\n return [innerContentsWidthList, updateInnerContentsWidth];\n};\n\nexport default useTabInnerContentsWidth;\n"],"mappings":"AAAA,SAAgBA,MAAhB,EAAwBC,QAAxB,QAAwC,OAAxC;AACA,SAASC,4BAAT,QAA6C,SAA7C;;AAMA,MAAMC,wBAAwB,GAAIC,WAAD,IAAwE;EACrG,MAAM,CAACC,sBAAD,EAAyBC,qBAAzB,IAAkDL,QAAQ,CAAW,EAAX,CAAhE;EAEA,MAAMM,QAAQ,GAAGP,MAAM,CAAW,EAAX,CAAvB;;EAEA,MAAMQ,wBAAkD,GAAG,CAACC,KAAD,EAAQC,KAAR,KAAkB;IACzEH,QAAQ,CAACI,OAAT,CAAiBF,KAAjB,IAA0BC,KAA1B;;IAEA,IAAIR,4BAA4B,CAACK,QAAQ,CAACI,OAAV,EAAmBP,WAAnB,CAAhC,EAAiE;MAC7DE,qBAAqB,CAAC,CAAC,GAAGC,QAAQ,CAACI,OAAb,CAAD,CAArB;MAEAJ,QAAQ,CAACI,OAAT,GAAmB,EAAnB;IACH;EACJ,CARD;;EAUA,OAAO,CAACN,sBAAD,EAAyBG,wBAAzB,CAAP;AACH,CAhBD;;AAkBA,eAAeL,wBAAf"}
@@ -1 +1 @@
1
- {"version":3,"names":["Children","isEveryDefined","isEveryTabCoordinatesDefined","coordinates","tabElements","numberOfTabs","count","numberOfCoordinates","length","everyCoordinatesDefined"],"sources":["utils.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Children } from 'react';\nimport { isEveryDefined } from '@fountain-ui/utils';\nimport type TabCoordinate from './TabCoordinate';\n\n\nexport function isEveryTabCoordinatesDefined(coordinates: TabCoordinate[], tabElements: ReactNode): boolean {\n const numberOfTabs = Children.count(tabElements);\n const numberOfCoordinates = coordinates.length;\n\n const everyCoordinatesDefined = isEveryDefined(coordinates);\n\n return numberOfTabs === numberOfCoordinates && everyCoordinatesDefined;\n}\n"],"mappings":"AACA,SAASA,QAAT,QAAyB,OAAzB;AACA,SAASC,cAAT,QAA+B,oBAA/B;AAIA,OAAO,SAASC,4BAAT,CAAsCC,WAAtC,EAAoEC,WAApE,EAAqG;EACxG,MAAMC,YAAY,GAAGL,QAAQ,CAACM,KAAT,CAAeF,WAAf,CAArB;EACA,MAAMG,mBAAmB,GAAGJ,WAAW,CAACK,MAAxC;EAEA,MAAMC,uBAAuB,GAAGR,cAAc,CAACE,WAAD,CAA9C;EAEA,OAAOE,YAAY,KAAKE,mBAAjB,IAAwCE,uBAA/C;AACH"}
1
+ {"version":3,"names":["Children","isEveryDefined","isEveryTabCoordinatesDefined","coordinates","tabElements","numberOfTabs","count","numberOfCoordinates","length","everyCoordinatesDefined"],"sources":["utils.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Children } from 'react';\nimport { isEveryDefined } from '@fountain-ui/utils';\nimport type TabCoordinate from './TabCoordinate';\n\n\nexport function isEveryTabCoordinatesDefined(coordinates: (TabCoordinate | number)[], tabElements: ReactNode): boolean {\n const numberOfTabs = Children.count(tabElements);\n const numberOfCoordinates = coordinates.length;\n\n const everyCoordinatesDefined = isEveryDefined(coordinates);\n\n return numberOfTabs === numberOfCoordinates && everyCoordinatesDefined;\n}\n"],"mappings":"AACA,SAASA,QAAT,QAAyB,OAAzB;AACA,SAASC,cAAT,QAA+B,oBAA/B;AAIA,OAAO,SAASC,4BAAT,CAAsCC,WAAtC,EAA+EC,WAA/E,EAAgH;EACnH,MAAMC,YAAY,GAAGL,QAAQ,CAACM,KAAT,CAAeF,WAAf,CAArB;EACA,MAAMG,mBAAmB,GAAGJ,WAAW,CAACK,MAAxC;EAEA,MAAMC,uBAAuB,GAAGR,cAAc,CAACE,WAAD,CAA9C;EAEA,OAAOE,YAAY,KAAKE,mBAAjB,IAAwCE,uBAA/C;AACH"}
@@ -21,6 +21,16 @@ export default interface ModalProps extends OverridableComponentProps<ViewProps,
21
21
  * @default false
22
22
  */
23
23
  disableAnimation?: boolean;
24
+ /**
25
+ * The number of milliseconds to enter animation.
26
+ * @default 300
27
+ */
28
+ enterDuration?: number;
29
+ /**
30
+ * The number of milliseconds to exit animation.
31
+ * @default 150
32
+ */
33
+ exitDuration?: number;
24
34
  /**
25
35
  * If `true`, the backdrop is not rendered.
26
36
  * @default false
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
- import type { TabIndicatorColor } from './TabProps';
3
- declare const _default: React.MemoExoticComponent<({ color }: {
2
+ import type { TabIndicatorColor, TabIndicatorSize } from './TabProps';
3
+ declare const _default: React.MemoExoticComponent<({ indicatorSize, color }: {
4
+ indicatorSize: TabIndicatorSize;
4
5
  color: TabIndicatorColor;
5
6
  }) => JSX.Element>;
6
7
  export default _default;
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
+ import type { LayoutChangeEvent } from 'react-native';
2
3
  import type { TabBaseProps } from '../TabBase';
3
4
  import type { OverridableComponentProps } from '../types';
4
5
  export declare type TabVariant = 'primary' | 'secondary' | 'bottom-navigation';
5
6
  export declare type TabIndicatorColor = 'primary' | 'secondary';
7
+ export declare type TabIndicatorSize = 'full' | 'fit-content';
6
8
  export default interface TabProps extends OverridableComponentProps<TabBaseProps, {
7
9
  /**
8
10
  * If `true`, the badge is visible.
@@ -12,7 +14,7 @@ export default interface TabProps extends OverridableComponentProps<TabBaseProps
12
14
  /**
13
15
  * The label of the Tab.
14
16
  */
15
- children: string;
17
+ children: string | React.ReactElement;
16
18
  /**
17
19
  * If `true`, the indicator is enabled.
18
20
  * @default false
@@ -32,6 +34,13 @@ export default interface TabProps extends OverridableComponentProps<TabBaseProps
32
34
  * @default 'primary'
33
35
  */
34
36
  indicatorColor?: TabIndicatorColor;
37
+ /**
38
+ * The size of tab indicator.
39
+ * 'full' adjusts the indicator to the size of the Tab,
40
+ * while 'fit-content' adjusts the indicator to the size of the content inside the Tab.
41
+ * @default 'full'
42
+ */
43
+ indicatorSize?: TabIndicatorSize;
35
44
  /**
36
45
  * If supplied, use this icon on selected state.
37
46
  */
@@ -41,5 +50,9 @@ export default interface TabProps extends OverridableComponentProps<TabBaseProps
41
50
  * @default 'primary'
42
51
  */
43
52
  variant?: TabVariant;
53
+ /**
54
+ * Function to be passed to the child component's onLayout prop.
55
+ */
56
+ onTabInnerLayout?: (event: LayoutChangeEvent) => void;
44
57
  }> {
45
58
  }
@@ -1,2 +1,2 @@
1
1
  export { default } from './Tab';
2
- export type { default as TabProps, TabVariant } from './TabProps';
2
+ export type { default as TabProps, TabVariant, TabIndicatorSize } from './TabProps';
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import type TabsProps from './TabsProps';
3
3
  import type { TabsInstance } from './types';
4
- declare const Tabs: React.ForwardRefExoticComponent<Pick<TabsProps, "testID" | "style" | "onLayout" | "keyboardDismissMode" | "children" | "pointerEvents" | "onStartShouldSetResponder" | "onMoveShouldSetResponder" | "onResponderEnd" | "onResponderGrant" | "onResponderReject" | "onResponderMove" | "onResponderRelease" | "onResponderStart" | "onResponderTerminationRequest" | "onResponderTerminate" | "onStartShouldSetResponderCapture" | "onMoveShouldSetResponderCapture" | "accessibilityLabel" | "accessible" | "hitSlop" | "removeClippedSubviews" | "nativeID" | "collapsable" | "needsOffscreenAlphaCompositing" | "renderToHardwareTextureAndroid" | "focusable" | "shouldRasterizeIOS" | "isTVSelectable" | "hasTVPreferredFocus" | "tvParallaxProperties" | "tvParallaxShiftDistanceX" | "tvParallaxShiftDistanceY" | "tvParallaxTiltAngle" | "tvParallaxMagnification" | "onTouchStart" | "onTouchMove" | "onTouchEnd" | "onTouchCancel" | "onTouchEndCapture" | "accessibilityActions" | "accessibilityRole" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityLabelledBy" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "variant" | "keyboardShouldPersistTaps" | "onChange" | "indicatorColor" | "initialIndex" | "scrollable" | "disableIndicator" | "UNSTABLE_sharedIndex"> & React.RefAttributes<TabsInstance>>;
4
+ declare const Tabs: React.ForwardRefExoticComponent<Pick<TabsProps, "testID" | "style" | "onLayout" | "keyboardDismissMode" | "children" | "pointerEvents" | "onStartShouldSetResponder" | "onMoveShouldSetResponder" | "onResponderEnd" | "onResponderGrant" | "onResponderReject" | "onResponderMove" | "onResponderRelease" | "onResponderStart" | "onResponderTerminationRequest" | "onResponderTerminate" | "onStartShouldSetResponderCapture" | "onMoveShouldSetResponderCapture" | "accessibilityLabel" | "accessible" | "hitSlop" | "removeClippedSubviews" | "nativeID" | "collapsable" | "needsOffscreenAlphaCompositing" | "renderToHardwareTextureAndroid" | "focusable" | "shouldRasterizeIOS" | "isTVSelectable" | "hasTVPreferredFocus" | "tvParallaxProperties" | "tvParallaxShiftDistanceX" | "tvParallaxShiftDistanceY" | "tvParallaxTiltAngle" | "tvParallaxMagnification" | "onTouchStart" | "onTouchMove" | "onTouchEnd" | "onTouchCancel" | "onTouchEndCapture" | "accessibilityActions" | "accessibilityRole" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityLabelledBy" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "variant" | "keyboardShouldPersistTaps" | "onChange" | "indicatorColor" | "indicatorSize" | "initialIndex" | "scrollable" | "disableIndicator" | "UNSTABLE_sharedIndex" | "onTabSelected"> & React.RefAttributes<TabsInstance>>;
5
5
  export default Tabs;
@@ -1,7 +1,7 @@
1
1
  import type { ReactNode, Ref } from 'react';
2
2
  import type { ViewProps } from 'react-native';
3
3
  import type { TabIndicatorColor } from './TabIndicatorProps';
4
- import type { TabVariant } from '../Tab';
4
+ import type { TabVariant, TabIndicatorSize } from '../Tab';
5
5
  import type { OverridableComponentProps, SyncAnimatedValue } from '../types';
6
6
  import type { KeyboardDismissMode, KeyboardShouldPersistTaps, TabsInstance } from './types';
7
7
  export default interface TabsProps extends OverridableComponentProps<ViewProps, {
@@ -20,6 +20,13 @@ export default interface TabsProps extends OverridableComponentProps<ViewProps,
20
20
  * @default 'primary'
21
21
  */
22
22
  indicatorColor?: TabIndicatorColor;
23
+ /**
24
+ * The size of tab indicator.
25
+ * 'full' adjusts the indicator to the size of the Tab,
26
+ * while 'fit-content' adjusts the indicator to the size of the content inside the Tab.
27
+ * @default 'full'
28
+ */
29
+ indicatorSize?: TabIndicatorSize;
23
30
  /**
24
31
  * Index of initial tab that should be selected.
25
32
  * @default 0
@@ -53,5 +60,11 @@ export default interface TabsProps extends OverridableComponentProps<ViewProps,
53
60
  * @default 'primary'
54
61
  */
55
62
  variant?: TabVariant;
63
+ /**
64
+ * Callback function executed when a Tab is selected.
65
+ * Executed even if the index does not change when a Tab is pressed.
66
+ * Receives the next tab index and the current tab index as parameters.
67
+ */
68
+ onTabSelected?: (newIndex: number, currentIndex: number) => void;
56
69
  }> {
57
70
  }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface UpdateInnerContentsWidth {
3
+ (index: number, width: number): void;
4
+ }
5
+ declare const useTabInnerContentsWidth: (tabElements: React.ReactNode) => [number[], UpdateInnerContentsWidth];
6
+ export default useTabInnerContentsWidth;
@@ -1,3 +1,3 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type TabCoordinate from './TabCoordinate';
3
- export declare function isEveryTabCoordinatesDefined(coordinates: TabCoordinate[], tabElements: ReactNode): boolean;
3
+ export declare function isEveryTabCoordinatesDefined(coordinates: (TabCoordinate | number)[], tabElements: ReactNode): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/core",
3
- "version": "2.0.0-beta.75",
3
+ "version": "2.0.0-beta.77",
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": "474e7eda06ca67e0986459cb8426e9323eb328a5"
70
+ "gitHead": "3edf58805967bc1a5f73ed1d5833fa5a55f59504"
71
71
  }
@@ -1,9 +1,11 @@
1
- import React from 'react';
2
- import { useWindowDimensions } from 'react-native';
1
+ import React, { useEffect } from 'react';
2
+ import { useWindowDimensions, Animated } from 'react-native';
3
3
  import { css, NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';
4
4
  import Column from '../Column';
5
5
  import Modal from '../Modal';
6
6
  import Paper from '../Paper';
7
+ import { useAnimatedValue } from '../hooks';
8
+ import { isNotAndroid12 } from '../utils';
7
9
  import { useTheme } from '../styles';
8
10
  import type DialogProps from './DialogProps';
9
11
 
@@ -20,6 +22,10 @@ type DialogStyles = NamedStylesStringUnion<DialogStyleKeys>;
20
22
 
21
23
  const DIALOG_MAX_WIDTH = 328;
22
24
 
25
+ const fadeInDuration = 300;
26
+ const fadeOutDuration = 100;
27
+ const fadeAnimationDelay = 50;
28
+
23
29
  const useStyles: UseStyles<DialogStyles> = function (): DialogStyles {
24
30
  const theme = useTheme();
25
31
 
@@ -74,16 +80,32 @@ export default function Dialog(props: DialogProps) {
74
80
 
75
81
  const styles = useStyles();
76
82
  const theme = useTheme();
83
+ const animatedOpacity = useAnimatedValue(fullScreen ? 1 : 0);
84
+
85
+ useEffect(() => {
86
+ if(!fullScreen){
87
+ Animated.timing(animatedOpacity, {
88
+ toValue: visible ? 1 : 0,
89
+ duration: visible ? fadeInDuration: fadeOutDuration,
90
+ delay: visible ? fadeAnimationDelay : 0,
91
+ useNativeDriver: isNotAndroid12,
92
+ }).start();
93
+ }
94
+ }, [fullScreen, visible]);
77
95
 
78
96
  return (
79
97
  <Modal
80
98
  animationStyle={fullScreen ? styles.animationFullScreen : styles.animation}
81
99
  onClose={onClose}
100
+ exitDuration={fullScreen ? 150 : 300}
82
101
  visible={visible}
83
102
  style={styles.root}
84
103
  {...otherProps}
85
104
  >
86
- <React.Fragment>
105
+ <Animated.View
106
+ needsOffscreenAlphaCompositing={true}
107
+ style={{ opacity: animatedOpacity }}
108
+ >
87
109
  {topElement ? (
88
110
  <Column style={fullScreen ? undefined : styles.topElementSize}>
89
111
  <Column style={styles.topElementPosition}>
@@ -103,7 +125,7 @@ export default function Dialog(props: DialogProps) {
103
125
  >
104
126
  {children}
105
127
  </Paper>
106
- </React.Fragment>
128
+ </Animated.View>
107
129
  </Modal>
108
130
  );
109
131
  };
@@ -14,6 +14,9 @@ export interface ModalCloseEvent {
14
14
  };
15
15
  }
16
16
 
17
+ const defaultEnterDuration = 300;
18
+ const defaultExitDuration = 150;
19
+
17
20
  export const createModalCloseEvent = (reason: ModalCloseReasonType) => ({
18
21
  metadata: {
19
22
  reason,
@@ -26,6 +29,8 @@ export default function Modal(props: ModalProps) {
26
29
  backdropOpacity = 0.5,
27
30
  children,
28
31
  disableAnimation = false,
32
+ enterDuration = defaultEnterDuration,
33
+ exitDuration = defaultExitDuration,
29
34
  hideBackdrop = false,
30
35
  onClose,
31
36
  style,
@@ -68,7 +73,8 @@ export default function Modal(props: ModalProps) {
68
73
  {!disableAnimation ? (
69
74
  <Slide
70
75
  appear={visible}
71
- exitDuration={150}
76
+ enterDuration={enterDuration}
77
+ exitDuration={exitDuration}
72
78
  onEnter={() => setExited(false)}
73
79
  onExited={() => setExited(true)}
74
80
  style={animationStyle}
@@ -26,6 +26,18 @@ export default interface ModalProps extends OverridableComponentProps<ViewProps,
26
26
  */
27
27
  disableAnimation?: boolean;
28
28
 
29
+ /**
30
+ * The number of milliseconds to enter animation.
31
+ * @default 300
32
+ */
33
+ enterDuration?: number;
34
+
35
+ /**
36
+ * The number of milliseconds to exit animation.
37
+ * @default 150
38
+ */
39
+ exitDuration?: number;
40
+
29
41
  /**
30
42
  * If `true`, the backdrop is not rendered.
31
43
  * @default false
@@ -1,14 +1,20 @@
1
- import React from 'react';
2
- import { View } from 'react-native';
1
+ import React, { useEffect } from 'react';
2
+ import { Animated } from 'react-native';
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
- import { css, NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';
4
+ import { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';
5
5
  import Slide from '../Slide';
6
6
  import SnackbarContent from '../SnackbarContent';
7
+ import { useAnimatedValue } from '../hooks';
7
8
  import { useTheme } from '../styles';
9
+ import { isNotAndroid12 } from '../utils';
8
10
  import type SnackbarProps from './SnackbarProps';
9
11
 
10
12
  type SnackBarStyles = NamedStylesStringUnion<'root'>;
11
13
 
14
+ const fadeInDuration = 300;
15
+ const fadeOutDuration = 110;
16
+ const fadeAnimationDelay = 100;
17
+
12
18
  const useStyles: UseStyles<SnackBarStyles> = function (): SnackBarStyles {
13
19
  const theme = useTheme();
14
20
  const insets = useSafeAreaInsets();
@@ -75,16 +81,32 @@ export default function Snackbar(props: SnackbarProps) {
75
81
 
76
82
  const [exited, setExited] = React.useState(true);
77
83
 
84
+ const animatedOpacity = useAnimatedValue(0);
85
+
86
+ const animatedStyle = {
87
+ opacity: animatedOpacity,
88
+ };
89
+
90
+ useEffect(() => {
91
+ Animated.timing(animatedOpacity, {
92
+ toValue: visible ? 1 : 0,
93
+ duration: visible ? fadeInDuration : fadeOutDuration,
94
+ delay: visible ? fadeAnimationDelay : 0,
95
+ useNativeDriver: isNotAndroid12,
96
+ }).start();
97
+ }, [visible]);
98
+
78
99
  if (!visible && exited) {
79
100
  return null;
80
101
  }
81
102
 
82
103
  return (
83
- <View
84
- style={css([
104
+ <Animated.View
105
+ style={[
106
+ animatedStyle,
85
107
  styles.root,
86
108
  style,
87
- ])}
109
+ ]}
88
110
  {...otherProps}
89
111
  >
90
112
  <Slide
@@ -103,6 +125,6 @@ export default function Snackbar(props: SnackbarProps) {
103
125
  />
104
126
  )}
105
127
  </Slide>
106
- </View>
128
+ </Animated.View>
107
129
  );
108
130
  };
package/src/Tab/Tab.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { cloneElement } from 'react';
2
- import { Platform, Text } from 'react-native';
2
+ import { Platform, Text, View } from 'react-native';
3
3
  import Badge from '../Badge';
4
4
  import TabBase from '../TabBase';
5
5
  import type TabProps from './TabProps';
@@ -10,16 +10,14 @@ const styles = StyleSheet.create({
10
10
  root: {
11
11
  // TODO: Remove redundant platform checking
12
12
  ...(Platform.OS === 'web' ? { minWidth: 'auto' } : {}),
13
- },
14
- primary: {
15
- minHeight: 40,
16
- },
17
- secondary: {
18
13
  minHeight: 40,
19
14
  },
20
15
  bottomNavigation: {
21
16
  minHeight: 56,
22
17
  },
18
+ filledInner: {
19
+ justifyContent: 'center',
20
+ }
23
21
  });
24
22
 
25
23
  export default function Tab(props: TabProps) {
@@ -29,10 +27,12 @@ export default function Tab(props: TabProps) {
29
27
  enableIndicator = false,
30
28
  icon: defaultIcon,
31
29
  indicatorColor = 'primary',
30
+ indicatorSize = 'full',
32
31
  selected = false,
33
32
  selectedIcon,
34
33
  variant = 'primary',
35
34
  style,
35
+ onTabInnerLayout,
36
36
  ...otherProps
37
37
  } = props;
38
38
 
@@ -44,12 +44,15 @@ export default function Tab(props: TabProps) {
44
44
 
45
45
  const tabBaseStyle = css([
46
46
  styles.root,
47
- variant === 'primary'
48
- ? styles.primary
49
- : (variant === 'secondary' ? styles.secondary : styles.bottomNavigation),
47
+ variant === 'bottom-navigation' && styles.bottomNavigation,
50
48
  style,
51
49
  ]);
52
50
 
51
+ const tabInnerStyle = css([
52
+ styles.root,
53
+ styles.filledInner,
54
+ ]);
55
+
53
56
  const fontStyle = createFontStyle(theme, {
54
57
  selector: (typo) => variant === 'primary'
55
58
  ? typo.h2
@@ -62,13 +65,12 @@ export default function Tab(props: TabProps) {
62
65
  const icon = selected ? (selectedIcon || defaultIcon) : defaultIcon;
63
66
  const iconElement = icon ? cloneElement(icon, { fill: color }) : null;
64
67
 
65
- return (
66
- <TabBase
67
- pressEffect={pressEffect}
68
- style={tabBaseStyle}
69
- vertical={vertical}
70
- {...otherProps}
71
- >
68
+ const tabElement = typeof children !== 'string' ? (
69
+ React.cloneElement(children, {
70
+ selected,
71
+ })
72
+ ) : (
73
+ <React.Fragment>
72
74
  <Badge
73
75
  children={iconElement}
74
76
  invisible={!badgeVisible}
@@ -78,8 +80,32 @@ export default function Tab(props: TabProps) {
78
80
  children={children}
79
81
  style={css(fontStyle)}
80
82
  />
83
+ </React.Fragment>
84
+ );
85
+ const tabIndicator = (enableIndicator && selected)
86
+ ? <TabIndicator indicatorSize={indicatorSize} color={indicatorColor}/>
87
+ : null;
88
+
89
+ return (
90
+ <TabBase
91
+ pressEffect={pressEffect}
92
+ style={tabBaseStyle}
93
+ vertical={vertical}
94
+ {...otherProps}
95
+ >
96
+ {indicatorSize === 'fit-content' ? (
97
+ <View onLayout={onTabInnerLayout} style={tabInnerStyle}>
98
+ {tabElement}
99
+
100
+ {tabIndicator}
101
+ </View>
102
+ ) : (
103
+ <React.Fragment>
104
+ {tabElement}
81
105
 
82
- {(enableIndicator && selected) ? <TabIndicator color={indicatorColor}/> : null}
106
+ {tabIndicator}
107
+ </React.Fragment>
108
+ )}
83
109
  </TabBase>
84
110
  );
85
111
  };
@@ -2,12 +2,12 @@ import React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { NamedStylesStringUnion } from '@fountain-ui/styles';
4
4
  import { useTheme } from '../styles';
5
- import type { TabIndicatorColor } from './TabProps';
5
+ import type { TabIndicatorColor, TabIndicatorSize } from './TabProps';
6
6
 
7
7
  type TabIndicatorStyles = NamedStylesStringUnion<'root'>;
8
8
 
9
- const useStyles: (color: TabIndicatorColor) => TabIndicatorStyles =
10
- function (color: TabIndicatorColor): TabIndicatorStyles {
9
+ const useStyles: (color: TabIndicatorColor, indicatorSize: TabIndicatorSize) => TabIndicatorStyles =
10
+ function (color: TabIndicatorColor, indicatorSize): TabIndicatorStyles {
11
11
  const theme = useTheme();
12
12
 
13
13
  return {
@@ -15,15 +15,15 @@ const useStyles: (color: TabIndicatorColor) => TabIndicatorStyles =
15
15
  backgroundColor: theme.palette[color].main,
16
16
  bottom: 0,
17
17
  height: 2,
18
- left: 12,
19
- right: 12,
18
+ left: indicatorSize === 'fit-content' ? 0 : 12,
19
+ right: indicatorSize === 'fit-content' ? 0 : 12,
20
20
  position: 'absolute',
21
21
  },
22
22
  };
23
23
  };
24
24
 
25
- const TabIndicator = function TabIndicator({ color }: { color: TabIndicatorColor }) {
26
- const styles = useStyles(color);
25
+ const TabIndicator = function TabIndicator({ indicatorSize, color }: { indicatorSize: TabIndicatorSize; color: TabIndicatorColor }) {
26
+ const styles = useStyles(color, indicatorSize);
27
27
 
28
28
  return (
29
29
  <View
@@ -1,9 +1,11 @@
1
1
  import React from 'react';
2
+ import type { LayoutChangeEvent } from 'react-native';
2
3
  import type { TabBaseProps } from '../TabBase';
3
4
  import type { OverridableComponentProps } from '../types';
4
5
 
5
6
  export type TabVariant = 'primary' | 'secondary' | 'bottom-navigation';
6
7
  export type TabIndicatorColor = 'primary' | 'secondary'
8
+ export type TabIndicatorSize = 'full' | 'fit-content';
7
9
 
8
10
  export default interface TabProps extends OverridableComponentProps<TabBaseProps, {
9
11
  /**
@@ -15,7 +17,7 @@ export default interface TabProps extends OverridableComponentProps<TabBaseProps
15
17
  /**
16
18
  * The label of the Tab.
17
19
  */
18
- children: string;
20
+ children: string | React.ReactElement;
19
21
 
20
22
  /**
21
23
  * If `true`, the indicator is enabled.
@@ -40,6 +42,14 @@ export default interface TabProps extends OverridableComponentProps<TabBaseProps
40
42
  */
41
43
  indicatorColor?: TabIndicatorColor;
42
44
 
45
+ /**
46
+ * The size of tab indicator.
47
+ * 'full' adjusts the indicator to the size of the Tab,
48
+ * while 'fit-content' adjusts the indicator to the size of the content inside the Tab.
49
+ * @default 'full'
50
+ */
51
+ indicatorSize?: TabIndicatorSize;
52
+
43
53
  /**
44
54
  * If supplied, use this icon on selected state.
45
55
  */
@@ -50,4 +60,9 @@ export default interface TabProps extends OverridableComponentProps<TabBaseProps
50
60
  * @default 'primary'
51
61
  */
52
62
  variant?: TabVariant;
63
+
64
+ /**
65
+ * Function to be passed to the child component's onLayout prop.
66
+ */
67
+ onTabInnerLayout?: (event: LayoutChangeEvent) => void;
53
68
  }> {}