@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
@@ -1,12 +1,11 @@
1
- # ColorField (https://design.candescent.com/docs/components/color-field)
1
+ # Color Field (https://design.candescent.com/docs/components/color-field)
2
2
 
3
3
  Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorfield--default)
4
4
 
5
5
  `ColorField` parses full hex values or edits a single RGB or HSL channel.
6
6
 
7
7
  ```tsx
8
- import { ColorField, ColorSwatch, Field } from '@cdx-ui/components';
9
- import { parseColor } from '@cdx-ui/primitives';
8
+ import { ColorField, ColorSwatch, Field, parseColor } from '@cdx-ui/components';
10
9
  ```
11
10
 
12
11
  ## Basic
@@ -15,8 +14,7 @@ Compose `Field` for the visible label and place an optional swatch in `ColorFiel
15
14
 
16
15
  ```tsx
17
16
  import { useState } from 'react';
18
- import { ColorField, ColorSwatch, Field } from '@cdx-ui/components';
19
- import { parseColor, type Color } from '@cdx-ui/primitives';
17
+ import { ColorField, ColorSwatch, Field, parseColor, type Color } from '@cdx-ui/components';
20
18
 
21
19
  function requiredColor(value: string): Color {
22
20
  const color = parseColor(value);
@@ -1,4 +1,4 @@
1
- # ColorPicker (https://design.candescent.com/docs/components/color-picker)
1
+ # Color Picker (https://design.candescent.com/docs/components/color-picker)
2
2
 
3
3
  Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorpicker--default)
4
4
 
@@ -15,8 +15,8 @@ import {
15
15
  HStack,
16
16
  Select,
17
17
  Text,
18
+ parseColor,
18
19
  } from '@cdx-ui/components';
19
- import { parseColor } from '@cdx-ui/primitives';
20
20
  ```
21
21
 
22
22
  ## Basic
@@ -35,8 +35,9 @@ import {
35
35
  HStack,
36
36
  Select,
37
37
  Text,
38
+ parseColor,
39
+ type Color,
38
40
  } from '@cdx-ui/components';
39
- import { parseColor, type Color } from '@cdx-ui/primitives';
40
41
 
41
42
  type ColorFormat = 'hex' | 'rgb' | 'hsl';
42
43
 
@@ -66,7 +67,7 @@ export default function ColorPickerBasicDemo() {
66
67
  return (
67
68
  <ColorPicker value={value} onValueChange={setValue} className="w-full max-w-sm">
68
69
  <ColorPicker.Trigger accessibilityLabel="Choose brand color">
69
- <ColorSwatch size="sm" />
70
+ <ColorSwatch />
70
71
  <Text>{value.toString('hex')}</Text>
71
72
  </ColorPicker.Trigger>
72
73
  <ColorPicker.Popover>
@@ -1,20 +1,18 @@
1
- # ColorSlider (https://design.candescent.com/docs/components/color-slider)
1
+ # Color Slider (https://design.candescent.com/docs/components/color-slider)
2
2
 
3
3
  Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorslider--default)
4
4
 
5
5
  `ColorSlider` adjusts one color channel and renders the channel gradient in its rail.
6
6
 
7
7
  ```tsx
8
- import { ColorSlider } from '@cdx-ui/components';
9
- import { parseColor } from '@cdx-ui/primitives';
8
+ import { ColorSlider, parseColor } from '@cdx-ui/components';
10
9
  ```
11
10
 
12
11
  ## Basic
13
12
 
14
13
  ```tsx
15
14
  import { useState } from 'react';
16
- import { ColorSlider } from '@cdx-ui/components';
17
- import { parseColor, type Color } from '@cdx-ui/primitives';
15
+ import { ColorSlider, parseColor, type Color } from '@cdx-ui/components';
18
16
 
19
17
  function requiredColor(value: string): Color {
20
18
  const color = parseColor(value);
@@ -1,19 +1,17 @@
1
- # ColorSwatch (https://design.candescent.com/docs/components/color-swatch)
1
+ # Color Swatch (https://design.candescent.com/docs/components/color-swatch)
2
2
 
3
3
  Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorswatch--default)
