@uselets/ui 1.20.3 → 1.20.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.
Files changed (196) hide show
  1. package/README.md +14 -0
  2. package/dist/cli/uselets.mjs +3 -3
  3. package/dist/cli/uselets.mjs.map +1 -1
  4. package/dist/components/accordion.js +1 -1
  5. package/dist/components/accordion.js.map +1 -1
  6. package/dist/components/alert-dialog.js +1 -1
  7. package/dist/components/alert-dialog.js.map +1 -1
  8. package/dist/components/alert.js +1 -1
  9. package/dist/components/alert.js.map +1 -1
  10. package/dist/components/anchor.js +1 -1
  11. package/dist/components/anchor.js.map +1 -1
  12. package/dist/components/area-chart.js +1 -1
  13. package/dist/components/area-chart.js.map +1 -1
  14. package/dist/components/avatar.js +1 -1
  15. package/dist/components/avatar.js.map +1 -1
  16. package/dist/components/badge.js +1 -1
  17. package/dist/components/badge.js.map +1 -1
  18. package/dist/components/bar-chart.js +1 -1
  19. package/dist/components/bar-chart.js.map +1 -1
  20. package/dist/components/bottom-nav.js +1 -1
  21. package/dist/components/bottom-nav.js.map +1 -1
  22. package/dist/components/breadcrumb.js +1 -1
  23. package/dist/components/breadcrumb.js.map +1 -1
  24. package/dist/components/button-group.js +1 -1
  25. package/dist/components/button-group.js.map +1 -1
  26. package/dist/components/button.js +1 -1
  27. package/dist/components/button.js.map +1 -1
  28. package/dist/components/calendar.js +1 -1
  29. package/dist/components/calendar.js.map +1 -1
  30. package/dist/components/card.js +1 -1
  31. package/dist/components/card.js.map +1 -1
  32. package/dist/components/carousel.js +1 -1
  33. package/dist/components/carousel.js.map +1 -1
  34. package/dist/components/center.js +1 -1
  35. package/dist/components/center.js.map +1 -1
  36. package/dist/components/chart.js +2 -2
  37. package/dist/components/chart.js.map +1 -1
  38. package/dist/components/checkbox.js +1 -1
  39. package/dist/components/checkbox.js.map +1 -1
  40. package/dist/components/code.js +1 -1
  41. package/dist/components/code.js.map +1 -1
  42. package/dist/components/collapsible.js +1 -1
  43. package/dist/components/collapsible.js.map +1 -1
  44. package/dist/components/combobox.js +1 -1
  45. package/dist/components/combobox.js.map +1 -1
  46. package/dist/components/command.js +1 -1
  47. package/dist/components/command.js.map +1 -1
  48. package/dist/components/container.js +1 -1
  49. package/dist/components/container.js.map +1 -1
  50. package/dist/components/data-table.d.ts +138 -2
  51. package/dist/components/data-table.js +1 -1
  52. package/dist/components/data-table.js.map +1 -1
  53. package/dist/components/date-range-picker.js +1 -1
  54. package/dist/components/date-range-picker.js.map +1 -1
  55. package/dist/components/dialog.js +1 -1
  56. package/dist/components/dialog.js.map +1 -1
  57. package/dist/components/donut-chart.js +1 -1
  58. package/dist/components/donut-chart.js.map +1 -1
  59. package/dist/components/drawer.js +1 -1
  60. package/dist/components/drawer.js.map +1 -1
  61. package/dist/components/dropdown-menu.js +1 -1
  62. package/dist/components/dropdown-menu.js.map +1 -1
  63. package/dist/components/dropzone.js +1 -1
  64. package/dist/components/dropzone.js.map +1 -1
  65. package/dist/components/empty.js +1 -1
  66. package/dist/components/empty.js.map +1 -1
  67. package/dist/components/field.js +1 -1
  68. package/dist/components/field.js.map +1 -1
  69. package/dist/components/flex.js +1 -1
  70. package/dist/components/flex.js.map +1 -1
  71. package/dist/components/grid.js +1 -1
  72. package/dist/components/grid.js.map +1 -1
  73. package/dist/components/group.js +1 -1
  74. package/dist/components/group.js.map +1 -1
  75. package/dist/components/heading.js +1 -1
  76. package/dist/components/heading.js.map +1 -1
  77. package/dist/components/hover-card.js +1 -1
  78. package/dist/components/hover-card.js.map +1 -1
  79. package/dist/components/input-group.js +1 -1
  80. package/dist/components/input-group.js.map +1 -1
  81. package/dist/components/input-otp.js +1 -1
  82. package/dist/components/input-otp.js.map +1 -1
  83. package/dist/components/input.js +1 -1
  84. package/dist/components/input.js.map +1 -1
  85. package/dist/components/kbd.js +1 -1
  86. package/dist/components/kbd.js.map +1 -1
  87. package/dist/components/label.js +1 -1
  88. package/dist/components/label.js.map +1 -1
  89. package/dist/components/list.js +1 -1
  90. package/dist/components/list.js.map +1 -1
  91. package/dist/components/logo.js +1 -1
  92. package/dist/components/marker.js +1 -1
  93. package/dist/components/marker.js.map +1 -1
  94. package/dist/components/mask-input.js +1 -1
  95. package/dist/components/mask-input.js.map +1 -1
  96. package/dist/components/native-select.js +1 -1
  97. package/dist/components/native-select.js.map +1 -1
  98. package/dist/components/navigation-menu.js +1 -1
  99. package/dist/components/navigation-menu.js.map +1 -1
  100. package/dist/components/number-field.js +1 -1
  101. package/dist/components/number-field.js.map +1 -1
  102. package/dist/components/pagination.js +1 -1
  103. package/dist/components/pagination.js.map +1 -1
  104. package/dist/components/phone-input.d.ts +3 -0
  105. package/dist/components/phone-input.js +1 -1
  106. package/dist/components/phone-input.js.map +1 -1
  107. package/dist/components/pie-chart.js +1 -1
  108. package/dist/components/pie-chart.js.map +1 -1
  109. package/dist/components/popover.js +1 -1
  110. package/dist/components/popover.js.map +1 -1
  111. package/dist/components/progress.js +1 -1
  112. package/dist/components/progress.js.map +1 -1
  113. package/dist/components/radio-group.js +1 -1
  114. package/dist/components/radio-group.js.map +1 -1
  115. package/dist/components/resizable.js +1 -1
  116. package/dist/components/resizable.js.map +1 -1
  117. package/dist/components/ring-progress.js +1 -1
  118. package/dist/components/ring-progress.js.map +1 -1
  119. package/dist/components/scroll-area.js +1 -1
  120. package/dist/components/scroll-area.js.map +1 -1
  121. package/dist/components/select.js +1 -1
  122. package/dist/components/select.js.map +1 -1
  123. package/dist/components/separator.js +1 -1
  124. package/dist/components/separator.js.map +1 -1
  125. package/dist/components/sidebar.js +1 -1
  126. package/dist/components/sidebar.js.map +1 -1
  127. package/dist/components/simple-grid.js +1 -1
  128. package/dist/components/simple-grid.js.map +1 -1
  129. package/dist/components/skeleton.js +1 -1
  130. package/dist/components/skeleton.js.map +1 -1
  131. package/dist/components/slider.js +1 -1
  132. package/dist/components/slider.js.map +1 -1
  133. package/dist/components/sonner.js +1 -1
  134. package/dist/components/sonner.js.map +1 -1
  135. package/dist/components/spinner.js +1 -1
  136. package/dist/components/spinner.js.map +1 -1
  137. package/dist/components/stack.js +1 -1
  138. package/dist/components/stack.js.map +1 -1
  139. package/dist/components/stepper.js +1 -1
  140. package/dist/components/stepper.js.map +1 -1
  141. package/dist/components/switch.js +1 -1
  142. package/dist/components/switch.js.map +1 -1
  143. package/dist/components/table.js +1 -1
  144. package/dist/components/table.js.map +1 -1
  145. package/dist/components/tabs.js +1 -1
  146. package/dist/components/tabs.js.map +1 -1
  147. package/dist/components/text.js +1 -1
  148. package/dist/components/text.js.map +1 -1
  149. package/dist/components/textarea.js +1 -1
  150. package/dist/components/textarea.js.map +1 -1
  151. package/dist/components/theme.js +1 -1
  152. package/dist/components/theme.js.map +1 -1
  153. package/dist/components/timeline.js +1 -1
  154. package/dist/components/timeline.js.map +1 -1
  155. package/dist/components/toggle-group.js +1 -1
  156. package/dist/components/toggle-group.js.map +1 -1
  157. package/dist/components/toggle.js +1 -1
  158. package/dist/components/toggle.js.map +1 -1
  159. package/dist/components/tooltip.js +1 -1
  160. package/dist/components/tooltip.js.map +1 -1
  161. package/dist/components/unstyled-button.js +1 -1
  162. package/dist/components/unstyled-button.js.map +1 -1
  163. package/dist/components/visibility.js +1 -1
  164. package/dist/components/visibility.js.map +1 -1
  165. package/dist/hooks/use-breakpoint-value.js.map +1 -1
  166. package/dist/hooks/use-breakpoint.js.map +1 -1
  167. package/dist/hooks/use-disclosure.js.map +1 -1
  168. package/dist/hooks/use-document-visibility.js.map +1 -1
  169. package/dist/hooks/use-hotkeys.js +1 -1
  170. package/dist/hooks/use-idle.js.map +1 -1
  171. package/dist/hooks/use-interval.js.map +1 -1
  172. package/dist/hooks/use-local-storage.js +1 -1
  173. package/dist/hooks/use-local-storage.js.map +1 -1
  174. package/dist/hooks/use-mask.js.map +1 -1
  175. package/dist/hooks/use-mobile.js.map +1 -1
  176. package/dist/index.d.ts +3 -3
  177. package/dist/index.js +1 -1
  178. package/dist/lib/badge.js.map +1 -1
  179. package/dist/lib/button.js.map +1 -1
  180. package/dist/lib/color.js.map +1 -1
  181. package/dist/lib/compose-refs.js +1 -1
  182. package/dist/lib/compose-refs.js.map +1 -1
  183. package/dist/lib/progress.js.map +1 -1
  184. package/dist/lib/utils.js.map +1 -1
  185. package/dist/logo--R3_XDgA.js +2 -0
  186. package/dist/logo--R3_XDgA.js.map +1 -0
  187. package/dist/postcss.config.js.map +1 -1
  188. package/dist/skills/uselets-ui/SKILL.md +1 -0
  189. package/dist/skills/uselets-ui/references/package-guide.md +16 -0
  190. package/dist/use-hotkeys-YDJmGWX6.js.map +1 -1
  191. package/package.json +12 -12
  192. package/skills/uselets-ui/SKILL.md +1 -0
  193. package/skills/uselets-ui/references/package-guide.md +16 -0
  194. package/dist/data-table-DWWVGWbU.d.ts +0 -4184
  195. package/dist/logo-B0thHtTS.js +0 -2
  196. package/dist/logo-B0thHtTS.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"postcss.config.js","names":[],"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,MAAM,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"}
