@chassis-ui/react 0.0.0-20260831090525

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 (275) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/dist/index.d.ts +5909 -0
  4. package/dist/index.js +2 -0
  5. package/dist/style.css +1 -0
  6. package/package.json +114 -0
  7. package/src/components/accordion/Accordion.tsx +190 -0
  8. package/src/components/accordion/AccordionBody.tsx +46 -0
  9. package/src/components/accordion/AccordionHeader.tsx +21 -0
  10. package/src/components/accordion/AccordionItem.tsx +59 -0
  11. package/src/components/accordion/context.ts +8 -0
  12. package/src/components/accordion/index.ts +8 -0
  13. package/src/components/autocomplete/Autocomplete.tsx +464 -0
  14. package/src/components/autocomplete/AutocompleteGroup.tsx +20 -0
  15. package/src/components/autocomplete/AutocompleteItem.tsx +18 -0
  16. package/src/components/autocomplete/index.ts +6 -0
  17. package/src/components/avatar/Avatar.tsx +134 -0
  18. package/src/components/avatar/AvatarImage.tsx +19 -0
  19. package/src/components/avatar/AvatarStack.tsx +98 -0
  20. package/src/components/avatar/index.ts +6 -0
  21. package/src/components/badge/Badge.tsx +94 -0
  22. package/src/components/badge/index.ts +2 -0
  23. package/src/components/breadcrumb/Breadcrumb.tsx +59 -0
  24. package/src/components/breadcrumb/BreadcrumbItem.tsx +38 -0
  25. package/src/components/breadcrumb/index.ts +4 -0
  26. package/src/components/button/Button.tsx +229 -0
  27. package/src/components/button/index.ts +2 -0
  28. package/src/components/button-group/ButtonGroup.tsx +55 -0
  29. package/src/components/button-group/ButtonToolbar.tsx +47 -0
  30. package/src/components/button-group/index.ts +4 -0
  31. package/src/components/calendar/Calendar.scss +57 -0
  32. package/src/components/calendar/Calendar.tsx +324 -0
  33. package/src/components/calendar/CalendarMonthBlock.tsx +57 -0
  34. package/src/components/calendar/CalendarMonthGrid.tsx +92 -0
  35. package/src/components/calendar/CalendarMonthYearPicker.tsx +162 -0
  36. package/src/components/calendar/CalendarNavButton.tsx +24 -0
  37. package/src/components/calendar/CalendarWeekGrid.tsx +58 -0
  38. package/src/components/calendar/CalendarYearGrid.tsx +126 -0
  39. package/src/components/calendar/RangeCalendar.scss +95 -0
  40. package/src/components/calendar/RangeCalendar.tsx +361 -0
  41. package/src/components/calendar/index.ts +5 -0
  42. package/src/components/card/Card.tsx +173 -0
  43. package/src/components/card/CardBody.tsx +75 -0
  44. package/src/components/card/CardFooter.tsx +47 -0
  45. package/src/components/card/CardGroup.tsx +51 -0
  46. package/src/components/card/CardHeader.tsx +47 -0
  47. package/src/components/card/CardImage.tsx +70 -0
  48. package/src/components/card/CardImageOverlay.tsx +47 -0
  49. package/src/components/card/CardLink.tsx +40 -0
  50. package/src/components/card/CardSubtitle.tsx +47 -0
  51. package/src/components/card/CardText.tsx +47 -0
  52. package/src/components/card/CardTitle.tsx +47 -0
  53. package/src/components/card/index.ts +22 -0
  54. package/src/components/carousel/Carousel.tsx +742 -0
  55. package/src/components/carousel/CarouselControlButton.tsx +74 -0
  56. package/src/components/carousel/CarouselControlNext.tsx +22 -0
  57. package/src/components/carousel/CarouselControlPrev.tsx +22 -0
  58. package/src/components/carousel/CarouselIndicators.tsx +44 -0
  59. package/src/components/carousel/CarouselInner.tsx +56 -0
  60. package/src/components/carousel/CarouselItem.tsx +51 -0
  61. package/src/components/carousel/CarouselOverlay.tsx +51 -0
  62. package/src/components/carousel/CarouselPlayPause.tsx +61 -0
  63. package/src/components/carousel/carouselEngine.ts +170 -0
  64. package/src/components/carousel/context.ts +29 -0
  65. package/src/components/carousel/index.ts +21 -0
  66. package/src/components/checkbox/Checkbox.tsx +236 -0
  67. package/src/components/checkbox/CheckboxGroup.tsx +145 -0
  68. package/src/components/checkbox/context.ts +14 -0
  69. package/src/components/checkbox/index.ts +4 -0
  70. package/src/components/chip/Chip.tsx +183 -0
  71. package/src/components/chip/index.ts +2 -0
  72. package/src/components/chip-input/ChipInput.tsx +363 -0
  73. package/src/components/chip-input/ChipList.tsx +95 -0
  74. package/src/components/chip-input/index.ts +2 -0
  75. package/src/components/close-button/CloseButton.tsx +205 -0
  76. package/src/components/close-button/index.ts +2 -0
  77. package/src/components/collapse/Collapse.tsx +128 -0
  78. package/src/components/collapse/index.ts +2 -0
  79. package/src/components/color-input/ColorInput.tsx +106 -0
  80. package/src/components/color-input/index.ts +2 -0
  81. package/src/components/combobox/Combobox.tsx +320 -0
  82. package/src/components/combobox/ComboboxGroup.tsx +27 -0
  83. package/src/components/combobox/ComboboxItem.tsx +44 -0
  84. package/src/components/combobox/ComboboxListBox.tsx +98 -0
  85. package/src/components/combobox/index.ts +6 -0
  86. package/src/components/datepicker/CalendarToggleButton.tsx +58 -0
  87. package/src/components/datepicker/ClearButton.tsx +35 -0
  88. package/src/components/datepicker/DateField.tsx +54 -0
  89. package/src/components/datepicker/DatePicker.scss +51 -0
  90. package/src/components/datepicker/DatePicker.tsx +574 -0
  91. package/src/components/datepicker/DateRangePicker.scss +11 -0
  92. package/src/components/datepicker/DateRangePicker.tsx +343 -0
  93. package/src/components/datepicker/index.ts +4 -0
  94. package/src/components/datepicker/renderDatePickerShell.tsx +104 -0
  95. package/src/components/drawer/Drawer.tsx +211 -0
  96. package/src/components/drawer/DrawerBody.tsx +47 -0
  97. package/src/components/drawer/DrawerFooter.tsx +51 -0
  98. package/src/components/drawer/DrawerHeader.tsx +60 -0
  99. package/src/components/drawer/DrawerTitle.tsx +49 -0
  100. package/src/components/drawer/index.ts +10 -0
  101. package/src/components/file-input/FileInput.tsx +100 -0
  102. package/src/components/file-input/index.ts +2 -0
  103. package/src/components/flex/Flex.tsx +134 -0
  104. package/src/components/flex/index.ts +2 -0
  105. package/src/components/floating-input/FloatingInput.tsx +94 -0
  106. package/src/components/floating-input/index.ts +2 -0
  107. package/src/components/form/Form.tsx +26 -0
  108. package/src/components/form/FormFeedback.tsx +64 -0
  109. package/src/components/form/FormHelp.tsx +46 -0
  110. package/src/components/form/FormLabel.tsx +26 -0
  111. package/src/components/form/index.ts +8 -0
  112. package/src/components/form/renderFormCheck.tsx +86 -0
  113. package/src/components/form-field/FormField.tsx +84 -0
  114. package/src/components/form-field/index.ts +2 -0
  115. package/src/components/form-field/renderFormField.tsx +74 -0
  116. package/src/components/grid/Col.tsx +69 -0
  117. package/src/components/grid/Container.tsx +59 -0
  118. package/src/components/grid/Grid.tsx +86 -0
  119. package/src/components/grid/GridItem.tsx +123 -0
  120. package/src/components/grid/Row.tsx +71 -0
  121. package/src/components/grid/gap.ts +8 -0
  122. package/src/components/grid/index.ts +10 -0
  123. package/src/components/icon/Icon.tsx +74 -0
  124. package/src/components/icon/index.ts +2 -0
  125. package/src/components/input-adorn/InputAdorn.tsx +55 -0
  126. package/src/components/input-adorn/index.ts +2 -0
  127. package/src/components/input-group/InputGroup.tsx +50 -0
  128. package/src/components/input-group/InputGroupAddon.tsx +50 -0
  129. package/src/components/input-group/index.ts +4 -0
  130. package/src/components/link/Link.tsx +148 -0
  131. package/src/components/link/index.ts +2 -0
  132. package/src/components/list/List.tsx +193 -0
  133. package/src/components/list/ListItem.tsx +91 -0
  134. package/src/components/list/index.ts +4 -0
  135. package/src/components/menu/Menu.tsx +398 -0
  136. package/src/components/menu/MenuDivider.tsx +19 -0
  137. package/src/components/menu/MenuHeader.tsx +55 -0
  138. package/src/components/menu/MenuItem.tsx +85 -0
  139. package/src/components/menu/MenuItemDef.ts +83 -0
  140. package/src/components/menu/MenuList.tsx +142 -0
  141. package/src/components/menu/MenuSubmenu.tsx +284 -0
  142. package/src/components/menu/MenuSubmenuBack.tsx +39 -0
  143. package/src/components/menu/MenuText.tsx +47 -0
  144. package/src/components/menu/MenuToggle.tsx +148 -0
  145. package/src/components/menu/index.ts +19 -0
  146. package/src/components/menu/menuNavigation.ts +106 -0
  147. package/src/components/menu/submenuGroup.ts +43 -0
  148. package/src/components/modal/Modal.tsx +162 -0
  149. package/src/components/modal/ModalBody.tsx +47 -0
  150. package/src/components/modal/ModalFooter.tsx +51 -0
  151. package/src/components/modal/ModalHeader.tsx +60 -0
  152. package/src/components/modal/ModalTitle.tsx +49 -0
  153. package/src/components/modal/index.ts +10 -0
  154. package/src/components/nav/Nav.tsx +97 -0
  155. package/src/components/nav/NavItem.tsx +42 -0
  156. package/src/components/nav/NavLink.tsx +48 -0
  157. package/src/components/nav/NavTitle.tsx +22 -0
  158. package/src/components/nav/index.ts +7 -0
  159. package/src/components/navbar/Navbar.tsx +112 -0
  160. package/src/components/navbar/NavbarBrand.tsx +55 -0
  161. package/src/components/navbar/NavbarNav.tsx +47 -0
  162. package/src/components/navbar/NavbarText.tsx +47 -0
  163. package/src/components/navbar/NavbarToggler.tsx +34 -0
  164. package/src/components/navbar/index.ts +10 -0
  165. package/src/components/notification/Notification.scss +15 -0
  166. package/src/components/notification/Notification.tsx +187 -0
  167. package/src/components/notification/NotificationIcon.tsx +21 -0
  168. package/src/components/notification/NotificationStack.tsx +66 -0
  169. package/src/components/notification/NotificationText.tsx +47 -0
  170. package/src/components/notification/NotificationTitle.tsx +47 -0
  171. package/src/components/notification/context.ts +14 -0
  172. package/src/components/notification/index.ts +17 -0
  173. package/src/components/notification/notificationQueue.ts +48 -0
  174. package/src/components/otp-input/OtpBox.tsx +68 -0
  175. package/src/components/otp-input/OtpInput.tsx +341 -0
  176. package/src/components/otp-input/index.ts +2 -0
  177. package/src/components/pagination/Pagination.tsx +199 -0
  178. package/src/components/pagination/PaginationItem.tsx +133 -0
  179. package/src/components/pagination/index.ts +4 -0
  180. package/src/components/password-strength/PasswordStrength.tsx +155 -0
  181. package/src/components/password-strength/index.ts +2 -0
  182. package/src/components/password-strength/strengthScore.ts +79 -0
  183. package/src/components/placeholder/Placeholder.tsx +178 -0
  184. package/src/components/placeholder/index.ts +2 -0
  185. package/src/components/popover/Popover.tsx +243 -0
  186. package/src/components/popover/index.ts +2 -0
  187. package/src/components/progress/Progress.tsx +154 -0
  188. package/src/components/progress/ProgressBar.tsx +88 -0
  189. package/src/components/progress/index.ts +4 -0
  190. package/src/components/radio/Radio.tsx +88 -0
  191. package/src/components/radio/RadioGroup.tsx +142 -0
  192. package/src/components/radio/context.ts +14 -0
  193. package/src/components/radio/index.ts +4 -0
  194. package/src/components/range-input/RangeInput.tsx +109 -0
  195. package/src/components/range-input/index.ts +2 -0
  196. package/src/components/select/Select.tsx +277 -0
  197. package/src/components/select/index.ts +2 -0
  198. package/src/components/skeleton/Skeleton.tsx +89 -0
  199. package/src/components/skeleton/SkeletonLoader.tsx +91 -0
  200. package/src/components/skeleton/index.ts +4 -0
  201. package/src/components/spinner/Spinner.tsx +77 -0
  202. package/src/components/spinner/index.ts +2 -0
  203. package/src/components/stack/Stack.tsx +81 -0
  204. package/src/components/stack/index.ts +2 -0
  205. package/src/components/stepper/Stepper.tsx +172 -0
  206. package/src/components/stepper/StepperItem.tsx +66 -0
  207. package/src/components/stepper/index.ts +4 -0
  208. package/src/components/switch/Switch.tsx +246 -0
  209. package/src/components/switch/index.ts +2 -0
  210. package/src/components/table/Table.css +39 -0
  211. package/src/components/table/Table.tsx +390 -0
  212. package/src/components/table/TableBody.tsx +25 -0
  213. package/src/components/table/TableCell.tsx +27 -0
  214. package/src/components/table/TableColumn.tsx +31 -0
  215. package/src/components/table/TableHeader.tsx +26 -0
  216. package/src/components/table/TableRow.tsx +24 -0
  217. package/src/components/table/index.ts +12 -0
  218. package/src/components/tabs/Tab.tsx +36 -0
  219. package/src/components/tabs/TabList.tsx +76 -0
  220. package/src/components/tabs/TabPanel.tsx +68 -0
  221. package/src/components/tabs/Tabs.tsx +136 -0
  222. package/src/components/tabs/context.ts +24 -0
  223. package/src/components/tabs/index.ts +8 -0
  224. package/src/components/text-input/TextInput.tsx +188 -0
  225. package/src/components/text-input/index.ts +2 -0
  226. package/src/components/textarea/Textarea.tsx +145 -0
  227. package/src/components/textarea/index.ts +2 -0
  228. package/src/components/toast/Toast.tsx +219 -0
  229. package/src/components/toast/ToastBody.tsx +64 -0
  230. package/src/components/toast/ToastFooter.tsx +47 -0
  231. package/src/components/toast/ToastHeader.tsx +104 -0
  232. package/src/components/toast/ToastIcon.tsx +21 -0
  233. package/src/components/toast/Toaster.tsx +87 -0
  234. package/src/components/toast/context.ts +14 -0
  235. package/src/components/toast/index.ts +18 -0
  236. package/src/components/toast/toastQueue.ts +56 -0
  237. package/src/components/tooltip/Tooltip.tsx +155 -0
  238. package/src/components/tooltip/index.ts +2 -0
  239. package/src/global.d.ts +2 -0
  240. package/src/hooks/index.ts +57 -0
  241. package/src/hooks/useAutoDismiss.ts +88 -0
  242. package/src/hooks/useButtonSemantics.ts +33 -0
  243. package/src/hooks/useControllableState.ts +24 -0
  244. package/src/hooks/useDialogElement.ts +216 -0
  245. package/src/hooks/useDisabledAnchorGuard.ts +22 -0
  246. package/src/hooks/useDismissibleTransition.ts +126 -0
  247. package/src/hooks/useDrawer.ts +9 -0
  248. package/src/hooks/useFloatingOverlay.ts +115 -0
  249. package/src/hooks/useForkedRef.ts +50 -0
  250. package/src/hooks/useFormField.ts +89 -0
  251. package/src/hooks/useIsomorphicLayoutEffect.ts +9 -0
  252. package/src/hooks/useModal.ts +9 -0
  253. package/src/hooks/useNotification.ts +10 -0
  254. package/src/hooks/useOverlayPlacement.ts +93 -0
  255. package/src/hooks/usePagination.ts +85 -0
  256. package/src/hooks/useToast.ts +9 -0
  257. package/src/hooks/useToastRegionQueue.ts +27 -0
  258. package/src/index.ts +276 -0
  259. package/src/types.ts +133 -0
  260. package/src/utils/breakpoints.ts +43 -0
  261. package/src/utils/comboboxCollection.tsx +152 -0
  262. package/src/utils/dateRangePresets.ts +6 -0
  263. package/src/utils/dialogTransition.ts +39 -0
  264. package/src/utils/focusRedirect.ts +29 -0
  265. package/src/utils/isWholeUnitDisabled.ts +17 -0
  266. package/src/utils/mergeIsDateUnavailable.ts +15 -0
  267. package/src/utils/overlayPlacement.ts +93 -0
  268. package/src/utils/pointerInteraction.ts +21 -0
  269. package/src/utils/polymorphic.ts +36 -0
  270. package/src/utils/renderMenuItemContent.tsx +62 -0
  271. package/src/utils/setVisibleRangeStart.ts +64 -0
  272. package/src/utils/spacingClassName.ts +14 -0
  273. package/src/utils/suppressFocusRingGlobally.ts +69 -0
  274. package/src/utils/validationClassName.ts +8 -0
  275. package/src/utils/virtualFocusStyle.ts +16 -0
