@cdx-ui/components 0.2.4 → 0.2.5

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 (94) hide show
  1. package/docs/components/accordion/content.md +2 -2
  2. package/docs/components/alert/content.md +1 -1
  3. package/docs/components/badge/content.md +5 -15
  4. package/docs/components/bottom-sheet/content.md +16 -14
  5. package/docs/components/box/content.md +141 -0
  6. package/docs/components/breadcrumbs/content.md +9 -9
  7. package/docs/components/button/content.md +19 -19
  8. package/docs/components/card/content.md +2 -2
  9. package/docs/components/carousel/content.md +9 -8
  10. package/docs/components/chip/content.md +1 -1
  11. package/docs/components/color-area/content.md +3 -5
  12. package/docs/components/color-field/content.md +3 -5
  13. package/docs/components/color-picker/content.md +5 -4
  14. package/docs/components/color-slider/content.md +3 -5
  15. package/docs/components/color-swatch/content.md +3 -5
  16. package/docs/components/color-swatch-picker/content.md +3 -5
  17. package/docs/components/content.md +10 -9
  18. package/docs/components/data-grid/content.md +10 -11
  19. package/docs/components/drawer/content.md +17 -25
  20. package/docs/components/full-screen-dialog/content.md +2 -2
  21. package/docs/components/icon/content.md +1 -1
  22. package/docs/components/icon-button/content.md +3 -3
  23. package/docs/components/input/content.md +65 -0
  24. package/docs/components/list-item/content.md +9 -9
  25. package/docs/components/menu/content.md +57 -50
  26. package/docs/components/reorderable-list/content.md +5 -3
  27. package/docs/components/scoped-theme/content.md +1 -1
  28. package/docs/components/scroll-shadow/content.md +43 -36
  29. package/docs/components/select/content.md +80 -7
  30. package/docs/components/skeleton/content.md +7 -6
  31. package/docs/components/table/content.md +2 -2
  32. package/docs/components/tabs/content.md +14 -9
  33. package/docs/components/tile/content.md +9 -10
  34. package/docs/components/toggle-button/content.md +1 -1
  35. package/docs/components/tooltip/content.md +9 -9
  36. package/docs/components/virtualized-list/content.md +14 -14
  37. package/docs/getting-started/developers/content.md +2 -2
  38. package/docs/getting-started/developers/styling/content.md +20 -18
  39. package/docs/llms.txt +11 -9
  40. package/docs/patterns/authentication/content.md +4 -6
  41. package/docs/patterns/dashboard/content.md +8 -13
  42. package/docs/patterns/empty-states/content.md +7 -6
  43. package/docs/patterns/forms/content.md +6 -7
  44. package/docs/patterns/onboarding/content.md +4 -4
  45. package/docs/patterns/settings/content.md +5 -5
  46. package/docs/resources/release-notes/0.2.4/content.md +17 -0
  47. package/docs/resources/release-notes/content.md +1 -0
  48. package/lib/commonjs/components/Box/Box.js +9 -1
  49. package/lib/commonjs/components/Box/Box.js.map +1 -1
  50. package/lib/commonjs/components/Breadcrumbs/index.js +28 -3
  51. package/lib/commonjs/components/Breadcrumbs/index.js.map +1 -1
  52. package/lib/commonjs/components/Breadcrumbs/styles.js +27 -0
  53. package/lib/commonjs/components/Breadcrumbs/styles.js.map +1 -1
  54. package/lib/commonjs/components/Stack/HStack.js +6 -2
  55. package/lib/commonjs/components/Stack/HStack.js.map +1 -1
  56. package/lib/commonjs/components/Stack/VStack.js +6 -2
  57. package/lib/commonjs/components/Stack/VStack.js.map +1 -1
  58. package/lib/commonjs/index.js +10 -10
  59. package/lib/commonjs/index.js.map +1 -1
  60. package/lib/module/components/Box/Box.js +9 -1
  61. package/lib/module/components/Box/Box.js.map +1 -1
  62. package/lib/module/components/Breadcrumbs/index.js +29 -4
  63. package/lib/module/components/Breadcrumbs/index.js.map +1 -1
  64. package/lib/module/components/Breadcrumbs/styles.js +26 -0
  65. package/lib/module/components/Breadcrumbs/styles.js.map +1 -1
  66. package/lib/module/components/Stack/HStack.js +6 -2
  67. package/lib/module/components/Stack/HStack.js.map +1 -1
  68. package/lib/module/components/Stack/VStack.js +6 -2
  69. package/lib/module/components/Stack/VStack.js.map +1 -1
  70. package/lib/module/index.js +6 -1
  71. package/lib/module/index.js.map +1 -1
  72. package/lib/typescript/animation/hooks/usePopupDialogContentAnimation.d.ts +2 -2
  73. package/lib/typescript/animation/hooks/usePopupOverlayAnimation.d.ts +2 -2
  74. package/lib/typescript/components/Box/Box.d.ts +4 -0
  75. package/lib/typescript/components/Box/Box.d.ts.map +1 -1
  76. package/lib/typescript/components/Breadcrumbs/index.d.ts +3 -1
  77. package/lib/typescript/components/Breadcrumbs/index.d.ts.map +1 -1
  78. package/lib/typescript/components/Breadcrumbs/styles.d.ts +2 -0
  79. package/lib/typescript/components/Breadcrumbs/styles.d.ts.map +1 -1
  80. package/lib/typescript/components/Stack/HStack.d.ts +3 -2
  81. package/lib/typescript/components/Stack/HStack.d.ts.map +1 -1
  82. package/lib/typescript/components/Stack/VStack.d.ts +3 -2
  83. package/lib/typescript/components/Stack/VStack.d.ts.map +1 -1
  84. package/lib/typescript/components/Toast/animation.d.ts +3 -3
  85. package/lib/typescript/components/Toast/animation.d.ts.map +1 -1
  86. package/lib/typescript/index.d.ts +6 -1
  87. package/lib/typescript/index.d.ts.map +1 -1
  88. package/package.json +8 -8
  89. package/src/components/Box/Box.tsx +18 -4
  90. package/src/components/Breadcrumbs/index.tsx +28 -4
  91. package/src/components/Breadcrumbs/styles.ts +30 -0
  92. package/src/components/Stack/HStack.tsx +8 -4
  93. package/src/components/Stack/VStack.tsx +8 -4
  94. package/src/index.ts +8 -1