@@ -53,6 +53,7 @@ To set up a consumer project after installing `@uselets/ui`, run `bun uselets in
53
53
  app's entry file (`import '@fontsource-variable/inter'` in `app/layout.tsx`, `pages/_app.tsx`, or `src/main.tsx`),
54
54
  not via `@import` in CSS — some bundlers, including Next.js, don't resolve third-party CSS `@import`s reliably.
55
55
  - Recommend `@uselets/ui/postcss.config` when the app needs the package PostCSS preset for Tailwind v4.
56
+ - For Vite apps, `@tailwindcss/vite` (registered in `vite.config.ts`, no `postcss.config.mjs`) is a valid alternative to PostCSS; prefer it when the project uses isolated installs (pnpm, Bun workspaces). See `references/package-guide.md`.
56
57
  - For tooltip-heavy apps, wrap the app with `TooltipProvider`; use `Tooltip label={...}` for common trigger/content usage and `TooltipRoot` only when manual composition is needed.
57
58
  - Use `UnstyledButton` when button semantics are needed without `Button` variants; it provides reset styles, pointer cursor, focus ring, default `type="button"`, and `asChild`.
58
59
  - For toast usage, mount `Toaster` near the app root before calling `toast(...)`.
@@ -121,6 +121,22 @@ If the app needs Tailwind v4 PostCSS setup, reuse the package preset:
121
121
  export { default } from '@uselets/ui/postcss.config'
122
122
  ```