package/src/index.ts ADDED
@@ -0,0 +1,276 @@
1
+ 'use client'
2
+
3
+ // Side-effect only: installs the single document-level pointerdown listener that works around the
4
+ // browser's `:focus-visible` first-click heuristic misfire — see the module's own comment. Needs to
5
+ // run once wherever this package is used, not per-component, so it's imported here rather than
6
+ // from any individual component.
7
+ import './utils/suppressFocusRingGlobally'
8
+
9
+ import { Accordion, AccordionBody, AccordionHeader, AccordionItem } from './components/accordion'
10
+ import { Autocomplete, AutocompleteGroup, AutocompleteItem } from './components/autocomplete'
11
+ import { Avatar, AvatarImage, AvatarStack } from './components/avatar'
12
+ import {
13
+ Notification,
14
+ NotificationTitle,
15
+ NotificationIcon,
16
+ NotificationText,
17
+ NotificationStack,
18
+ addNotification,
19
+ closeNotification,
20
+ notificationQueue
21
+ } from './components/notification'
22
+ import { Badge } from './components/badge'
23
+ import { Breadcrumb, BreadcrumbItem } from './components/breadcrumb'
24
+ import { Button } from './components/button'
25
+ import { ButtonGroup, ButtonToolbar } from './components/button-group'
26
+ import { Calendar, RangeCalendar } from './components/calendar'
27
+ import {
28
+ Card,
29
+ CardBody,
30
+ CardFooter,
31
+ CardGroup,
32
+ CardHeader,
33
+ CardImage,
34
+ CardImageOverlay,
35
+ CardLink,
36
+ CardSubtitle,
37
+ CardText,
38
+ CardTitle
39
+ } from './components/card'
40
+ import {
41
+ Carousel,
42
+ CarouselControlNext,
43
+ CarouselControlPrev,
44
+ CarouselIndicators,
45
+ CarouselInner,
46
+ CarouselItem,
47
+ CarouselOverlay,
48
+ CarouselPlayPause
49
+ } from './components/carousel'
50
+ import { Collapse } from './components/collapse'
51
+ import { ChipInput } from './components/chip-input'
52
+ import { CloseButton } from './components/close-button'
53
+ import { ColorInput } from './components/color-input'
54
+ import { FileInput } from './components/file-input'
55
+ import { Combobox, ComboboxGroup, ComboboxItem } from './components/combobox'
56
+ import { DatePicker, DateRangePicker } from './components/datepicker'
57
+ import { OtpInput } from './components/otp-input'
58
+ import { PasswordStrength } from './components/password-strength'
59
+ import { I18nProvider } from 'react-aria'
60
+ import {
61
+ Menu,
62
+ MenuDivider,
63
+ MenuHeader,
64
+ MenuItem,
65
+ MenuList,
66
+ MenuText,
67
+ MenuToggle,
68
+ MenuSubmenu,
69
+ MenuSubmenuBack
70
+ } from './components/menu'
71
+ import { Col, Container, Grid, GridItem, Row } from './components/grid'
72
+ import { Checkbox, CheckboxGroup } from './components/checkbox'
73
+ import { Form, FormFeedback, FormHelp, FormLabel } from './components/form'
74
+ import { FloatingInput } from './components/floating-input'
75
+ import { FormField } from './components/form-field'
76
+ import { InputGroup, InputGroupAddon } from './components/input-group'
77
+ import { InputAdorn } from './components/input-adorn'
78
+ import { Radio, RadioGroup } from './components/radio'
79
+ import { RangeInput } from './components/range-input'
80
+ import { Select } from './components/select'
81
+ import { Switch } from './components/switch'
82
+ import { TextInput } from './components/text-input'
83
+ import { Textarea } from './components/textarea'
84
+ import { Icon } from './components/icon'
85
+ import { Placeholder } from './components/placeholder'
86
+ import { Link } from './components/link'
87
+ import { List, ListItem } from './components/list'
88
+ import { Modal, ModalBody, ModalFooter, ModalHeader, ModalTitle } from './components/modal'
89
+ import { Nav, NavItem, NavLink, NavTitle } from './components/nav'
90
+ import { Navbar, NavbarBrand, NavbarNav, NavbarText, NavbarToggler } from './components/navbar'
91
+ import { Pagination, PaginationItem } from './components/pagination'
92
+ import { Popover } from './components/popover'
93
+ import { Progress, ProgressBar } from './components/progress'
94
+ import { Drawer, DrawerBody, DrawerFooter, DrawerHeader, DrawerTitle } from './components/drawer'
95
+ import { Skeleton, SkeletonLoader } from './components/skeleton'
96
+ import { Spinner } from './components/spinner'
97
+ import { Stepper, StepperItem } from './components/stepper'
98
+ import { Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from './components/table'
99
+ import { Tabs, Tab, TabList, TabPanel } from './components/tabs'
100
+ import {
101
+ Toast,
102
+ ToastBody,
103
+ ToastFooter,
104
+ ToastHeader,
105
+ ToastIcon,
106
+ Toaster,
107
+ addToast,
108
+ closeToast,
109
+ toastQueue
110
+ } from './components/toast'
111
+ import { Tooltip } from './components/tooltip'
112
+ import { useDrawer, useModal, useNotification, usePagination, useToast } from './hooks'
113
+ import { Chip } from './components/chip'
114
+ import { Flex } from './components/flex'
115
+ import { Stack } from './components/stack'
116
+
117
+ export {
118
+ Chip,
119
+ Flex,
120
+ Stack,
121
+ Accordion,
122
+ AccordionBody,
123
+ AccordionHeader,
124
+ AccordionItem,
125
+ Autocomplete,
126
+ AutocompleteGroup,
127
+ AutocompleteItem,
128
+ Avatar,
129
+ AvatarImage,
130
+ AvatarStack,
131
+ Notification,
132
+ NotificationTitle,
133
+ NotificationIcon,
134
+ NotificationText,
135
+ NotificationStack,
136
+ addNotification,
137
+ closeNotification,
138
+ notificationQueue,
139
+ useNotification,
140
+ Badge,
141
+ Breadcrumb,
142
+ BreadcrumbItem,
143
+ Button,
144
+ ButtonGroup,
145
+ ButtonToolbar,
146
+ Calendar,
147
+ RangeCalendar,
148
+ Card,
149
+ CardBody,
150
+ CardFooter,
151
+ CardGroup,
152
+ CardHeader,
153
+ CardImage,
154
+ CardImageOverlay,
155
+ CardLink,
156
+ CardSubtitle,
157
+ CardText,
158
+ CardTitle,
159
+ Carousel,
160
+ CarouselControlNext,
161
+ CarouselControlPrev,
162
+ CarouselIndicators,
163
+ CarouselInner,
164
+ CarouselItem,
165
+ CarouselOverlay,
166
+ CarouselPlayPause,
167
+ ChipInput,
168
+ CloseButton,
169
+ Collapse,
170
+ ColorInput,
171
+ Combobox,
172
+ ComboboxGroup,
173
+ ComboboxItem,
174
+ DatePicker,
175
+ DateRangePicker,
176
+ FileInput,
177
+ // Re-exported (not a component from this package): react-aria is a bundled dependency, not a
178
+ // peer, so its module — including the `I18nProvider` context `DatePicker` reads locale from via
179
+ // `useLocale()` — is inlined into this package's own build output, distinct from any react-aria
180
+ // copy a consumer might separately install. A consumer's own `<I18nProvider>` would set a
181
+ // *different* context instance and silently have no effect on `DatePicker`; this re-export is
182
+ // the one that actually reaches it.
183
+ I18nProvider,
184
+ OtpInput,
185
+ PasswordStrength,
186
+ Menu,
187
+ MenuDivider,
188
+ MenuHeader,
189
+ MenuItem,
190
+ MenuList,
191
+ MenuText,
192
+ MenuToggle,
193
+ MenuSubmenu,
194
+ MenuSubmenuBack,
195
+ Col,
196
+ Container,
197
+ Grid,
198
+ GridItem,
199
+ Row,
200
+ Checkbox,
201
+ CheckboxGroup,
202
+ FloatingInput,
203
+ Form,
204
+ FormField,
205
+ FormFeedback,
206
+ FormHelp,
207
+ FormLabel,
208
+ Icon,
209
+ Placeholder,
210
+ InputGroup,
211
+ InputGroupAddon,
212
+ InputAdorn,
213
+ Link,
214
+ List,
215
+ ListItem,
216
+ Modal,
217
+ ModalBody,
218
+ ModalFooter,
219
+ ModalHeader,
220
+ ModalTitle,
221
+ useModal,
222
+ Nav,
223
+ NavItem,
224
+ NavLink,
225
+ NavTitle,
226
+ Navbar,
227
+ NavbarBrand,
228
+ NavbarNav,
229
+ NavbarText,
230
+ NavbarToggler,
231
+ Pagination,
232
+ PaginationItem,
233
+ usePagination,
234
+ Popover,
235
+ Progress,
236
+ ProgressBar,
237
+ Radio,
238
+ RadioGroup,
239
+ RangeInput,
240
+ Drawer,
241
+ DrawerBody,
242
+ DrawerFooter,
243
+ DrawerHeader,
244
+ DrawerTitle,
245
+ useDrawer,
246
+ Select,
247
+ Skeleton,
248
+ SkeletonLoader,
249
+ Spinner,
250
+ Stepper,
251
+ StepperItem,
252
+ Switch,
253
+ Table,
254
+ TableBody,
255
+ TableCell,
256
+ TableColumn,
257
+ TableHeader,
258
+ TableRow,
259
+ Tabs,
260
+ Tab,
261
+ TabList,
262
+ TabPanel,
263
+ TextInput,
264
+ Textarea,
265
+ Toast,
266
+ ToastBody,
267
+ ToastFooter,
268
+ ToastHeader,
269
+ ToastIcon,
270
+ Toaster,
271
+ addToast,
272
+ closeToast,
273
+ toastQueue,
274
+ useToast,
275
+ Tooltip
276
+ }
package/src/types.ts ADDED
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Breakpoints
3
+ */
4
+ export type Breakpoint = 'small' | 'medium' | 'large' | 'xlarge' | '2xlarge'
5
+
6
+ /**
7
+ * Context colors
8
+ */
9
+ export type ContextColor =
10
+ | 'default'
11
+ | 'alternate'
12
+ | 'primary'
13
+ | 'secondary'
14
+ | 'neutral'
15
+ | 'success'
16
+ | 'danger'
17
+ | 'warning'
18
+ | 'info'
19
+ | 'black'
20
+ | 'white'
21
+
22
+ /**
23
+ * Context styles
24
+ */
25
+ export type ContextStyle = 'basic' | 'solid' | 'outline' | 'smooth'
26
+
27
+ /**
28
+ * Component sizes
29
+ */
30
+ export type Sizing = 'small' | 'medium' | 'large'
31
+
32
+ /**
33
+ * Extended sizes
34
+ */
35
+ export type ExtendedSizing = '2xsmall' | 'xsmall' | Sizing | 'xlarge' | '2xlarge'
36
+
37
+ /**
38
+ * Spacing values. `SPACING` is the runtime source of truth — `Spacing` is derived from it so the
39
+ * two can't drift apart; anything needing the values at runtime (e.g. validating a string against
40
+ * the scale) should import `SPACING`, not hand-copy the list.
41
+ */
42
+ export const SPACING = [
43
+ 'zero',
44
+ '4xsmall',
45
+ '3xsmall',
46
+ '2xsmall',
47
+ 'xsmall',
48
+ 'small',
49
+ 'medium',
50
+ 'large',
51
+ 'xlarge',
52
+ '2xlarge',
53
+ '3xlarge',
54
+ '4xlarge',
55
+ '5xlarge',
56
+ '6xlarge'
57
+ ] as const
58
+
59
+ export type Spacing = (typeof SPACING)[number]
60
+
61
+ /**
62
+ * Font families
63
+ */
64
+ export type FontFamily = 'text' | 'display' | 'code' | 'html'
65
+
66
+ /**
67
+ * Font weights
68
+ */
69
+ export type FontWeight = 'elegant' | 'normal' | 'strong' | 'mass'
70
+
71
+ /**
72
+ * Font sizes
73
+ */
74
+ export type FontSize =
75
+ | '2xsmall'
76
+ | 'xsmall'
77
+ | 'small'
78
+ | 'medium'
79
+ | 'large'
80
+ | 'xlarge'
81
+ | '2xlarge'
82
+ | '3xlarge'
83
+ | '4xlarge'
84
+ | '5xlarge'
85
+
86
+ /**
87
+ * Component placements
88
+ */
89
+ export type Placements =
90
+ | 'auto'
91
+ | 'auto-start'
92
+ | 'auto-end'
93
+ | 'top-end'
94
+ | 'top'
95
+ | 'top-start'
96
+ | 'bottom-end'
97
+ | 'bottom'
98
+ | 'bottom-start'
99
+ | 'right-start'
100
+ | 'right'
101
+ | 'right-end'
102
+ | 'left-start'
103
+ | 'left'
104
+ | 'left-end'
105
+
106
+ /**
107
+ * Component shapes
108
+ */
109
+ export type Shapes =
110
+ | 'rounded'
111
+ | 'rounded-top'
112
+ | 'rounded-end'
113
+ | 'rounded-bottom'
114
+ | 'rounded-start'
115
+ | 'rounded-circle'
116
+ | 'rounded-pill'
117
+ | 'rounded-0'
118
+ | 'rounded-1'
119
+ | 'rounded-2'
120
+ | 'rounded-3'
121
+
122
+ export type TextColor =
123
+ | ContextColor
124
+ | 'main'
125
+ | 'subtle'
126
+ | 'slight'
127
+ | 'solid'
128
+ | 'inverse'
129
+ | 'highlight'
130
+ | 'active'
131
+ | 'contrast'
132
+
133
+ export type Triggers = 'hover' | 'focus' | 'click'
@@ -0,0 +1,43 @@
1
+ import { Breakpoint } from '../types'
2
+
3
+ // Mobile-first ascending order. Every responsive layout prop (`Flex`/`Stack`/`Row`/`Col`/
4
+ // `Skeleton`'s `responsive`) keys its overrides by these literal chassis-css breakpoint names.
5
+ export const BREAKPOINTS: Breakpoint[] = ['small', 'medium', 'large', 'xlarge', '2xlarge']
6
+
7
+ // A column/width span: a track count, `'auto'` for a natural-width track, or `true` for the bare
8
+ // (no explicit width) case. Shared by `Col` and `Skeleton`, both of which map it to the same
9
+ // `col-{n}` / `col` chassis-css classes.
10
+ export type Span = 'auto' | number | string | boolean
11
+
12
+ /**
13
+ * Builds the class list for a component's base layout plus per-breakpoint overrides supplied via
14
+ * a `responsive` prop — the pattern shared by `Flex`, `Stack`, and (from Phase 2) `Row`/`Col`.
15
+ *
16
+ * `toClassNames` maps one breakpoint's layout value to class name fragments for a given prefix
17
+ * (`''` for the base/unprefixed case, `` `${breakpoint}:` `` otherwise). Falsy entries in its
18
+ * return value are fine — `classnames` drops them at the call site — so fields the layout object
19
+ * doesn't set can just map to `undefined`/`false`.
20
+ */
21
+ export function buildResponsiveClassNames<TLayout>(
22
+ toClassNames: (layout: TLayout, prefix: string) => Array<string | false | null | undefined>,
23
+ base: TLayout,
24
+ responsive?: Partial<Record<Breakpoint, TLayout>>
25
+ ): Array<string | false | null | undefined> {
26
+ const responsiveClassNames = responsive
27
+ ? BREAKPOINTS.filter((bp) => responsive[bp]).flatMap((bp) =>
28
+ toClassNames(responsive[bp] as TLayout, `${bp}:`)
29
+ )
30
+ : []
31
+
32
+ return [...toClassNames(base, ''), ...responsiveClassNames]
33
+ }
34
+
35
+ export type FlexDirection = 'row' | 'column'
36
+
37
+ // A `buildResponsiveClassNames` `toClassNames` fn for the `flex-row`/`flex-column` direction
38
+ // toggle shared by `Card` and `CardBody`, both of which map a `direction` prop to the same
39
+ // chassis-css class.
40
+ export const flexDirectionClassNames = (
41
+ direction: FlexDirection | undefined,
42
+ prefix: string
43
+ ): Array<string | false | undefined> => [direction && `${prefix}flex-${direction}`]
@@ -0,0 +1,152 @@
1
+ import React, { ComponentType, ReactElement, ReactNode } from 'react'
2
+ import { Item, Key, Section } from 'react-stately'
3
+
4
+ import { ComboboxGroupProps } from '../components/combobox/ComboboxGroup'
5
+ import { ComboboxItem, ComboboxItemProps } from '../components/combobox/ComboboxItem'
6
+ import { MenuItemsDef } from '../components/menu/MenuItemDef'
7
+ import { renderMenuItemContent } from './renderMenuItemContent'
8
+
9
+ // Shared between Combobox.tsx/ComboboxListBox.tsx (which build/render this collection) and
10
+ // Autocomplete.tsx (which reuses the same entry shape — see the comment on
11
+ // `buildEntriesFromChildren` below). Lives in `utils/` rather than `components/combobox/` because
12
+ // it crosses that folder boundary; kept in its own file to also avoid a circular import between
13
+ // Combobox.tsx and ComboboxListBox.tsx.
14
+
15
+ export type ComboboxItemElement = ReactElement<ComboboxItemProps>
16
+
17
+ export interface ComboboxGroupEntry {
18
+ entryType: 'group'
19
+ key: Key
20
+ label: ReactNode
21
+ items: ComboboxItemElement[]
22
+ }
23
+
24
+ export type ComboboxEntry = ComboboxItemElement | ComboboxGroupEntry
25
+
26
+ // `useComboBoxState`/`useComboBox`'s own `SelectionMode` ('single' | 'multiple') isn't
27
+ // re-exported from react-stately's public entry point (only `ComboBoxState` etc. are) — this is
28
+ // a structurally-identical stand-in so `ComboboxListBox` can stay generic over it without a
29
+ // fragile deep import.
30
+ export type ComboboxSelectionMode = 'single' | 'multiple'
31
+
32
+ export const isComboboxGroupEntry = (entry: ComboboxEntry): entry is ComboboxGroupEntry =>
33
+ (entry as ComboboxGroupEntry).entryType === 'group'
34
+
35
+ // `Autocomplete`'s own `AutocompleteItem`/`AutocompleteGroup` are structurally identical to
36
+ // `ComboboxItem`/`ComboboxGroup` (see AutocompleteItem.tsx/AutocompleteGroup.tsx — kept as
37
+ // separate named types only so `Autocomplete`'s public API doesn't leak `Combobox`'s own prop
38
+ // type), but they're different *runtime* component identities, which is what
39
+ // `buildEntriesFromChildren` below needs to check consumer-authored `children` against. Passing
40
+ // the pair in lets one implementation serve both families instead of two near-duplicate copies.
41
+ export interface ComboboxCollectionComponents {
42
+ Group: ComponentType<ComboboxGroupProps>
43
+ Item: ComponentType<ComboboxItemProps>
44
+ }
45
+
46
+ // Splits `children` into a flat, ordered list of entries — bare `Item` elements and
47
+ // `Group`-wrapped clusters of them — mirroring how `useComboBoxState`'s dynamic collection needs
48
+ // top-level nodes: some rendered as a plain `<Item>`, some as a `<Section>` wrapping several
49
+ // `<Item>`s (see `comboboxCollectionChildren` below).
50
+ export const buildEntriesFromChildren = (
51
+ children: ReactNode,
52
+ { Group, Item: ItemComponent }: ComboboxCollectionComponents
53
+ ): ComboboxEntry[] => {
54
+ const entries: ComboboxEntry[] = []
55
+ React.Children.forEach(children, (child, index) => {
56
+ if (!React.isValidElement(child)) return
57
+ if (child.type === Group) {
58
+ const groupProps = child.props as ComboboxGroupProps
59
+ const items: ComboboxItemElement[] = []
60
+ React.Children.forEach(groupProps.children, (groupChild) => {
61
+ if (React.isValidElement(groupChild) && groupChild.type === ItemComponent) {
62
+ items.push(groupChild as ComboboxItemElement)
63
+ }
64
+ })
65
+ entries.push({ entryType: 'group', key: `group-${index}`, label: groupProps.label, items })
66
+ return
67
+ }
68
+ if (child.type === ItemComponent) {
69
+ entries.push(child as ComboboxItemElement)
70
+ }
71
+ })
72
+ return entries
73
+ }
74
+
75
+ // Same shape as `buildEntriesFromChildren`, from a flat `MenuItemsDef` instead. A `'header'`
76
+ // entry opens a new group that all following items join until the next header (or the end of
77
+ // the array) — matching how chassis-css itself renders grouped items (flat siblings, no
78
+ // wrapping element per group). `'divider'` entries aren't meaningful for a listbox/option
79
+ // collection and are skipped.
80
+ //
81
+ // Always builds a bare `ComboboxItem` internally regardless of which family (`Combobox` or
82
+ // `Autocomplete`) called it: unlike `buildEntriesFromChildren`, nothing downstream re-checks
83
+ // these elements' runtime type (they're read only via `.props.*`, never matched against a
84
+ // component reference again), so there's no need to thread `ComboboxCollectionComponents`
85
+ // through here too. `def.href`/`def.onClick` are intentionally not read — see the doc comments on
86
+ // `MenuItemDef` itself for why: they're `Menu`-only fields on this shared type.
87
+ export const buildEntriesFromItemsDef = (defs: MenuItemsDef): ComboboxEntry[] => {
88
+ const entries: ComboboxEntry[] = []
89
+ let currentGroup: ComboboxGroupEntry | null = null
90
+
91
+ defs.forEach((def) => {
92
+ if (def.type === 'divider') return
93
+ if (def.type === 'header') {
94
+ currentGroup = { entryType: 'group', key: def.id, label: def.label, items: [] }
95
+ entries.push(currentGroup)
96
+ return
97
+ }
98
+ const item = (
99
+ <ComboboxItem
100
+ key={def.id}
101
+ id={def.id}
102
+ disabled={def.disabled}
103
+ icon={def.icon}
104
+ description={def.description}
105
+ textValue={def.textValue}
106
+ >
107
+ {def.label}
108
+ </ComboboxItem>
109
+ )
110
+ if (currentGroup) currentGroup.items.push(item)
111
+ else entries.push(item)
112
+ })
113
+
114
+ return entries
115
+ }
116
+
117
+ export const getDisabledKeys = (entries: ComboboxEntry[]): Key[] =>
118
+ entries.reduce<Key[]>((keys, entry) => {
119
+ const items = isComboboxGroupEntry(entry) ? entry.items : [entry]
120
+ return keys.concat(items.filter((item) => item.props.disabled).map((item) => item.props.id))
121
+ }, [])
122
+
123
+ // Builds the react-stately `Item` node `useComboBoxState`'s collection actually renders from one
124
+ // entry's props — identical for `Combobox` and `Autocomplete` regardless of which authoring
125
+ // component (`ComboboxItem`/`AutocompleteItem`) produced it, since both share the same prop shape.
126
+ export const renderComboboxCollectionItem = (item: ComboboxItemElement) => (
127
+ <Item
128
+ key={item.props.id}
129
+ textValue={
130
+ item.props.textValue ??
131
+ (typeof item.props.children === 'string' ? item.props.children : undefined)
132
+ }
133
+ >
134
+ {renderMenuItemContent({
135
+ icon: item.props.icon,
136
+ label: item.props.children,
137
+ description: item.props.description
138
+ })}
139
+ </Item>
140
+ )
141
+
142
+ // `useComboBoxState`'s own `children` render prop, given one `ComboboxEntry` — a plain `Item` for
143
+ // a bare entry, a `Section` wrapping its items for a group. Identical for `Combobox` and
144
+ // `Autocomplete`'s state setup.
145
+ export const comboboxCollectionChildren = (entry: ComboboxEntry) =>
146
+ isComboboxGroupEntry(entry) ? (
147
+ <Section key={entry.key} title={entry.label} items={entry.items}>
148
+ {renderComboboxCollectionItem}
149
+ </Section>
150
+ ) : (
151
+ renderComboboxCollectionItem(entry)
152
+ )
@@ -0,0 +1,6 @@
1
+ import { DateValue, RangeValue } from 'react-aria'
2
+
3
+ export interface DateRangePreset {
4
+ label: string
5
+ range: RangeValue<DateValue>
6
+ }
@@ -0,0 +1,39 @@
1
+ // Shared transition timing for native <dialog>-based components (Modal, Drawer). Body-scroll
2
+ // locking is handled by react-aria's usePreventScroll directly in each component.
3
+
4
+ export const getTransitionDuration = (element: HTMLElement) => {
5
+ const { transitionDuration, transitionDelay } = window.getComputedStyle(element)
6
+ const duration = Number.parseFloat(transitionDuration) || 0
7
+ const delay = Number.parseFloat(transitionDelay) || 0
8
+ if (!duration && !delay) return 0
9
+ return (duration + delay) * 1000
10
+ }
11
+
12
+ export const executeAfterTransition = (
13
+ element: HTMLElement,
14
+ callback: () => void,
15
+ animated: boolean
16
+ ) => {
17
+ if (!animated) {
18
+ callback()
19
+ return () => undefined
20
+ }
21
+
22
+ let called = false
23
+ const done = () => {
24
+ if (called) return
25
+ called = true
26
+ element.removeEventListener('transitionend', handleEnd)
27
+ clearTimeout(timer)
28
+ callback()
29
+ }
30
+ const handleEnd = (event: Event) => {
31
+ if (event.target === element) done()
32
+ }
33
+ element.addEventListener('transitionend', handleEnd)
34
+ const timer = setTimeout(done, getTransitionDuration(element) + 50)
35
+ return () => {
36
+ element.removeEventListener('transitionend', handleEnd)
37
+ clearTimeout(timer)
38
+ }
39
+ }
@@ -0,0 +1,29 @@
1
+ // Safari shows a `:focus-visible` ring on an element focused via script even when the
2
+ // interaction that triggered the script was a real pointer click — unlike Chromium/Firefox,
3
+ // which correctly suppress it in that case. Force the ring off for a pointer-triggered redirect,
4
+ // then let normal focus-visible behavior resume the next time this element is genuinely
5
+ // (re)focused, e.g. via Tab.
6
+ export function focusRedirect(
7
+ el: HTMLElement | null,
8
+ viaPointer: boolean,
9
+ focusOptions?: FocusOptions
10
+ ): void {
11
+ if (!el) return
12
+ if (!viaPointer) {
13
+ el.focus(focusOptions)
14
+ return
15
+ }
16
+ const prevOutline = el.style.outline
17
+ const prevBoxShadow = el.style.boxShadow
18
+ el.style.outline = 'none'
19
+ el.style.boxShadow = 'none'
20
+ el.focus(focusOptions)
21
+ el.addEventListener(
22
+ 'blur',
23
+ () => {
24
+ el.style.outline = prevOutline
25
+ el.style.boxShadow = prevBoxShadow
26
+ },
27
+ { once: true }
28
+ )
29
+ }
@@ -0,0 +1,17 @@
1
+ import { CalendarState, RangeCalendarState } from 'react-stately'
2
+ import { CalendarDate, toCalendarDate } from '@internationalized/date'
3
+
4
+ // Shared by `CalendarMonthGrid` and `CalendarYearGrid` — a month/year button is disabled when
5
+ // every day it covers falls outside `minValue`/`maxValue`, not just when its first day does (e.g.
6
+ // a `maxValue` of March 15th still leaves March itself partly selectable, so March's button stays
7
+ // enabled; April's doesn't). `unitEnd` is the last day of the button's own month/year.
8
+ export const isWholeUnitDisabled = (
9
+ state: CalendarState<'single' | 'multiple'> | RangeCalendarState,
10
+ unitStart: CalendarDate,
11
+ unitEnd: CalendarDate
12
+ ): boolean => {
13
+ if (state.isDisabled) return true
14
+ if (state.maxValue && unitStart.compare(toCalendarDate(state.maxValue)) > 0) return true
15
+ if (state.minValue && unitEnd.compare(toCalendarDate(state.minValue)) < 0) return true
16
+ return false
17
+ }