@uselets/ui 2.0.0 → 2.0.2

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 (209) hide show
  1. package/dist/{as-child-Dxg3Xo1G.d.ts → as-child-T9W73ZYU.d.ts} +1 -3
  2. package/dist/{chart-B_6nC_ih.d.ts → chart-8rgtsk95.d.ts} +1 -3
  3. package/dist/cli/uselets.mjs.map +1 -1
  4. package/dist/components/accordion.d.ts +1 -3
  5. package/dist/components/accordion.js.map +1 -1
  6. package/dist/components/alert-dialog.d.ts +5 -5
  7. package/dist/components/alert-dialog.js +1 -1
  8. package/dist/components/alert-dialog.js.map +1 -1
  9. package/dist/components/alert.d.ts +0 -2
  10. package/dist/components/alert.js.map +1 -1
  11. package/dist/components/anchor.d.ts +1 -3
  12. package/dist/components/anchor.js.map +1 -1
  13. package/dist/components/area-chart.d.ts +1 -3
  14. package/dist/components/area-chart.js.map +1 -1
  15. package/dist/components/avatar.d.ts +1 -3
  16. package/dist/components/avatar.js.map +1 -1
  17. package/dist/components/badge.d.ts +1 -3
  18. package/dist/components/badge.js.map +1 -1
  19. package/dist/components/bar-chart.d.ts +1 -3
  20. package/dist/components/bar-chart.js.map +1 -1
  21. package/dist/components/bottom-nav.d.ts +1 -3
  22. package/dist/components/bottom-nav.js.map +1 -1
  23. package/dist/components/breadcrumb.d.ts +1 -3
  24. package/dist/components/breadcrumb.js.map +1 -1
  25. package/dist/components/button-group.d.ts +1 -3
  26. package/dist/components/button-group.js.map +1 -1
  27. package/dist/components/button.d.ts +1 -3
  28. package/dist/components/button.js.map +1 -1
  29. package/dist/components/calendar.d.ts +0 -2
  30. package/dist/components/calendar.js +1 -1
  31. package/dist/components/calendar.js.map +1 -1
  32. package/dist/components/card.d.ts +0 -2
  33. package/dist/components/card.js.map +1 -1
  34. package/dist/components/carousel.d.ts +0 -2
  35. package/dist/components/carousel.js.map +1 -1
  36. package/dist/components/center.d.ts +0 -2
  37. package/dist/components/center.js.map +1 -1
  38. package/dist/components/chart.d.ts +1 -1
  39. package/dist/components/chart.js.map +1 -1
  40. package/dist/components/checkbox.d.ts +0 -2
  41. package/dist/components/checkbox.js.map +1 -1
  42. package/dist/components/code.d.ts +0 -2
  43. package/dist/components/code.js.map +1 -1
  44. package/dist/components/collapsible.d.ts +1 -3
  45. package/dist/components/collapsible.js.map +1 -1
  46. package/dist/components/combobox.d.ts +1 -3
  47. package/dist/components/combobox.js.map +1 -1
  48. package/dist/components/command.d.ts +0 -2
  49. package/dist/components/command.js.map +1 -1
  50. package/dist/components/container.d.ts +0 -2
  51. package/dist/components/container.js.map +1 -1
  52. package/dist/components/data-table.d.ts +0 -2
  53. package/dist/components/data-table.js.map +1 -1
  54. package/dist/components/date-range-picker.d.ts +0 -2
  55. package/dist/components/date-range-picker.js.map +1 -1
  56. package/dist/components/dialog.d.ts +5 -5
  57. package/dist/components/dialog.js +1 -1
  58. package/dist/components/dialog.js.map +1 -1
  59. package/dist/components/direction.d.ts +0 -2
  60. package/dist/components/donut-chart.d.ts +0 -2
  61. package/dist/components/donut-chart.js.map +1 -1
  62. package/dist/components/drawer.d.ts +2 -4
  63. package/dist/components/drawer.js +1 -1
  64. package/dist/components/drawer.js.map +1 -1
  65. package/dist/components/dropdown-menu.d.ts +1 -3
  66. package/dist/components/dropdown-menu.js.map +1 -1
  67. package/dist/components/dropzone.d.ts +0 -2
  68. package/dist/components/dropzone.js.map +1 -1
  69. package/dist/components/empty.d.ts +0 -2
  70. package/dist/components/empty.js.map +1 -1
  71. package/dist/components/field.d.ts +0 -2
  72. package/dist/components/field.js.map +1 -1
  73. package/dist/components/flex.d.ts +0 -2
  74. package/dist/components/flex.js.map +1 -1
  75. package/dist/components/grid.d.ts +0 -2
  76. package/dist/components/grid.js.map +1 -1
  77. package/dist/components/group.d.ts +0 -2
  78. package/dist/components/group.js.map +1 -1
  79. package/dist/components/heading.d.ts +1 -3
  80. package/dist/components/heading.js.map +1 -1
  81. package/dist/components/hover-card.d.ts +1 -3
  82. package/dist/components/hover-card.js.map +1 -1
  83. package/dist/components/input-group.d.ts +0 -2
  84. package/dist/components/input-group.js.map +1 -1
  85. package/dist/components/input-otp.d.ts +0 -2
  86. package/dist/components/input-otp.js.map +1 -1
  87. package/dist/components/input.d.ts +0 -2
  88. package/dist/components/input.js.map +1 -1
  89. package/dist/components/kbd.d.ts +0 -2
  90. package/dist/components/kbd.js.map +1 -1
  91. package/dist/components/label.d.ts +1 -3
  92. package/dist/components/label.js.map +1 -1
  93. package/dist/components/list.d.ts +1 -3
  94. package/dist/components/list.js.map +1 -1
  95. package/dist/components/logo.d.ts +0 -2
  96. package/dist/components/marker.d.ts +1 -3
  97. package/dist/components/marker.js.map +1 -1
  98. package/dist/components/mask-input.d.ts +0 -2
  99. package/dist/components/mask-input.js.map +1 -1
  100. package/dist/components/native-select.d.ts +0 -2
  101. package/dist/components/native-select.js.map +1 -1
  102. package/dist/components/navigation-menu.d.ts +1 -3
  103. package/dist/components/navigation-menu.js.map +1 -1
  104. package/dist/components/number-field.d.ts +1 -3
  105. package/dist/components/number-field.js.map +1 -1
  106. package/dist/components/pagination.d.ts +0 -2
  107. package/dist/components/pagination.js.map +1 -1
  108. package/dist/components/phone-input.d.ts +0 -2
  109. package/dist/components/phone-input.js.map +1 -1
  110. package/dist/components/pie-chart.d.ts +1 -3
  111. package/dist/components/pie-chart.js.map +1 -1
  112. package/dist/components/popover.d.ts +1 -3
  113. package/dist/components/popover.js.map +1 -1
  114. package/dist/components/progress.d.ts +0 -2
  115. package/dist/components/progress.js.map +1 -1
  116. package/dist/components/radio-group.d.ts +0 -2
  117. package/dist/components/radio-group.js.map +1 -1
  118. package/dist/components/resizable.d.ts +0 -2
  119. package/dist/components/resizable.js.map +1 -1
  120. package/dist/components/ring-progress.d.ts +0 -2
  121. package/dist/components/ring-progress.js.map +1 -1
  122. package/dist/components/scroll-area.d.ts +0 -2
  123. package/dist/components/scroll-area.js.map +1 -1
  124. package/dist/components/select.d.ts +1 -3
  125. package/dist/components/select.js.map +1 -1
  126. package/dist/components/separator.d.ts +1 -3
  127. package/dist/components/separator.js.map +1 -1
  128. package/dist/components/sidebar.d.ts +1 -3
  129. package/dist/components/sidebar.js.map +1 -1
  130. package/dist/components/simple-grid.d.ts +0 -2
  131. package/dist/components/simple-grid.js.map +1 -1
  132. package/dist/components/skeleton.d.ts +0 -2
  133. package/dist/components/skeleton.js.map +1 -1
  134. package/dist/components/slider.d.ts +0 -2
  135. package/dist/components/slider.js.map +1 -1
  136. package/dist/components/sonner.d.ts +0 -2
  137. package/dist/components/sonner.js.map +1 -1
  138. package/dist/components/spinner.d.ts +0 -2
  139. package/dist/components/spinner.js.map +1 -1
  140. package/dist/components/stack.d.ts +0 -2
  141. package/dist/components/stack.js.map +1 -1
  142. package/dist/components/stepper.d.ts +1 -3
  143. package/dist/components/stepper.js.map +1 -1
  144. package/dist/components/switch.d.ts +0 -2
  145. package/dist/components/switch.js.map +1 -1
  146. package/dist/components/table.d.ts +0 -2
  147. package/dist/components/table.js.map +1 -1
  148. package/dist/components/tabs.d.ts +1 -3
  149. package/dist/components/tabs.js.map +1 -1
  150. package/dist/components/text.d.ts +1 -3
  151. package/dist/components/text.js.map +1 -1
  152. package/dist/components/textarea.d.ts +0 -2
  153. package/dist/components/textarea.js.map +1 -1
  154. package/dist/components/theme.d.ts +0 -2
  155. package/dist/components/theme.js.map +1 -1
  156. package/dist/components/timeline.d.ts +0 -2
  157. package/dist/components/timeline.js.map +1 -1
  158. package/dist/components/toggle-group.d.ts +1 -3
  159. package/dist/components/toggle-group.js.map +1 -1
  160. package/dist/components/toggle.d.ts +1 -3
  161. package/dist/components/toggle.js.map +1 -1
  162. package/dist/components/tooltip.d.ts +1 -3
  163. package/dist/components/tooltip.js.map +1 -1
  164. package/dist/components/unstyled-button.d.ts +1 -3
  165. package/dist/components/unstyled-button.js.map +1 -1
  166. package/dist/components/visibility.d.ts +0 -2
  167. package/dist/components/visibility.js.map +1 -1
  168. package/dist/hooks/use-breakpoint-value.d.ts +0 -2
  169. package/dist/hooks/use-breakpoint-value.js.map +1 -1
  170. package/dist/hooks/use-breakpoint.d.ts +0 -2
  171. package/dist/hooks/use-breakpoint.js.map +1 -1
  172. package/dist/hooks/use-disclosure.d.ts +0 -2
  173. package/dist/hooks/use-disclosure.js.map +1 -1
  174. package/dist/hooks/use-document-visibility.d.ts +0 -2
  175. package/dist/hooks/use-document-visibility.js.map +1 -1
  176. package/dist/hooks/use-hotkeys.d.ts +1 -1
  177. package/dist/hooks/use-idle.d.ts +0 -2
  178. package/dist/hooks/use-idle.js.map +1 -1
  179. package/dist/hooks/use-interval.d.ts +0 -2
  180. package/dist/hooks/use-interval.js.map +1 -1
  181. package/dist/hooks/use-local-storage.d.ts +0 -2
  182. package/dist/hooks/use-local-storage.js.map +1 -1
  183. package/dist/hooks/use-mask.d.ts +0 -2
  184. package/dist/hooks/use-mask.js.map +1 -1
  185. package/dist/hooks/use-mobile.d.ts +0 -2
  186. package/dist/hooks/use-mobile.js.map +1 -1
  187. package/dist/index.d.ts +3 -3
  188. package/dist/lib/as-child.d.ts +1 -1
  189. package/dist/lib/as-child.js.map +1 -1
  190. package/dist/lib/badge.d.ts +0 -2
  191. package/dist/lib/badge.js.map +1 -1
  192. package/dist/lib/button.d.ts +0 -2
  193. package/dist/lib/button.js.map +1 -1
  194. package/dist/lib/color.d.ts +0 -2
  195. package/dist/lib/color.js.map +1 -1
  196. package/dist/lib/compose-refs.d.ts +0 -2
  197. package/dist/lib/compose-refs.js.map +1 -1
  198. package/dist/lib/progress.d.ts +0 -2
  199. package/dist/lib/progress.js.map +1 -1
  200. package/dist/lib/utils.d.ts +0 -2
  201. package/dist/lib/utils.js.map +1 -1
  202. package/dist/logo--R3_XDgA.js.map +1 -1
  203. package/dist/postcss.config.js.map +1 -1
  204. package/dist/resolve-class-name-BurP8ngI.js.map +1 -1
  205. package/dist/skills/uselets-ui/references/component-catalog.md +3 -3
  206. package/dist/{use-hotkeys-D1_TEIwN.d.ts → use-hotkeys-BVm0IGb8.d.ts} +1 -5
  207. package/dist/use-hotkeys-YDJmGWX6.js.map +1 -1
  208. package/package.json +9 -9
  209. package/skills/uselets-ui/references/component-catalog.md +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"postcss.config.js","names":["config"],"sources":["../postcss.config.mjs"],"sourcesContent":["/** @type {import('postcss-load-config').Config} */\nconst config = {\n plugins: { \"@tailwindcss/postcss\": {} },\n};\n\nexport default config;\n"],"mappings":"AACA,MAAMA,EAAS,CACX,QAAS,CAAE,uBAAwB,CAAC,CAAE,CAC1C"}