123
123
 
124
+ Vite apps may use `@tailwindcss/vite` instead of PostCSS (use one integration, never both):
125
+
126
+ - Install `tailwindcss` and `@tailwindcss/vite`; register `tailwindcss()` in `plugins` of `vite.config.ts`; do not create `postcss.config.mjs`.
127
+ - Prefer `@tailwindcss/vite` when the project uses isolated installs (pnpm, Bun workspaces). With `@tailwindcss/postcss` under Vite plus isolated installs, the build fails with `Can't resolve 'tailwind-scrollbar'` because the theme's `@plugin` is resolved from the app's stylesheet. Fix by switching to `@tailwindcss/vite` (or adding `tailwind-scrollbar` to the app's dependencies).
128
+ - Non-Vite bundlers (for example Next.js) keep `@tailwindcss/postcss` with `@uselets/ui/postcss.config`.
129
+
130
+ ```ts
131
+ // vite.config.ts
132
+ import tailwindcss from '@tailwindcss/vite'
133
+ import { defineConfig } from 'vite'
134
+
135
+ export default defineConfig({
136
+ plugins: [tailwindcss()]
137
+ })
138
+ ```
139
+
124
140
  When the app uses installed `@uselets/ui` components, add a Tailwind source directive so component classes from the package are generated:
125
141
 
126
142
  ```css
@@ -1 +1 @@
1
- {"version":3,"file":"use-hotkeys-YDJmGWX6.js","names":[],"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\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":"6FAcA,MAAM,EAAqC,CACzC,IAAK,QACL,UAAW,YACX,WAAY,aACZ,QAAS,UACT,UAAW,YACX,OAAQ,SACR,IAAK,SACL,IAAK,SACL,MAAO,QACP,IAAK,MACL,UAAW,YACX,OAAQ,SACR,OAAQ,SACR,KAAM,OACN,IAAK,MACL,OAAQ,SACR,SAAU,WACV,IAAK,OACL,IAAK,QACL,IAAK,WACL,IAAK,OACP,EAEA,SAAS,aAAa,EAAqB,CACzC,IAAM,EAAW,EAAI,QAAQ,MAAO,EAAE,CAAC,CAAC,YAAY,EACpD,OAAO,EAAW,IAAQ,CAC5B,CAEA,SAAgB,YAAY,EAAwB,CAClD,IAAM,EAAO,EACV,YAAY,CAAC,CACb,MAAM,GAAG,CAAC,CACV,IAAK,GAAS,EAAK,KAAK,CAAC,EAEtB,EAA+B,CACnC,IAAK,EAAK,SAAS,KAAK,EACxB,KAAM,EAAK,SAAS,MAAM,EAC1B,KAAM,EAAK,SAAS,MAAM,EAC1B,IAAK,EAAK,SAAS,KAAK,EACxB,MAAO,EAAK,SAAS,OAAO,CAC9B,EAEM,EAAe,CAAC,MAAO,OAAQ,OAAQ,QAAS,KAAK,EAErD,EAAU,EAAK,KAAM,GAAQ,CAAC,EAAa,SAAS,CAAG,CAAC,EAE9D,MAAO,CACL,GAAG,EACH,IAAK,IAAY,SAAW,IAAM,CACpC,CACF,CAEA,SAAS,cAAc,EAAgB,EAAsB,EAAoC,CAC/F,GAAM,CAAE,MAAK,OAAM,OAAM,MAAK,QAAO,OAAQ,EACvC,CAAE,SAAQ,UAAS,UAAS,WAAU,IAAK,EAAY,KAAM,GAAgB,EAEnF,GAAI,IAAQ,EACV,MAAO,GAGT,GAAI,EACE,IAAA,CAAC,GAAW,CAAC,EACf,MAAO,EAAA,MAMT,GAHI,IAAS,GAGT,IAAS,EACX,MAAO,GAgBX,OAbI,IAAU,GAId,GACE,IACC,EACG,aAAa,CAAW,IAAM,aAAa,CAAG,EAC9C,aAAa,GAAc,CAAW,IAAM,aAAa,CAAG,GAMpE,CAEA,SAAgB,iBAAiB,EAAgB,EAA6C,CAC5F,MAAQ,IAAU,cAAc,YAAY,CAAM,EAAG,EAAO,CAAe,CAC7E,CASA,SAAgB,iBAAiB,EAAuB,CACtD,MAAQ,IAA4D,CAClE,IAAM,EAAS,gBAAiB,EAAQ,EAAM,YAAc,EAC5D,EAAQ,SAAS,CAAC,EAAQ,EAAS,EAAU,CAAE,eAAgB,GAAM,gBAAiB,EAAM,KAAO,CAC7F,iBAAiB,EAAQ,EAAQ,eAAe,CAAC,CAAC,CAAM,IACtD,EAAQ,gBACV,EAAM,eAAe,EAGvB,EAAQ,CAAM,EAElB,CAAC,CACH,CACF,CCtHA,SAAS,gBAAgB,EAAsB,EAAwB,EAA2B,GAAO,CASvG,OARI,EAAM,kBAAkB,aACtB,GAIG,CAAC,EAAM,OAAO,oBAHZ,CAAC,EAAa,SAAS,EAAM,OAAO,OAAO,EAM/C,EACT,CAEA,SAAgB,WACd,EACA,EAAyB,CAAC,QAAS,WAAY,QAAQ,EACvD,EAA2B,GAC3B,CACA,IAAM,EAAgB,EAAgB,GAAyB,CAC7D,EAAQ,SAAS,CAAC,EAAQ,EAAS,EAAU,CAAE,eAAgB,GAAM,gBAAiB,EAAM,KAAO,CAE/F,iBAAiB,EAAQ,EAAQ,eAAe,CAAC,CAAC,CAAK,GACvD,gBAAgB,EAAO,EAAc,CAAwB,IAEzD,EAAQ,gBACV,EAAM,eAAe,EAGvB,EAAQ,CAAK,EAEjB,CAAC,CACH,CAAC,EAED,OACE,SAAS,gBAAgB,iBAAiB,UAAW,CAAa,MACrD,SAAS,gBAAgB,oBAAoB,UAAW,CAAa,GACjF,CAAC,CAAC,CACP"}
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\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": "1.20.3",
3
+ "version": "1.20.4",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -63,8 +63,8 @@
63
63
  "@base-ui/react": "1.8.0",
64
64
  "@fontsource-variable/inter": "^5.3.0",
65
65
  "@react-input/mask": "2.0.4",
66
- "@tabler/icons-react": "^3.48.0",
67
- "@tanstack/react-table": "9.2.4",
66
+ "@tabler/icons-react": "^3.49.0",
67
+ "@tanstack/react-table": "9.2.6",
68
68
  "@uselets/tokens": "0.2.0",
69
69
  "class-variance-authority": "^0.7.1",
70
70
  "cmdk": "1.1.1",
@@ -74,13 +74,13 @@
74
74
  "embla-carousel-react": "^8.6.0",
75
75
  "input-otp": "1.5.0",
76
76
  "next-themes": "0.4.6",
77
- "radix-ui": "1.6.7",
78
- "react-day-picker": "10.0.1",
77
+ "radix-ui": "1.7.0",
78
+ "react-day-picker": "10.0.2",
79
79
  "react-dropzone": "20.1.2",
80
80
  "react-phone-number-input": "^3.4.18",
81
- "react-resizable-panels": "4.13.2",
81
+ "react-resizable-panels": "4.14.2",
82
82
  "recharts": "^3.10.1",
83
- "shadcn": "4.21.0",
83
+ "shadcn": "4.21.3",
84
84
  "sonner": "2.0.8"
85
85
  },
86
86
  "peerDependencies": {
@@ -91,16 +91,16 @@
91
91
  "@bosh-code/tsdown-plugin-tailwindcss": "1.0.1",
92
92
  "@tailwindcss/postcss": "4.3.3",
93
93
  "@testing-library/react": "16.3.3",
94
- "@vitest/coverage-v8": "5.0.1",
94
+ "@vitest/coverage-v8": "5.0.3",
95
95
  "@tsdown/css": "0.23.0",
96
- "@turbo/gen": "2.11.3",
97
- "@types/node": "26.6.2",
96
+ "@turbo/gen": "2.11.7",
97
+ "@types/node": "26.6.4",
98
98
  "@types/react": "19.3.0",
99
99
  "@types/react-dom": "19.3.0",
100
- "jsdom": "30.1.1",
100
+ "jsdom": "30.1.2",
101
101
  "tailwindcss": "4.3.3",
102
102
  "tsdown": "0.23.0",
103
103
  "typescript": "7.0.2",
104
- "vitest": "5.0.1"
104
+ "vitest": "5.0.3"
105
105
  }
106
106
  }
@@ -53,6 +53,7 @@ To set up a consumer project after installing `@uselets/ui`, run `bun uselets in
53
53
  app's entry file (`import '@fontsource-variable/inter'` in `app/layout.tsx`, `pages/_app.tsx`, or `src/main.tsx`),
54
54
  not via `@import` in CSS — some bundlers, including Next.js, don't resolve third-party CSS `@import`s reliably.
55
55
  - Recommend `@uselets/ui/postcss.config` when the app needs the package PostCSS preset for Tailwind v4.
56
+ - For Vite apps, `@tailwindcss/vite` (registered in `vite.config.ts`, no `postcss.config.mjs`) is a valid alternative to PostCSS; prefer it when the project uses isolated installs (pnpm, Bun workspaces). See `references/package-guide.md`.
56
57
  - For tooltip-heavy apps, wrap the app with `TooltipProvider`; use `Tooltip label={...}` for common trigger/content usage and `TooltipRoot` only when manual composition is needed.
57
58
  - Use `UnstyledButton` when button semantics are needed without `Button` variants; it provides reset styles, pointer cursor, focus ring, default `type="button"`, and `asChild`.
58
59
  - For toast usage, mount `Toaster` near the app root before calling `toast(...)`.
@@ -121,6 +121,22 @@ If the app needs Tailwind v4 PostCSS setup, reuse the package preset:
121
121
  export { default } from '@uselets/ui/postcss.config'
122
122
  ```
123
123
 
124
+ Vite apps may use `@tailwindcss/vite` instead of PostCSS (use one integration, never both):
125
+
126
+ - Install `tailwindcss` and `@tailwindcss/vite`; register `tailwindcss()` in `plugins` of `vite.config.ts`; do not create `postcss.config.mjs`.
127
+ - Prefer `@tailwindcss/vite` when the project uses isolated installs (pnpm, Bun workspaces). With `@tailwindcss/postcss` under Vite plus isolated installs, the build fails with `Can't resolve 'tailwind-scrollbar'` because the theme's `@plugin` is resolved from the app's stylesheet. Fix by switching to `@tailwindcss/vite` (or adding `tailwind-scrollbar` to the app's dependencies).
128
+ - Non-Vite bundlers (for example Next.js) keep `@tailwindcss/postcss` with `@uselets/ui/postcss.config`.
129
+
130
+ ```ts
131
+ // vite.config.ts
132
+ import tailwindcss from '@tailwindcss/vite'
133
+ import { defineConfig } from 'vite'
134
+
135
+ export default defineConfig({
136
+ plugins: [tailwindcss()]
137
+ })
138
+ ```
139
+
124
140
  When the app uses installed `@uselets/ui` components, add a Tailwind source directive so component classes from the package are generated:
125
141
 
126
142
  ```css