@cdx-ui/components 0.0.1-beta.5 → 0.0.1-beta.51
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/README.md +28 -18
- package/lib/commonjs/components/AlertDialog/index.js +1 -1
- package/lib/commonjs/components/AlertDialog/index.js.map +1 -1
- package/lib/commonjs/components/Avatar/index.js +1 -1
- package/lib/commonjs/components/Avatar/styles.js +36 -29
- package/lib/commonjs/components/Avatar/styles.js.map +1 -1
- package/lib/commonjs/components/Button/index.js +16 -1
- package/lib/commonjs/components/Button/index.js.map +1 -1
- package/lib/commonjs/components/Button/styles.js +85 -26
- package/lib/commonjs/components/Button/styles.js.map +1 -1
- package/lib/commonjs/components/CLAUDE.md +90 -0
- package/lib/commonjs/components/Card/index.js +22 -4
- package/lib/commonjs/components/Card/index.js.map +1 -1
- package/lib/commonjs/components/Card/styles.js +27 -4
- package/lib/commonjs/components/Card/styles.js.map +1 -1
- package/lib/commonjs/components/Checkbox/index.js +5 -29
- package/lib/commonjs/components/Checkbox/index.js.map +1 -1
- package/lib/commonjs/components/Checkbox/styles.js +39 -47
- package/lib/commonjs/components/Checkbox/styles.js.map +1 -1
- package/lib/commonjs/components/Chip/index.js +78 -9
- package/lib/commonjs/components/Chip/index.js.map +1 -1
- package/lib/commonjs/components/Chip/styles.js +207 -21
- package/lib/commonjs/components/Chip/styles.js.map +1 -1
- package/lib/commonjs/components/Field/index.js +8 -2
- package/lib/commonjs/components/Field/index.js.map +1 -1
- package/lib/commonjs/components/Field/styles.js +4 -4
- package/lib/commonjs/components/Field/styles.js.map +1 -1
- package/lib/commonjs/components/Heading/styles.js +1 -1
- package/lib/commonjs/components/Heading/styles.js.map +1 -1
- package/lib/commonjs/components/Icon/index.js +3 -4
- package/lib/commonjs/components/Icon/index.js.map +1 -1
- package/lib/commonjs/components/IconButton/index.js +6 -1
- package/lib/commonjs/components/IconButton/index.js.map +1 -1
- package/lib/commonjs/components/IconButton/styles.js +135 -10
- package/lib/commonjs/components/IconButton/styles.js.map +1 -1
- package/lib/commonjs/components/Input/styles.js +7 -6
- package/lib/commonjs/components/Input/styles.js.map +1 -1
- package/lib/commonjs/components/Link/index.js +22 -3
- package/lib/commonjs/components/Link/index.js.map +1 -1
- package/lib/commonjs/components/Link/styles.js +56 -6
- package/lib/commonjs/components/Link/styles.js.map +1 -1
- package/lib/commonjs/components/ListItem/styles.js +9 -9
- package/lib/commonjs/components/ListItem/styles.js.map +1 -1
- package/lib/commonjs/components/ProgressSegmented/index.js +24 -10
- package/lib/commonjs/components/ProgressSegmented/index.js.map +1 -1
- package/lib/commonjs/components/Radio/index.js +167 -0
- package/lib/commonjs/components/Radio/index.js.map +1 -0
- package/lib/commonjs/components/Radio/styles.js +31 -0
- package/lib/commonjs/components/Radio/styles.js.map +1 -0
- package/lib/commonjs/components/ScopedTheme/index.js +24 -0
- package/lib/commonjs/components/ScopedTheme/index.js.map +1 -0
- package/lib/commonjs/components/Select/SelectTriggerHost.web.js +4 -0
- package/lib/commonjs/components/Select/SelectTriggerHost.web.js.map +1 -1
- package/lib/commonjs/components/Select/index.js +9 -3
- package/lib/commonjs/components/Select/index.js.map +1 -1
- package/lib/commonjs/components/Select/styles.js +17 -20
- package/lib/commonjs/components/Select/styles.js.map +1 -1
- package/lib/commonjs/components/Text/styles.js +2 -2
- package/lib/commonjs/components/Text/styles.js.map +1 -1
- package/lib/commonjs/components/Tile/index.js +251 -0
- package/lib/commonjs/components/Tile/index.js.map +1 -0
- package/lib/commonjs/components/Tile/styles.js +52 -0
- package/lib/commonjs/components/Tile/styles.js.map +1 -0
- package/lib/commonjs/components/index.js +36 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/figma/Avatar.figma.js +54 -0
- package/lib/commonjs/figma/Avatar.figma.js.map +1 -0
- package/lib/commonjs/figma/Button.figma.js +28 -15
- package/lib/commonjs/figma/Button.figma.js.map +1 -1
- package/lib/commonjs/figma/CLAUDE.md +30 -0
- package/lib/commonjs/figma/Card.Header.figma.js +28 -0
- package/lib/commonjs/figma/Card.Header.figma.js.map +1 -0
- package/lib/commonjs/figma/Card.figma.js +42 -0
- package/lib/commonjs/figma/Card.figma.js.map +1 -0
- package/lib/commonjs/figma/Checkbox.figma.js +55 -0
- package/lib/commonjs/figma/Checkbox.figma.js.map +1 -0
- package/lib/commonjs/figma/Chip.figma.js +68 -0
- package/lib/commonjs/figma/Chip.figma.js.map +1 -0
- package/lib/commonjs/figma/Field.Input.figma.js +57 -0
- package/lib/commonjs/figma/Field.Input.figma.js.map +1 -0
- package/lib/commonjs/figma/Field.Select.figma.js +57 -0
- package/lib/commonjs/figma/Field.Select.figma.js.map +1 -0
- package/lib/commonjs/figma/Heading.figma.js +30 -0
- package/lib/commonjs/figma/Heading.figma.js.map +1 -0
- package/lib/commonjs/figma/Icon.figma.js +20 -0
- package/lib/commonjs/figma/Icon.figma.js.map +1 -0
- package/lib/commonjs/figma/IconButton.figma.js +47 -0
- package/lib/commonjs/figma/IconButton.figma.js.map +1 -0
- package/lib/commonjs/figma/Input.figma.js +52 -0
- package/lib/commonjs/figma/Input.figma.js.map +1 -0
- package/lib/commonjs/figma/Link.figma.js +30 -0
- package/lib/commonjs/figma/Link.figma.js.map +1 -0
- package/lib/commonjs/figma/ProgressSegmented.figma.js +39 -0
- package/lib/commonjs/figma/ProgressSegmented.figma.js.map +1 -0
- package/lib/commonjs/figma/Radio.figma.js +40 -0
- package/lib/commonjs/figma/Radio.figma.js.map +1 -0
- package/lib/commonjs/figma/Select.figma.js +53 -0
- package/lib/commonjs/figma/Select.figma.js.map +1 -0
- package/lib/commonjs/figma/Text.figma.js +29 -0
- package/lib/commonjs/figma/Text.figma.js.map +1 -0
- package/lib/commonjs/figma/icons.figma.batch.js +27 -0
- package/lib/commonjs/figma/icons.figma.batch.js.map +1 -0
- package/lib/commonjs/figma/icons.figma.batch.json +17705 -0
- package/lib/commonjs/hooks/index.js +19 -0
- package/lib/commonjs/hooks/index.js.map +1 -0
- package/lib/commonjs/hooks/useForgeBottomTabScreenOptions.js +246 -0
- package/lib/commonjs/hooks/useForgeBottomTabScreenOptions.js.map +1 -0
- package/lib/commonjs/index.js +24 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/metro/withCdxMetroConfig.js +7 -18
- package/lib/commonjs/metro/withCdxMetroConfig.js.map +1 -1
- package/lib/commonjs/metro/withForgeMetroConfig.js +24 -0
- package/lib/commonjs/metro/withForgeMetroConfig.js.map +1 -0
- package/lib/commonjs/navigation/forgeTabIcon.js +43 -0
- package/lib/commonjs/navigation/forgeTabIcon.js.map +1 -0
- package/lib/commonjs/navigation/forgeTabIcon.native.js +35 -0
- package/lib/commonjs/navigation/forgeTabIcon.native.js.map +1 -0
- package/lib/commonjs/navigation/index.js +13 -0
- package/lib/commonjs/navigation/index.js.map +1 -0
- package/lib/commonjs/navigation/types.js +40 -0
- package/lib/commonjs/navigation/types.js.map +1 -0
- package/lib/commonjs/styles/primitives.js +43 -6
- package/lib/commonjs/styles/primitives.js.map +1 -1
- package/lib/module/components/AlertDialog/index.js +1 -1
- package/lib/module/components/AlertDialog/index.js.map +1 -1
- package/lib/module/components/Avatar/index.js +1 -1
- package/lib/module/components/Avatar/styles.js +36 -29
- package/lib/module/components/Avatar/styles.js.map +1 -1
- package/lib/module/components/Button/index.js +17 -2
- package/lib/module/components/Button/index.js.map +1 -1
- package/lib/module/components/Button/styles.js +85 -26
- package/lib/module/components/Button/styles.js.map +1 -1
- package/lib/module/components/CLAUDE.md +90 -0
- package/lib/module/components/Card/index.js +23 -4
- package/lib/module/components/Card/index.js.map +1 -1
- package/lib/module/components/Card/styles.js +27 -4
- package/lib/module/components/Card/styles.js.map +1 -1
- package/lib/module/components/Checkbox/index.js +6 -30
- package/lib/module/components/Checkbox/index.js.map +1 -1
- package/lib/module/components/Checkbox/styles.js +40 -48
- package/lib/module/components/Checkbox/styles.js.map +1 -1
- package/lib/module/components/Chip/index.js +82 -13
- package/lib/module/components/Chip/index.js.map +1 -1
- package/lib/module/components/Chip/styles.js +206 -20
- package/lib/module/components/Chip/styles.js.map +1 -1
- package/lib/module/components/Field/index.js +9 -3
- package/lib/module/components/Field/index.js.map +1 -1
- package/lib/module/components/Field/styles.js +4 -4
- package/lib/module/components/Field/styles.js.map +1 -1
- package/lib/module/components/Heading/styles.js +1 -1
- package/lib/module/components/Heading/styles.js.map +1 -1
- package/lib/module/components/Icon/index.js +3 -4
- package/lib/module/components/Icon/index.js.map +1 -1
- package/lib/module/components/IconButton/index.js +6 -1
- package/lib/module/components/IconButton/index.js.map +1 -1
- package/lib/module/components/IconButton/styles.js +135 -10
- package/lib/module/components/IconButton/styles.js.map +1 -1
- package/lib/module/components/Input/styles.js +7 -6
- package/lib/module/components/Input/styles.js.map +1 -1
- package/lib/module/components/Link/index.js +25 -6
- package/lib/module/components/Link/index.js.map +1 -1
- package/lib/module/components/Link/styles.js +55 -6
- package/lib/module/components/Link/styles.js.map +1 -1
- package/lib/module/components/ListItem/styles.js +10 -10
- package/lib/module/components/ListItem/styles.js.map +1 -1
- package/lib/module/components/ProgressSegmented/index.js +25 -11
- package/lib/module/components/ProgressSegmented/index.js.map +1 -1
- package/lib/module/components/Radio/index.js +164 -0
- package/lib/module/components/Radio/index.js.map +1 -0
- package/lib/module/components/Radio/styles.js +27 -0
- package/lib/module/components/Radio/styles.js.map +1 -0
- package/lib/module/components/ScopedTheme/index.js +19 -0
- package/lib/module/components/ScopedTheme/index.js.map +1 -0
- package/lib/module/components/Select/SelectTriggerHost.web.js +4 -0
- package/lib/module/components/Select/SelectTriggerHost.web.js.map +1 -1
- package/lib/module/components/Select/index.js +10 -4
- package/lib/module/components/Select/index.js.map +1 -1
- package/lib/module/components/Select/styles.js +18 -21
- package/lib/module/components/Select/styles.js.map +1 -1
- package/lib/module/components/Text/styles.js +2 -2
- package/lib/module/components/Text/styles.js.map +1 -1
- package/lib/module/components/Tile/index.js +243 -0
- package/lib/module/components/Tile/index.js.map +1 -0
- package/lib/module/components/Tile/styles.js +48 -0
- package/lib/module/components/Tile/styles.js.map +1 -0
- package/lib/module/components/index.js +3 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/figma/Avatar.figma.js +48 -0
- package/lib/module/figma/Avatar.figma.js.map +1 -0
- package/lib/module/figma/Button.figma.js +28 -15
- package/lib/module/figma/Button.figma.js.map +1 -1
- package/lib/module/figma/CLAUDE.md +30 -0
- package/lib/module/figma/Card.Header.figma.js +22 -0
- package/lib/module/figma/Card.Header.figma.js.map +1 -0
- package/lib/module/figma/Card.figma.js +36 -0
- package/lib/module/figma/Card.figma.js.map +1 -0
- package/lib/module/figma/Checkbox.figma.js +49 -0
- package/lib/module/figma/Checkbox.figma.js.map +1 -0
- package/lib/module/figma/Chip.figma.js +62 -0
- package/lib/module/figma/Chip.figma.js.map +1 -0
- package/lib/module/figma/Field.Input.figma.js +51 -0
- package/lib/module/figma/Field.Input.figma.js.map +1 -0
- package/lib/module/figma/Field.Select.figma.js +51 -0
- package/lib/module/figma/Field.Select.figma.js.map +1 -0
- package/lib/module/figma/Heading.figma.js +24 -0
- package/lib/module/figma/Heading.figma.js.map +1 -0
- package/lib/module/figma/Icon.figma.js +14 -0
- package/lib/module/figma/Icon.figma.js.map +1 -0
- package/lib/module/figma/IconButton.figma.js +41 -0
- package/lib/module/figma/IconButton.figma.js.map +1 -0
- package/lib/module/figma/Input.figma.js +46 -0
- package/lib/module/figma/Input.figma.js.map +1 -0
- package/lib/module/figma/Link.figma.js +24 -0
- package/lib/module/figma/Link.figma.js.map +1 -0
- package/lib/module/figma/ProgressSegmented.figma.js +33 -0
- package/lib/module/figma/ProgressSegmented.figma.js.map +1 -0
- package/lib/module/figma/Radio.figma.js +34 -0
- package/lib/module/figma/Radio.figma.js.map +1 -0
- package/lib/module/figma/Select.figma.js +47 -0
- package/lib/module/figma/Select.figma.js.map +1 -0
- package/lib/module/figma/Text.figma.js +23 -0
- package/lib/module/figma/Text.figma.js.map +1 -0
- package/lib/module/figma/icons.figma.batch.js +22 -0
- package/lib/module/figma/icons.figma.batch.js.map +1 -0
- package/lib/module/figma/icons.figma.batch.json +17705 -0
- package/lib/module/hooks/index.js +4 -0
- package/lib/module/hooks/index.js.map +1 -0
- package/lib/module/hooks/useForgeBottomTabScreenOptions.js +242 -0
- package/lib/module/hooks/useForgeBottomTabScreenOptions.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/metro/withCdxMetroConfig.js +3 -17
- package/lib/module/metro/withCdxMetroConfig.js.map +1 -1
- package/lib/module/metro/withForgeMetroConfig.js +20 -0
- package/lib/module/metro/withForgeMetroConfig.js.map +1 -0
- package/lib/module/navigation/forgeTabIcon.js +39 -0
- package/lib/module/navigation/forgeTabIcon.js.map +1 -0
- package/lib/module/navigation/forgeTabIcon.native.js +31 -0
- package/lib/module/navigation/forgeTabIcon.native.js.map +1 -0
- package/lib/module/navigation/index.js +4 -0
- package/lib/module/navigation/index.js.map +1 -0
- package/lib/module/navigation/types.js +38 -0
- package/lib/module/navigation/types.js.map +1 -0
- package/lib/module/styles/primitives.js +43 -6
- package/lib/module/styles/primitives.js.map +1 -1
- package/lib/typescript/components/Avatar/styles.d.ts +4 -4
- package/lib/typescript/components/Avatar/styles.d.ts.map +1 -1
- package/lib/typescript/components/Button/index.d.ts +13 -1
- package/lib/typescript/components/Button/index.d.ts.map +1 -1
- package/lib/typescript/components/Button/styles.d.ts +5 -3
- package/lib/typescript/components/Button/styles.d.ts.map +1 -1
- package/lib/typescript/components/Card/index.d.ts +4 -3
- package/lib/typescript/components/Card/index.d.ts.map +1 -1
- package/lib/typescript/components/Card/styles.d.ts +13 -3
- package/lib/typescript/components/Card/styles.d.ts.map +1 -1
- package/lib/typescript/components/Checkbox/index.d.ts +1 -2
- package/lib/typescript/components/Checkbox/index.d.ts.map +1 -1
- package/lib/typescript/components/Checkbox/styles.d.ts +4 -14
- package/lib/typescript/components/Checkbox/styles.d.ts.map +1 -1
- package/lib/typescript/components/Chip/index.d.ts +19 -6
- package/lib/typescript/components/Chip/index.d.ts.map +1 -1
- package/lib/typescript/components/Chip/styles.d.ts +13 -4
- package/lib/typescript/components/Chip/styles.d.ts.map +1 -1
- package/lib/typescript/components/Field/FieldLabel.web.d.ts +2 -2
- package/lib/typescript/components/Field/FieldLabel.web.d.ts.map +1 -1
- package/lib/typescript/components/Field/index.d.ts.map +1 -1
- package/lib/typescript/components/Field/styles.d.ts.map +1 -1
- package/lib/typescript/components/Heading/styles.d.ts +1 -1
- package/lib/typescript/components/Icon/index.d.ts +5 -5
- package/lib/typescript/components/Icon/index.d.ts.map +1 -1
- package/lib/typescript/components/IconButton/index.d.ts +3 -3
- package/lib/typescript/components/IconButton/index.d.ts.map +1 -1
- package/lib/typescript/components/IconButton/styles.d.ts +6 -2
- package/lib/typescript/components/IconButton/styles.d.ts.map +1 -1
- package/lib/typescript/components/Input/styles.d.ts.map +1 -1
- package/lib/typescript/components/Link/index.d.ts +2 -2
- package/lib/typescript/components/Link/index.d.ts.map +1 -1
- package/lib/typescript/components/Link/styles.d.ts +9 -2
- package/lib/typescript/components/Link/styles.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
- package/lib/typescript/components/ProgressSegmented/index.d.ts +14 -3
- package/lib/typescript/components/ProgressSegmented/index.d.ts.map +1 -1
- package/lib/typescript/components/Radio/index.d.ts +40 -0
- package/lib/typescript/components/Radio/index.d.ts.map +1 -0
- package/lib/typescript/components/Radio/styles.d.ts +8 -0
- package/lib/typescript/components/Radio/styles.d.ts.map +1 -0
- package/lib/typescript/components/ScopedTheme/index.d.ts +16 -0
- package/lib/typescript/components/ScopedTheme/index.d.ts.map +1 -0
- package/lib/typescript/components/Select/SelectTriggerHost.web.d.ts +3 -0
- package/lib/typescript/components/Select/SelectTriggerHost.web.d.ts.map +1 -1
- package/lib/typescript/components/Select/index.d.ts +1 -1
- package/lib/typescript/components/Select/index.d.ts.map +1 -1
- package/lib/typescript/components/Select/styles.d.ts.map +1 -1
- package/lib/typescript/components/Stack/styles.d.ts +2 -2
- package/lib/typescript/components/Text/styles.d.ts +1 -1
- package/lib/typescript/components/Tile/index.d.ts +70 -0
- package/lib/typescript/components/Tile/index.d.ts.map +1 -0
- package/lib/typescript/components/Tile/styles.d.ts +18 -0
- package/lib/typescript/components/Tile/styles.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +3 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/figma/Avatar.figma.d.ts +8 -0
- package/lib/typescript/figma/Avatar.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Button.figma.d.ts.map +1 -1
- package/lib/typescript/figma/Card.Header.figma.d.ts +8 -0
- package/lib/typescript/figma/Card.Header.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Card.figma.d.ts +8 -0
- package/lib/typescript/figma/Card.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Checkbox.figma.d.ts +8 -0
- package/lib/typescript/figma/Checkbox.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Chip.figma.d.ts +8 -0
- package/lib/typescript/figma/Chip.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Field.Input.figma.d.ts +8 -0
- package/lib/typescript/figma/Field.Input.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Field.Select.figma.d.ts +8 -0
- package/lib/typescript/figma/Field.Select.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Heading.figma.d.ts +8 -0
- package/lib/typescript/figma/Heading.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Icon.figma.d.ts +8 -0
- package/lib/typescript/figma/Icon.figma.d.ts.map +1 -0
- package/lib/typescript/figma/IconButton.figma.d.ts +8 -0
- package/lib/typescript/figma/IconButton.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Input.figma.d.ts +8 -0
- package/lib/typescript/figma/Input.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Link.figma.d.ts +8 -0
- package/lib/typescript/figma/Link.figma.d.ts.map +1 -0
- package/lib/typescript/figma/ProgressSegmented.figma.d.ts +8 -0
- package/lib/typescript/figma/ProgressSegmented.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Radio.figma.d.ts +8 -0
- package/lib/typescript/figma/Radio.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Select.figma.d.ts +8 -0
- package/lib/typescript/figma/Select.figma.d.ts.map +1 -0
- package/lib/typescript/figma/Text.figma.d.ts +8 -0
- package/lib/typescript/figma/Text.figma.d.ts.map +1 -0
- package/lib/typescript/figma/icons.figma.batch.d.ts +14 -0
- package/lib/typescript/figma/icons.figma.batch.d.ts.map +1 -0
- package/lib/typescript/hooks/index.d.ts +2 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -0
- package/lib/typescript/hooks/useForgeBottomTabScreenOptions.d.ts +137 -0
- package/lib/typescript/hooks/useForgeBottomTabScreenOptions.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/metro/withCdxMetroConfig.d.ts +4 -18
- package/lib/typescript/metro/withCdxMetroConfig.d.ts.map +1 -1
- package/lib/typescript/metro/withForgeMetroConfig.d.ts +19 -0
- package/lib/typescript/metro/withForgeMetroConfig.d.ts.map +1 -0
- package/lib/typescript/navigation/forgeTabIcon.d.ts +27 -0
- package/lib/typescript/navigation/forgeTabIcon.d.ts.map +1 -0
- package/lib/typescript/navigation/forgeTabIcon.native.d.ts +15 -0
- package/lib/typescript/navigation/forgeTabIcon.native.d.ts.map +1 -0
- package/lib/typescript/navigation/index.d.ts +4 -0
- package/lib/typescript/navigation/index.d.ts.map +1 -0
- package/lib/typescript/navigation/types.d.ts +37 -0
- package/lib/typescript/navigation/types.d.ts.map +1 -0
- package/lib/typescript/styles/primitives.d.ts +38 -0
- package/lib/typescript/styles/primitives.d.ts.map +1 -1
- package/package.json +10 -8
- package/src/components/AlertDialog/index.tsx +1 -1
- package/src/components/Avatar/index.tsx +1 -1
- package/src/components/Avatar/styles.ts +49 -34
- package/src/components/Button/index.tsx +39 -5
- package/src/components/Button/styles.ts +56 -27
- package/src/components/CLAUDE.md +90 -0
- package/src/components/Card/index.tsx +41 -16
- package/src/components/Card/styles.ts +42 -15
- package/src/components/Checkbox/index.tsx +8 -19
- package/src/components/Checkbox/styles.ts +82 -86
- package/src/components/Chip/index.tsx +104 -27
- package/src/components/Chip/styles.ts +232 -18
- package/src/components/Field/FieldLabel.web.tsx +1 -1
- package/src/components/Field/index.tsx +10 -3
- package/src/components/Field/styles.ts +5 -4
- package/src/components/Heading/styles.ts +1 -1
- package/src/components/Icon/index.tsx +6 -7
- package/src/components/IconButton/index.tsx +7 -6
- package/src/components/IconButton/styles.ts +136 -10
- package/src/components/Input/styles.ts +15 -9
- package/src/components/Link/index.tsx +22 -9
- package/src/components/Link/styles.ts +49 -9
- package/src/components/ListItem/styles.ts +12 -19
- package/src/components/ProgressSegmented/index.tsx +50 -14
- package/src/components/Radio/index.tsx +192 -0
- package/src/components/Radio/styles.ts +59 -0
- package/src/components/ScopedTheme/index.tsx +17 -0
- package/src/components/Select/SelectTriggerHost.web.tsx +8 -1
- package/src/components/Select/index.tsx +9 -4
- package/src/components/Select/styles.ts +49 -51
- package/src/components/Text/styles.ts +2 -2
- package/src/components/Tile/index.tsx +296 -0
- package/src/components/Tile/styles.ts +82 -0
- package/src/components/index.ts +3 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useForgeBottomTabScreenOptions.ts +245 -0
- package/src/index.ts +2 -0
- package/src/metro/withCdxMetroConfig.ts +4 -29
- package/src/metro/withForgeMetroConfig.ts +29 -0
- package/src/navigation/forgeTabIcon.native.ts +36 -0
- package/src/navigation/forgeTabIcon.ts +33 -0
- package/src/navigation/index.ts +3 -0
- package/src/navigation/types.ts +55 -0
- package/src/styles/primitives.ts +43 -6
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { forwardRef, type ReactNode } from 'react';
|
|
2
|
+
import { Pressable, Text, View, type TextProps, type ViewProps } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
createTile,
|
|
5
|
+
type ITileGroupMultipleProps,
|
|
6
|
+
type ITileGroupSingleProps,
|
|
7
|
+
type ITileIndicatorProps,
|
|
8
|
+
type ITileLeadingSlotProps,
|
|
9
|
+
type ITileProps,
|
|
10
|
+
type ITileTrailingSlotProps,
|
|
11
|
+
useTileContext,
|
|
12
|
+
} from '@cdx-ui/primitives';
|
|
13
|
+
import { Check } from '@cdx-ui/icons';
|
|
14
|
+
import { dataAttributes } from '@cdx-ui/primitives';
|
|
15
|
+
import { cn, useStyleContext, withStyleContext } from '@cdx-ui/utils';
|
|
16
|
+
import { checkboxIndicatorVariants, checkboxIconVariants } from '../Checkbox/styles';
|
|
17
|
+
import { Icon } from '../Icon';
|
|
18
|
+
import { radioIndicatorVariants, radioInnerDotVariants } from '../Radio/styles';
|
|
19
|
+
import {
|
|
20
|
+
tileContentVariants,
|
|
21
|
+
tileDescriptionVariants,
|
|
22
|
+
tileGroupVariants,
|
|
23
|
+
tileIndicatorVariants,
|
|
24
|
+
tileLeadingSlotVariants,
|
|
25
|
+
tileRootVariants,
|
|
26
|
+
tileTitleVariants,
|
|
27
|
+
tileTrailingSlotVariants,
|
|
28
|
+
type TileGroupVariantProps,
|
|
29
|
+
type TileVariantProps,
|
|
30
|
+
} from './styles';
|
|
31
|
+
|
|
32
|
+
const TILE_SCOPE = 'TILE';
|
|
33
|
+
const TILE_GROUP_SCOPE = 'TILE_GROUP';
|
|
34
|
+
|
|
35
|
+
const RootPressable = withStyleContext(Pressable, TILE_SCOPE);
|
|
36
|
+
const GroupView = withStyleContext(View, TILE_GROUP_SCOPE);
|
|
37
|
+
|
|
38
|
+
interface TileGroupStyleContext {
|
|
39
|
+
shape?: TileVariantProps['shape'];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const useTileGroupStyleContext = (): TileGroupStyleContext => {
|
|
43
|
+
// `useStyleContext` types the result as a `Record`, but at runtime the value is
|
|
44
|
+
// `undefined` when no provider is in scope (e.g. standalone Tile). Cast through
|
|
45
|
+
// `unknown` to acknowledge that.
|
|
46
|
+
const ctx = useStyleContext(TILE_GROUP_SCOPE) as unknown as TileGroupStyleContext | undefined;
|
|
47
|
+
return ctx ?? {};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const TilePrimitive = createTile({
|
|
51
|
+
Pressable: RootPressable,
|
|
52
|
+
Group: GroupView,
|
|
53
|
+
LeadingSlot: View,
|
|
54
|
+
Content: View,
|
|
55
|
+
Title: Text,
|
|
56
|
+
Description: Text,
|
|
57
|
+
Indicator: View,
|
|
58
|
+
TrailingSlot: View,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// =============================================================================
|
|
62
|
+
// TILE GROUP
|
|
63
|
+
// =============================================================================
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Discriminated union mirroring `ITileGroupProps`, with `className` and layout variants added at
|
|
67
|
+
* the styled layer. Distributing the intersection across each branch keeps `interface … extends`
|
|
68
|
+
* ergonomics and avoids tripping `@typescript-eslint` on `(union) & { ... }`.
|
|
69
|
+
*
|
|
70
|
+
* `direction` and `spacing` constrain the group layout to the three supported patterns:
|
|
71
|
+
* - `direction="column"` + `spacing="default"` — vertical stack with gaps (default).
|
|
72
|
+
* - `direction="column"` + `spacing="none"` — tight vertical stack (rows touch).
|
|
73
|
+
* - `direction="row"` + `spacing="default"` — side-by-side horizontal layout.
|
|
74
|
+
*
|
|
75
|
+
* `shape` (when set) is propagated to child `Tile`s via `withStyleContext`, matching the
|
|
76
|
+
* Avatar size-propagation pattern. A per-tile `shape` prop overrides the inherited value.
|
|
77
|
+
*/
|
|
78
|
+
export interface TileGroupSingleProps extends ITileGroupSingleProps, TileGroupVariantProps {
|
|
79
|
+
className?: string;
|
|
80
|
+
/** Visual shape inherited by child `Tile`s. Per-tile `shape` overrides this. */
|
|
81
|
+
shape?: TileVariantProps['shape'];
|
|
82
|
+
}
|
|
83
|
+
export interface TileGroupMultipleProps extends ITileGroupMultipleProps, TileGroupVariantProps {
|
|
84
|
+
className?: string;
|
|
85
|
+
/** Visual shape inherited by child `Tile`s. Per-tile `shape` overrides this. */
|
|
86
|
+
shape?: TileVariantProps['shape'];
|
|
87
|
+
}
|
|
88
|
+
export type TileGroupProps = TileGroupSingleProps | TileGroupMultipleProps;
|
|
89
|
+
|
|
90
|
+
const TileGroup = forwardRef<View, TileGroupProps>(
|
|
91
|
+
({ className, style, children, direction, spacing, shape, ...props }, ref) => (
|
|
92
|
+
<TilePrimitive.Group
|
|
93
|
+
ref={ref as never}
|
|
94
|
+
className={cn(tileGroupVariants({ direction, spacing }), className)}
|
|
95
|
+
style={style}
|
|
96
|
+
context={{ shape }}
|
|
97
|
+
{...props}
|
|
98
|
+
>
|
|
99
|
+
{children}
|
|
100
|
+
</TilePrimitive.Group>
|
|
101
|
+
),
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
TileGroup.displayName = 'Tile.Group';
|
|
105
|
+
|
|
106
|
+
// =============================================================================
|
|
107
|
+
// TILE ROOT
|
|
108
|
+
// =============================================================================
|
|
109
|
+
|
|
110
|
+
export interface TileProps extends ITileProps, TileVariantProps {
|
|
111
|
+
className?: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const TileRoot = forwardRef<View, TileProps>(
|
|
115
|
+
({ shape: shapeProp, showSeparator, className, style, context, ...props }, ref) => {
|
|
116
|
+
const { shape: inheritedShape } = useTileGroupStyleContext();
|
|
117
|
+
const shape = shapeProp ?? inheritedShape ?? 'card';
|
|
118
|
+
const computedClassName = cn(tileRootVariants({ shape, showSeparator }), className);
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<TilePrimitive
|
|
122
|
+
ref={ref as never}
|
|
123
|
+
className={computedClassName}
|
|
124
|
+
context={{ ...context, shape }}
|
|
125
|
+
style={style}
|
|
126
|
+
{...props}
|
|
127
|
+
/>
|
|
128
|
+
);
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
TileRoot.displayName = 'Tile';
|
|
133
|
+
|
|
134
|
+
// =============================================================================
|
|
135
|
+
// SLOTS
|
|
136
|
+
// =============================================================================
|
|
137
|
+
|
|
138
|
+
export interface TileLeadingSlotProps extends ITileLeadingSlotProps {
|
|
139
|
+
className?: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const TileLeadingSlot = forwardRef<View, TileLeadingSlotProps>(
|
|
143
|
+
({ className, style, ...props }, ref) => (
|
|
144
|
+
<TilePrimitive.LeadingSlot
|
|
145
|
+
ref={ref as never}
|
|
146
|
+
className={cn(tileLeadingSlotVariants(), className)}
|
|
147
|
+
style={style}
|
|
148
|
+
{...props}
|
|
149
|
+
/>
|
|
150
|
+
),
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
TileLeadingSlot.displayName = 'Tile.LeadingSlot';
|
|
154
|
+
|
|
155
|
+
export interface TileContentProps extends ViewProps {
|
|
156
|
+
className?: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const TileContent = forwardRef<View, TileContentProps>(({ className, style, ...props }, ref) => (
|
|
160
|
+
<TilePrimitive.Content
|
|
161
|
+
ref={ref as never}
|
|
162
|
+
className={cn(tileContentVariants(), className)}
|
|
163
|
+
style={style}
|
|
164
|
+
{...props}
|
|
165
|
+
/>
|
|
166
|
+
));
|
|
167
|
+
|
|
168
|
+
TileContent.displayName = 'Tile.Content';
|
|
169
|
+
|
|
170
|
+
export interface TileTitleProps extends TextProps {
|
|
171
|
+
className?: string;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const TileTitle = forwardRef<Text, TileTitleProps>(
|
|
175
|
+
({ className, style, numberOfLines = 1, ...props }, ref) => (
|
|
176
|
+
<TilePrimitive.Title
|
|
177
|
+
ref={ref as never}
|
|
178
|
+
className={cn(tileTitleVariants(), className)}
|
|
179
|
+
style={style}
|
|
180
|
+
numberOfLines={numberOfLines}
|
|
181
|
+
{...props}
|
|
182
|
+
/>
|
|
183
|
+
),
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
TileTitle.displayName = 'Tile.Title';
|
|
187
|
+
|
|
188
|
+
export interface TileDescriptionProps extends TextProps {
|
|
189
|
+
className?: string;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const TileDescription = forwardRef<Text, TileDescriptionProps>(
|
|
193
|
+
({ className, style, ...props }, ref) => (
|
|
194
|
+
<TilePrimitive.Description
|
|
195
|
+
ref={ref as never}
|
|
196
|
+
className={cn(tileDescriptionVariants(), className)}
|
|
197
|
+
style={style}
|
|
198
|
+
{...props}
|
|
199
|
+
/>
|
|
200
|
+
),
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
TileDescription.displayName = 'Tile.Description';
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Decorative selection affordance. Renders pure CVA-styled Views — no interactive hooks,
|
|
207
|
+
* no nested Pressable, zero runtime overhead. The Tile root owns the press target and
|
|
208
|
+
* ARIA role; this subtree is `aria-hidden` via `createTileIndicator`.
|
|
209
|
+
*
|
|
210
|
+
* The visual is inferred from the tile context: `single` (radio semantics) → radio ring,
|
|
211
|
+
* `multiple` (checkbox semantics) → checkbox square. An explicit `indicatorType` prop
|
|
212
|
+
* overrides — primarily for standalone tiles that want a radio-style visual.
|
|
213
|
+
*/
|
|
214
|
+
function TileIndicatorVisual({ indicatorType }: { indicatorType?: 'radio' | 'checkbox' }) {
|
|
215
|
+
const { isSelected, isDisabled, selectionType } = useTileContext();
|
|
216
|
+
const effectiveType: 'radio' | 'checkbox' =
|
|
217
|
+
indicatorType ?? (selectionType === 'single' ? 'radio' : 'checkbox');
|
|
218
|
+
const stateAttrs = dataAttributes({ checked: isSelected, disabled: isDisabled });
|
|
219
|
+
|
|
220
|
+
if (effectiveType === 'radio') {
|
|
221
|
+
return (
|
|
222
|
+
<View className={radioIndicatorVariants()} {...stateAttrs}>
|
|
223
|
+
<View
|
|
224
|
+
className={radioInnerDotVariants()}
|
|
225
|
+
{...dataAttributes({ checked: isSelected, invalid: false })}
|
|
226
|
+
/>
|
|
227
|
+
</View>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
<View className={cn(checkboxIndicatorVariants())} {...stateAttrs}>
|
|
233
|
+
{isSelected && <Icon as={Check} className={checkboxIconVariants()} />}
|
|
234
|
+
</View>
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export interface TileIndicatorProps extends ITileIndicatorProps {
|
|
239
|
+
className?: string;
|
|
240
|
+
children?: ReactNode;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const TileIndicator = forwardRef<View, TileIndicatorProps>(
|
|
244
|
+
({ className, children, style, indicatorType, ...props }, ref) => (
|
|
245
|
+
<TilePrimitive.Indicator
|
|
246
|
+
ref={ref as never}
|
|
247
|
+
className={cn(tileIndicatorVariants(), className)}
|
|
248
|
+
style={style}
|
|
249
|
+
indicatorType={indicatorType}
|
|
250
|
+
{...props}
|
|
251
|
+
>
|
|
252
|
+
{children ?? <TileIndicatorVisual indicatorType={indicatorType} />}
|
|
253
|
+
</TilePrimitive.Indicator>
|
|
254
|
+
),
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
TileIndicator.displayName = 'Tile.Indicator';
|
|
258
|
+
|
|
259
|
+
export interface TileTrailingSlotProps extends ITileTrailingSlotProps {
|
|
260
|
+
className?: string;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const TileTrailingSlot = forwardRef<View, TileTrailingSlotProps>(
|
|
264
|
+
({ className, style, ...props }, ref) => (
|
|
265
|
+
<TilePrimitive.TrailingSlot
|
|
266
|
+
ref={ref as never}
|
|
267
|
+
className={cn(tileTrailingSlotVariants(), className)}
|
|
268
|
+
style={style}
|
|
269
|
+
{...props}
|
|
270
|
+
/>
|
|
271
|
+
),
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
TileTrailingSlot.displayName = 'Tile.TrailingSlot';
|
|
275
|
+
|
|
276
|
+
type TileCompound = typeof TileRoot & {
|
|
277
|
+
Group: typeof TileGroup;
|
|
278
|
+
LeadingSlot: typeof TileLeadingSlot;
|
|
279
|
+
Content: typeof TileContent;
|
|
280
|
+
Title: typeof TileTitle;
|
|
281
|
+
Description: typeof TileDescription;
|
|
282
|
+
Indicator: typeof TileIndicator;
|
|
283
|
+
TrailingSlot: typeof TileTrailingSlot;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
export const Tile = Object.assign(TileRoot, {
|
|
287
|
+
Group: TileGroup,
|
|
288
|
+
LeadingSlot: TileLeadingSlot,
|
|
289
|
+
Content: TileContent,
|
|
290
|
+
Title: TileTitle,
|
|
291
|
+
Description: TileDescription,
|
|
292
|
+
Indicator: TileIndicator,
|
|
293
|
+
TrailingSlot: TileTrailingSlot,
|
|
294
|
+
}) as TileCompound;
|
|
295
|
+
|
|
296
|
+
export { useTileContext };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { TRANSITION_COLORS } from '../../styles/primitives';
|
|
4
|
+
|
|
5
|
+
export const tileGroupVariants = cva(['flex w-full'], {
|
|
6
|
+
variants: {
|
|
7
|
+
direction: {
|
|
8
|
+
column: 'flex-col',
|
|
9
|
+
row: 'flex-row',
|
|
10
|
+
},
|
|
11
|
+
spacing: {
|
|
12
|
+
default: 'gap-2',
|
|
13
|
+
none: 'gap-0',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: {
|
|
17
|
+
direction: 'column',
|
|
18
|
+
spacing: 'default',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export type TileGroupVariantProps = VariantProps<typeof tileGroupVariants>;
|
|
23
|
+
|
|
24
|
+
export const tileRootVariants = cva(
|
|
25
|
+
[
|
|
26
|
+
'flex-row self-stretch gap-3 px-4 py-3',
|
|
27
|
+
'data-[disabled=true]:opacity-50',
|
|
28
|
+
TRANSITION_COLORS,
|
|
29
|
+
Platform.select({
|
|
30
|
+
web: [
|
|
31
|
+
'outline-none',
|
|
32
|
+
'data-[hover=true]:data-[disabled=false]:bg-surface-action-tint-hover',
|
|
33
|
+
'data-[active=true]:data-[disabled=false]:data-[hover=true]:bg-surface-action-tint-active',
|
|
34
|
+
'data-[hover=true]:data-[disabled=false]:data-[state=unselected]:border-stroke-action',
|
|
35
|
+
'focus-visible:data-[disabled=false]:ring-2 focus-visible:data-[disabled=false]:ring-stroke-focus focus-visible:data-[disabled=false]:ring-offset-2',
|
|
36
|
+
].join(' '),
|
|
37
|
+
default: [
|
|
38
|
+
'data-[active=true]:bg-surface-action-tint-hover',
|
|
39
|
+
'data-[active=true]:border-stroke-action',
|
|
40
|
+
].join(' '),
|
|
41
|
+
}),
|
|
42
|
+
],
|
|
43
|
+
{
|
|
44
|
+
variants: {
|
|
45
|
+
shape: {
|
|
46
|
+
flat: 'rounded-none border-0 bg-transparent',
|
|
47
|
+
card: [
|
|
48
|
+
'rounded-[var(--border-radius-default)] border-1 border-solid',
|
|
49
|
+
'border-stroke-secondary',
|
|
50
|
+
'bg-surface-primary',
|
|
51
|
+
'data-[state=selected]:border-stroke-action',
|
|
52
|
+
'data-[state=selected]:border-1.5',
|
|
53
|
+
'data-[state=selected]:bg-surface-action-tint',
|
|
54
|
+
].join(' '),
|
|
55
|
+
},
|
|
56
|
+
showSeparator: {
|
|
57
|
+
true: [
|
|
58
|
+
'border-b border-solid border-stroke-secondary! native:data-[active=true]:border-stroke-secondary', // Override border-stroke-action on hover
|
|
59
|
+
],
|
|
60
|
+
false: '',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
defaultVariants: {
|
|
64
|
+
shape: 'card',
|
|
65
|
+
showSeparator: false,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
export const tileLeadingSlotVariants = cva(['flex shrink-0 items-center justify-center']);
|
|
71
|
+
|
|
72
|
+
export const tileTrailingSlotVariants = cva(['flex shrink-0 items-center justify-center']);
|
|
73
|
+
|
|
74
|
+
export const tileContentVariants = cva(['min-w-0 flex-1 flex-col gap-0.5 no-underline']);
|
|
75
|
+
|
|
76
|
+
export const tileTitleVariants = cva(['text-base font-medium text-content-primary no-underline']);
|
|
77
|
+
|
|
78
|
+
export const tileDescriptionVariants = cva(['text-sm text-content-secondary no-underline']);
|
|
79
|
+
|
|
80
|
+
export const tileIndicatorVariants = cva(['flex shrink-0 items-center justify-center']);
|
|
81
|
+
|
|
82
|
+
export type TileVariantProps = VariantProps<typeof tileRootVariants>;
|
package/src/components/index.ts
CHANGED
|
@@ -16,9 +16,12 @@ export * from './Link';
|
|
|
16
16
|
export * from './ListItem';
|
|
17
17
|
export * from './ProgressBar';
|
|
18
18
|
export * from './ProgressSegmented';
|
|
19
|
+
export * from './Radio';
|
|
20
|
+
export * from './ScopedTheme';
|
|
19
21
|
export * from './Select';
|
|
20
22
|
export * from './VirtualizedList';
|
|
21
23
|
export * from './Switch';
|
|
24
|
+
export * from './Tile';
|
|
22
25
|
export { HStack, VStack } from './Stack';
|
|
23
26
|
export * from './Heading';
|
|
24
27
|
export * from './Text';
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useForgeBottomTabScreenOptions
|
|
3
|
+
*
|
|
4
|
+
* Returns a `screenOptions` object for **React Navigation bottom tab navigators**
|
|
5
|
+
* (`@react-navigation/bottom-tabs` v7+), populated with CDX UI design-system
|
|
6
|
+
* token values.
|
|
7
|
+
*
|
|
8
|
+
* CDX UI does not import `@react-navigation` — the consumer passes the returned
|
|
9
|
+
* object to their own navigator. This keeps the dependency out of
|
|
10
|
+
* `@cdx-ui/components` and works with any React Navigation tab variant:
|
|
11
|
+
* `createNativeBottomTabNavigator` (iOS/Android) or `createBottomTabNavigator`
|
|
12
|
+
* (web/JS).
|
|
13
|
+
*
|
|
14
|
+
* **Not compatible with:**
|
|
15
|
+
* - Expo Router `<NativeTabs>` — uses different prop names
|
|
16
|
+
* - React Router or DOM tab components — these are not React Navigation
|
|
17
|
+
*
|
|
18
|
+
* ## Basic usage
|
|
19
|
+
*
|
|
20
|
+
* ```tsx
|
|
21
|
+
* import { useForgeBottomTabScreenOptions } from '@cdx-ui/components';
|
|
22
|
+
* import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
|
|
23
|
+
*
|
|
24
|
+
* const Tab = createNativeBottomTabNavigator<AppTabs>();
|
|
25
|
+
*
|
|
26
|
+
* function AppTabs() {
|
|
27
|
+
* const screenOptions = useForgeBottomTabScreenOptions();
|
|
28
|
+
* return (
|
|
29
|
+
* <Tab.Navigator screenOptions={screenOptions}>
|
|
30
|
+
* <Tab.Screen name="Home" component={HomeScreen} />
|
|
31
|
+
* </Tab.Navigator>
|
|
32
|
+
* );
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* ## Overriding individual tokens
|
|
37
|
+
*
|
|
38
|
+
* Spread the returned object and override only the keys you need.
|
|
39
|
+
* Nested style objects (`tabBarLabelStyle`, `tabBarStyle`, `tabBarBadgeStyle`)
|
|
40
|
+
* must be spread individually to preserve unrelated DS defaults:
|
|
41
|
+
*
|
|
42
|
+
* ```tsx
|
|
43
|
+
* const dsOptions = useForgeBottomTabScreenOptions();
|
|
44
|
+
* const screenOptions = {
|
|
45
|
+
* ...dsOptions,
|
|
46
|
+
* tabBarActiveTintColor: '#custom',
|
|
47
|
+
* tabBarLabelStyle: { ...dsOptions.tabBarLabelStyle, fontFamily: 'MyFont' },
|
|
48
|
+
* };
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ## Token variable names
|
|
52
|
+
*
|
|
53
|
+
* | screenOption | CSS variable |
|
|
54
|
+
* | ---------------------------------- | ---------------------------------- |
|
|
55
|
+
* | tabBarActiveTintColor | --color-content-action |
|
|
56
|
+
* | tabBarInactiveTintColor | --color-content-secondary |
|
|
57
|
+
* | tabBarStyle.backgroundColor | --color-surface-primary |
|
|
58
|
+
* | tabBarLabelStyle.fontFamily | --font-body |
|
|
59
|
+
* | tabBarLabelStyle.fontSize | --text-xs (via `text-xs` class) |
|
|
60
|
+
* | tabBarLabelStyle.fontWeight | --font-weight-medium |
|
|
61
|
+
* | tabBarBadgeStyle.backgroundColor | --color-surface-danger-strong |
|
|
62
|
+
*
|
|
63
|
+
* ## Platform notes
|
|
64
|
+
*
|
|
65
|
+
* - `tabBarInactiveTintColor` has no effect on iOS — inactive items always use
|
|
66
|
+
* system grey.
|
|
67
|
+
* - `tabBarStyle.backgroundColor` is ignored on iOS 26+ (liquid glass takes
|
|
68
|
+
* over). It is honoured on iOS ≤18 and all Android versions.
|
|
69
|
+
* - The hook resolves CSS variables via Uniwind's `useCSSVariable`. If the
|
|
70
|
+
* Uniwind runtime is not set up (e.g. in a plain Jest test without a CSS
|
|
71
|
+
* context), each variable resolves to `undefined` and the hardcoded fallback
|
|
72
|
+
* is used instead — fallbacks intentionally match the CDX UI light-theme
|
|
73
|
+
* values.
|
|
74
|
+
* - `tabBarLabelStyle.fontSize` is resolved via Uniwind's
|
|
75
|
+
* `useResolveClassNames('text-xs')` rather than reading the rem-valued
|
|
76
|
+
* `--text-xs` variable directly. React Navigation v7 requires a numeric
|
|
77
|
+
* `fontSize`, and letting Uniwind resolve the class means the rem→px
|
|
78
|
+
* conversion uses the consumer's configured rem base (default 16px,
|
|
79
|
+
* overridable via the `polyfills.rem` Metro option) instead of a constant
|
|
80
|
+
* hardcoded here.
|
|
81
|
+
*/
|
|
82
|
+
import type { TextStyle } from 'react-native';
|
|
83
|
+
import { useCSSVariable, useResolveClassNames } from 'uniwind';
|
|
84
|
+
import type { BottomTabNavigationOptions } from '@react-navigation/bottom-tabs';
|
|
85
|
+
|
|
86
|
+
// ── Types ────────────────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The `screenOptions` shape returned by `useForgeBottomTabScreenOptions`.
|
|
90
|
+
*
|
|
91
|
+
* These are concrete types (not the broad `StyleProp<…>` React Navigation
|
|
92
|
+
* uses internally) so consumers get precise IDE completion. The compile-time
|
|
93
|
+
* drift guard below ensures this type stays assignable to
|
|
94
|
+
* `BottomTabNavigationOptions` — the TypeScript compiler will error if CDX UI
|
|
95
|
+
* adds a key or value that React Navigation no longer accepts.
|
|
96
|
+
*
|
|
97
|
+
* Pass directly as `screenOptions` on a `createNativeBottomTabNavigator` or
|
|
98
|
+
* `createBottomTabNavigator` navigator, or spread and override individual keys.
|
|
99
|
+
*/
|
|
100
|
+
export interface ForgeReactNavigationBottomTabScreenOptions {
|
|
101
|
+
tabBarActiveTintColor: string;
|
|
102
|
+
tabBarInactiveTintColor: string;
|
|
103
|
+
tabBarStyle: { backgroundColor: string };
|
|
104
|
+
tabBarLabelStyle: {
|
|
105
|
+
fontFamily: string;
|
|
106
|
+
/** Pixel size — React Navigation requires a number for tab label fontSize. */
|
|
107
|
+
fontSize: number;
|
|
108
|
+
fontWeight: TextStyle['fontWeight'];
|
|
109
|
+
};
|
|
110
|
+
tabBarBadgeStyle: { backgroundColor: string };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Compile-time drift guard.
|
|
115
|
+
*
|
|
116
|
+
* `ForgeReactNavigationBottomTabScreenOptions` must be assignable to
|
|
117
|
+
* `BottomTabNavigationOptions`. TypeScript checks this assignment at build
|
|
118
|
+
* time — if React Navigation removes or incompatibly narrows one of our keys,
|
|
119
|
+
* this line becomes a type error before it reaches consumers.
|
|
120
|
+
*
|
|
121
|
+
* The `null as unknown as ...` cast keeps the runtime value `null` so tree-
|
|
122
|
+
* shakers eliminate the variable from the final bundle entirely.
|
|
123
|
+
*/
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
|
+
const _rnDriftGuard: BottomTabNavigationOptions =
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
|
+
null as any as ForgeReactNavigationBottomTabScreenOptions;
|
|
128
|
+
|
|
129
|
+
// ── Fallbacks ────────────────────────────────────────────────────────────────
|
|
130
|
+
//
|
|
131
|
+
// Resolved light-theme values for each token. Used when useCSSVariable returns
|
|
132
|
+
// undefined (no Uniwind CSS context in scope, e.g. Jest).
|
|
133
|
+
|
|
134
|
+
const FALLBACKS = {
|
|
135
|
+
activeTintColor: '#346099', // --color-brand-700 (--color-content-action)
|
|
136
|
+
inactiveTintColor: '#4a4c4f', // --color-base-800 (--color-content-secondary)
|
|
137
|
+
fontFamily: 'Inter', // --font-sans (--font-body)
|
|
138
|
+
fontSize: 12, // px (--text-xs)
|
|
139
|
+
fontWeight: '500' as TextStyle['fontWeight'], // (--font-weight-medium)
|
|
140
|
+
backgroundColor: '#ffffff', // --color-white (--color-surface-primary)
|
|
141
|
+
badgeBackgroundColor: '#c10007', // --color-red-700 (--color-surface-danger-strong)
|
|
142
|
+
} as const;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Coerces a Uniwind-resolved `fontSize` to a finite pixel number, falling
|
|
146
|
+
* back when the style could not be resolved (e.g. no Uniwind runtime in Jest).
|
|
147
|
+
*
|
|
148
|
+
* `useResolveClassNames('text-xs')` performs the rem→px conversion using
|
|
149
|
+
* Uniwind's configured rem base, so the value is already numeric on native.
|
|
150
|
+
* React Native Web may surface string values; unit-less and `px` strings are
|
|
151
|
+
* accepted, but anything else (`rem`, `em`, `%`) falls back rather than
|
|
152
|
+
* guessing a rem base here.
|
|
153
|
+
*/
|
|
154
|
+
function toPx(value: string | number | undefined, fallbackPx: number): number {
|
|
155
|
+
if (typeof value === 'number') {
|
|
156
|
+
return Number.isFinite(value) ? value : fallbackPx;
|
|
157
|
+
}
|
|
158
|
+
if (typeof value !== 'string') return fallbackPx;
|
|
159
|
+
const trimmed = value.trim();
|
|
160
|
+
if (!/^-?\d*\.?\d+(px)?$/.test(trimmed)) return fallbackPx;
|
|
161
|
+
return parseFloat(trimmed);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Coerces a Uniwind `useCSSVariable` fontWeight value to a string.
|
|
166
|
+
*
|
|
167
|
+
* `--font-weight-*` variables are emitted as unit-less numbers (e.g. `500`),
|
|
168
|
+
* and `useCSSVariable` may return them as numbers. React Native's `TextStyle`
|
|
169
|
+
* accepts numeric fontWeight, but react-native-screens' native bottom tabs
|
|
170
|
+
* declare the corresponding host prop (`tabBarItemTitleFontWeight`) as a
|
|
171
|
+
* String — passing a number crashes Android Fabric with
|
|
172
|
+
* "java.lang.Double cannot be cast to java.lang.String".
|
|
173
|
+
*/
|
|
174
|
+
function toFontWeight(
|
|
175
|
+
value: string | number | undefined,
|
|
176
|
+
fallback: TextStyle['fontWeight'],
|
|
177
|
+
): TextStyle['fontWeight'] {
|
|
178
|
+
if (value === undefined) return fallback;
|
|
179
|
+
return String(value) as TextStyle['fontWeight'];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ── Hook ─────────────────────────────────────────────────────────────────────
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Returns a `screenOptions` object for **React Navigation bottom tab
|
|
186
|
+
* navigators** (`@react-navigation/bottom-tabs` v7+), populated with CDX UI
|
|
187
|
+
* design-system token values.
|
|
188
|
+
*
|
|
189
|
+
* Must be called inside a React component or custom hook (React hook rules
|
|
190
|
+
* apply).
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* Deep-merges consumer overrides into a base `ForgeReactNavigationBottomTabScreenOptions`
|
|
194
|
+
* object. Nested style objects (`tabBarLabelStyle`, `tabBarStyle`,
|
|
195
|
+
* `tabBarBadgeStyle`) are merged property-by-property so consumers can override
|
|
196
|
+
* individual style properties without losing unrelated DS defaults.
|
|
197
|
+
*
|
|
198
|
+
* Use with `useForgeBottomTabScreenOptions` to apply targeted overrides:
|
|
199
|
+
*
|
|
200
|
+
* ```tsx
|
|
201
|
+
* const dsOptions = useForgeBottomTabScreenOptions();
|
|
202
|
+
* const screenOptions = mergeForgeBottomTabScreenOptions(dsOptions, {
|
|
203
|
+
* tabBarActiveTintColor: '#custom',
|
|
204
|
+
* tabBarLabelStyle: { fontFamily: 'MyFont' }, // fontSize + fontWeight preserved
|
|
205
|
+
* });
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
export function mergeForgeBottomTabScreenOptions(
|
|
209
|
+
base: ForgeReactNavigationBottomTabScreenOptions,
|
|
210
|
+
overrides: Partial<ForgeReactNavigationBottomTabScreenOptions>,
|
|
211
|
+
): ForgeReactNavigationBottomTabScreenOptions {
|
|
212
|
+
return {
|
|
213
|
+
...base,
|
|
214
|
+
...overrides,
|
|
215
|
+
tabBarLabelStyle: { ...base.tabBarLabelStyle, ...overrides.tabBarLabelStyle },
|
|
216
|
+
tabBarStyle: { ...base.tabBarStyle, ...overrides.tabBarStyle },
|
|
217
|
+
tabBarBadgeStyle: { ...base.tabBarBadgeStyle, ...overrides.tabBarBadgeStyle },
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function useForgeBottomTabScreenOptions(): ForgeReactNavigationBottomTabScreenOptions {
|
|
222
|
+
const activeTintColor = useCSSVariable('--color-content-action');
|
|
223
|
+
const inactiveTintColor = useCSSVariable('--color-content-secondary');
|
|
224
|
+
const fontFamily = useCSSVariable('--font-body');
|
|
225
|
+
const labelTextStyle = useResolveClassNames('text-xs');
|
|
226
|
+
const fontWeight = useCSSVariable('--font-weight-medium');
|
|
227
|
+
const backgroundColor = useCSSVariable('--color-surface-primary');
|
|
228
|
+
const badgeBackgroundColor = useCSSVariable('--color-surface-danger-strong');
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
tabBarActiveTintColor: String(activeTintColor ?? FALLBACKS.activeTintColor),
|
|
232
|
+
tabBarInactiveTintColor: String(inactiveTintColor ?? FALLBACKS.inactiveTintColor),
|
|
233
|
+
tabBarStyle: {
|
|
234
|
+
backgroundColor: String(backgroundColor ?? FALLBACKS.backgroundColor),
|
|
235
|
+
},
|
|
236
|
+
tabBarLabelStyle: {
|
|
237
|
+
fontFamily: String(fontFamily ?? FALLBACKS.fontFamily),
|
|
238
|
+
fontSize: toPx(labelTextStyle?.fontSize, FALLBACKS.fontSize),
|
|
239
|
+
fontWeight: toFontWeight(fontWeight, FALLBACKS.fontWeight),
|
|
240
|
+
},
|
|
241
|
+
tabBarBadgeStyle: {
|
|
242
|
+
backgroundColor: String(badgeBackgroundColor ?? FALLBACKS.badgeBackgroundColor),
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="uniwind/types" preserve="true" />
|
|
2
2
|
export * from './components';
|
|
3
|
+
export * from './hooks';
|
|
4
|
+
export * from './navigation';
|
|
3
5
|
export { View, ScrollView, KeyboardAvoidingView } from 'react-native';
|
|
4
6
|
export { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
@@ -1,29 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
/** Path to the CSS entry file (e.g., `'./global.css'`). */
|
|
6
|
-
cssEntryFile: string;
|
|
7
|
-
/** Path where generated Tailwind class type definitions are written. */
|
|
8
|
-
generatedTypesFile?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Wraps a Metro config with CDX UI's styling-layer configuration.
|
|
13
|
-
*
|
|
14
|
-
* Today this delegates to Uniwind. If the styling layer is swapped (see
|
|
15
|
-
* `docs/research/uniwind-to-nativewind-contingency.md`), only the internals
|
|
16
|
-
* of this function change — consuming Metro configs stay the same.
|
|
17
|
-
*
|
|
18
|
-
* Must be the **outermost** Metro config wrapper (after any other wrappers
|
|
19
|
-
* like `withStorybook`).
|
|
20
|
-
*/
|
|
21
|
-
export function withCdxMetroConfig<T extends MetroConfig>(
|
|
22
|
-
config: T,
|
|
23
|
-
options: CdxMetroConfigOptions,
|
|
24
|
-
): T {
|
|
25
|
-
return withUniwindConfig(config, {
|
|
26
|
-
cssEntryFile: options.cssEntryFile,
|
|
27
|
-
dtsFile: options.generatedTypesFile,
|
|
28
|
-
}) as T;
|
|
29
|
-
}
|
|
1
|
+
/** @deprecated Use `withForgeMetroConfig` instead. Will be removed in a future major release. */
|
|
2
|
+
export { withForgeMetroConfig as withCdxMetroConfig } from './withForgeMetroConfig';
|
|
3
|
+
/** @deprecated Use `ForgeMetroConfigOptions` instead. Will be removed in a future major release. */
|
|
4
|
+
export type { ForgeMetroConfigOptions as CdxMetroConfigOptions } from './withForgeMetroConfig';
|