4
4
 
5
5
  `ColorSwatch` displays an explicit color or the current value from a surrounding `ColorPicker`.
6
6
 
7
7
  ```tsx
8
- import { ColorSwatch, HStack } from '@cdx-ui/components';
9
- import { parseColor } from '@cdx-ui/primitives';
8
+ import { ColorSwatch, HStack, parseColor } from '@cdx-ui/components';
10
9
  ```
11
10
 
12
11
  ## Basic
13
12
 
14
13
  ```tsx
15
- import { ColorSwatch, HStack } from '@cdx-ui/components';
16
- import { parseColor, type Color } from '@cdx-ui/primitives';
14
+ import { ColorSwatch, HStack, parseColor, type Color } from '@cdx-ui/components';
17
15
 
18
16
  function requiredColor(value: string): Color {
19
17
  const color = parseColor(value);
@@ -1,20 +1,18 @@
1
- # ColorSwatchPicker (https://design.candescent.com/docs/components/color-swatch-picker)
1
+ # Color Swatch Picker (https://design.candescent.com/docs/components/color-swatch-picker)
2
2
 
3
3
  Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/inputs-colorswatchpicker--default)
4
4
 
5
5
  `ColorSwatchPicker` selects one color from a consumer-supplied set of presets.
6
6
 
7
7
  ```tsx
8
- import { ColorSwatchPicker } from '@cdx-ui/components';
9
- import { parseColor } from '@cdx-ui/primitives';
8
+ import { ColorSwatchPicker, parseColor } from '@cdx-ui/components';
10
9
  ```
11
10
 
12
11
  ## Basic
13
12
 
14
13
  ```tsx
15
14
  import { useState } from 'react';
16
- import { ColorSwatchPicker } from '@cdx-ui/components';
17
- import { parseColor, type Color } from '@cdx-ui/primitives';
15
+ import { ColorSwatchPicker, parseColor, type Color } from '@cdx-ui/components';
18
16
 