1
+ {"version":3,"file":"postcss.config.js","names":["config"],"sources":["../postcss.config.mjs"],"sourcesContent":["/** @type {import('postcss-load-config').Config} */\nconst config = {\n plugins: { \"@tailwindcss/postcss\": {} },\n};\n\nexport default config;\n"],"mappings":"AACA,MAAMA,EAAS,CACX,QAAS,CAAE,uBAAwB,CAAC,CAAE,CAC1C,E"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-class-name-BurP8ngI.js","names":["className","state"],"sources":["../src/utils/resolve-class-name.ts"],"sourcesContent":["/** Resolves a Base UI `className`, which can also be a function of the component state, for that state. */\nexport function resolveClassName<State>(\n className: string | ((state: State) => string | undefined) | undefined,\n state: State\n) {\n return typeof className === 'function' ? className(state) : className\n}\n"],"mappings":"uCACA,SAAgB,iBACd,EACA,EACA,CACA,OAAO,OAAOA,GAAc,WAAaA,EAAUC,CAAK,EAAID,CAC9D"}
1
+ {"version":3,"file":"resolve-class-name-BurP8ngI.js","names":["className","state"],"sources":["../src/utils/resolve-class-name.ts"],"sourcesContent":["/** Resolves a Base UI `className`, which can also be a function of the component state, for that state. */\nexport function resolveClassName<State>(\n className: string | ((state: State) => string | undefined) | undefined,\n state: State\n) {\n return typeof className === 'function' ? className(state) : className\n}\n"],"mappings":"A,uCACA,SAAgB,iBACd,EACA,EACA,CACA,OAAO,OAAOA,GAAc,WAAaA,EAAUC,CAAK,EAAID,CAC9D,C"}
@@ -106,7 +106,7 @@ Unless noted otherwise, each module also exports its public `*Props` types from
106
106
  - Notes: alert surface with `default` and `destructive` variants
107
107
  - `alert-dialog`
108
108
  - Exports: `AlertDialog`, `AlertDialogAction`, `AlertDialogCancel`, `AlertDialogContent`, `AlertDialogDescription`, `AlertDialogFooter`, `AlertDialogHeader`, `AlertDialogMedia`, `AlertDialogOverlay`, `AlertDialogPortal`, `AlertDialogTitle`, `AlertDialogTrigger`
109
- - Notes: confirmation dialog composition
109
+ - Notes: confirmation dialog composition. `AlertDialogContent.overlayProps?: AlertDialogOverlayProps` forwards props to the overlay it renders. `AlertDialogOverlay.forceRender` defaults to `true`, so an alert dialog opened inside a `Dialog`/`Drawer` keeps its own overlay; pass `forceRender={false}` (directly or via `overlayProps`) to skip it
110
110
  - `badge`
111
111
  - Exports: `Badge`, `badgeVariants`
112
112
  - Notes: pill-shaped tag with `size: 'xs' | 'sm' | 'md' | 'lg' | 'xl'` (default `md`), `solid`/`secondary`/`outline`/`subtle` variants, `color: UIColor` (`primary` default), and `asChild`
@@ -204,13 +204,13 @@ Unless noted otherwise, each module also exports its public `*Props` types from
204
204
 
205
205
  - `dialog`
206
206
  - Exports: `Dialog`, `DialogBody`, `DialogClose`, `DialogContent`, `DialogDescription`, `DialogFooter`, `DialogHeader`, `DialogOverlay`, `DialogPortal`, `DialogTitle`, `DialogTrigger`
207
- - Notes: `Dialog` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `full` occupies the entire viewport. `DialogContent` caps its height at `calc(100dvh - 2rem)` and lays out children as a flex column. For long content, wrap the middle in `DialogBody` (`flex-1 overflow-y-auto`) so the body scrolls while `DialogHeader` and `DialogFooter` remain pinned; for short content, omit `DialogBody`. `DialogContent.showCloseButton` defaults to `true`; `DialogFooter.showCloseButton` defaults to `false`. `Dialog.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DialogClose` still work). `DialogOverlay` and `DialogContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree
207
+ - Notes: `Dialog` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `full` occupies the entire viewport. `DialogContent` caps its height at `calc(100dvh - 2rem)` and lays out children as a flex column. For long content, wrap the middle in `DialogBody` (`flex-1 overflow-y-auto`) so the body scrolls while `DialogHeader` and `DialogFooter` remain pinned; for short content, omit `DialogBody`. `DialogContent.showCloseButton` defaults to `true`; `DialogFooter.showCloseButton` defaults to `false`. `Dialog.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DialogClose` still work). `DialogOverlay` and `DialogContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree. `DialogContent.overlayProps?: DialogOverlayProps` forwards props to the overlay it renders (`overlayRef` still works and takes precedence over `overlayProps.ref`). `DialogOverlay.forceRender` defaults to `true`, so a dialog opened inside another `Dialog`/`Drawer`/`AlertDialog` keeps its own overlay; pass `forceRender={false}` (directly or via `overlayProps`) to skip it
208
208
  - `direction`
