@cdx-ui/components 0.2.3 → 0.2.4
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/AGENTS.md +24 -0
- package/README.md +2 -0
- package/coverage.svg +1 -1
- package/docs/components/accordion/content.md +538 -0
- package/docs/components/alert/content.md +203 -0
- package/docs/components/alert-dialog/content.md +319 -0
- package/docs/components/avatar/content.md +368 -0
- package/docs/components/avatar/design.md +202 -0
- package/docs/components/badge/content.md +235 -0
- package/docs/components/bottom-sheet/content.md +351 -0
- package/docs/components/bottom-sheet/design.md +249 -0
- package/docs/components/breadcrumbs/content.md +169 -0
- package/docs/components/button/content.md +398 -0
- package/docs/components/button/design.md +258 -0
- package/docs/components/calendar/content.md +137 -0
- package/docs/components/card/content.md +283 -0
- package/docs/components/carousel/content.md +416 -0
- package/docs/components/checkbox/content.md +236 -0
- package/docs/components/checkbox/design.md +214 -0
- package/docs/components/chip/content.md +439 -0
- package/docs/components/chip/design.md +418 -0
- package/docs/components/color-area/content.md +86 -0
- package/docs/components/color-field/content.md +134 -0
- package/docs/components/color-picker/content.md +208 -0
- package/docs/components/color-slider/content.md +120 -0
- package/docs/components/color-swatch/content.md +64 -0
- package/docs/components/color-swatch-picker/content.md +126 -0
- package/docs/components/content.md +97 -0
- package/docs/components/currency-input/content.md +205 -0
- package/docs/components/data-grid/content.md +522 -0
- package/docs/components/date-field/content.md +147 -0
- package/docs/components/date-picker/content.md +360 -0
- package/docs/components/date-range-picker/content.md +301 -0
- package/docs/components/date-time-field/content.md +157 -0
- package/docs/components/date-time-list/content.md +105 -0
- package/docs/components/date-time-picker/content.md +272 -0
- package/docs/components/dialog/content.md +436 -0
- package/docs/components/dialog/design.md +192 -0
- package/docs/components/divider/content.md +112 -0
- package/docs/components/drawer/content.md +436 -0
- package/docs/components/field/content.md +277 -0
- package/docs/components/form/content.md +62 -0
- package/docs/components/full-screen-dialog/content.md +881 -0
- package/docs/components/heading/content.md +55 -0
- package/docs/components/icon/content.md +190 -0
- package/docs/components/icon-button/content.md +200 -0
- package/docs/components/icon-button/design.md +165 -0
- package/docs/components/image/content.md +104 -0
- package/docs/components/input/content.md +281 -0
- package/docs/components/input/design.md +389 -0
- package/docs/components/insurance-disclosure/content.md +103 -0
- package/docs/components/link/content.md +180 -0
- package/docs/components/link/design.md +160 -0
- package/docs/components/list-item/content.md +695 -0
- package/docs/components/menu/content.md +1247 -0
- package/docs/components/month-calendar/content.md +84 -0
- package/docs/components/month-picker/content.md +273 -0
- package/docs/components/otp-input/content.md +327 -0
- package/docs/components/progress-bar/content.md +87 -0
- package/docs/components/progress-circle/content.md +176 -0
- package/docs/components/progress-segmented/content.md +119 -0
- package/docs/components/quick-action-button/content.md +154 -0
- package/docs/components/quick-action-button/design.md +170 -0
- package/docs/components/radio/content.md +224 -0
- package/docs/components/range-calendar/content.md +123 -0
- package/docs/components/reorderable-list/content.md +309 -0
- package/docs/components/scoped-theme/content.md +47 -0
- package/docs/components/scroll-shadow/content.md +686 -0
- package/docs/components/select/content.md +400 -0
- package/docs/components/select/design.md +301 -0
- package/docs/components/skeleton/content.md +103 -0
- package/docs/components/slider/content.md +423 -0
- package/docs/components/stack/content.md +161 -0
- package/docs/components/switch/content.md +150 -0
- package/docs/components/switch/design.md +208 -0
- package/docs/components/table/content.md +548 -0
- package/docs/components/table-pagination/content.md +177 -0
- package/docs/components/tabs/content.md +292 -0
- package/docs/components/text/content.md +142 -0
- package/docs/components/textarea/content.md +222 -0
- package/docs/components/tile/content.md +703 -0
- package/docs/components/toast/content.md +456 -0
- package/docs/components/toggle-button/content.md +505 -0
- package/docs/components/tooltip/content.md +350 -0
- package/docs/components/virtualized-list/content.md +250 -0
- package/docs/foundations/content.md +9 -0
- package/docs/foundations/expressions/icons/content.md +19 -0
- package/docs/foundations/styles/tokens/all-tokens/content.md +192 -0
- package/docs/foundations/styles/tokens/what-are-tokens/content.md +33 -0
- package/docs/foundations/styles/tokens/what-are-tokens/design.md +33 -0
- package/docs/getting-started/content.md +4 -0
- package/docs/getting-started/designers/content.md +13 -0
- package/docs/getting-started/designers/design.md +13 -0
- package/docs/getting-started/developers/accessibility/content.md +31 -0
- package/docs/getting-started/developers/content.md +612 -0
- package/docs/getting-started/developers/styling/content.md +193 -0
- package/docs/llms.txt +193 -0
- package/docs/patterns/account-management/content.md +75 -0
- package/docs/patterns/authentication/content.md +52 -0
- package/docs/patterns/content.md +10 -0
- package/docs/patterns/dashboard/content.md +39 -0
- package/docs/patterns/empty-states/content.md +31 -0
- package/docs/patterns/forms/content.md +109 -0
- package/docs/patterns/onboarding/content.md +69 -0
- package/docs/patterns/payments/content.md +35 -0
- package/docs/patterns/settings/content.md +72 -0
- package/docs/resources/content.md +9 -0
- package/docs/resources/figma-libraries/content.md +42 -0
- package/docs/resources/release-notes/0.0.1-beta.118/content.md +27 -0
- package/docs/resources/release-notes/0.0.1-beta.122/content.md +21 -0
- package/docs/resources/release-notes/0.0.1-beta.124/content.md +16 -0
- package/docs/resources/release-notes/0.0.1-beta.126/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.127/content.md +14 -0
- package/docs/resources/release-notes/0.0.1-beta.128/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.129/content.md +18 -0
- package/docs/resources/release-notes/0.0.1-beta.130/content.md +18 -0
- package/docs/resources/release-notes/0.0.1-beta.133/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.134/content.md +17 -0
- package/docs/resources/release-notes/0.0.1-beta.136/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.137/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.138/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.139/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.140/content.md +26 -0
- package/docs/resources/release-notes/0.0.1-beta.141/content.md +63 -0
- package/docs/resources/release-notes/0.0.1-beta.142/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.143/content.md +12 -0
- package/docs/resources/release-notes/0.0.1-beta.144/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.145/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.147/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.149/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.150/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.152/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.154/content.md +15 -0
- package/docs/resources/release-notes/0.0.1-beta.156/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.158/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.159/content.md +11 -0
- package/docs/resources/release-notes/0.0.1-beta.160/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.161/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.163/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.164/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.166/content.md +17 -0
- package/docs/resources/release-notes/0.0.1-beta.167/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.168/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.169/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.171/content.md +16 -0
- package/docs/resources/release-notes/0.0.1-beta.172/content.md +24 -0
- package/docs/resources/release-notes/0.0.1-beta.173/content.md +15 -0
- package/docs/resources/release-notes/0.0.1-beta.174/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.176/content.md +32 -0
- package/docs/resources/release-notes/0.0.1-beta.179/content.md +11 -0
- package/docs/resources/release-notes/0.0.1-beta.182/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.185/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.187/content.md +27 -0
- package/docs/resources/release-notes/0.1.1/content.md +23 -0
- package/docs/resources/release-notes/0.1.2/content.md +7 -0
- package/docs/resources/release-notes/0.1.4/content.md +19 -0
- package/docs/resources/release-notes/0.1.5/content.md +7 -0
- package/docs/resources/release-notes/0.1.6/content.md +7 -0
- package/docs/resources/release-notes/0.2.0/content.md +31 -0
- package/docs/resources/release-notes/0.2.1/content.md +17 -0
- package/docs/resources/release-notes/0.2.2/content.md +11 -0
- package/docs/resources/release-notes/0.2.3/content.md +15 -0
- package/docs/resources/release-notes/content.md +64 -0
- package/lib/commonjs/components/DateTimeList/index.js +11 -26
- package/lib/commonjs/components/DateTimeList/index.js.map +1 -1
- package/lib/commonjs/components/DateTimeList/styles.js +2 -12
- package/lib/commonjs/components/DateTimeList/styles.js.map +1 -1
- package/lib/commonjs/components/ListItem/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/styles.js +2 -1
- package/lib/commonjs/components/ListItem/styles.js.map +1 -1
- package/lib/commonjs/components/Menu/index.js +11 -5
- package/lib/commonjs/components/Menu/index.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/gradient.js +29 -0
- package/lib/commonjs/components/ScrollShadow/gradient.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/index.js +171 -44
- package/lib/commonjs/components/ScrollShadow/index.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/styles.js +58 -14
- package/lib/commonjs/components/ScrollShadow/styles.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js +63 -0
- package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +48 -8
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/commonjs/components/Tabs/index.js +16 -23
- package/lib/commonjs/components/Tabs/index.js.map +1 -1
- package/lib/commonjs/components/Tabs/styles.js +1 -10
- package/lib/commonjs/components/Tabs/styles.js.map +1 -1
- package/lib/commonjs/figma/ListItem.SectionHeader.figma.js +20 -5
- package/lib/commonjs/figma/ListItem.SectionHeader.figma.js.map +1 -1
- package/lib/module/components/DateTimeList/index.js +12 -27
- package/lib/module/components/DateTimeList/index.js.map +1 -1
- package/lib/module/components/DateTimeList/styles.js +1 -11
- package/lib/module/components/DateTimeList/styles.js.map +1 -1
- package/lib/module/components/ListItem/index.js.map +1 -1
- package/lib/module/components/ListItem/styles.js +2 -1
- package/lib/module/components/ListItem/styles.js.map +1 -1
- package/lib/module/components/Menu/index.js +11 -5
- package/lib/module/components/Menu/index.js.map +1 -1
- package/lib/module/components/ScrollShadow/gradient.js +24 -0
- package/lib/module/components/ScrollShadow/gradient.js.map +1 -0
- package/lib/module/components/ScrollShadow/index.js +170 -48
- package/lib/module/components/ScrollShadow/index.js.map +1 -1
- package/lib/module/components/ScrollShadow/styles.js +57 -13
- package/lib/module/components/ScrollShadow/styles.js.map +1 -1
- package/lib/module/components/ScrollShadow/useComposedScrollHandler.js +57 -0
- package/lib/module/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
- package/lib/module/components/ScrollShadow/useScrollShadow.js +46 -8
- package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/module/components/Tabs/index.js +17 -24
- package/lib/module/components/Tabs/index.js.map +1 -1
- package/lib/module/components/Tabs/styles.js +0 -9
- package/lib/module/components/Tabs/styles.js.map +1 -1
- package/lib/module/figma/ListItem.SectionHeader.figma.js +20 -5
- package/lib/module/figma/ListItem.SectionHeader.figma.js.map +1 -1
- package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -1
- package/lib/typescript/components/DateTimeList/styles.d.ts +1 -4
- package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/index.d.ts +5 -4
- package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
- package/lib/typescript/components/Menu/index.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/gradient.d.ts +7 -0
- package/lib/typescript/components/ScrollShadow/gradient.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/index.d.ts +57 -15
- package/lib/typescript/components/ScrollShadow/index.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/styles.d.ts +8 -2
- package/lib/typescript/components/ScrollShadow/styles.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts +13 -0
- package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts +15 -2
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
- package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
- package/lib/typescript/components/Tabs/styles.d.ts +0 -7
- package/lib/typescript/components/Tabs/styles.d.ts.map +1 -1
- package/lib/typescript/figma/ListItem.SectionHeader.figma.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/components/DateTimeList/index.tsx +13 -26
- package/src/components/DateTimeList/styles.ts +1 -10
- package/src/components/ListItem/index.tsx +5 -4
- package/src/components/ListItem/styles.ts +1 -0
- package/src/components/Menu/index.tsx +11 -8
- package/src/components/ScrollShadow/gradient.ts +48 -0
- package/src/components/ScrollShadow/index.tsx +300 -69
- package/src/components/ScrollShadow/styles.ts +45 -28
- package/src/components/ScrollShadow/useComposedScrollHandler.ts +58 -0
- package/src/components/ScrollShadow/useScrollShadow.ts +72 -10
- package/src/components/Tabs/index.tsx +25 -35
- package/src/components/Tabs/styles.ts +0 -9
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# Tooltip (https://design.candescent.com/docs/components/tooltip)
|
|
2
|
+
|
|
3
|
+
Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=12996-1099), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/overlays-tooltip--default)
|
|
4
|
+
|
|
5
|
+
`Tooltip` is a compound component for short contextual hints. Compose `Tooltip.Trigger` with the interactive element and `Tooltip.Content` for the overlay body.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Tooltip } from '@cdx-ui/components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic
|
|
12
|
+
|
|
13
|
+
The default `hover` trigger opens on hover and focus on web, and on long press on native. Include `Tooltip.Arrow` inside `Tooltip.Content` when you want a directional pointer; omit it for a plain surface.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Button, Tooltip } from '@cdx-ui/components';
|
|
17
|
+
|
|
18
|
+
export default function TooltipBasicDemo() {
|
|
19
|
+
return (
|
|
20
|
+
<Tooltip>
|
|
21
|
+
<Tooltip.Trigger asChild>
|
|
22
|
+
<Button variant="solid" color="action">
|
|
23
|
+
<Button.Label>Hover for tooltip</Button.Label>
|
|
24
|
+
</Button>
|
|
25
|
+
</Tooltip.Trigger>
|
|
26
|
+
<Tooltip.Content>
|
|
27
|
+
<Tooltip.Arrow />
|
|
28
|
+
Helpful information about this element
|
|
29
|
+
</Tooltip.Content>
|
|
30
|
+
</Tooltip>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Without arrow
|
|
36
|
+
|
|
37
|
+
Omit `Tooltip.Arrow` for a plain tooltip surface.
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { Button, Tooltip } from '@cdx-ui/components';
|
|
41
|
+
|
|
42
|
+
export default function TooltipWithoutArrowDemo() {
|
|
43
|
+
return (
|
|
44
|
+
<Tooltip>
|
|
45
|
+
<Tooltip.Trigger asChild>
|
|
46
|
+
<Button variant="solid" color="action">
|
|
47
|
+
<Button.Label>Hover me</Button.Label>
|
|
48
|
+
</Button>
|
|
49
|
+
</Tooltip.Trigger>
|
|
50
|
+
<Tooltip.Content>Plain tooltip without an arrow</Tooltip.Content>
|
|
51
|
+
</Tooltip>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Focus trigger
|
|
57
|
+
|
|
58
|
+
Set `trigger="focus"` to open when the trigger receives keyboard focus. On native, focus and hover both map to long press.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { Button, Tooltip } from '@cdx-ui/components';
|
|
62
|
+
|
|
63
|
+
export default function TooltipFocusTriggerDemo() {
|
|
64
|
+
return (
|
|
65
|
+
<Tooltip trigger="focus">
|
|
66
|
+
<Tooltip.Trigger asChild>
|
|
67
|
+
<Button variant="solid" color="action">
|
|
68
|
+
<Button.Label>Focus me</Button.Label>
|
|
69
|
+
</Button>
|
|
70
|
+
</Tooltip.Trigger>
|
|
71
|
+
<Tooltip.Content>
|
|
72
|
+
<Tooltip.Arrow />
|
|
73
|
+
Keyboard-accessible tooltip
|
|
74
|
+
</Tooltip.Content>
|
|
75
|
+
</Tooltip>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Click trigger
|
|
81
|
+
|
|
82
|
+
Set `trigger="click"` to toggle the tooltip on press. On web, it closes on outside click or Escape.
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { Button, Tooltip } from '@cdx-ui/components';
|
|
86
|
+
|
|
87
|
+
export default function TooltipClickTriggerDemo() {
|
|
88
|
+
return (
|
|
89
|
+
<Tooltip trigger="click">
|
|
90
|
+
<Tooltip.Trigger asChild>
|
|
91
|
+
<Button variant="solid" color="action">
|
|
92
|
+
<Button.Label>Click for tooltip</Button.Label>
|
|
93
|
+
</Button>
|
|
94
|
+
</Tooltip.Trigger>
|
|
95
|
+
<Tooltip.Content>
|
|
96
|
+
<Tooltip.Arrow />
|
|
97
|
+
Opens on click or press. On web, closes on outside click or Escape.
|
|
98
|
+
</Tooltip.Content>
|
|
99
|
+
</Tooltip>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Placement
|
|
105
|
+
|
|
106
|
+
Set `placement` to position the tooltip relative to the trigger. The component flips when there is not enough space.
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { Box, Button, Tooltip, type TooltipPlacement } from '@cdx-ui/components';
|
|
110
|
+
|
|
111
|
+
function PlacementExample({
|
|
112
|
+
placement,
|
|
113
|
+
label,
|
|
114
|
+
}: Readonly<{
|
|
115
|
+
placement: TooltipPlacement;
|
|
116
|
+
label: string;
|
|
117
|
+
}>) {
|
|
118
|
+
return (
|
|
119
|
+
<Tooltip placement={placement}>
|
|
120
|
+
<Tooltip.Trigger asChild>
|
|
121
|
+
<Button variant="solid" color="action">
|
|
122
|
+
<Button.Label>{label}</Button.Label>
|
|
123
|
+
</Button>
|
|
124
|
+
</Tooltip.Trigger>
|
|
125
|
+
<Tooltip.Content>
|
|
126
|
+
<Tooltip.Arrow />
|
|
127
|
+
{label} placement
|
|
128
|
+
</Tooltip.Content>
|
|
129
|
+
</Tooltip>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export default function TooltipPlacementDemo() {
|
|
134
|
+
return (
|
|
135
|
+
<Box className="items-center gap-8">
|
|
136
|
+
<PlacementExample placement="top" label="Top" />
|
|
137
|
+
<Box className="flex-row items-center gap-16">
|
|
138
|
+
<PlacementExample placement="left" label="Left" />
|
|
139
|
+
<PlacementExample placement="right" label="Right" />
|
|
140
|
+
</Box>
|
|
141
|
+
<PlacementExample placement="bottom" label="Bottom" />
|
|
142
|
+
</Box>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Custom triggers
|
|
148
|
+
|
|
149
|
+
Use `Tooltip.Trigger` with `asChild` to attach tooltips to avatars, chips, switches, icons, and other interactive elements.
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
import { useState, type ReactElement } from 'react';
|
|
153
|
+
import { Avatar, Box, Button, Chip, IconButton, Switch, Text, Tooltip } from '@cdx-ui/components';
|
|
154
|
+
import { Info } from '@cdx-ui/icons';
|
|
155
|
+
|
|
156
|
+
function CustomTriggerRow({
|
|
157
|
+
label,
|
|
158
|
+
content,
|
|
159
|
+
children,
|
|
160
|
+
}: Readonly<{
|
|
161
|
+
label: string;
|
|
162
|
+
content: string;
|
|
163
|
+
children: ReactElement;
|
|
164
|
+
}>) {
|
|
165
|
+
return (
|
|
166
|
+
<Box className="flex-row items-center gap-6">
|
|
167
|
+
<Text color="secondary" size="sm" className="w-20">
|
|
168
|
+
{label}
|
|
169
|
+
</Text>
|
|
170
|
+
<Tooltip>
|
|
171
|
+
<Tooltip.Trigger asChild>{children}</Tooltip.Trigger>
|
|
172
|
+
<Tooltip.Content>
|
|
173
|
+
<Tooltip.Arrow />
|
|
174
|
+
{content}
|
|
175
|
+
</Tooltip.Content>
|
|
176
|
+
</Tooltip>
|
|
177
|
+
</Box>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export default function TooltipCustomTriggersDemo() {
|
|
182
|
+
const [notifications, setNotifications] = useState(false);
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<Box className="items-start gap-8">
|
|
186
|
+
<CustomTriggerRow label="Avatar" content="Account owner profile">
|
|
187
|
+
<Avatar size="md">
|
|
188
|
+
<Avatar.Image src="https://www.loremfaces.net/128/id/1.jpg" />
|
|
189
|
+
<Avatar.Text>Jane Doe</Avatar.Text>
|
|
190
|
+
</Avatar>
|
|
191
|
+
</CustomTriggerRow>
|
|
192
|
+
|
|
193
|
+
<CustomTriggerRow label="Chip" content="Filter by premium members">
|
|
194
|
+
<Chip color="action" variant="outline">
|
|
195
|
+
<Chip.Label>Premium</Chip.Label>
|
|
196
|
+
</Chip>
|
|
197
|
+
</CustomTriggerRow>
|
|
198
|
+
|
|
199
|
+
<CustomTriggerRow label="Switch" content="Enable email notifications">
|
|
200
|
+
<Switch
|
|
201
|
+
value={notifications}
|
|
202
|
+
onValueChange={setNotifications}
|
|
203
|
+
accessibilityLabel="Email notifications"
|
|
204
|
+
/>
|
|
205
|
+
</CustomTriggerRow>
|
|
206
|
+
|
|
207
|
+
<CustomTriggerRow label="Icon" content="Additional account information">
|
|
208
|
+
<IconButton as={Info} variant="ghost" accessibilityLabel="More information" />
|
|
209
|
+
</CustomTriggerRow>
|
|
210
|
+
|
|
211
|
+
<CustomTriggerRow label="Button" content="Initiate a funds transfer">
|
|
212
|
+
<Button color="action" variant="outline">
|
|
213
|
+
<Button.Label>Transfer</Button.Label>
|
|
214
|
+
</Button>
|
|
215
|
+
</CustomTriggerRow>
|
|
216
|
+
</Box>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Delay
|
|
222
|
+
|
|
223
|
+
Use `enterDelay` and `leaveDelay` to debounce show and hide timing.
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
import { Button, Tooltip } from '@cdx-ui/components';
|
|
227
|
+
|
|
228
|
+
export default function TooltipDelayDemo() {
|
|
229
|
+
return (
|
|
230
|
+
<Tooltip enterDelay={500} leaveDelay={300}>
|
|
231
|
+
<Tooltip.Trigger asChild>
|
|
232
|
+
<Button variant="solid" color="action">
|
|
233
|
+
<Button.Label>Delayed tooltip</Button.Label>
|
|
234
|
+
</Button>
|
|
235
|
+
</Tooltip.Trigger>
|
|
236
|
+
<Tooltip.Content>
|
|
237
|
+
<Tooltip.Arrow />
|
|
238
|
+
Waits 500ms to open and 300ms to close
|
|
239
|
+
</Tooltip.Content>
|
|
240
|
+
</Tooltip>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Disabled
|
|
246
|
+
|
|
247
|
+
Set `isDisabled` to block tooltip interactions.
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
import { Button, Tooltip } from '@cdx-ui/components';
|
|
251
|
+
|
|
252
|
+
export default function TooltipDisabledDemo() {
|
|
253
|
+
return (
|
|
254
|
+
<Tooltip isDisabled>
|
|
255
|
+
<Tooltip.Trigger asChild>
|
|
256
|
+
<Button variant="solid" color="action">
|
|
257
|
+
<Button.Label>Disabled tooltip</Button.Label>
|
|
258
|
+
</Button>
|
|
259
|
+
</Tooltip.Trigger>
|
|
260
|
+
<Tooltip.Content>
|
|
261
|
+
<Tooltip.Arrow />
|
|
262
|
+
This tooltip does not open
|
|
263
|
+
</Tooltip.Content>
|
|
264
|
+
</Tooltip>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## API
|
|
270
|
+
|
|
271
|
+
### Tooltip
|
|
272
|
+
|
|
273
|
+
Root container for trigger and content. Controls open state, placement, offset, and trigger mode.
|
|
274
|
+
|
|
275
|
+
| Prop | Type | Default | Description |
|
|
276
|
+
| --- | --- | --- | --- |
|
|
277
|
+
| `className?` | `string` | — | — |
|
|
278
|
+
| `children?` | `ReactNode` | — | — |
|
|
279
|
+
| `isDisabled?` | `boolean` | — | — |
|
|
280
|
+
| `enterDelay?` | `number` | ``0`` | Milliseconds to wait before showing the tooltip. |
|
|
281
|
+
| `leaveDelay?` | `number` | ``0`` | Milliseconds to wait before hiding the tooltip. |
|
|
282
|
+
| `isOpen?` | `boolean` | — | Controlled open state. |
|
|
283
|
+
| `defaultOpen?` | `boolean` | ``false`` | Uncontrolled initial open state. |
|
|
284
|
+
| `onOpen?` | `(() => void)` | — | Called when the tooltip opens. |
|
|
285
|
+
| `onClose?` | `(() => void)` | — | Called when the tooltip closes. |
|
|
286
|
+
| `placement?` | `'auto' \| 'auto-start' \| 'auto-end' \| 'top' \| 'top-start' \| 'top-end' \| 'right' \| 'right-start' \| 'right-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end'` | ``'top'`` | Preferred placement relative to the trigger. |
|
|
287
|
+
| `offset?` | `number` | ``8`` | Distance in pixels between the tooltip and the trigger. |
|
|
288
|
+
| `trigger?` | `'hover' \| 'focus' \| 'click'` | ``'hover'`` | Interaction that opens the tooltip. On web, `hover` opens on hover and focus; on native, long press. `focus` opens on focus (web) or long press (native). `click` toggles on press — on web, dismisses on outside click or Escape. |
|
|
289
|
+
|
|
290
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
291
|
+
|
|
292
|
+
| Attribute | Values | Description |
|
|
293
|
+
| --------------- | ------------------ | ------------------------------ |
|
|
294
|
+
| `data-state` | `open` \| `closed` | Whether the tooltip is visible |
|
|
295
|
+
| `data-disabled` | `true` \| `false` | Disabled state |
|
|
296
|
+
|
|
297
|
+
## Sub-components
|
|
298
|
+
|
|
299
|
+
### Tooltip.Trigger
|
|
300
|
+
|
|
301
|
+
Wraps the element that opens the tooltip. Use `asChild` when composing with `Button` or other interactive children so hover and focus attach to the correct element.
|
|
302
|
+
|
|
303
|
+
| Prop | Type | Default | Description |
|
|
304
|
+
| --- | --- | --- | --- |
|
|
305
|
+
| `className?` | `string` | — | — |
|
|
306
|
+
| `children?` | `ReactNode` | — | Either children or a render prop that receives a boolean reflecting whether the component is currently pressed. |
|
|
307
|
+
| `asChild?` | `boolean` | — | When true, merges trigger props onto the single child element. |
|
|
308
|
+
|
|
309
|
+
Inherits all [`PressableProps`](https://reactnative.dev/docs/pressable#props).
|
|
310
|
+
|
|
311
|
+
### Tooltip.Content
|
|
312
|
+
|
|
313
|
+
Tooltip body rendered in a portal. Plain string and number children are wrapped in styled text.
|
|
314
|
+
|
|
315
|
+
| Prop | Type | Default | Description |
|
|
316
|
+
| --- | --- | --- | --- |
|
|
317
|
+
| `className?` | `string` | — | — |
|
|
318
|
+
| `children?` | `ReactNode` | — | — |
|
|
319
|
+
| `asChild?` | `boolean` | — | — |
|
|
320
|
+
|
|
321
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
322
|
+
|
|
323
|
+
### Tooltip.Arrow
|
|
324
|
+
|
|
325
|
+
Optional directional arrow that points toward the trigger. Compose inside `Tooltip.Content`; positioning follows the resolved placement.
|
|
326
|
+
|
|
327
|
+
| Prop | Type | Default | Description |
|
|
328
|
+
| --- | --- | --- | --- |
|
|
329
|
+
| `className?` | `string` | — | — |
|
|
330
|
+
| `children?` | `ReactNode` | — | — |
|
|
331
|
+
| `asChild?` | `boolean` | — | Optional directional arrow that points toward the trigger. Compose inside `Tooltip.Content`. |
|
|
332
|
+
|
|
333
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
334
|
+
|
|
335
|
+
| Attribute | Values | Description |
|
|
336
|
+
| ----------- | -------------------------------------- | ----------------------- |
|
|
337
|
+
| `data-slot` | `tooltip-arrow` | Arrow element |
|
|
338
|
+
| `data-side` | `top` \| `bottom` \| `left` \| `right` | Resolved placement side |
|
|
339
|
+
|
|
340
|
+
## Anatomy
|
|
341
|
+
|
|
342
|
+
| `data-slot` | Element |
|
|
343
|
+
| ----------------- | ---------------------- |
|
|
344
|
+
| `tooltip-trigger` | Trigger wrapper |
|
|
345
|
+
| `tooltip-content` | Portal content surface |
|
|
346
|
+
| `tooltip-arrow` | Directional arrow |
|
|
347
|
+
|
|
348
|
+
## Accessibility
|
|
349
|
+
|
|
350
|
+
On web, tooltip content uses `role="tooltip"` and the trigger is linked via `aria-describedby`. On native, content uses `accessibilityLiveRegion="polite"`. Tooltip content is decorative on native and does not trap focus.
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Virtualized List (https://design.candescent.com/docs/components/virtualized-list)
|
|
2
|
+
|
|
3
|
+
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)
|
|
4
|
+
|
|
5
|
+
A thin wrapper around [`@shopify/flash-list`](https://shopify.github.io/flash-list/) that sets `role="list"` for accessibility. Use it when a list is long enough that mounting every row would hurt scroll performance.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { VirtualizedList } from '@cdx-ui/components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic
|
|
12
|
+
|
|
13
|
+
Pass `data` and `renderItem`. Give the list a bounded height (or nest it in a flex parent that has one) so it can scroll. Use `ItemSeparatorComponent` for dividers between rows.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Avatar, Box, Card, Divider, Text, VirtualizedList } from '@cdx-ui/components';
|
|
17
|
+
import { CONTACTS } from './_data';
|
|
18
|
+
|
|
19
|
+
export default function VirtualizedListBasicDemo() {
|
|
20
|
+
return (
|
|
21
|
+
<Box className="h-96 w-full max-w-md">
|
|
22
|
+
<Card fullBleed className="flex-1">
|
|
23
|
+
<Card.Content className="flex-1">
|
|
24
|
+
<VirtualizedList
|
|
25
|
+
data={CONTACTS}
|
|
26
|
+
keyExtractor={(item) => item.id}
|
|
27
|
+
ItemSeparatorComponent={() => <Divider />}
|
|
28
|
+
renderItem={({ item }) => (
|
|
29
|
+
<Box className="flex-row items-center gap-3 px-4 py-3">
|
|
30
|
+
<Avatar size="md">
|
|
31
|
+
<Avatar.Text>{item.name.slice(0, 2)}</Avatar.Text>
|
|
32
|
+
</Avatar>
|
|
33
|
+
<Box className="flex-1 gap-0.5">
|
|
34
|
+
<Text weight="semibold">{item.name}</Text>
|
|
35
|
+
<Text color="secondary" size="sm">
|
|
36
|
+
{item.role}
|
|
37
|
+
</Text>
|
|
38
|
+
</Box>
|
|
39
|
+
</Box>
|
|
40
|
+
)}
|
|
41
|
+
/>
|
|
42
|
+
</Card.Content>
|
|
43
|
+
</Card>
|
|
44
|
+
</Box>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Empty state
|
|
50
|
+
|
|
51
|
+
Set `ListEmptyComponent` to show placeholder content when `data` is empty.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { Box, Card, Heading, Text, VirtualizedList } from '@cdx-ui/components';
|
|
55
|
+
import type { Contact } from './_data';
|
|
56
|
+
|
|
57
|
+
export default function VirtualizedListEmptyDemo() {
|
|
58
|
+
return (
|
|
59
|
+
<Box className="h-72 w-full max-w-md">
|
|
60
|
+
<Card fullBleed className="flex-1">
|
|
61
|
+
<Card.Content className="flex-1">
|
|
62
|
+
<VirtualizedList
|
|
63
|
+
data={[] as Contact[]}
|
|
64
|
+
keyExtractor={(item) => item.id}
|
|
65
|
+
renderItem={({ item }) => <Text>{item.name}</Text>}
|
|
66
|
+
ListEmptyComponent={
|
|
67
|
+
<Box className="items-center justify-center gap-2 px-4 py-12">
|
|
68
|
+
<Heading size="md">No contacts found</Heading>
|
|
69
|
+
<Text color="secondary" size="sm" className="text-center">
|
|
70
|
+
Try adjusting your search or filters to find what you{"'"}re looking for.
|
|
71
|
+
</Text>
|
|
72
|
+
</Box>
|
|
73
|
+
}
|
|
74
|
+
/>
|
|
75
|
+
</Card.Content>
|
|
76
|
+
</Card>
|
|
77
|
+
</Box>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Header and footer
|
|
83
|
+
|
|
84
|
+
`ListHeaderComponent` and `ListFooterComponent` render above and below the scrollable items.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { Avatar, Box, Card, Divider, Text, VirtualizedList } from '@cdx-ui/components';
|
|
88
|
+
import { CONTACTS } from './_data';
|
|
89
|
+
|
|
90
|
+
export default function VirtualizedListHeaderFooterDemo() {
|
|
91
|
+
return (
|
|
92
|
+
<Box className="h-96 w-full max-w-md">
|
|
93
|
+
<Card fullBleed className="flex-1">
|
|
94
|
+
<Card.Content className="flex-1">
|
|
95
|
+
<VirtualizedList
|
|
96
|
+
data={CONTACTS}
|
|
97
|
+
keyExtractor={(item) => item.id}
|
|
98
|
+
ItemSeparatorComponent={() => <Divider />}
|
|
99
|
+
ListHeaderComponent={
|
|
100
|
+
<Box className="gap-0.5 border-b border-stroke-secondary bg-surface-secondary px-4 py-3">
|
|
101
|
+
<Text weight="semibold">My Team</Text>
|
|
102
|
+
<Text color="secondary" size="sm">
|
|
103
|
+
{CONTACTS.length} members
|
|
104
|
+
</Text>
|
|
105
|
+
</Box>
|
|
106
|
+
}
|
|
107
|
+
ListFooterComponent={
|
|
108
|
+
<Box className="items-center border-t border-stroke-secondary bg-surface-secondary px-4 py-3">
|
|
109
|
+
<Text color="secondary" size="sm">
|
|
110
|
+
Showing all {CONTACTS.length} members
|
|
111
|
+
</Text>
|
|
112
|
+
</Box>
|
|
113
|
+
}
|
|
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>
|
|
126
|
+
)}
|
|
127
|
+
/>
|
|
128
|
+
</Card.Content>
|
|
129
|
+
</Card>
|
|
130
|
+
</Box>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## With ListItem
|
|
136
|
+
|
|
137
|
+
Compose with [`ListItem`](https://design.candescent.com/docs/components/list-item/content.md) inside a `fullBleed` [`Card`](https://design.candescent.com/docs/components/card/content.md) for account, transaction, and settings rows. Only visible rows mount at a time.
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import { Avatar, Box, Card, ListItem, Text, VirtualizedList } from '@cdx-ui/components';
|
|
141
|
+
|
|
142
|
+
const TITLES = ['Coffee Shop', 'Grocery Store', 'Gas Station', 'Online Transfer', 'Restaurant'];
|
|
143
|
+
const DESCRIPTIONS = ['Visa · *4321', 'Debit · *6643', 'Visa · *8821', 'Internal', 'Visa · *4321'];
|
|
144
|
+
const AMOUNTS = ['$12.45', '$84.20', '$41.75', '$250.00', '$36.18'];
|
|
145
|
+
|
|
146
|
+
const transactions = Array.from({ length: 50 }, (_, i) => ({
|
|
147
|
+
id: String(i),
|
|
148
|
+
title: TITLES[i % TITLES.length],
|
|
149
|
+
description: DESCRIPTIONS[i % DESCRIPTIONS.length],
|
|
150
|
+
amount: AMOUNTS[i % AMOUNTS.length],
|
|
151
|
+
date: `May ${String((i % 28) + 1)}`,
|
|
152
|
+
}));
|
|
153
|
+
|
|
154
|
+
export default function VirtualizedListWithListItemDemo() {
|
|
155
|
+
return (
|
|
156
|
+
<Box className="h-96 w-full max-w-md">
|
|
157
|
+
<Card fullBleed className="flex-1">
|
|
158
|
+
<Card.Content className="flex-1">
|
|
159
|
+
<ListItem.SectionHeader>Recent Transactions</ListItem.SectionHeader>
|
|
160
|
+
<VirtualizedList
|
|
161
|
+
data={transactions}
|
|
162
|
+
keyExtractor={(item) => item.id}
|
|
163
|
+
renderItem={({ item, index }) => (
|
|
164
|
+
<ListItem onPress={() => undefined} showSeparator={index < transactions.length - 1}>
|
|
165
|
+
<ListItem.LeadingSlot>
|
|
166
|
+
<Avatar size="md">
|
|
167
|
+
<Avatar.Text>{item.title.slice(0, 2).toUpperCase()}</Avatar.Text>
|
|
168
|
+
</Avatar>
|
|
169
|
+
</ListItem.LeadingSlot>
|
|
170
|
+
<ListItem.Content>
|
|
171
|
+
<ListItem.Title>{item.title}</ListItem.Title>
|
|
172
|
+
<ListItem.Description>{item.description}</ListItem.Description>
|
|
173
|
+
<ListItem.Meta>{item.date}</ListItem.Meta>
|
|
174
|
+
</ListItem.Content>
|
|
175
|
+
<ListItem.TrailingSlot>
|
|
176
|
+
<Text>{item.amount}</Text>
|
|
177
|
+
</ListItem.TrailingSlot>
|
|
178
|
+
</ListItem>
|
|
179
|
+
)}
|
|
180
|
+
/>
|
|
181
|
+
</Card.Content>
|
|
182
|
+
</Card>
|
|
183
|
+
</Box>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## API
|
|
189
|
+
|
|
190
|
+
### VirtualizedList
|
|
191
|
+
|
|
192
|
+
Accepts all [`FlashListProps<T>`](https://shopify.github.io/flash-list/docs/usage) from `@shopify/flash-list`. Key props:
|
|
193
|
+
|
|
194
|
+
| Prop | Type | Description |
|
|
195
|
+
| ------------------------ | ------------------------------- | ------------------------------------------------------------ |
|
|
196
|
+
| `data` | `T[]` | Array of items to render |
|
|
197
|
+
| `renderItem` | `ListRenderItem<T>` | Render function for each item |
|
|
198
|
+
| `keyExtractor` | `(item, index) => string` | Unique key for each item |
|
|
199
|
+
| `horizontal` | `boolean` | Horizontal scroll direction |
|
|
200
|
+
| `numColumns` | `number` | Multi-column grid layout |
|
|
201
|
+
| `ItemSeparatorComponent` | `ReactElement \| ComponentType` | Separator between items |
|
|
202
|
+
| `ListHeaderComponent` | `ReactElement \| ComponentType` | Header above the list |
|
|
203
|
+
| `ListFooterComponent` | `ReactElement \| ComponentType` | Footer below the list |
|
|
204
|
+
| `ListEmptyComponent` | `ReactElement \| ComponentType` | Shown when `data` is empty |
|
|
205
|
+
| `onEndReached` | `() => void` | Called when the end of the list is approached |
|
|
206
|
+
| `onEndReachedThreshold` | `number` | How far from the end to trigger `onEndReached` |
|
|
207
|
+
| `extraData` | `unknown` | Extra value that triggers re-render of items when it changes |
|
|
208
|
+
|
|
209
|
+
For the full FlashList API (e.g. `getItemType`, `overrideItemLayout`, `drawDistance`), see the [FlashList documentation](https://shopify.github.io/flash-list/docs/usage).
|
|
210
|
+
|
|
211
|
+
## Ref
|
|
212
|
+
|
|
213
|
+
Access the underlying list for imperative methods via `VirtualizedListRef`:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import { useRef } from 'react';
|
|
217
|
+
import { VirtualizedList, type VirtualizedListRef } from '@cdx-ui/components';
|
|
218
|
+
|
|
219
|
+
const listRef = useRef<VirtualizedListRef>(null);
|
|
220
|
+
|
|
221
|
+
<VirtualizedList ref={listRef} data={items} renderItem={renderItem} />;
|
|
222
|
+
|
|
223
|
+
listRef.current?.scrollToIndex({ index: 10, animated: true });
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Types
|
|
227
|
+
|
|
228
|
+
Common FlashList types are re-exported from `@cdx-ui/components` so consumers do not need to depend on `@shopify/flash-list` directly:
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
import type {
|
|
232
|
+
VirtualizedListProps,
|
|
233
|
+
VirtualizedListRef,
|
|
234
|
+
ListRenderItem,
|
|
235
|
+
ListRenderItemInfo,
|
|
236
|
+
ViewToken,
|
|
237
|
+
} from '@cdx-ui/components';
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
| Type | Description |
|
|
241
|
+
| ------------------------- | ---------------------------------------------------------------------- |
|
|
242
|
+
| `VirtualizedListProps<T>` | Props accepted by `VirtualizedList` (alias for `FlashListProps<T>`) |
|
|
243
|
+
| `VirtualizedListRef` | Ref type for imperative methods |
|
|
244
|
+
| `ListRenderItem<T>` | Type for the `renderItem` callback |
|
|
245
|
+
| `ListRenderItemInfo<T>` | Object passed to `renderItem` — `item`, `index`, `target`, `extraData` |
|
|
246
|
+
| `ViewToken` | Item visibility info for `onViewableItemsChanged` |
|
|
247
|
+
|
|
248
|
+
## Accessibility
|
|
249
|
+
|
|
250
|
+
`VirtualizedList` sets `role="list"` on the root. Add `role="listitem"` on row roots (or use components that provide it) when the list should be announced as a list to assistive technology.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Foundations (https://design.candescent.com/docs/foundations)
|
|
2
|
+
|
|
3
|
+
## Styles
|
|
4
|
+
|
|
5
|
+
- [Tokens](https://design.candescent.com/docs/foundations/styles/tokens/what-are-tokens/content.md) — Named design decisions for color, type, spacing, and more that keep every brand consistent.
|
|
6
|
+
|
|
7
|
+
## Expressions
|
|
8
|
+
|
|
9
|
+
- [Icons](https://design.candescent.com/docs/foundations/expressions/icons/content.md) — Browse all available icons in the Forge UI icon library. Search, filter, and copy import statements.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Icons (https://design.candescent.com/docs/foundations/expressions/icons)
|
|
2
|
+
|
|
3
|
+
Cross-platform icon library for Forge UI, built on [Material Symbols](https://fonts.google.com/icons) (outlined style, weight 400, optical size 24). Renders via `react-native-svg` and targets iOS, Android, and Web.
|
|
4
|
+
|
|
5
|
+
3,983 icons are available, each with outlined and filled variants, plus support for custom
|
|
6
|
+
SVGs.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pnpm add @cdx-ui/icons
|
|
10
|
+
# or: npm install @cdx-ui/icons
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Search icons
|
|
14
|
+
|
|
15
|
+
The browser on the site searches icons by name. To find an icon without it:
|
|
16
|
+
|
|
17
|
+
- An export name is the Material Symbols name in PascalCase: `arrow_forward` is `ArrowForward`. A name that starts with a digit gets a leading underscore: `10k` is `_10k`. Look names up at [Material Symbols](https://fonts.google.com/icons).
|
|
18
|
+
- Every icon is also exported with an `Icon` suffix (`ArrowForwardIcon`) and a `Cdx` prefix (`CdxArrowForward`). Pass `filled` for the filled variant where one exists.
|
|
19
|
+
- To confirm a name exists, search `lib/typescript/icons/index.d.ts` in the installed `@cdx-ui/icons` package, or the "Icon names" section of [llms-full.txt](https://design.candescent.com/llms-full.txt), which lists every export, custom icons included.
|