19
17
  function requiredColor(value: string): Color {
20
18
  const color = parseColor(value);
@@ -22,12 +22,12 @@
22
22
  - [Select](https://design.candescent.com/docs/components/select/content.md) — A form control that allows users to choose one option from a dropdown list.
23
23
  - [Textarea](https://design.candescent.com/docs/components/textarea/content.md) — A multi-line text entry for longer free-form content.
24
24
  - [Slider](https://design.candescent.com/docs/components/slider/content.md) — A control for selecting a numeric value along a track.
25
- - [ColorPicker](https://design.candescent.com/docs/components/color-picker/content.md) — A compound color picker that coordinates an opaque color value with a trigger and popover.
26
- - [ColorArea](https://design.candescent.com/docs/components/color-area/content.md) — A two-dimensional control for selecting saturation and brightness in the HSB color space.
27
- - [ColorSlider](https://design.candescent.com/docs/components/color-slider/content.md) — A one-dimensional control for selecting a channel from an opaque RGB, HSL, or HSB color.
28
- - [ColorField](https://design.candescent.com/docs/components/color-field/content.md) — A text field for editing an opaque color or one RGB or HSL channel.
29
- - [ColorSwatch](https://design.candescent.com/docs/components/color-swatch/content.md) — A presentational sample of an opaque color in configurable sizes and shapes.
30
- - [ColorSwatchPicker](https://design.candescent.com/docs/components/color-swatch-picker/content.md) — A radio-style compound for choosing from consumer-supplied color presets.
25
+ - [Color Picker](https://design.candescent.com/docs/components/color-picker/content.md) — A compound color picker that coordinates an opaque color value with a trigger and popover.
26
+ - [Color Area](https://design.candescent.com/docs/components/color-area/content.md) — A two-dimensional control for selecting saturation and brightness in the HSB color space.
27
+ - [Color Slider](https://design.candescent.com/docs/components/color-slider/content.md) — A one-dimensional control for selecting a channel from an opaque RGB, HSL, or HSB color.
28
+ - [Color Field](https://design.candescent.com/docs/components/color-field/content.md) — A text field for editing an opaque color or one RGB or HSL channel.
29
+ - [Color Swatch](https://design.candescent.com/docs/components/color-swatch/content.md) — A presentational sample of an opaque color in configurable sizes and shapes.
30
+ - [Color Swatch Picker](https://design.candescent.com/docs/components/color-swatch-picker/content.md) — A radio-style compound for choosing from consumer-supplied color presets.
31
31
  - [Switch](https://design.candescent.com/docs/components/switch/content.md) — A toggle control that lets users turn a single option on or off.
32
32
  - [Tile](https://design.candescent.com/docs/components/tile/content.md) — A composable, selectable card/row for pick-one or pick-many flows such as account pickers and category selectors.
33
33
 
@@ -62,7 +62,7 @@
62
62
  - [Icon](https://design.candescent.com/docs/components/icon/content.md) — A cross-platform SVG icon wrapper with semantic color, sizing, filled variants, and accessibility support.
63
63
  - [Image](https://design.candescent.com/docs/components/image/content.md) — Displays local or remote images across native and web platforms.
64
64
  - [List Item](https://design.candescent.com/docs/components/list-item/content.md) — A composable row for display and navigation — accounts, transactions, alerts, settings, and nav rows.
65
- - [ReorderableList](https://design.candescent.com/docs/components/reorderable-list/content.md) — A short, mount-all list that lets members drag rows into a new order via an explicit handle.
65
+ - [Reorderable List](https://design.candescent.com/docs/components/reorderable-list/content.md) — A short, mount-all list that lets members drag rows into a new order via an explicit handle.
66
66
  - [Virtualized List](https://design.candescent.com/docs/components/virtualized-list/content.md) — A performant virtualized list for large datasets — only visible rows mount at a time.
67
67
  - [Text](https://design.candescent.com/docs/components/text/content.md) — Body text with a responsive, token-based typography scale.
68
68
  - [Heading](https://design.candescent.com/docs/components/heading/content.md) — Semantic heading text with an accessible, token-based typography scale.
@@ -79,10 +79,11 @@
79
79
  ## Surfaces & layout
80
80
 
81
81
  - [Bottom Sheet](https://design.candescent.com/docs/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.
82
+ - [Box](https://design.candescent.com/docs/components/box/content.md) — The layout container for building screens, with semantic web elements through role and an asChild escape hatch.
82
83
  - [Card](https://design.candescent.com/docs/components/card/content.md) — A composable surface for grouping related content, with optional brand stripe, header, content, and footer regions.
83
84
  - [Drawer](https://design.candescent.com/docs/components/drawer/content.md) — A panel attached to an edge of the viewport or container, with modal and permanent presentations.
84
- - [ScopedTheme](https://design.candescent.com/docs/components/scoped-theme/content.md) — Forces a specific theme on a component subtree, regardless of the application's global theme.
85
- - [ScrollShadow](https://design.candescent.com/docs/components/scroll-shadow/content.md) — Fades the edges of a scroll view so overflowing content reads as scrollable on iOS, Android, and web.
85
+ - [Scoped Theme](https://design.candescent.com/docs/components/scoped-theme/content.md) — Forces a specific theme on a component subtree, regardless of the application's global theme.
86
+ - [Scroll Shadow](https://design.candescent.com/docs/components/scroll-shadow/content.md) — Fades the edges of a scroll view so overflowing content reads as scrollable on iOS, Android, and web.
86
87
  - [Stack](https://design.candescent.com/docs/components/stack/content.md) — Horizontal and vertical layout primitives with token-based spacing and optional reversed order.
87
88
 
88
89
  ## Navigation
@@ -15,7 +15,7 @@ Pass `rows` and `columns`. This account grid starts with the features most appli
15
15
 
16
16
  Search is **not** always on. Set `showToolbar` to show the search field (same opt-in as MUI Community’s toolbar / quick filter). Set `headerFilters` to show per-column filter inputs in a second header row.
17
17
 
18
- The grid is a fixed viewport like MUI Data Grid Community: **300px** tall by default. Column headers stay visible while rows scroll; pagination stays at the bottom. Override height with `className` or `style` (`h-full`, `h-[520px]`, or `style={{ height: 520 }}`).
18
+ The grid is a fixed viewport like MUI Data Grid Community: **300px** tall by default. Column headers stay visible while rows scroll; pagination stays at the bottom. Override height with a `className` such as `h-full` or a spacing-scale height (`h-130`).
19
19
 
20
20
  When `rows` is empty, a centered "No rows" message is shown and pagination is omitted. Pass `noRowsOverlay` to replace the default message.
21
21
 
@@ -70,7 +70,7 @@ export default function DataGridBasicDemo() {
70
70
  aria-label="Accounts"
71
71
  defaultPaginationModel={{ page: 0, pageSize: 5 }}
72
72
  pageSizeOptions={[5, 10, 25]}
73
- className="h-[420px]"
73
+ className="h-105"
74
74
  />
75
75
  );
76
76
  }
@@ -138,7 +138,7 @@ const columns: GridColDef<Account>[] = [
138
138
  value={row.automation}
139
139
  max={100}
140
140
  accessibilityLabel={`${row.name} is ${row.automation.toString()}% automated`}
141
- className="w-20"
141
+ className="w-full max-w-20"
142
142
  >
143
143
  <ProgressBar.Indicator />
144
144
  </ProgressBar>
@@ -198,7 +198,7 @@ export default function DataGridRichCellsDemo() {
198
198
  columns={columns}
199
199
  hideFooter
200
200
  aria-label="Account operations"
201
- className="h-[520px]"
201
+ className="h-130"
202
202
  />
203
203
  );
204
204
  }
@@ -259,10 +259,10 @@ export default function DataGridToolbarActionsDemo() {
259
259
  onFilterModelChange={setFilterModel}
260
260
  toolbarActions={
261
261
  <>
262
- <Chip color={filterModel.length > 0 ? 'action' : 'neutral'} variant="subtle" size="small">
262
+ <Chip color={filterModel.length > 0 ? 'action' : 'neutral'} size="small">
263
263
  <Chip.Label>{filterModel.length} active</Chip.Label>
264
264
  </Chip>
265
- <Button variant="ghost" color="action" size="small" onPress={toggleHeaderFilters}>
265
+ <Button variant="ghost" size="small" onPress={toggleHeaderFilters}>
266
266
  <Button.Label>Filters</Button.Label>
267
267
  <Button.Icon as={FilterList} position="trailing" />
268
268
  </Button>
@@ -271,7 +271,7 @@ export default function DataGridToolbarActionsDemo() {
271
271
  aria-label="Accounts"
272
272
  defaultPaginationModel={{ page: 0, pageSize: 5 }}
273
273
  pageSizeOptions={[5, 10, 25]}
274
- className="h-[420px]"
274
+ className="h-105"
275
275
  />
276
276
  );
277
277
  }
@@ -315,7 +315,6 @@ export default function DataGridSelectionDemo() {
315
315
  </Chip>
316
316
  <Button
317
317
  variant="ghost"
318
- color="action"
319
318
  size="small"
320
319
  isDisabled={selectedCount === 0}
321
320
  onPress={() => setSelectionModel({ type: 'include', ids: new Set() })}
@@ -327,7 +326,7 @@ export default function DataGridSelectionDemo() {
327
326
  aria-label="Accounts"
328
327
  defaultPaginationModel={{ page: 0, pageSize: 5 }}
329
328
  pageSizeOptions={[5, 10]}
330
- className="h-[420px]"
329
+ className="h-105"
331
330
  />
332
331
  );
333
332
  }
@@ -408,7 +407,7 @@ export default function DataGridServerDataDemo() {
408
407
  onSortModelChange={setSortModel}
409
408
  pageSizeOptions={[5, 10]}
410
409
  aria-label="Server-managed accounts"
411
- className="h-[420px]"
410
+ className="h-105"
412
411
  />
413
412
  );
414
413
  }
@@ -478,7 +477,7 @@ export default function DataGridEmptyDemo() {
478
477
  </VStack>
479
478
  }
480
479
  aria-label="Accounts"
481
- className="h-[300px]"
480
+ className="h-75"
482
481
  />
483
482
  );
484
483
  }
@@ -36,7 +36,7 @@ export default function DrawerBasicDemo() {
36
36
  <Button onPress={() => setOpen(true)}>
37
37
  <Button.Label>Open drawer</Button.Label>
38
38
  </Button>
39
- <Drawer variant="modal" isOpen={open} onOpenChange={setOpen} size="default">
39
+ <Drawer variant="modal" isOpen={open} onOpenChange={setOpen}>
40
40
  <Drawer.Header>
41
41
  <Drawer.Title>Filter accounts</Drawer.Title>
42
42
  <Drawer.Description>Choose which accounts appear in this view.</Drawer.Description>
@@ -70,7 +70,7 @@ import { Box, Button, Drawer, Text } from '@cdx-ui/components';
70
70
 
71
71
  export default function DrawerPermanentDemo() {
72
72
  return (
73
- <Box className="h-[360px] flex-row border border-stroke-secondary">
73
+ <Box className="h-90 flex-row border border-stroke-secondary">
74
74
  <Box className="flex-1 items-center justify-center gap-4 p-4">
75
75
  <Text>Main content area</Text>
76
76
  <Button variant="outline">
@@ -116,7 +116,7 @@ export default function DrawerSizesDemo() {
116
116
  return (
117
117
  <Box className="gap-4">
118
118
  {(Object.keys(sizeLabels) as (keyof typeof sizeLabels)[]).map((size) => (
119
- <Drawer key={size} variant="permanent" size={size} className="h-[120px]">
119
+ <Drawer key={size} size={size} className="h-30">
120
120
  <Drawer.Header showSeparator={false}>
121
121
  <Drawer.Title>{size}</Drawer.Title>
122
122
  </Drawer.Header>
@@ -163,13 +163,7 @@ export default function DrawerSidesDemo() {
163
163
  </Button>
164
164
  ))}
165
165
  </Box>
166
- <Drawer
167
- variant="modal"
168
- isOpen={open}
169
- onOpenChange={setOpen}
170
- placement={placement}
171
- size="default"
172
- >
166
+ <Drawer variant="modal" isOpen={open} onOpenChange={setOpen} placement={placement}>
173
167
  <Drawer.Header>
174
168
  <Drawer.Title>{placement} drawer</Drawer.Title>
175
169
  <Drawer.Description>The panel attaches to this edge of the viewport.</Drawer.Description>
@@ -193,25 +187,23 @@ export default function DrawerSidesDemo() {
193
187
  Set `fullBleed` on `Drawer.Content` to remove horizontal padding for edge-to-edge lists, dividers, or imagery.
194
188
 
195
189
  ```tsx
196
- import { Box, Drawer, Text } from '@cdx-ui/components';
190
+ import { Box, Drawer, ListItem } from '@cdx-ui/components';
197
191
 
198
192
  export default function DrawerFullBleedDemo() {
199
193
  return (
200
- <Box className="h-[280px] flex-row border border-stroke-secondary">
201
- <Drawer variant="permanent" size="default">
194
+ <Box className="h-70 flex-row border border-stroke-secondary">
195
+ <Drawer>
202
196
  <Drawer.Header>
203
197
  <Drawer.Title>Recent activity</Drawer.Title>
204
198
  </Drawer.Header>
205
199
  <Drawer.Content fullBleed>
206
- <Box className="border-b border-stroke-secondary px-4 py-3">
207
- <Text size="sm">Coffee shop</Text>
208
- </Box>
209
- <Box className="border-b border-stroke-secondary px-4 py-3">
210
- <Text size="sm">Direct deposit</Text>
211
- </Box>
212
- <Box className="px-4 py-3">
213
- <Text size="sm">Transfer to savings</Text>
214
- </Box>
200
+ {['Coffee shop', 'Direct deposit', 'Transfer to savings'].map((label, index, labels) => (
201
+ <ListItem key={label} size="compact" showSeparator={index < labels.length - 1}>
202
+ <ListItem.Content>
203
+ <ListItem.Title>{label}</ListItem.Title>
204
+ </ListItem.Content>
205
+ </ListItem>
206
+ ))}
215
207
  </Drawer.Content>
216
208
  </Drawer>
217
209
  </Box>
@@ -232,10 +224,10 @@ import { Box, Drawer, Icon, Text } from '@cdx-ui/components';
232
224
  export default function DrawerHeaderVariantsDemo() {
233
225
  return (
234
226
  <Box className="gap-4">
235
- <Drawer variant="permanent" size="default" className="h-[160px]">
227
+ <Drawer className="h-40">
236
228
  <Drawer.Header>
237
229
  <Drawer.LeadingSlot>
238
- <Icon as={FilterList} size={24} />
230
+ <Icon as={FilterList} className="size-6" />
239
231
  </Drawer.LeadingSlot>
240
232
  <Drawer.Title>Filter accounts</Drawer.Title>
241
233
  <Drawer.Description>Choose which accounts appear in this view.</Drawer.Description>
@@ -246,7 +238,7 @@ export default function DrawerHeaderVariantsDemo() {
246
238
  </Text>
247
239
  </Drawer.Content>
248
240
  </Drawer>
249
- <Drawer variant="permanent" size="default" className="h-[120px]">
241
+ <Drawer className="h-30">
250
242
  <Drawer.Header close={null}>
251
243
  <Drawer.Title>Accounts</Drawer.Title>
252
244
  </Drawer.Header>
@@ -114,7 +114,7 @@ export default function FullScreenDialogWithFooterDemo() {
114
114
  <FullScreenDialog.Content className="w-full max-w-md self-center">
115
115
  <ScrollView className="flex-1" contentContainerClassName="gap-6 p-4">
116
116
  <Box className="items-center gap-3 py-4">
117
- <Avatar size="2xl" color="brand" accessibilityLabel="Springfield Electric">
117
+ <Avatar size="2xl" accessibilityLabel="Springfield Electric">
118
118
  <Avatar.Text>Springfield Electric</Avatar.Text>
119
119
  </Avatar>
120
120
  <Heading size="xl">$84.12</Heading>
@@ -349,7 +349,7 @@ export default function FullScreenDialogHeaderContentDemo() {
349
349
  <FullScreenDialog.Trigger asChild>
350
350
  <ListItem showSeparator={false} accessibilityHint="Opens a searchable list of payees">
351
351
  <ListItem.LeadingSlot>
352
- <Avatar size="lg" color="brand" accessibilityLabel={payee?.name ?? 'Payee'}>
352
+ <Avatar size="lg" accessibilityLabel={payee?.name ?? 'Payee'}>
353
353
  <Avatar.Text>{payee?.name ?? ''}</Avatar.Text>
354
354
  </Avatar>
355
355
  </ListItem.LeadingSlot>
@@ -180,7 +180,7 @@ Inherits all `ForgeIconProps` except the SVG `color`: [`SvgProps`](https://githu
180
180
  - A raw `color` value, such as a hex string, is deprecated. It is passed to the SVG unchanged and logs a one-time warning in development. Use a semantic color instead.
181
181
  - `className` defaults to `size-5 shrink-0`, so an icon keeps its size in a row of text on web.
182
182
  - Consumer classes are merged after the defaults, so `size-*` and `shrink` utilities override them.
183
- - The inherited `size` prop can set the SVG dimensions directly when a `size-*` class is not appropriate.
183
+ - Don't pass the inherited numeric `size` prop; it bypasses the spacing scale. Use `size-4` or `size-6` when the default doesn't fit.
184
184
  - `filled` defaults to `false`.
185
185
 
186
186
  ## Accessibility
@@ -34,9 +34,9 @@ import { ArrowCircleUp } from '@cdx-ui/icons';
34
34
  export default function IconButtonSolidDemo() {
35
35
  return (
36
36
  <Box className="flex-row gap-4">
37
- <IconButton as={ArrowCircleUp} variant="solid" color="neutral" accessibilityLabel="Neutral" />
38
- <IconButton as={ArrowCircleUp} variant="solid" color="action" accessibilityLabel="Action" />
39
- <IconButton as={ArrowCircleUp} variant="solid" color="danger" accessibilityLabel="Danger" />
37
+ <IconButton as={ArrowCircleUp} color="neutral" accessibilityLabel="Neutral" />
38
+ <IconButton as={ArrowCircleUp} color="action" accessibilityLabel="Action" />
39
+ <IconButton as={ArrowCircleUp} color="danger" accessibilityLabel="Danger" />
40
40
  </Box>
41
41
  );
42
42
  }
@@ -101,6 +101,71 @@ export default function InputPasswordDemo() {
101
101
  }
102
102
  ```
103
103
 
104
+ ## Character count
105
+
106
+ Derive the count from the field value and render it as adornment text in a trailing `Input.Slot` — a raw count, or the count alongside a limit.
107
+
108
+ ```tsx
109
+ import { useState } from 'react';
110
+ import { Box, Input, Text } from '@cdx-ui/components';
111
+
112
+ const MEMO_LIMIT = 40;
113
+
114
+ export default function InputCharacterCountDemo() {
115
+ const [nickname, setNickname] = useState('Checking');
116
+ const [memo, setMemo] = useState('Rent for October');
117
+ const nicknameCount = String(nickname.length);
118
+ const memoLength = String(memo.length);
119
+ const memoLimit = String(MEMO_LIMIT);
120
+ const memoCount = `${memoLength}/${memoLimit}`;
121
+
122
+ return (
123
+ <Box className="w-full gap-4">
124
+ <Box className="gap-2">
125
+ <Text size="sm" color="secondary">
126
+ Count
127
+ </Text>
128
+ <Input>
129
+ <Input.Field
130
+ accessibilityLabel="Account nickname"
131
+ value={nickname}
132
+ onChangeText={setNickname}
133
+ />
134
+ <Input.Slot>
135
+ <Text
136
+ size="sm"
137
+ color="tertiary"
138
+ className="tabular-nums"
139
+ accessibilityLabel={`${nicknameCount} characters`}
140
+ >
141
+ {nicknameCount}
142
+ </Text>
143
+ </Input.Slot>
144
+ </Input>
145
+ </Box>
146
+ <Box className="gap-2">
147
+ <Text size="sm" color="secondary">
148
+ Count and limit
149
+ </Text>
150
+ <Input>
151
+ <Input.Field accessibilityLabel="Transfer memo" value={memo} onChangeText={setMemo} />
152
+ <Input.Slot>
153
+ <Text
154
+ size="sm"
155
+ color="tertiary"
156
+ className="tabular-nums"
157
+ accessibilityLabel={`${memoLength} of ${memoLimit} characters`}
158
+ >
159
+ {memoCount}
160
+ </Text>
161
+ </Input.Slot>
162
+ </Input>
163
+ </Box>
164
+ </Box>
165
+ );
166
+ }
167
+ ```
168
+
104
169
  ## States
105
170
 
106
171
  The root controls disabled, read-only, required, and invalid state for the field.
@@ -22,7 +22,7 @@ export default function ListItemBasicDemo() {
22
22
  <Card.Content>
23
23
  <ListItem onPress={() => {}} showSeparator={false}>
24
24
  <ListItem.LeadingSlot>
25
- <Avatar size="md">
25
+ <Avatar>
26
26
  <Avatar.Icon as={Person} />
27
27
  </Avatar>
28
28
  </ListItem.LeadingSlot>
@@ -102,7 +102,7 @@ export default function ListItemSizesDemo() {
102
102
  <Card.Content>
103
103
  <ListItem size={size} onPress={() => {}} showSeparator={false}>
104
104
  <ListItem.LeadingSlot>
105
- <Avatar size="md">
105
+ <Avatar>
106
106
  <Avatar.Icon as={Person} />
107
107
  </Avatar>
108
108
  </ListItem.LeadingSlot>
@@ -268,7 +268,7 @@ export default function ListItemSectionedSubtleDemo() {
268
268
 
269
269
  <ListItem onPress={() => {}}>
270
270
  <ListItem.LeadingSlot>
271
- <Avatar size="md">
271
+ <Avatar>
272
272
  <Avatar.Text>Adam White</Avatar.Text>
273
273
  </Avatar>
274
274
  </ListItem.LeadingSlot>
@@ -280,7 +280,7 @@ export default function ListItemSectionedSubtleDemo() {
280
280
 
281
281
  <ListItem onPress={() => {}} showSeparator={false}>
282
282
  <ListItem.LeadingSlot>
283
- <Avatar size="md">
283
+ <Avatar>
284
284
  <Avatar.Text>Aron Smith</Avatar.Text>
285
285
  </Avatar>
286
286
  </ListItem.LeadingSlot>
@@ -296,7 +296,7 @@ export default function ListItemSectionedSubtleDemo() {
296
296
 
297
297
  <ListItem onPress={() => {}}>
298
298
  <ListItem.LeadingSlot>
299
- <Avatar size="md">
299
+ <Avatar>
300
300
  <Avatar.Text>Bennett Charles</Avatar.Text>
301
301
  </Avatar>
302
302
  </ListItem.LeadingSlot>
@@ -308,7 +308,7 @@ export default function ListItemSectionedSubtleDemo() {
308
308
 
309
309
  <ListItem onPress={() => {}} showSeparator={false}>
310
310
  <ListItem.LeadingSlot>
311
- <Avatar size="md">
311
+ <Avatar>
312
312
  <Avatar.Text>Brightside Dental</Avatar.Text>
313
313
  </Avatar>
314
314
  </ListItem.LeadingSlot>
@@ -392,7 +392,7 @@ export default function ListItemVirtualizedDemo() {
392
392
  renderItem={({ item, index }) => (
393
393
  <ListItem onPress={() => undefined} showSeparator={index < transactions.length - 1}>
394
394
  <ListItem.LeadingSlot>
395
- <Avatar size="md">
395
+ <Avatar>
396
396
  <Avatar.Text>{item.title.slice(0, 2).toUpperCase()}</Avatar.Text>
397
397
  </Avatar>
398
398
  </ListItem.LeadingSlot>
@@ -428,7 +428,7 @@ export default function ListItemMultipleTrailingDemo() {
428
428
  <Card.Content>
429
429
  <ListItem onPress={() => {}} showSeparator={false}>
430
430
  <ListItem.LeadingSlot>
431
- <Avatar size="md">
431
+ <Avatar>
432
432
  <Avatar.Icon as={Person} />
433
433
  </Avatar>
434
434
  </ListItem.LeadingSlot>
@@ -461,7 +461,7 @@ export default function ListItemDisabledDemo() {
461
461
  <Card.Content>
462
462
  <ListItem onPress={() => {}} isDisabled showSeparator={false}>
463
463
  <ListItem.LeadingSlot>
464
- <Avatar size="md">
464
+ <Avatar>
465
465
  <Avatar.Icon as={Person} />
466
466
  </Avatar>
467
467
  </ListItem.LeadingSlot>