@@ -15,7 +15,7 @@ import { Tabs, Text } from '@cdx-ui/components';
15
15
 
16
16
  export default function TabsBasicDemo() {
17
17
  return (
18
- <Tabs defaultValue="overview" className="w-[360px]">
18
+ <Tabs defaultValue="overview" className="w-full max-w-90">
19
19
  <Tabs.List accessibilityLabel="Account sections">
20
20
  <Tabs.Tab value="overview">
21
21
  <Tabs.TabLabel>Overview</Tabs.TabLabel>
@@ -50,7 +50,7 @@ import { Box, Tabs, Text } from '@cdx-ui/components';
50
50
 
51
51
  export default function TabsVariantsDemo() {
52
52
  return (
53
- <Box className="w-[360px] gap-8">
53
+ <Box className="w-full max-w-90 gap-8">
54
54
  <Tabs defaultValue="checking">
55
55
  <Tabs.List accessibilityLabel="Solid account tabs">
56
56
  <Tabs.Tab value="checking">
@@ -60,10 +60,10 @@ export default function TabsVariantsDemo() {
60
60
  <Tabs.TabLabel>Savings</Tabs.TabLabel>
61
61
  </Tabs.Tab>
62
62
  </Tabs.List>
63
- <Tabs.Panel value="checking" className="pt-3">
63
+ <Tabs.Panel value="checking" className="mt-3">
64
64
  <Text>Solid (default)</Text>
65
65
  </Tabs.Panel>
66
- <Tabs.Panel value="savings" className="pt-3">
66
+ <Tabs.Panel value="savings" className="mt-3">
67
67
  <Text>Savings account</Text>
68
68
  </Tabs.Panel>
69
69
  </Tabs>
@@ -77,10 +77,10 @@ export default function TabsVariantsDemo() {
77
77
  <Tabs.TabLabel>Savings</Tabs.TabLabel>
78
78
  </Tabs.Tab>
79
79
  </Tabs.List>
80
- <Tabs.Panel value="checking" className="pt-3">
80
+ <Tabs.Panel value="checking" className="mt-3">
81
81
  <Text>Outline</Text>
82
82
  </Tabs.Panel>
83
- <Tabs.Panel value="savings" className="pt-3">
83
+ <Tabs.Panel value="savings" className="mt-3">
84
84
  <Text>Savings account</Text>
85
85
  </Tabs.Panel>
86
86
  </Tabs>
@@ -102,7 +102,12 @@ function VerticalTabs({ variant }: { variant: TabsVariant }) {
102
102
  <Text weight="semibold" className="capitalize">
103
103
  {variant}
104
104
  </Text>
105
- <Tabs defaultValue="profile" orientation="vertical" variant={variant} className="w-105">
105
+ <Tabs
106
+ defaultValue="profile"
107
+ orientation="vertical"
108
+ variant={variant}
109
+ className="w-full max-w-105"
110
+ >
106
111
  <Tabs.List accessibilityLabel={`${variant} settings sections`}>
107
112
  <Tabs.Tab value="profile">
108
113
  <Tabs.TabLabel>Profile</Tabs.TabLabel>
@@ -149,7 +154,7 @@ const sections = ['Overview', 'Activity', 'Statements', 'Settings', 'Security',
149
154
 
150
155
  export default function TabsOverflowDemo() {
151
156
  return (
152
- <Tabs defaultValue="overview" className="w-[360px]">
157
+ <Tabs defaultValue="overview" className="w-90">
153
158
  <Tabs.List accessibilityLabel="Account sections">
154
159
  {sections.map((section) => {
155
160
  const value = section.toLowerCase();
@@ -184,7 +189,7 @@ import { Tabs, Text } from '@cdx-ui/components';
184
189
 
185
190
  export default function TabsDisabledDemo() {
186
191
  return (
187
- <Tabs defaultValue="open" className="w-[360px]">
192
+ <Tabs defaultValue="open" className="w-full max-w-90">
188
193
  <Tabs.List accessibilityLabel="Request status">
189
194
  <Tabs.Tab value="open">
190
195
  <Tabs.TabLabel>Open</Tabs.TabLabel>
@@ -14,14 +14,14 @@ import { Tile } from '@cdx-ui/components';
14
14
 
15
15
  ```tsx
16
16
  import { useState } from 'react';
17
- import { Tile, View } from '@cdx-ui/components';
17
+ import { Box, Tile } from '@cdx-ui/components';
18
18
 
19
19
  export default function TileShapesDemo() {
20
20
  const [card, setCard] = useState('checking');
21
21
  const [flat, setFlat] = useState('checking');
22
22
 
23
23
  return (
24
- <View className="w-full max-w-md gap-6">
24
+ <Box className="w-full max-w-md gap-6">
25
25
  <Tile.Group
26
26
  type="single"
27
27
  shape="card"
@@ -67,7 +67,7 @@ export default function TileShapesDemo() {
67
67
  <Tile.Indicator />
68
68
  </Tile>
69
69
  </Tile.Group>
70
- </View>
70
+ </Box>
71
71
  );
72
72
  }
73
73
  ```
@@ -95,7 +95,7 @@ export default function TileCardDemo() {
95
95
  >
96
96
  <Tile value="checking">
97
97
  <Tile.LeadingSlot>
98
- <Avatar size="md">
98
+ <Avatar>
99
99
  <Avatar.Icon as={Person} />
100
100
  </Avatar>
101
101
  </Tile.LeadingSlot>
@@ -107,7 +107,7 @@ export default function TileCardDemo() {
107
107
  </Tile>
108
108
  <Tile value="savings">
109
109
  <Tile.LeadingSlot>
110
- <Avatar size="md">
110
+ <Avatar>
111
111
  <Avatar.Icon as={Person} />
112
112
  </Avatar>
113
113
  </Tile.LeadingSlot>
@@ -409,7 +409,6 @@ export default function TileStandaloneDemo() {
409
409
  return (
410
410
  <Tile
411
411
  value="terms"
412
- shape="card"
413
412
  isSelected={agreed}
414
413
  onSelectedChange={setAgreed}
415
414
  className="w-full max-w-md"
@@ -447,7 +446,7 @@ export default function TileWithTrailingDemo() {
447
446
  >
448
447
  <Tile value="checking">
449
448
  <Tile.LeadingSlot>
450
- <Avatar size="md">
449
+ <Avatar>
451
450
  <Avatar.Icon as={Person} />
452
451
  </Avatar>
453
452
  </Tile.LeadingSlot>
@@ -462,7 +461,7 @@ export default function TileWithTrailingDemo() {
462
461
  </Tile>
463
462
  <Tile value="savings">
464
463
  <Tile.LeadingSlot>
465
- <Avatar size="md">
464
+ <Avatar>
466
465
  <Avatar.Icon as={Person} />
467
466
  </Avatar>
468
467
  </Tile.LeadingSlot>
@@ -499,7 +498,7 @@ export default function TileDisabledDemo() {
499
498
  >
500
499
  <Tile value="open">
501
500
  <Tile.LeadingSlot>
502
- <Avatar size="md">
501
+ <Avatar>
503
502
  <Avatar.Icon as={Person} />
504
503
  </Avatar>
505
504
  </Tile.LeadingSlot>
@@ -511,7 +510,7 @@ export default function TileDisabledDemo() {
511
510
  </Tile>
512
511
  <Tile value="closed" disabled>
513
512
  <Tile.LeadingSlot>
514
- <Avatar size="md">
513
+ <Avatar>
515
514
  <Avatar.Icon as={Person} />
516
515
  </Avatar>
517
516
  </Tile.LeadingSlot>
@@ -314,7 +314,7 @@ export default function ToggleButtonControlledDemo() {
314
314
  Everyday Checking ••4821
315
315
  </Text>
316
316
  {hideBalance ? (
317
- <Heading size="lg" accessibilityLabel="Balance hidden" className="py-0.5">
317
+ <Heading accessibilityLabel="Balance hidden" className="my-0.5">
318
318
  $•,•••.••
319
319
  </Heading>
320
320
  ) : (
@@ -19,7 +19,7 @@ export default function TooltipBasicDemo() {
19
19
  return (
20
20
  <Tooltip>
21
21
  <Tooltip.Trigger asChild>
22
- <Button variant="solid" color="action">
22
+ <Button>
23
23
  <Button.Label>Hover for tooltip</Button.Label>
24
24
  </Button>
25
25
  </Tooltip.Trigger>
@@ -43,7 +43,7 @@ export default function TooltipWithoutArrowDemo() {
43
43
  return (
44
44
  <Tooltip>
45
45
  <Tooltip.Trigger asChild>
46
- <Button variant="solid" color="action">
46
+ <Button>
47
47
  <Button.Label>Hover me</Button.Label>
48
48
  </Button>
49
49
  </Tooltip.Trigger>
@@ -64,7 +64,7 @@ export default function TooltipFocusTriggerDemo() {
64
64
  return (
65
65
  <Tooltip trigger="focus">
66
66
  <Tooltip.Trigger asChild>
67
- <Button variant="solid" color="action">
67
+ <Button>
68
68
  <Button.Label>Focus me</Button.Label>
69
69
  </Button>
70
70
  </Tooltip.Trigger>
@@ -88,7 +88,7 @@ export default function TooltipClickTriggerDemo() {
88
88
  return (
89
89
  <Tooltip trigger="click">
90
90
  <Tooltip.Trigger asChild>
91
- <Button variant="solid" color="action">
91
+ <Button>
92
92
  <Button.Label>Click for tooltip</Button.Label>
93
93
  </Button>
94
94
  </Tooltip.Trigger>
@@ -118,7 +118,7 @@ function PlacementExample({
118
118
  return (
119
119
  <Tooltip placement={placement}>
120
120
  <Tooltip.Trigger asChild>
121
- <Button variant="solid" color="action">
121
+ <Button>
122
122
  <Button.Label>{label}</Button.Label>
123
123
  </Button>
124
124
  </Tooltip.Trigger>
@@ -184,7 +184,7 @@ export default function TooltipCustomTriggersDemo() {
184
184
  return (
185
185
  <Box className="items-start gap-8">
186
186
  <CustomTriggerRow label="Avatar" content="Account owner profile">
187
- <Avatar size="md">
187
+ <Avatar>
188
188
  <Avatar.Image src="https://www.loremfaces.net/128/id/1.jpg" />
189
189
  <Avatar.Text>Jane Doe</Avatar.Text>
190
190
  </Avatar>
@@ -209,7 +209,7 @@ export default function TooltipCustomTriggersDemo() {
209
209
  </CustomTriggerRow>
210
210
 
211
211
  <CustomTriggerRow label="Button" content="Initiate a funds transfer">
212
- <Button color="action" variant="outline">
212
+ <Button variant="outline">
213
213
  <Button.Label>Transfer</Button.Label>
214
214
  </Button>
215
215
  </CustomTriggerRow>
@@ -229,7 +229,7 @@ export default function TooltipDelayDemo() {
229
229
  return (
230
230
  <Tooltip enterDelay={500} leaveDelay={300}>
231
231
  <Tooltip.Trigger asChild>
232
- <Button variant="solid" color="action">
232
+ <Button>
233
233
  <Button.Label>Delayed tooltip</Button.Label>
234
234
  </Button>
235
235
  </Tooltip.Trigger>
@@ -253,7 +253,7 @@ export default function TooltipDisabledDemo() {
253
253
  return (
254
254
  <Tooltip isDisabled>
255
255
  <Tooltip.Trigger asChild>
256
- <Button variant="solid" color="action">
256
+ <Button>
257
257
  <Button.Label>Disabled tooltip</Button.Label>
258
258
  </Button>
259
259
  </Tooltip.Trigger>
@@ -27,7 +27,7 @@ export default function VirtualizedListBasicDemo() {
27
27
  ItemSeparatorComponent={() => <Divider />}
28
28
  renderItem={({ item }) => (
29
29
  <Box className="flex-row items-center gap-3 px-4 py-3">
30
- <Avatar size="md">
30
+ <Avatar>
31
31
  <Avatar.Text>{item.name.slice(0, 2)}</Avatar.Text>
32
32
  </Avatar>
33
33
  <Box className="flex-1 gap-0.5">
@@ -84,7 +84,7 @@ export default function VirtualizedListEmptyDemo() {
84
84
  `ListHeaderComponent` and `ListFooterComponent` render above and below the scrollable items.
85
85
 
86
86
  ```tsx
87
- import { Avatar, Box, Card, Divider, Text, VirtualizedList } from '@cdx-ui/components';
87
+ import { Avatar, Box, Card, Divider, ListItem, Text, VirtualizedList } from '@cdx-ui/components';
88
88
  import { CONTACTS } from './_data';
89
89
 
90
90
  export default function VirtualizedListHeaderFooterDemo() {
@@ -112,17 +112,17 @@ export default function VirtualizedListHeaderFooterDemo() {
112
112
  </Box>
113
113
  }
114
114
  renderItem={({ item }) => (
115
- <Box className="flex-row items-center gap-3 px-4 py-3">
116
- <Avatar size="md">
117
- <Avatar.Text>{item.name.slice(0, 2)}</Avatar.Text>
118
- </Avatar>
119
- <Box className="flex-1 gap-0.5">
120
- <Text weight="semibold">{item.name}</Text>
121
- <Text color="secondary" size="sm">
122
- {item.role}
123
- </Text>
124
- </Box>
125
- </Box>
115
+ <ListItem showSeparator={false}>
116
+ <ListItem.LeadingSlot>
117
+ <Avatar>
118
+ <Avatar.Text>{item.name.slice(0, 2)}</Avatar.Text>
119
+ </Avatar>
120
+ </ListItem.LeadingSlot>
121
+ <ListItem.Content>
122
+ <ListItem.Title>{item.name}</ListItem.Title>
123
+ <ListItem.Description>{item.role}</ListItem.Description>
124
+ </ListItem.Content>
125
+ </ListItem>
126
126
  )}
127
127
  />
128
128
  </Card.Content>
@@ -163,7 +163,7 @@ export default function VirtualizedListWithListItemDemo() {
163
163
  renderItem={({ item, index }) => (
164
164
  <ListItem onPress={() => undefined} showSeparator={index < transactions.length - 1}>
165
165
  <ListItem.LeadingSlot>
166
- <Avatar size="md">
166
+ <Avatar>
167
167
  <Avatar.Text>{item.title.slice(0, 2).toUpperCase()}</Avatar.Text>
168
168
  </Avatar>
169
169
  </ListItem.LeadingSlot>
@@ -228,7 +228,6 @@ Components carry their own look, so the example sets no colors or typography. Be
228
228
 
229
229
  ```tsx
230
230
  import {
231
- View,
232
231
  ScrollView,
233
232
  KeyboardAvoidingView,
234
233
  SafeAreaView,
@@ -238,12 +237,13 @@ import {
238
237
 
239
238
  | Export | Source |
240
239
  | ---------------------- | -------------------------------- |
241
- | `View` | `react-native` |
242
240
  | `ScrollView` | `react-native` |
243
241
  | `KeyboardAvoidingView` | `react-native` |
244
242
  | `SafeAreaView` | `react-native-safe-area-context` |
245
243
  | `useSafeAreaInsets` | `react-native-safe-area-context` |
246
244
 
245
+ `View` is also still exported but is deprecated — use `Box` for layout containers.
246
+
247
247
  These are convenience re-exports of the underlying packages — not Uniwind wrappers. `className` works on RN views when Uniwind's Metro pipeline is configured; importing from `@cdx-ui/components` vs `react-native` does not change that.
248
248
 
249
249
  ---
@@ -72,7 +72,7 @@ Every component's API table lists the props that choose its look. Reach for them
72
72
  > **Text on a colored surface**
73
73
  >
74
74
  > The `text-content-*-on-strong` and `text-content-*-on-subtle` tokens have no prop. Use them as a
75
- > class only when your own code paints the surface underneath, such as a `View` with
75
+ > class only when your own code paints the surface underneath, such as a `Box` with
76
76
  > `bg-surface-action-strong`. For a status message use `Alert`; for a dark section use
77
77
  > `ScopedTheme`.
78
78
 
@@ -102,7 +102,7 @@ Padding, backgrounds, borders, radii, colors, typography and heights are not all
102
102
 
103
103
  ## Lay out screens with layout primitives
104
104
 
105
- `View`, `ScrollView`, `SafeAreaView`, `KeyboardAvoidingView`, `HStack` and `VStack` have no look of their own. They can take layout classes (`flex-row`, `items-center`, `justify-between`, `flex-wrap`), padding on the spacing scale, and a semantic surface background (`bg-surface-*`). On `HStack` and `VStack`, set the gap between children with `space`, not `gap-*`.
105
+ `Box`, `HStack`, `VStack`, `ScrollView`, `SafeAreaView` and `KeyboardAvoidingView` have no look of their own. They can take layout classes (`flex-row`, `items-center`, `justify-between`, `flex-wrap`), padding on the spacing scale, and a semantic surface background (`bg-surface-*`). `Box` is the general-purpose container: use it wherever you would reach for a `View`. On `HStack` and `VStack`, set the gap between children with `space`, not `gap-*`.
106
106
 
107
107
  ```tsx
108
108
  // Wrong: a react-native View with pixel values
@@ -118,7 +118,7 @@ import { VStack } from '@cdx-ui/components';
118
118
  </VStack>;
119
119
  ```
120
120
 
121
- Don't add a `View` or a stack that does nothing. If a design's spacing doesn't match a component's default, keep the default and raise the difference with whoever owns the design.
121
+ Don't add a `Box` or a stack that does nothing. If a design's spacing doesn't match a component's default, keep the default and raise the difference with whoever owns the design.
122
122
 
123
123
  ## Use semantic tokens
124
124
 
@@ -140,9 +140,9 @@ Wrap a dark or inverse section in [`ScopedTheme`](https://design.candescent.com/
140
140
 
141
141
  ```tsx
142
142
  // Wrong
143
- <View className="bg-black">
143
+ <Box className="bg-black">
144
144
  <Text className="text-white">Premium rewards</Text>
145
- </View>
145
+ </Box>
146
146
 
147
147
  // Right
148
148
  <ScopedTheme theme="dark">
@@ -156,7 +156,8 @@ Wrap a dark or inverse section in [`ScopedTheme`](https://design.candescent.com/
156
156
 
157
157
  ## Imports
158
158
 
159
- - Import `View`, `ScrollView`, `SafeAreaView` and `KeyboardAvoidingView` from `@cdx-ui/components`, not from `react-native`.
159
+ - Use `Box` in place of `View`. `View` from `react-native` is not part of the Forge UI API, and the `View` export of `@cdx-ui/components` is deprecated.
160
+ - Import `ScrollView`, `SafeAreaView` and `KeyboardAvoidingView` from `@cdx-ui/components`, not from `react-native`.
160
161
  - Don't wrap Forge UI components with `withUniwind`; they already accept `className`.
161
162
  - Don't import from `@cdx-ui/primitives` or from deep paths inside a package. Only the public entry points are a stable API across releases.
162
163
  - Merge class names with `cn` from `@cdx-ui/utils`.
@@ -179,15 +180,16 @@ When generating or reviewing code:
179
180
  - When a rule blocks the design, don't work around it. Apply the closest variant, leave the `TODO`, and tell the person you're working for what's missing.
180
181
  - Review your own output for these patterns before you finish:
181
182
 
182
- | Pattern | Fix |
183
- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
184
- | `text-content-*`, `body-*` or `font-*` classes on `Text` or `Icon` | Use the `color`, `size` and `weight` props |
185
- | Padding, background, border, radius or height classes on a Forge UI component or its parts | Remove them. Use props, or move layout to a layout primitive |
186
- | `style={...}` on a Forge UI component | Remove it. Use props or placement classes |
187
- | Primitive tokens, hex or rgb values, `white`, `black`, or `[...]` values | Use a semantic token |
188
- | `text-left` or `text-right` | Use `text-start` or `text-end` |
189
- | `View`, `ScrollView`, `SafeAreaView` or `KeyboardAvoidingView` imported from `react-native` | Import it from `@cdx-ui/components` |
190
- | Imports from `@cdx-ui/primitives` or a deep package path | Import from the package's public entry point |
191
- | `withUniwind` around a Forge UI component | Remove the wrapper |
192
- | A dark section built from `bg-black` and `text-white` | Use `ScopedTheme` |
193
- | A default restated, such as `color="primary"` or `size-5` on `Icon` | Remove it |
183
+ | Pattern | Fix |
184
+ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------ |
185
+ | `text-content-*`, `body-*` or `font-*` classes on `Text` or `Icon` | Use the `color`, `size` and `weight` props |
186
+ | Padding, background, border, radius or height classes on a Forge UI component or its parts | Remove them. Use props, or move layout to a layout primitive |
187
+ | `style={...}` on a Forge UI component | Remove it. Use props or placement classes |
188
+ | Primitive tokens, hex or rgb values, `white`, `black`, or `[...]` values | Use a semantic token |
189
+ | `text-left` or `text-right` | Use `text-start` or `text-end` |
190
+ | `View` imported from `react-native` or `@cdx-ui/components` | Use `Box` |
191
+ | `ScrollView`, `SafeAreaView` or `KeyboardAvoidingView` imported from `react-native` | Import it from `@cdx-ui/components` |
192
+ | Imports from `@cdx-ui/primitives` or a deep package path | Import from the package's public entry point |
193
+ | `withUniwind` around a Forge UI component | Remove the wrapper |
194
+ | A dark section built from `bg-black` and `text-white` | Use `ScopedTheme` |
195
+ | A default restated, such as `color="primary"` or `size-5` on `Icon` | Remove it |
package/docs/llms.txt CHANGED
@@ -49,12 +49,12 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
49
49
  - [Select](components/select/content.md): A form control that allows users to choose one option from a dropdown list. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=427-2296), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-select--default) Design guidance: [design.md](components/select/design.md)
50
50
  - [Textarea](components/textarea/content.md): A multi-line text entry for longer free-form content. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=7078-1235), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-textarea--default)
51
51
  - [Slider](components/slider/content.md): A control for selecting a numeric value along a track. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=11500-17763), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-slider--default)
52
- - [ColorPicker](components/color-picker/content.md): A compound color picker that coordinates an opaque color value with a trigger and popover. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorpicker--default)
53
- - [ColorArea](components/color-area/content.md): A two-dimensional control for selecting saturation and brightness in the HSB color space. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorarea--default)
54
- - [ColorSlider](components/color-slider/content.md): A one-dimensional control for selecting a channel from an opaque RGB, HSL, or HSB color. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorslider--default)
55
- - [ColorField](components/color-field/content.md): A text field for editing an opaque color or one RGB or HSL channel. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorfield--default)
56
- - [ColorSwatch](components/color-swatch/content.md): A presentational sample of an opaque color in configurable sizes and shapes. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorswatch--default)
57
- - [ColorSwatchPicker](components/color-swatch-picker/content.md): A radio-style compound for choosing from consumer-supplied color presets. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorswatchpicker--default)
52
+ - [Color Picker](components/color-picker/content.md): A compound color picker that coordinates an opaque color value with a trigger and popover. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorpicker--default)
53
+ - [Color Area](components/color-area/content.md): A two-dimensional control for selecting saturation and brightness in the HSB color space. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorarea--default)
54
+ - [Color Slider](components/color-slider/content.md): A one-dimensional control for selecting a channel from an opaque RGB, HSL, or HSB color. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorslider--default)
55
+ - [Color Field](components/color-field/content.md): A text field for editing an opaque color or one RGB or HSL channel. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorfield--default)
56
+ - [Color Swatch](components/color-swatch/content.md): A presentational sample of an opaque color in configurable sizes and shapes. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorswatch--default)
57
+ - [Color Swatch Picker](components/color-swatch-picker/content.md): A radio-style compound for choosing from consumer-supplied color presets. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorswatchpicker--default)
58
58
  - [Switch](components/switch/content.md): A toggle control that lets users turn a single option on or off. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=308-19827), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-switch--default) Design guidance: [design.md](components/switch/design.md)
59
59
  - [Tile](components/tile/content.md): A composable, selectable card/row for pick-one or pick-many flows such as account pickers and category selectors. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=8843-7101), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/surfaces-tile--default)
60
60
 
@@ -86,7 +86,7 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
86
86
  - [Icon](components/icon/content.md): A cross-platform SVG icon wrapper with semantic color, sizing, filled variants, and accessibility support. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=397-33), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-icon--default)
87
87
  - [Image](components/image/content.md): Displays local or remote images across native and web platforms. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=9091-16186), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-image--default)
88
88
  - [List Item](components/list-item/content.md): A composable row for display and navigation — accounts, transactions, alerts, settings, and nav rows. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=3710-4649), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/surfaces-listitem--default)
89
- - [ReorderableList](components/reorderable-list/content.md): A short, mount-all list that lets members drag rows into a new order via an explicit handle. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-reorderablelist--default)
89
+ - [Reorderable List](components/reorderable-list/content.md): A short, mount-all list that lets members drag rows into a new order via an explicit handle. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-reorderablelist--default)
90
90
  - [Virtualized List](components/virtualized-list/content.md): A performant virtualized list for large datasets — only visible rows mount at a time. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=4040-4933), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-virtualizedlist--large-data-set)
91
91
  - [Text](components/text/content.md): Body text with a responsive, token-based typography scale. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=400-3), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-text--default)
92
92
  - [Heading](components/heading/content.md): Semantic heading text with an accessible, token-based typography scale. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=399-3385), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-heading--default)
@@ -101,10 +101,11 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
101
101
 
102
102
  - **Surfaces & layout**
103
103
  - [Bottom Sheet](components/bottom-sheet/content.md): A surface that slides up from the bottom of the screen to present secondary tasks without leaving the current context. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=3187-706), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/overlays-bottomsheet--default) Design guidance: [design.md](components/bottom-sheet/design.md)
104
+ - [Box](components/box/content.md): The layout container for building screens, with semantic web elements through role and an asChild escape hatch. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-box--default)
104
105
  - [Card](components/card/content.md): A composable surface for grouping related content, with optional brand stripe, header, content, and footer regions. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=456-14), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/surfaces-card--with-stripe)
105
106
  - [Drawer](components/drawer/content.md): A panel attached to an edge of the viewport or container, with modal and permanent presentations. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=9956-15204), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/overlays-drawer--default)
106
- - [ScopedTheme](components/scoped-theme/content.md): Forces a specific theme on a component subtree, regardless of the application's global theme. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/theming-scopedtheme--default)
107
- - [ScrollShadow](components/scroll-shadow/content.md): Fades the edges of a scroll view so overflowing content reads as scrollable on iOS, Android, and web. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-scrollshadow--default)
107
+ - [Scoped Theme](components/scoped-theme/content.md): Forces a specific theme on a component subtree, regardless of the application's global theme. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/theming-scopedtheme--default)
108
+ - [Scroll Shadow](components/scroll-shadow/content.md): Fades the edges of a scroll view so overflowing content reads as scrollable on iOS, Android, and web. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-scrollshadow--default)
108
109
  - [Stack](components/stack/content.md): Horizontal and vertical layout primitives with token-based spacing and optional reversed order. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-vstack--default)
109
110
 
110
111
  - **Navigation**
@@ -137,6 +138,7 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
137
138
 
138
139
  ## Release notes
139
140
 
141
+ - [0.2.4](resources/release-notes/0.2.4/content.md): ScrollShadow fades scroll edges on iOS, Android, and web; ListItem.SectionHeader adds a gradient variant for account-style lists.
140
142
  - [0.2.3](resources/release-notes/0.2.3/content.md): ReorderableList brings drag-and-drop list reordering on web and native; Tile flat rows show the selected background again.
141
143
  - [0.2.2](resources/release-notes/0.2.2/content.md): Fixes web Text layout in production, Button solid edges on native, and Field required labels on web.
142
144
  - [0.2.1](resources/release-notes/0.2.1/content.md): Calendar and DatePicker add isDateUnavailable and shared typed-entry validation integrated with Field and @cdx-ui/formatters.
@@ -11,13 +11,11 @@ import { Button, Card, Field, Heading, Input, Link, Text, VStack } from '@cdx-ui
11
11
 
12
12
  export default function LoginSimpleBlock() {
13
13
  return (
14
- <Card className="w-full max-w-sm shadow-lg">
14
+ <Card className="w-full max-w-sm">
15
15
  <Card.Header>
16
16
  <VStack space="sm" className="items-center">
17
- <Heading size="lg">Sign in</Heading>
18
- <Text className="text-content-secondary">
19
- Enter your credentials to access your account
20
- </Text>
17
+ <Heading>Sign in</Heading>
18
+ <Text color="secondary">Enter your credentials to access your account</Text>
21
19
  </VStack>
22
20
  </Card.Header>
23
21
  <Card.Content>
@@ -34,7 +32,7 @@ export default function LoginSimpleBlock() {
34
32
  <Input.Field placeholder="Enter your password" secureTextEntry />
35
33
  </Input>
36
34
  </Field>
37
- <Button variant="solid" fullWidth>
35
+ <Button fullWidth>
38
36
  <Button.Label>Sign In</Button.Label>
39
37
  </Button>
40
38
  </VStack>
@@ -7,28 +7,23 @@ A personalized greeting header with search, notifications, and avatar.
7
7
  **Platforms:** iOS, Android
8
8
 
9
9
  ```tsx
10
- import { Avatar, Heading, HStack, IconButton, Text, VStack, View } from '@cdx-ui/components';
10
+ import { Avatar, Badge, Heading, HStack, IconButton, Text, VStack } from '@cdx-ui/components';
11
11
  import { Notifications, Search } from '@cdx-ui/icons';
12
12
 
13
13
  export default function DashboardGreetingBlock() {
14
14
  return (
15
15
  <HStack className="w-full max-w-md items-center justify-between py-4 px-4">
16
- <VStack className="gap-0.5">
17
- <Text size="sm" className="text-content-secondary">
16
+ <VStack space="xs">
17
+ <Text size="sm" color="secondary">
18
18
  Good morning,
19
19
  </Text>
20
- <Heading size="lg">Bernadette</Heading>
20
+ <Heading>Bernadette</Heading>
21
21
  </VStack>
22
22
  <HStack space="sm" className="items-center">
23
- <IconButton as={Search} color="neutral" />
24
- <View className="relative">
25
- <IconButton as={Notifications} color="neutral" />
26
- <View className="absolute -top-1 -right-1 flex size-5 items-center justify-center rounded-full bg-surface-danger-strong border border-white">
27
- <Text size="xs" className="font-bold text-white">
28
- 3
29
- </Text>
30
- </View>
31
- </View>
23
+ <IconButton as={Search} accessibilityLabel="Search" />
24
+ <Badge label={3} color="danger" overlap="circular" accessibilityLabel="3 notifications">
25
+ <IconButton as={Notifications} accessibilityLabel="Notifications" />
26
+ </Badge>
32
27
  <Avatar size="lg">
33
28
  <Avatar.Text>Bernadette Miller</Avatar.Text>
34
29
  </Avatar>
@@ -7,22 +7,23 @@ An empty state shown when no transaction history is available.
7
7
  **Platforms:** iOS, Android, Web
8
8
 
9
9
  ```tsx
10
- import { Button, Heading, Icon, Text, VStack } from '@cdx-ui/components';
10
+ import { Avatar, Button, Heading, Text, VStack } from '@cdx-ui/components';
11
11
  import { ReceiptLong } from '@cdx-ui/icons';
12
12
 
13
13
  export default function NoTransactionsBlock() {
14
14
  return (
15
15
  <VStack space="lg" className="w-full max-w-sm items-center py-12 px-6">
16
- <VStack space="md" className="items-center bg-surface-secondary rounded-full p-5">
17
- <Icon as={ReceiptLong} className="size-10 text-content-secondary" />
18
- </VStack>
16
+ {/* TODO(forge-ui): Avatar has no size larger than 2xl for an empty-state illustration; using 2xl. */}
17
+ <Avatar size="2xl" color="neutral">
18
+ <Avatar.Icon as={ReceiptLong} />
19
+ </Avatar>
19
20
  <VStack space="sm" className="items-center">
20
21
  <Heading size="md">No transactions yet</Heading>
21
- <Text className="text-content-secondary text-center">
22
+ <Text color="secondary" className="text-center">
22
23
  Once you make your first transaction, it will appear here.
23
24
  </Text>
24
25
  </VStack>
25
- <Button variant="solid">
26
+ <Button>
26
27
  <Button.Label>Make a transfer</Button.Label>
27
28
  </Button>
28
29
  </VStack>
@@ -11,7 +11,7 @@ import { Button, Card, Field, Heading, Input, VStack } from '@cdx-ui/components'
11
11
 
12
12
  export default function ContactInfoFormBlock() {
13
13
  return (
14
- <Card className="w-full max-w-md shadow-lg">
14
+ <Card className="w-full max-w-md">
15
15
  <Card.Header>
16
16
  <VStack space="xs">
17
17
  <Heading size="md">Contact information</Heading>
@@ -46,7 +46,7 @@ export default function ContactInfoFormBlock() {
46
46
  </VStack>
47
47
  </Card.Content>
48
48
  <Card.Footer>
49
- <Button variant="solid" fullWidth>
49
+ <Button fullWidth>
50
50
  <Button.Label>Save changes</Button.Label>
51
51
  </Button>
52
52
  </Card.Footer>
@@ -65,11 +65,10 @@ A card that reveals a date range picker for choosing a start and end date.
65
65
  import { useState } from 'react';
66
66
  import {
67
67
  Accordion,
68
- Box,
68
+ Avatar,
69
69
  Card,
70
70
  DateField,
71
71
  DateRangePicker,
72
- Icon,
73
72
  type DateRangeValue,
74
73
  } from '@cdx-ui/components';
75
74
  import { CalendarToday } from '@cdx-ui/icons';
@@ -83,9 +82,9 @@ export default function DateRangeBlock() {
83
82
  <Accordion.Item value="date-range" showSeparator={false}>
84
83
  <Accordion.Trigger>
85
84
  <Accordion.LeadingSlot>
86
- <Box className="size-10 items-center justify-center rounded-full bg-surface-info-subtle">
87
- <Icon as={CalendarToday} />
88
- </Box>
85
+ <Avatar size="lg" color="info">
86
+ <Avatar.Icon as={CalendarToday} />
87
+ </Avatar>
89
88
  </Accordion.LeadingSlot>
90
89
  <Accordion.Label>
91
90
  <Accordion.Title>Date range</Accordion.Title>