209
209
  - Exports: `DirectionProvider`, `useDirection`, types `DirectionProviderProps`, `TextDirection`
210
210
  - Notes: `DirectionProvider.direction: 'ltr' | 'rtl'` (default `'ltr'`) sets the text direction for keyboard navigation (`Tabs`, `ToggleGroup`, `RadioGroup`, `DropdownMenu`), `Slider`, `ScrollArea`, `Select`, `NavigationMenu`, `Combobox` and popup positioning. A `dir` prop/attribute on those components does not change their behavior; wrap the RTL subtree (or the app) in `DirectionProvider` and also set `dir` on the HTML for text layout. `useDirection()` reads the current direction
211
211
  - `drawer`
212
212
  - Exports: `Drawer`, `DrawerBody`, `DrawerClose`, `DrawerContent`, `DrawerDescription`, `DrawerFooter`, `DrawerHeader`, `DrawerOverlay`, `DrawerPortal`, `DrawerTitle`, `DrawerTrigger`
213
- - Notes: `Drawer` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `DrawerBody` provides padded auto-scroll content; `DrawerFooter` stacks actions on mobile and aligns them to the end on larger breakpoints; `DrawerContent.showCloseButton` controls the automatic close button and defaults to `true`. `Drawer.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DrawerClose` still work). `Drawer.direction: 'top' | 'right' | 'bottom' | 'left'` (default: `right`) controls which edge the drawer slides in from. `DrawerOverlay` and `DrawerContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree
213
+ - Notes: `Drawer` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `DrawerBody` provides padded auto-scroll content; `DrawerFooter` stacks actions on mobile and aligns them to the end on larger breakpoints; `DrawerContent.showCloseButton` controls the automatic close button and defaults to `true`. `Drawer.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DrawerClose` still work). `Drawer.direction: 'top' | 'right' | 'bottom' | 'left'` (default: `right`) controls which edge the drawer slides in from. `DrawerOverlay` and `DrawerContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree. `DrawerContent.overlayProps?: DrawerOverlayProps` forwards props to the overlay it renders. `DrawerOverlay.forceRender` defaults to `true`, so a drawer opened inside another `Drawer`/`Dialog` keeps its own overlay; pass `forceRender={false}` (directly or via `overlayProps`) to skip it
214
214
  - `popover`
215
215
  - Exports: `Popover`, `PopoverClose`, `PopoverContent`, `PopoverDescription`, `PopoverHeader`, `PopoverTitle`, `PopoverTrigger`
216
216
  - Notes: `PopoverContent` accepts `side`, `sideOffset`, `align`, `alignOffset`, and `anchor` (element, ref, or virtual element) to position against something other than the trigger; there is no `PopoverAnchor` component. `Popover.modal: boolean | 'trap-focus'` (default `false`) traps focus only when a `PopoverClose` (supports `asChild`) is rendered inside `PopoverContent`; without it, `modal` still blocks outside clicks and page scroll but `Tab` leaves the popup. Hide the close with `className="sr-only"` when there is no visible close button
@@ -1,19 +1,15 @@
1
1
  import { t as __name } from "./rolldown-runtime-BhWHdk3m.js";
2
- //#region src/utils/parse-hotkey.d.ts
3
2
  type HotkeyItemOptions = {
4
3
  preventDefault?: boolean;
5
4
  usePhysicalKeys?: boolean;
6
5
  };
7
6
  type HotkeyItem$1 = [string, (event: unknown) => void, HotkeyItemOptions?];
8
7
  declare function getHotkeyHandler(hotkeys: HotkeyItem$1[]): (event: React.KeyboardEvent<HTMLElement> | KeyboardEvent) => void;
9
- //#endregion
10
- //#region src/hooks/use-hotkeys.d.ts
11
8
  type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?];
12
9
  /** Registers keyboard shortcuts on the document. Items are `[hotkey, handler, options?]`; `mod` is `ctrl` or `⌘`. */
13
10
  declare function useHotkeys(hotkeys: HotkeyItem[], tagsToIgnore?: string[], triggerOnContentEditable?: boolean): void;
14
11
  declare namespace useHotkeys {
15
12
  type Hotkey = HotkeyItem;
16
13
  }
17
- //#endregion
18
14
  export { getHotkeyHandler as i, useHotkeys as n, HotkeyItemOptions as r, HotkeyItem as t };
19
- //# sourceMappingURL=use-hotkeys-D1_TEIwN.d.ts.map
15
+ //# sourceMappingURL=use-hotkeys-BVm0IGb8.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-hotkeys-YDJmGWX6.js","names":["keyNameMap","lowerKey","key","keys","hotkey","part","modifiers","reservedKeys","freeKey","pressedKey","pressedCode","event","alt","altKey","mod","ctrlKey","metaKey","ctrl","meta","shift","shiftKey","usePhysicalKeys","_event","hotkeys","handler","options","triggerOnContentEditable","tagsToIgnore","handleKeydown","useEffectEvent","useEffect"],"sources":["../src/utils/parse-hotkey.ts","../src/hooks/use-hotkeys.ts"],"sourcesContent":["export type KeyboardModifiers = {\n alt: boolean\n ctrl: boolean\n meta: boolean\n mod: boolean\n shift: boolean\n}\n\nexport type Hotkey = KeyboardModifiers & {\n key?: string\n}\n\ntype CheckHotkeyMatch = (event: KeyboardEvent) => boolean\n\nconst keyNameMap: Record<string, string> = {\n ' ': 'space',\n ArrowLeft: 'arrowleft',\n ArrowRight: 'arrowright',\n ArrowUp: 'arrowup',\n ArrowDown: 'arrowdown',\n Escape: 'escape',\n Esc: 'escape',\n esc: 'escape',\n Enter: 'enter',\n Tab: 'tab',\n Backspace: 'backspace',\n Delete: 'delete',\n Insert: 'insert',\n Home: 'home',\n End: 'end',\n PageUp: 'pageup',\n PageDown: 'pagedown',\n '+': 'plus',\n '-': 'minus',\n '*': 'asterisk',\n '/': 'slash'\n}\n\nfunction normalizeKey(key: string): string {\n const lowerKey = key.replace('Key', '').toLowerCase()\n return keyNameMap[key] || lowerKey\n}\n\nexport function parseHotkey(hotkey: string): Hotkey {\n const keys = hotkey\n .toLowerCase()\n .split('+')\n .map((part) => part.trim())\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n ctrl: keys.includes('ctrl'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n shift: keys.includes('shift')\n }\n\n const reservedKeys = ['alt', 'ctrl', 'meta', 'shift', 'mod']\n\n const freeKey = keys.find((key) => !reservedKeys.includes(key))\n\n return {\n ...modifiers,\n key: freeKey === '[plus]' ? '+' : freeKey\n }\n}\n\nfunction isExactHotkey(hotkey: Hotkey, event: KeyboardEvent, usePhysicalKeys?: boolean): boolean {\n const { alt, ctrl, meta, mod, shift, key } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKey, code: pressedCode } = event\n\n if (alt !== altKey) {\n return false\n }\n\n if (mod) {\n if (!ctrlKey && !metaKey) {\n return false\n }\n } else {\n if (ctrl !== ctrlKey) {\n return false\n }\n if (meta !== metaKey) {\n return false\n }\n }\n if (shift !== shiftKey) {\n return false\n }\n\n if (\n key &&\n (usePhysicalKeys\n ? normalizeKey(pressedCode) === normalizeKey(key)\n : normalizeKey(pressedKey ?? pressedCode) === normalizeKey(key))\n ) {\n return true\n }\n\n return false\n}\n\nexport function getHotkeyMatcher(hotkey: string, usePhysicalKeys?: boolean): CheckHotkeyMatch {\n return (event) => isExactHotkey(parseHotkey(hotkey), event, usePhysicalKeys)\n}\n\nexport type HotkeyItemOptions = {\n preventDefault?: boolean\n usePhysicalKeys?: boolean\n}\n\ntype HotkeyItem = [string, (event: unknown) => void, HotkeyItemOptions?]\n\nexport function getHotkeyHandler(hotkeys: HotkeyItem[]) {\n return (event: React.KeyboardEvent<HTMLElement> | KeyboardEvent) => {\n const _event = 'nativeEvent' in event ? event.nativeEvent : event\n hotkeys.forEach(([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (getHotkeyMatcher(hotkey, options.usePhysicalKeys)(_event)) {\n if (options.preventDefault) {\n event.preventDefault()\n }\n\n handler(_event)\n }\n })\n }\n}\n","import { useEffect, useEffectEvent } from 'react'\n\nimport { getHotkeyHandler, getHotkeyMatcher, type HotkeyItemOptions } from '../utils/parse-hotkey'\n\nexport type { HotkeyItemOptions }\nexport { getHotkeyHandler }\n\nexport type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?]\n\nfunction shouldFireEvent(event: KeyboardEvent, tagsToIgnore: string[], triggerOnContentEditable = false) {\n if (event.target instanceof HTMLElement) {\n if (triggerOnContentEditable) {\n return !tagsToIgnore.includes(event.target.tagName)\n }\n\n return !event.target.isContentEditable && !tagsToIgnore.includes(event.target.tagName)\n }\n\n return true\n}\n\n/** Registers keyboard shortcuts on the document. Items are `[hotkey, handler, options?]`; `mod` is `ctrl` or `⌘`. */\nexport function useHotkeys(\n hotkeys: HotkeyItem[],\n tagsToIgnore: string[] = ['INPUT', 'TEXTAREA', 'SELECT'],\n triggerOnContentEditable = false\n) {\n const handleKeydown = useEffectEvent((event: KeyboardEvent) => {\n hotkeys.forEach(([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (\n getHotkeyMatcher(hotkey, options.usePhysicalKeys)(event) &&\n shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable)\n ) {\n if (options.preventDefault) {\n event.preventDefault()\n }\n\n handler(event)\n }\n })\n })\n\n useEffect(() => {\n document.documentElement.addEventListener('keydown', handleKeydown)\n return () => document.documentElement.removeEventListener('keydown', handleKeydown)\n }, [])\n}\n\nexport namespace useHotkeys {\n export type Hotkey = HotkeyItem\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-hotkeys-YDJmGWX6.js","names":["keyNameMap","lowerKey","key","keys","hotkey","part","modifiers","reservedKeys","freeKey","pressedKey","pressedCode","event","alt","altKey","mod","ctrlKey","metaKey","ctrl","meta","shift","shiftKey","usePhysicalKeys","_event","hotkeys","handler","options","triggerOnContentEditable","tagsToIgnore","handleKeydown","useEffectEvent","useEffect"],"sources":["../src/utils/parse-hotkey.ts","../src/hooks/use-hotkeys.ts"],"sourcesContent":["export type KeyboardModifiers = {\n alt: boolean\n ctrl: boolean\n meta: boolean\n mod: boolean\n shift: boolean\n}\n\nexport type Hotkey = KeyboardModifiers & {\n key?: string\n}\n\ntype CheckHotkeyMatch = (event: KeyboardEvent) => boolean\n\nconst keyNameMap: Record<string, string> = {\n ' ': 'space',\n ArrowLeft: 'arrowleft',\n ArrowRight: 'arrowright',\n ArrowUp: 'arrowup',\n ArrowDown: 'arrowdown',\n Escape: 'escape',\n Esc: 'escape',\n esc: 'escape',\n Enter: 'enter',\n Tab: 'tab',\n Backspace: 'backspace',\n Delete: 'delete',\n Insert: 'insert',\n Home: 'home',\n End: 'end',\n PageUp: 'pageup',\n PageDown: 'pagedown',\n '+': 'plus',\n '-': 'minus',\n '*': 'asterisk',\n '/': 'slash'\n}\n\nfunction normalizeKey(key: string): string {\n const lowerKey = key.replace('Key', '').toLowerCase()\n return keyNameMap[key] || lowerKey\n}\n\nexport function parseHotkey(hotkey: string): Hotkey {\n const keys = hotkey\n .toLowerCase()\n .split('+')\n .map((part) => part.trim())\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n ctrl: keys.includes('ctrl'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n shift: keys.includes('shift')\n }\n\n const reservedKeys = ['alt', 'ctrl', 'meta', 'shift', 'mod']\n\n const freeKey = keys.find((key) => !reservedKeys.includes(key))\n\n return {\n ...modifiers,\n key: freeKey === '[plus]' ? '+' : freeKey\n }\n}\n\nfunction isExactHotkey(hotkey: Hotkey, event: KeyboardEvent, usePhysicalKeys?: boolean): boolean {\n const { alt, ctrl, meta, mod, shift, key } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKey, code: pressedCode } = event\n\n if (alt !== altKey) {\n return false\n }\n\n if (mod) {\n if (!ctrlKey && !metaKey) {\n return false\n }\n } else {\n if (ctrl !== ctrlKey) {\n return false\n }\n if (meta !== metaKey) {\n return false\n }\n }\n if (shift !== shiftKey) {\n return false\n }\n\n if (\n key &&\n (usePhysicalKeys\n ? normalizeKey(pressedCode) === normalizeKey(key)\n : normalizeKey(pressedKey ?? pressedCode) === normalizeKey(key))\n ) {\n return true\n }\n\n return false\n}\n\nexport function getHotkeyMatcher(hotkey: string, usePhysicalKeys?: boolean): CheckHotkeyMatch {\n return (event) => isExactHotkey(parseHotkey(hotkey), event, usePhysicalKeys)\n}\n\nexport type HotkeyItemOptions = {\n preventDefault?: boolean\n usePhysicalKeys?: boolean\n}\n\ntype HotkeyItem = [string, (event: unknown) => void, HotkeyItemOptions?]\n\nexport function getHotkeyHandler(hotkeys: HotkeyItem[]) {\n return (event: React.KeyboardEvent<HTMLElement> | KeyboardEvent) => {\n const _event = 'nativeEvent' in event ? event.nativeEvent : event\n hotkeys.forEach(([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (getHotkeyMatcher(hotkey, options.usePhysicalKeys)(_event)) {\n if (options.preventDefault) {\n event.preventDefault()\n }\n\n handler(_event)\n }\n })\n }\n}\n","import { useEffect, useEffectEvent } from 'react'\n\nimport { getHotkeyHandler, getHotkeyMatcher, type HotkeyItemOptions } from '../utils/parse-hotkey'\n\nexport type { HotkeyItemOptions }\nexport { getHotkeyHandler }\n\nexport type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?]\n\nfunction shouldFireEvent(event: KeyboardEvent, tagsToIgnore: string[], triggerOnContentEditable = false) {\n if (event.target instanceof HTMLElement) {\n if (triggerOnContentEditable) {\n return !tagsToIgnore.includes(event.target.tagName)\n }\n\n return !event.target.isContentEditable && !tagsToIgnore.includes(event.target.tagName)\n }\n\n return true\n}\n\n/** Registers keyboard shortcuts on the document. Items are `[hotkey, handler, options?]`; `mod` is `ctrl` or `⌘`. */\nexport function useHotkeys(\n hotkeys: HotkeyItem[],\n tagsToIgnore: string[] = ['INPUT', 'TEXTAREA', 'SELECT'],\n triggerOnContentEditable = false\n) {\n const handleKeydown = useEffectEvent((event: KeyboardEvent) => {\n hotkeys.forEach(([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (\n getHotkeyMatcher(hotkey, options.usePhysicalKeys)(event) &&\n shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable)\n ) {\n if (options.preventDefault) {\n event.preventDefault()\n }\n\n handler(event)\n }\n })\n })\n\n useEffect(() => {\n document.documentElement.addEventListener('keydown', handleKeydown)\n return () => document.documentElement.removeEventListener('keydown', handleKeydown)\n }, [])\n}\n\nexport namespace useHotkeys {\n export type Hotkey = HotkeyItem\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uselets/ui",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -63,7 +63,7 @@
63
63
  "@base-ui/react": "1.9.0",
64
64
  "@fontsource-variable/inter": "^5.3.0",
65
65
  "@react-input/mask": "2.0.4",
66
- "@tabler/icons-react": "^3.49.0",
66
+ "@tabler/icons-react": "^3.50.0",
67
67
  "@tanstack/react-table": "9.3.1",
68
68
  "@uselets/tokens": "0.2.0",
69
69
  "class-variance-authority": "^0.7.1",
@@ -75,11 +75,11 @@
75
75
  "input-otp": "1.5.0",
76
76
  "next-themes": "0.4.6",
77
77
  "react-day-picker": "10.0.2",
78
- "react-dropzone": "20.1.3",
78
+ "react-dropzone": "20.1.4",
79
79
  "react-phone-number-input": "^3.4.18",
80
- "react-resizable-panels": "4.14.5",
80
+ "react-resizable-panels": "4.15.0",
81
81
  "recharts": "^3.10.1",
82
- "shadcn": "4.22.0",
82
+ "shadcn": "4.23.0",
83
83
  "sonner": "2.0.8"
84
84
  },
85
85
  "peerDependencies": {
@@ -91,14 +91,14 @@
91
91
  "@tailwindcss/postcss": "4.3.3",
92
92
  "@testing-library/react": "16.3.3",
93
93
  "@vitest/coverage-v8": "5.0.5",
94
- "@tsdown/css": "0.23.1",
95
- "@turbo/gen": "2.11.9",
96
- "@types/node": "26.6.5",
94
+ "@tsdown/css": "0.23.4",
95
+ "@turbo/gen": "2.11.10",
96
+ "@types/node": "26.6.6",
97
97
  "@types/react": "19.3.0",
98
98
  "@types/react-dom": "19.3.0",
99
99
  "jsdom": "30.1.3",
100
100
  "tailwindcss": "4.3.3",
101
- "tsdown": "0.23.1",
101
+ "tsdown": "0.23.4",
102
102
  "typescript": "7.0.2",
103
103
  "vitest": "5.0.5"
104
104
  }
@@ -106,7 +106,7 @@ Unless noted otherwise, each module also exports its public `*Props` types from
106
106
  - Notes: alert surface with `default` and `destructive` variants
107
107
  - `alert-dialog`
108
108
  - Exports: `AlertDialog`, `AlertDialogAction`, `AlertDialogCancel`, `AlertDialogContent`, `AlertDialogDescription`, `AlertDialogFooter`, `AlertDialogHeader`, `AlertDialogMedia`, `AlertDialogOverlay`, `AlertDialogPortal`, `AlertDialogTitle`, `AlertDialogTrigger`
109
- - Notes: confirmation dialog composition
109
+ - Notes: confirmation dialog composition. `AlertDialogContent.overlayProps?: AlertDialogOverlayProps` forwards props to the overlay it renders. `AlertDialogOverlay.forceRender` defaults to `true`, so an alert dialog opened inside a `Dialog`/`Drawer` keeps its own overlay; pass `forceRender={false}` (directly or via `overlayProps`) to skip it
110
110
  - `badge`
111
111
  - Exports: `Badge`, `badgeVariants`
112
112
  - Notes: pill-shaped tag with `size: 'xs' | 'sm' | 'md' | 'lg' | 'xl'` (default `md`), `solid`/`secondary`/`outline`/`subtle` variants, `color: UIColor` (`primary` default), and `asChild`
@@ -204,13 +204,13 @@ Unless noted otherwise, each module also exports its public `*Props` types from
204
204
 
205
205
  - `dialog`
206
206
  - Exports: `Dialog`, `DialogBody`, `DialogClose`, `DialogContent`, `DialogDescription`, `DialogFooter`, `DialogHeader`, `DialogOverlay`, `DialogPortal`, `DialogTitle`, `DialogTrigger`
207
- - Notes: `Dialog` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `full` occupies the entire viewport. `DialogContent` caps its height at `calc(100dvh - 2rem)` and lays out children as a flex column. For long content, wrap the middle in `DialogBody` (`flex-1 overflow-y-auto`) so the body scrolls while `DialogHeader` and `DialogFooter` remain pinned; for short content, omit `DialogBody`. `DialogContent.showCloseButton` defaults to `true`; `DialogFooter.showCloseButton` defaults to `false`. `Dialog.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DialogClose` still work). `DialogOverlay` and `DialogContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree
207
+ - Notes: `Dialog` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `full` occupies the entire viewport. `DialogContent` caps its height at `calc(100dvh - 2rem)` and lays out children as a flex column. For long content, wrap the middle in `DialogBody` (`flex-1 overflow-y-auto`) so the body scrolls while `DialogHeader` and `DialogFooter` remain pinned; for short content, omit `DialogBody`. `DialogContent.showCloseButton` defaults to `true`; `DialogFooter.showCloseButton` defaults to `false`. `Dialog.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DialogClose` still work). `DialogOverlay` and `DialogContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree. `DialogContent.overlayProps?: DialogOverlayProps` forwards props to the overlay it renders (`overlayRef` still works and takes precedence over `overlayProps.ref`). `DialogOverlay.forceRender` defaults to `true`, so a dialog opened inside another `Dialog`/`Drawer`/`AlertDialog` keeps its own overlay; pass `forceRender={false}` (directly or via `overlayProps`) to skip it
208
208
  - `direction`
209
209
  - Exports: `DirectionProvider`, `useDirection`, types `DirectionProviderProps`, `TextDirection`
210
210
  - Notes: `DirectionProvider.direction: 'ltr' | 'rtl'` (default `'ltr'`) sets the text direction for keyboard navigation (`Tabs`, `ToggleGroup`, `RadioGroup`, `DropdownMenu`), `Slider`, `ScrollArea`, `Select`, `NavigationMenu`, `Combobox` and popup positioning. A `dir` prop/attribute on those components does not change their behavior; wrap the RTL subtree (or the app) in `DirectionProvider` and also set `dir` on the HTML for text layout. `useDirection()` reads the current direction
211
211
  - `drawer`
212
212
  - Exports: `Drawer`, `DrawerBody`, `DrawerClose`, `DrawerContent`, `DrawerDescription`, `DrawerFooter`, `DrawerHeader`, `DrawerOverlay`, `DrawerPortal`, `DrawerTitle`, `DrawerTrigger`
213
- - Notes: `Drawer` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `DrawerBody` provides padded auto-scroll content; `DrawerFooter` stacks actions on mobile and aligns them to the end on larger breakpoints; `DrawerContent.showCloseButton` controls the automatic close button and defaults to `true`. `Drawer.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DrawerClose` still work). `Drawer.direction: 'top' | 'right' | 'bottom' | 'left'` (default: `right`) controls which edge the drawer slides in from. `DrawerOverlay` and `DrawerContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree
213
+ - Notes: `Drawer` supports `size: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'` with default `md`; `DrawerBody` provides padded auto-scroll content; `DrawerFooter` stacks actions on mobile and aligns them to the end on larger breakpoints; `DrawerContent.showCloseButton` controls the automatic close button and defaults to `true`. `Drawer.dismissible` defaults to `true`; set it to `false` to prevent closing via outside click and Esc (the close button and `DrawerClose` still work). `Drawer.direction: 'top' | 'right' | 'bottom' | 'left'` (default: `right`) controls which edge the drawer slides in from. `DrawerOverlay` and `DrawerContent` stop `click`/`submit` propagation to ancestor elements by default, since portals move them elsewhere in the DOM but React still propagates their synthetic events through the component tree. `DrawerContent.overlayProps?: DrawerOverlayProps` forwards props to the overlay it renders. `DrawerOverlay.forceRender` defaults to `true`, so a drawer opened inside another `Drawer`/`Dialog` keeps its own overlay; pass `forceRender={false}` (directly or via `overlayProps`) to skip it
214
214
  - `popover`
215
215
  - Exports: `Popover`, `PopoverClose`, `PopoverContent`, `PopoverDescription`, `PopoverHeader`, `PopoverTitle`, `PopoverTrigger`
216
216
  - Notes: `PopoverContent` accepts `side`, `sideOffset`, `align`, `alignOffset`, and `anchor` (element, ref, or virtual element) to position against something other than the trigger; there is no `PopoverAnchor` component. `Popover.modal: boolean | 'trap-focus'` (default `false`) traps focus only when a `PopoverClose` (supports `asChild`) is rendered inside `PopoverContent`; without it, `modal` still blocks outside clicks and page scroll but `Tab` leaves the popup. Hide the close with `className="sr-only"` when there is no visible close button