@g4rcez/components 3.0.0 → 3.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 (303) hide show
  1. package/dist/MotionConfigContext-C7MqlSdv.js +2713 -0
  2. package/dist/MotionConfigContext-C7MqlSdv.js.map +1 -0
  3. package/dist/ai/SKILL.md +266 -0
  4. package/dist/ai/docs/Alert.md +167 -0
  5. package/dist/ai/docs/AnimatedList.md +205 -0
  6. package/dist/ai/docs/Autocomplete.md +225 -0
  7. package/dist/ai/docs/Button.md +182 -0
  8. package/dist/ai/docs/Calendar.md +219 -0
  9. package/dist/ai/docs/Card.md +174 -0
  10. package/dist/ai/docs/Checkbox.md +199 -0
  11. package/dist/ai/docs/CommandPalette.md +293 -0
  12. package/dist/ai/docs/DatePicker.md +171 -0
  13. package/dist/ai/docs/Dropdown.md +223 -0
  14. package/dist/ai/docs/Empty.md +163 -0
  15. package/dist/ai/docs/Expand.md +143 -0
  16. package/dist/ai/docs/FileUpload.md +225 -0
  17. package/dist/ai/docs/Form.md +107 -0
  18. package/dist/ai/docs/FormReset.md +117 -0
  19. package/dist/ai/docs/Heading.md +88 -0
  20. package/dist/ai/docs/Input.md +237 -0
  21. package/dist/ai/docs/InputField.md +170 -0
  22. package/dist/ai/docs/List.md +205 -0
  23. package/dist/ai/docs/Menu.md +166 -0
  24. package/dist/ai/docs/Modal.md +280 -0
  25. package/dist/ai/docs/MultiSelect.md +196 -0
  26. package/dist/ai/docs/Notifications.md +231 -0
  27. package/dist/ai/docs/PageCalendar.md +271 -0
  28. package/dist/ai/docs/Polymorph.md +159 -0
  29. package/dist/ai/docs/Progress.md +145 -0
  30. package/dist/ai/docs/Radiobox.md +128 -0
  31. package/dist/ai/docs/RenderOnView.md +138 -0
  32. package/dist/ai/docs/Resizable.md +159 -0
  33. package/dist/ai/docs/Select.md +284 -0
  34. package/dist/ai/docs/Shortcut.md +105 -0
  35. package/dist/ai/docs/Skeleton.md +166 -0
  36. package/dist/ai/docs/Slider.md +144 -0
  37. package/dist/ai/docs/Slot.md +173 -0
  38. package/dist/ai/docs/Spinner.md +118 -0
  39. package/dist/ai/docs/Stats.md +137 -0
  40. package/dist/ai/docs/Step.md +159 -0
  41. package/dist/ai/docs/Switch.md +167 -0
  42. package/dist/ai/docs/Table.md +298 -0
  43. package/dist/ai/docs/Tabs.md +191 -0
  44. package/dist/ai/docs/Tag.md +224 -0
  45. package/dist/ai/docs/TaskList.md +144 -0
  46. package/dist/ai/docs/Textarea.md +167 -0
  47. package/dist/ai/docs/Timeline.md +210 -0
  48. package/dist/ai/docs/Toolbar.md +132 -0
  49. package/dist/ai/docs/Tooltip.md +231 -0
  50. package/dist/ai/docs/TransferList.md +142 -0
  51. package/dist/ai/docs/Typography.md +187 -0
  52. package/dist/ai/docs/Wizard.md +213 -0
  53. package/dist/ai/docs/index.md +183 -0
  54. package/dist/autocomplete-Boida9R7.js +375 -0
  55. package/dist/autocomplete-Boida9R7.js.map +1 -0
  56. package/dist/calendar-BswV66Nx.js +1719 -0
  57. package/dist/calendar-BswV66Nx.js.map +1 -0
  58. package/dist/chevron-down-BBFYYzZq.js +6 -0
  59. package/dist/chevron-down-BBFYYzZq.js.map +1 -0
  60. package/dist/chevron-right-DvXGOiS_.js +6 -0
  61. package/dist/chevron-right-DvXGOiS_.js.map +1 -0
  62. package/dist/circle-check-big-3M5lhTxx.js +9 -0
  63. package/dist/circle-check-big-3M5lhTxx.js.map +1 -0
  64. package/dist/components/core/button.js +76 -0
  65. package/dist/components/core/button.js.map +1 -0
  66. package/dist/components/core/tag.d.ts +1 -1
  67. package/dist/components/core/tag.d.ts.map +1 -1
  68. package/dist/components/core/tag.js +67 -0
  69. package/dist/components/core/tag.js.map +1 -0
  70. package/dist/components/display/alert.js +94 -0
  71. package/dist/components/display/alert.js.map +1 -0
  72. package/dist/components/display/calendar.js +15 -0
  73. package/dist/components/display/calendar.js.map +1 -0
  74. package/dist/components/display/card.js +84 -0
  75. package/dist/components/display/card.js.map +1 -0
  76. package/dist/components/display/list.d.ts.map +1 -1
  77. package/dist/components/display/list.js +93 -0
  78. package/dist/components/display/list.js.map +1 -0
  79. package/dist/components/display/notifications.js +15 -0
  80. package/dist/components/display/notifications.js.map +1 -0
  81. package/dist/components/display/stats.js +16 -0
  82. package/dist/components/display/stats.js.map +1 -0
  83. package/dist/components/display/tabs.js +12 -0
  84. package/dist/components/display/tabs.js.map +1 -0
  85. package/dist/components/display/timeline.js +29 -0
  86. package/dist/components/display/timeline.js.map +1 -0
  87. package/dist/components/floating/dropdown.d.ts +1 -0
  88. package/dist/components/floating/dropdown.d.ts.map +1 -1
  89. package/dist/components/floating/dropdown.js +58 -0
  90. package/dist/components/floating/dropdown.js.map +1 -0
  91. package/dist/components/floating/expand.js +41 -0
  92. package/dist/components/floating/expand.js.map +1 -0
  93. package/dist/components/floating/menu.d.ts.map +1 -1
  94. package/dist/components/floating/menu.js +177 -0
  95. package/dist/components/floating/menu.js.map +1 -0
  96. package/dist/components/floating/modal.js +297 -0
  97. package/dist/components/floating/modal.js.map +1 -0
  98. package/dist/components/floating/tooltip.js +73 -0
  99. package/dist/components/floating/tooltip.js.map +1 -0
  100. package/dist/components/form/autocomplete.js +16 -0
  101. package/dist/components/form/autocomplete.js.map +1 -0
  102. package/dist/components/form/checkbox.js +44 -0
  103. package/dist/components/form/checkbox.js.map +1 -0
  104. package/dist/components/form/date-picker.js +12 -0
  105. package/dist/components/form/date-picker.js.map +1 -0
  106. package/dist/components/form/file-upload.js +11 -0
  107. package/dist/components/form/file-upload.js.map +1 -0
  108. package/dist/components/form/form.js +8 -0
  109. package/dist/components/form/form.js.map +1 -0
  110. package/dist/components/form/input.js +5 -0
  111. package/dist/components/form/input.js.map +1 -0
  112. package/dist/components/form/radiobox.js +30 -0
  113. package/dist/components/form/radiobox.js.map +1 -0
  114. package/dist/components/form/select.js +106 -0
  115. package/dist/components/form/select.js.map +1 -0
  116. package/dist/components/form/switch.js +65 -0
  117. package/dist/components/form/switch.js.map +1 -0
  118. package/dist/components/form/task-list.js +68 -0
  119. package/dist/components/form/task-list.js.map +1 -0
  120. package/dist/components/form/transfer-list.js +55 -0
  121. package/dist/components/form/transfer-list.js.map +1 -0
  122. package/dist/components/table/table.js +10 -0
  123. package/dist/components/table/table.js.map +1 -0
  124. package/dist/config/default-translations.d.ts +4 -4
  125. package/dist/constants-r-AHn273.js +6 -0
  126. package/dist/constants-r-AHn273.js.map +1 -0
  127. package/dist/context-BFXNJVn2.js +161 -0
  128. package/dist/context-BFXNJVn2.js.map +1 -0
  129. package/dist/createLucideIcon-CP-mMPfa.js +76 -0
  130. package/dist/createLucideIcon-CP-mMPfa.js.map +1 -0
  131. package/dist/date-picker-BxPTdZPy.js +1598 -0
  132. package/dist/date-picker-BxPTdZPy.js.map +1 -0
  133. package/dist/dom-Dl8XH0CK.js +2833 -0
  134. package/dist/dom-Dl8XH0CK.js.map +1 -0
  135. package/dist/file-CBCP85VI.js +15 -0
  136. package/dist/file-CBCP85VI.js.map +1 -0
  137. package/dist/file-upload-BB6BdGcE.js +3118 -0
  138. package/dist/file-upload-BB6BdGcE.js.map +1 -0
  139. package/dist/floating-ui.react-DycKASR0.js +3706 -0
  140. package/dist/floating-ui.react-DycKASR0.js.map +1 -0
  141. package/dist/fns-D2eyJKd5.js +33 -0
  142. package/dist/fns-D2eyJKd5.js.map +1 -0
  143. package/dist/hooks/use-translations.d.ts +4 -4
  144. package/dist/hooks/use-translations.d.ts.map +1 -1
  145. package/dist/index-0YMC-_Lt.js +20 -0
  146. package/dist/index-0YMC-_Lt.js.map +1 -0
  147. package/dist/index-BJ1ayTam.js +126 -0
  148. package/dist/index-BJ1ayTam.js.map +1 -0
  149. package/dist/index-BtlhELJ3.js +3416 -0
  150. package/dist/index-BtlhELJ3.js.map +1 -0
  151. package/dist/index-ChfR6F8d.js +1590 -0
  152. package/dist/index-ChfR6F8d.js.map +1 -0
  153. package/dist/index-DE4shK8D.js +215 -0
  154. package/dist/index-DE4shK8D.js.map +1 -0
  155. package/dist/index-DJSMaZR4.js +35 -0
  156. package/dist/index-DJSMaZR4.js.map +1 -0
  157. package/dist/index-t1qLJTt5.js +351 -0
  158. package/dist/index-t1qLJTt5.js.map +1 -0
  159. package/dist/index.css +1 -1
  160. package/dist/index.esm-BaIwleSE.js +343 -0
  161. package/dist/index.esm-BaIwleSE.js.map +1 -0
  162. package/dist/index.js +8050 -20
  163. package/dist/index.js.map +1 -1
  164. package/dist/info-N5jWZg2A.js +10 -0
  165. package/dist/info-N5jWZg2A.js.map +1 -0
  166. package/dist/input-CoJoHIhd.js +441 -0
  167. package/dist/input-CoJoHIhd.js.map +1 -0
  168. package/dist/input-field-DTeIrwpK.js +146 -0
  169. package/dist/input-field-DTeIrwpK.js.map +1 -0
  170. package/dist/notifications-NPuFDsBp.js +2550 -0
  171. package/dist/notifications-NPuFDsBp.js.map +1 -0
  172. package/dist/polymorph-B5n9fs_K.js +10 -0
  173. package/dist/polymorph-B5n9fs_K.js.map +1 -0
  174. package/dist/proxy-BZcQiBrp.js +2495 -0
  175. package/dist/proxy-BZcQiBrp.js.map +1 -0
  176. package/dist/skeleton-D75GFBV6.js +10 -0
  177. package/dist/skeleton-D75GFBV6.js.map +1 -0
  178. package/dist/slot-CQW8ZzBb.js +79 -0
  179. package/dist/slot-CQW8ZzBb.js.map +1 -0
  180. package/dist/styles/common.js +3 -3
  181. package/dist/styles/dark.js +4 -4
  182. package/dist/styles/design-tokens.js +89 -60
  183. package/dist/styles/light.js +4 -4
  184. package/dist/styles/theme.js +2 -2
  185. package/dist/tabs-ccIA7vMo.js +106 -0
  186. package/dist/tabs-ccIA7vMo.js.map +1 -0
  187. package/dist/triangle-alert-CHMhQ6yd.js +16 -0
  188. package/dist/triangle-alert-CHMhQ6yd.js.map +1 -0
  189. package/dist/use-motion-value-eGwNuWuw.js +14 -0
  190. package/dist/use-motion-value-eGwNuWuw.js.map +1 -0
  191. package/dist/use-stable-ref-CYh-YkID.js +11 -0
  192. package/dist/use-stable-ref-CYh-YkID.js.map +1 -0
  193. package/dist/use-translations-BwLKTrZv.js +10 -0
  194. package/dist/use-translations-BwLKTrZv.js.map +1 -0
  195. package/dist/x-B9bYxG31.js +9 -0
  196. package/dist/x-B9bYxG31.js.map +1 -0
  197. package/package.json +6 -7
  198. package/dist/components/core/button.jsx +0 -79
  199. package/dist/components/core/heading.jsx +0 -4
  200. package/dist/components/core/polymorph.jsx +0 -5
  201. package/dist/components/core/render-on-view.jsx +0 -31
  202. package/dist/components/core/resizable.jsx +0 -51
  203. package/dist/components/core/slot.jsx +0 -156
  204. package/dist/components/core/tag.jsx +0 -51
  205. package/dist/components/core/typography.jsx +0 -22
  206. package/dist/components/display/alert.jsx +0 -58
  207. package/dist/components/display/calendar.jsx +0 -299
  208. package/dist/components/display/card.jsx +0 -43
  209. package/dist/components/display/empty.jsx +0 -11
  210. package/dist/components/display/list.jsx +0 -81
  211. package/dist/components/display/notifications.jsx +0 -126
  212. package/dist/components/display/progress.jsx +0 -11
  213. package/dist/components/display/shortcut.jsx +0 -23
  214. package/dist/components/display/skeleton.jsx +0 -12
  215. package/dist/components/display/spinner.jsx +0 -7
  216. package/dist/components/display/stats.jsx +0 -20
  217. package/dist/components/display/step.jsx +0 -131
  218. package/dist/components/display/tabs.jsx +0 -98
  219. package/dist/components/display/timeline.jsx +0 -25
  220. package/dist/components/floating/command-palette.jsx +0 -194
  221. package/dist/components/floating/dropdown.jsx +0 -53
  222. package/dist/components/floating/expand.jsx +0 -44
  223. package/dist/components/floating/menu.jsx +0 -147
  224. package/dist/components/floating/modal.jsx +0 -299
  225. package/dist/components/floating/toolbar.jsx +0 -5
  226. package/dist/components/floating/tooltip.jsx +0 -58
  227. package/dist/components/floating/wizard.jsx +0 -161
  228. package/dist/components/form/autocomplete.jsx +0 -279
  229. package/dist/components/form/checkbox.jsx +0 -12
  230. package/dist/components/form/date-picker.jsx +0 -115
  231. package/dist/components/form/file-upload.jsx +0 -133
  232. package/dist/components/form/form.jsx +0 -10
  233. package/dist/components/form/formReset.jsx +0 -17
  234. package/dist/components/form/free-text.jsx +0 -41
  235. package/dist/components/form/input-field.jsx +0 -56
  236. package/dist/components/form/input.jsx +0 -36
  237. package/dist/components/form/multi-select.jsx +0 -328
  238. package/dist/components/form/radiobox.jsx +0 -6
  239. package/dist/components/form/select.jsx +0 -42
  240. package/dist/components/form/slider.jsx +0 -45
  241. package/dist/components/form/switch.jsx +0 -46
  242. package/dist/components/form/task-list.jsx +0 -26
  243. package/dist/components/form/textarea.jsx +0 -12
  244. package/dist/components/form/transfer-list.jsx +0 -39
  245. package/dist/components/index.js +0 -45
  246. package/dist/components/page-calendar/calendar-header.jsx +0 -81
  247. package/dist/components/page-calendar/day-view.jsx +0 -87
  248. package/dist/components/page-calendar/event-pill.jsx +0 -25
  249. package/dist/components/page-calendar/index.js +0 -2
  250. package/dist/components/page-calendar/month-view.jsx +0 -47
  251. package/dist/components/page-calendar/page-calendar.jsx +0 -41
  252. package/dist/components/page-calendar/page-calendar.types.js +0 -1
  253. package/dist/components/page-calendar/page-calendar.utils.js +0 -71
  254. package/dist/components/page-calendar/week-view.jsx +0 -64
  255. package/dist/components/table/filter.jsx +0 -141
  256. package/dist/components/table/group.jsx +0 -68
  257. package/dist/components/table/index.jsx +0 -60
  258. package/dist/components/table/inner-table.jsx +0 -104
  259. package/dist/components/table/metadata.jsx +0 -36
  260. package/dist/components/table/pagination.jsx +0 -73
  261. package/dist/components/table/row.jsx +0 -58
  262. package/dist/components/table/sort.jsx +0 -105
  263. package/dist/components/table/table-lib.js +0 -83
  264. package/dist/components/table/table.context.jsx +0 -4
  265. package/dist/components/table/thead.jsx +0 -103
  266. package/dist/config/context.js +0 -12
  267. package/dist/config/default-translations.jsx +0 -83
  268. package/dist/config/default-tweaks.js +0 -4
  269. package/dist/constants.js +0 -2
  270. package/dist/hooks/use-click-outside.js +0 -17
  271. package/dist/hooks/use-color-parser.js +0 -9
  272. package/dist/hooks/use-components-provider.jsx +0 -19
  273. package/dist/hooks/use-debounce.js +0 -12
  274. package/dist/hooks/use-floating-ref.js +0 -6
  275. package/dist/hooks/use-form.js +0 -550
  276. package/dist/hooks/use-hover.js +0 -18
  277. package/dist/hooks/use-input-id.js +0 -5
  278. package/dist/hooks/use-is-coarse-device.js +0 -12
  279. package/dist/hooks/use-locale.js +0 -10
  280. package/dist/hooks/use-media-query.js +0 -25
  281. package/dist/hooks/use-on-event.js +0 -7
  282. package/dist/hooks/use-parent.js +0 -21
  283. package/dist/hooks/use-preferences.js +0 -23
  284. package/dist/hooks/use-previous.js +0 -9
  285. package/dist/hooks/use-reactive.js +0 -9
  286. package/dist/hooks/use-remove-scroll.js +0 -61
  287. package/dist/hooks/use-resize-observer.js +0 -17
  288. package/dist/hooks/use-stable-ref.js +0 -9
  289. package/dist/hooks/use-swipe.js +0 -17
  290. package/dist/hooks/use-translations.js +0 -9
  291. package/dist/hooks/use-tweaks.js +0 -9
  292. package/dist/hooks/use-window-size.js +0 -14
  293. package/dist/index.mjs +0 -37103
  294. package/dist/index.mjs.map +0 -1
  295. package/dist/index.umd.js +0 -28
  296. package/dist/index.umd.js.map +0 -1
  297. package/dist/lib/combi-keys.js +0 -60
  298. package/dist/lib/dict.js +0 -39
  299. package/dist/lib/dom.js +0 -62
  300. package/dist/lib/fns.js +0 -46
  301. package/dist/lib/fzf.js +0 -117
  302. package/dist/lib/keyboard-area.js +0 -14
  303. package/dist/types.js +0 -1
@@ -1,161 +0,0 @@
1
- "use client";
2
- import { arrow, autoUpdate, flip, FloatingArrow, FloatingPortal, offset, shift, useFloating, useInteractions, useRole, } from "@floating-ui/react";
3
- import { AnimatePresence, motion } from "motion/react";
4
- import React, { Fragment, useEffect, useLayoutEffect, useRef, useState } from "react";
5
- import { useResizeObserver } from "../../hooks/use-resize-observer";
6
- import { useTranslations } from "../../hooks/use-translations";
7
- import { useWindowSize } from "../../hooks/use-window-size";
8
- import { noop } from "../../lib/fns";
9
- import { Button } from "../core/button";
10
- const getRect = (element) => {
11
- if (!element)
12
- return { top: 0, left: 0, width: 0, height: 0, bottom: 0, right: 0 };
13
- return element.getBoundingClientRect();
14
- };
15
- const resolveElement = (element) => {
16
- if (typeof element === "string") {
17
- return document.querySelector(element);
18
- }
19
- if ("current" in element) {
20
- return element.current;
21
- }
22
- return element;
23
- };
24
- export const Wizard = ({ steps, active = false, onClose = noop, onFinish = noop, onChange = noop, labels: labelsProp }) => {
25
- const translation = useTranslations();
26
- const [index, setIndex] = useState(0);
27
- const currentStep = steps[index];
28
- const [element, setElement] = useState(null);
29
- const [rect, setRect] = useState(getRect(null));
30
- const [isOverlayReady, setIsOverlayReady] = useState(false);
31
- const arrowRef = useRef(null);
32
- const { width, height } = useWindowSize();
33
- const labels = {
34
- next: labelsProp?.next ?? translation.driverNext,
35
- previous: labelsProp?.previous ?? translation.driverPrevious,
36
- finish: labelsProp?.finish ?? translation.driverFinish,
37
- skip: labelsProp?.skip ?? translation.driverSkip,
38
- };
39
- const { refs, floatingStyles, context } = useFloating({
40
- open: active && isOverlayReady,
41
- placement: currentStep?.side || "bottom",
42
- whileElementsMounted: autoUpdate,
43
- middleware: [offset(10), flip(), shift(), arrow({ element: arrowRef })],
44
- });
45
- const { getFloatingProps } = useInteractions([useRole(context)]);
46
- useEffect(() => {
47
- if (active) {
48
- setIndex(0);
49
- }
50
- }, [active]);
51
- useEffect(() => {
52
- setIsOverlayReady(false);
53
- }, [index, active]);
54
- useEffect(() => {
55
- if (!active || !currentStep)
56
- return;
57
- const el = resolveElement(currentStep.element);
58
- if (el) {
59
- currentStep.onEnter?.();
60
- setTimeout(() => {
61
- setRect(el.getBoundingClientRect());
62
- refs.setReference(el);
63
- setElement(el);
64
- }, 100);
65
- }
66
- else {
67
- console.warn(`Driver: Element not found:`, currentStep.element);
68
- setElement(null);
69
- setRect({ top: 0, left: 0, width: 0, height: 0, bottom: 0, right: 0 });
70
- }
71
- }, [index, active, currentStep, refs]);
72
- useLayoutEffect(() => {
73
- if (!element)
74
- return;
75
- const update = () => setRect(element.getBoundingClientRect());
76
- update();
77
- window.addEventListener("scroll", update, { capture: true, passive: true });
78
- window.addEventListener("resize", update, { capture: true, passive: true });
79
- return () => {
80
- window.removeEventListener("scroll", update, { capture: true });
81
- window.removeEventListener("resize", update, { capture: true });
82
- };
83
- }, [element, width, height]);
84
- useResizeObserver(element, (entry) => {
85
- setRect(entry.target.getBoundingClientRect());
86
- });
87
- const handleNext = () => {
88
- currentStep.onNext?.();
89
- setTimeout(() => {
90
- if (index < steps.length - 1) {
91
- setIndex((i) => i + 1);
92
- onChange(index + 1);
93
- }
94
- else {
95
- onFinish();
96
- onClose();
97
- }
98
- }, 0);
99
- };
100
- const handlePrevious = () => {
101
- currentStep.onPrevious?.();
102
- if (index > 0) {
103
- setIndex((i) => i - 1);
104
- onChange(index - 1);
105
- }
106
- };
107
- if (!active)
108
- return null;
109
- const hasNext = index < steps.length - 1;
110
- const hasPrevious = index > 0;
111
- return (<FloatingPortal>
112
- <div className="pointer-events-none fixed inset-0 z-wizard">
113
- <svg className="absolute inset-0 h-full w-full fill-current text-floating-overlay/70" xmlns="http://www.w3.org/2000/svg">
114
- <defs>
115
- <mask id="driver-mask">
116
- <rect x="0" y="0" width="100%" height="100%" fill="white"/>
117
- <motion.rect rx="4" fill="black" initial={false} onAnimationComplete={() => setIsOverlayReady(true)} transition={{ type: "spring", duration: 0.5, ease: "easeInOut" }} animate={{
118
- x: rect.left - 5,
119
- y: rect.top - 5,
120
- width: rect.width + 10,
121
- height: rect.height + 10,
122
- }}/>
123
- </mask>
124
- </defs>
125
- <rect x="0" y="0" width="100%" height="100%" mask="url(#driver-mask)" className="pointer-events-auto"/>
126
- </svg>
127
- <AnimatePresence mode="wait">
128
- {currentStep && isOverlayReady && (<div {...getFloatingProps()} ref={refs.setFloating} style={element
129
- ? floatingStyles
130
- : {
131
- position: "fixed",
132
- top: "50%",
133
- left: "50%",
134
- transform: "translate(-50%, -50%)",
135
- }} className="pointer-events-auto outline-none">
136
- <motion.div transition={{ duration: 0.2 }} exit={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1 }} initial={{ opacity: 0, scale: 0.9 }} className="flex w-80 max-w-sm flex-col gap-3 rounded-lg border border-floating-border bg-floating-background p-4 shadow-lg">
137
- {element && (<FloatingArrow ref={arrowRef} context={context} className="fill-floating-background stroke-floating-border"/>)}
138
- {currentStep.title && <h3>{currentStep.title}</h3>}
139
- {currentStep.description && <Fragment>{currentStep.description}</Fragment>}
140
- <div className="mt-2 flex items-center justify-between border-t border-floating-border pt-2">
141
- <Button theme="raw" size="small" onClick={onClose} className="text-xs text-muted-foreground hover:text-foreground">
142
- {labels.skip}
143
- </Button>
144
- <div className="flex gap-2">
145
- {hasPrevious && (<Button size="small" theme="ghost-muted" onClick={handlePrevious}>
146
- {labels.previous}
147
- </Button>)}
148
- <Button size="small" onClick={handleNext}>
149
- {hasNext ? labels.next : labels.finish}
150
- </Button>
151
- </div>
152
- </div>
153
- <div className="absolute right-2 top-2 text-xs text-muted-foreground">
154
- {index + 1} / {steps.length}
155
- </div>
156
- </motion.div>
157
- </div>)}
158
- </AnimatePresence>
159
- </div>
160
- </FloatingPortal>);
161
- };
@@ -1,279 +0,0 @@
1
- "use client";
2
- import { autoPlacement, autoUpdate, FloatingFocusManager, FloatingPortal, offset, size, useDismiss, useFloating, useInteractions, useListNavigation, useRole, useTransitionStyles, } from "@floating-ui/react";
3
- import { ChevronDown } from "lucide-react";
4
- import { AnimatePresence, motion } from "motion/react";
5
- import React, { forwardRef, Fragment, useEffect, useRef, useState } from "react";
6
- import { flushSync } from "react-dom";
7
- import { Virtuoso } from "react-virtuoso";
8
- import { Is } from "sidekicker";
9
- import { useRemoveScroll } from "../../hooks/use-remove-scroll";
10
- import { useTranslations } from "../../hooks/use-translations";
11
- import { css, dispatchInput, getRemainingSize, initializeInputDataset, mergeRefs } from "../../lib/dom";
12
- import { safeRegex } from "../../lib/fns";
13
- import { fzf } from "../../lib/fzf";
14
- import { InputField } from "./input-field";
15
- const Frag = (props) => <Fragment>{props.children}</Fragment>;
16
- const transitionStyles = {
17
- duration: 200,
18
- open: { transform: "scaleY(1)", opacity: 1 },
19
- close: { transform: "scaleY(0)", opacity: 0 },
20
- initial: { transform: "scaleY(0)", opacity: 0.2 },
21
- };
22
- const emptyRef = [];
23
- const List = forwardRef(function VirtualList(props, ref) {
24
- return (<motion.ul {...props} ref={ref} className="max-h-96 w-full overscroll-contain rounded-lg">
25
- <AnimatePresence>{props.children}</AnimatePresence>
26
- </motion.ul>);
27
- });
28
- const Item = forwardRef(function VirtualItem({ item, context, ...props }, ref) {
29
- return <motion.li {...props} ref={ref} className="first:rounded-t-lg last:rounded-t-lg"/>;
30
- });
31
- const components = { List, Item };
32
- const MIN_SIZE = 40;
33
- export const Autocomplete = forwardRef(({ left, error, right, loading, options, container, rightLabel, interactive, emptyMessage, optionalText, labelClassName, feedback = null, hideLeft = false, required = false, dynamicOption = false, ...props }, externalRef) => {
34
- const scroller = useRef(null);
35
- const fieldset = useRef(null);
36
- const virtuoso = useRef(null);
37
- const defaults = props.value ?? props.defaultValue ?? "";
38
- const translation = useTranslations();
39
- const [h, setH] = useState(() => Math.min(320, MIN_SIZE * options.length));
40
- const [open, setOpen] = useState(false);
41
- const [shadow, setShadow] = useState("");
42
- const [value, setValue] = useState(defaults);
43
- const [label, setLabel] = useState(() => options.find((x) => x.value === defaults)?.label ?? defaults);
44
- const [index, setIndex] = useState(null);
45
- const listRef = useRef(emptyRef);
46
- const removeScrollRef = useRemoveScroll(open, "block-only");
47
- const innerOptions = dynamicOption && shadow !== ""
48
- ? [
49
- {
50
- value: shadow,
51
- label: shadow,
52
- "data-dynamic": "true",
53
- },
54
- ...options,
55
- ]
56
- : options;
57
- const openDropdown = () => flushSync(() => setOpen(true));
58
- const list = shadow
59
- ? fzf(innerOptions, "value", [
60
- { key: "value", value: shadow },
61
- { key: "label", value: shadow },
62
- ])
63
- : innerOptions;
64
- const setClosed = () => {
65
- setOpen(false);
66
- setH(0);
67
- };
68
- const displayList = list.filter((x) => x.hidden !== true);
69
- const pattern = dynamicOption
70
- ? undefined
71
- : `^(${options.map((x) => `${safeRegex(x.value)}${x.label ? "|" + safeRegex(x.label) : ""}`).join("|")})$`;
72
- const { x, y, strategy, refs, context, placement } = useFloating({
73
- open,
74
- transform: true,
75
- onOpenChange: setOpen,
76
- placement: "bottom-start",
77
- whileElementsMounted: autoUpdate,
78
- middleware: [
79
- offset(4),
80
- autoPlacement({ allowedPlacements: ["top-start", "bottom-start"], alignment: "start" }),
81
- size({
82
- padding: 10,
83
- elementContext: "reference",
84
- apply(args) {
85
- const ul = args.elements.floating.querySelector("ul");
86
- const fullSize = ul?.getBoundingClientRect().height || 0;
87
- const DEFAULT_SIZE = getRemainingSize(refs.reference.current, window.innerHeight);
88
- const maxH = Math.min(fullSize < MIN_SIZE ? DEFAULT_SIZE : fullSize, DEFAULT_SIZE, args.availableHeight);
89
- const size = displayList.length === 0 ? MIN_SIZE : Math.min(maxH, DEFAULT_SIZE, fullSize);
90
- const mw = `${fieldset.current?.getBoundingClientRect().width || DEFAULT_SIZE}px`;
91
- Object.assign(args.elements.floating.style, { width: mw, maxWidth: mw, height: size });
92
- },
93
- }),
94
- ],
95
- });
96
- const transitions = useTransitionStyles(context, transitionStyles);
97
- const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
98
- useRole(context, { role: "listbox" }),
99
- useDismiss(context),
100
- useListNavigation(context, {
101
- cols: 0,
102
- listRef,
103
- loop: true,
104
- virtual: true,
105
- allowEscape: true,
106
- activeIndex: index,
107
- selectedIndex: index,
108
- focusItemOnOpen: "auto",
109
- openOnArrowKeyDown: true,
110
- scrollItemIntoView: true,
111
- }),
112
- ]);
113
- useEffect(() => {
114
- if (props.value) {
115
- const item = options.find((x) => x.value === props.value);
116
- if (item) {
117
- setLabel(item.label ?? item.value);
118
- setValue(props.value);
119
- }
120
- }
121
- }, [props.value, options.length]);
122
- useEffect(() => {
123
- if (!open)
124
- return setH(0);
125
- const inputRef = refs.reference;
126
- if (inputRef.current === null)
127
- return;
128
- const s = getRemainingSize(inputRef.current, window.innerHeight);
129
- setTimeout(() => setH(Math.min(s, displayList.length * MIN_SIZE)), 100);
130
- }, [shadow, open, refs.reference, displayList.length]);
131
- useEffect(() => {
132
- const input = refs.reference.current;
133
- if (!input)
134
- return;
135
- return initializeInputDataset(input);
136
- }, []);
137
- const onSelect = (opt, i) => {
138
- setValue(opt.value);
139
- const input = refs.reference.current;
140
- if (!input)
141
- return;
142
- input?.setAttribute("data-value", opt.value);
143
- input.value = opt.value;
144
- const event = new Event("change", { bubbles: false, cancelable: true });
145
- input.dispatchEvent(event);
146
- if (props.onChange)
147
- props.onChange(event);
148
- setLabel(opt.label ?? "");
149
- setClosed();
150
- setShadow("");
151
- setIndex(i);
152
- };
153
- const onChange = (event) => {
154
- const value = event.target.value;
155
- setShadow(value);
156
- if (!open && value === "")
157
- return setOpen(true);
158
- event.target.name = props.name || "";
159
- return value ? setOpen(true) : props.onChange?.(event);
160
- };
161
- const onCaretDownClick = () => {
162
- openDropdown();
163
- setShadow("");
164
- refs.reference.current?.focus();
165
- };
166
- const onFocus = () => {
167
- setIndex((prev) => (prev === null ? 0 : prev));
168
- openDropdown();
169
- setShadow("");
170
- };
171
- const onClose = () => {
172
- refs.reference.current?.setAttribute("data-value", "");
173
- setShadow("");
174
- setValue("");
175
- setLabel("");
176
- dispatchInput(refs.reference.current);
177
- setClosed();
178
- };
179
- const id = props.id || props.name;
180
- const shadowId = `${id}-shadow`;
181
- const isEmpty = displayList.length === 0;
182
- const isTopPlacement = placement === "top" || placement === "top-start";
183
- return (<InputField {...props} left={left} error={error} ref={fieldset} form={props.form} loading={loading} name={props.name} feedback={open && isTopPlacement ? props.title : feedback} hideLeft={hideLeft} required={required} title={props.title} container={container} rightLabel={rightLabel} interactive={interactive} id={shadowId} optionalText={optionalText} componentName="autocomplete" labelClassName={labelClassName} placeholder={props.placeholder} right={<span className="flex items-center gap-0.5">
184
- {right}
185
- <button type="button" className="p-2 transition-colors link:text-primary md:p-1" onClick={onCaretDownClick}>
186
- <ChevronDown size={20}/>
187
- <span className="sr-only">{translation.inputCaretDown}</span>
188
- </button>
189
- {value ? (<button type="button" onClick={onClose} className="p-2 transition-colors link:text-danger md:p-1">
190
- <svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
191
- <path d="M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z" fill="currentColor" fillRule="evenodd" clipRule="evenodd"/>
192
- </svg>
193
- </button>) : null}
194
- </span>}>
195
- <input data-shadow="true" {...getReferenceProps({
196
- ...props,
197
- onFocus,
198
- pattern,
199
- onChange,
200
- id: shadowId,
201
- name: shadowId,
202
- ref: refs.setReference,
203
- onClick: (e) => e.currentTarget.focus(),
204
- onKeyDown(event) {
205
- if (event.key === "Escape") {
206
- event.currentTarget.blur();
207
- return setClosed();
208
- }
209
- if (!open)
210
- return;
211
- if (event.key === "ArrowDown") {
212
- let next = Is.number(index) ? index + 1 : 0;
213
- if (next > displayList.length - 1)
214
- next = 0;
215
- virtuoso.current?.scrollIntoView({ index: next });
216
- return setIndex(next);
217
- }
218
- if (event.key === "ArrowUp") {
219
- let next = Is.number(index) ? index - 1 : displayList.length - 1;
220
- if (next < 0)
221
- next = displayList.length - 1;
222
- virtuoso.current?.scrollIntoView({ index: next });
223
- return setIndex(next);
224
- }
225
- if (event.key === "Enter") {
226
- if (index !== null && displayList[index]) {
227
- event.preventDefault();
228
- return onSelect(displayList[index], index);
229
- }
230
- if (displayList.length === 1) {
231
- event.preventDefault();
232
- return onSelect(displayList[0], 0);
233
- }
234
- }
235
- },
236
- })} data-value={value} data-error={!!error} data-name={id} data-target={id} required={required} value={open ? shadow : options.length === 0 ? "" : label || value} aria-autocomplete="list" autoComplete="off" className={css("input placeholder-input-mask group h-input-height w-full flex-1", "rounded-md bg-transparent px-input-x py-input-y text-foreground", "outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary", "group-error:text-danger group-error:placeholder-input-mask-error", "text-base group-focus-within:border-primary group-hover:border-primary", props.className)}/>
237
- <input id={id} name={id} type="hidden" data-origin={id} ref={externalRef} required={required} defaultValue={props.value || value || undefined}/>
238
- <FloatingPortal preserveTabOrder>
239
- {open ? (<FloatingFocusManager modal guards returnFocus={false} context={context} initialFocus={-1} visuallyHiddenDismiss>
240
- <motion.div {...getFloatingProps({
241
- ref: mergeRefs(removeScrollRef, refs.setFloating),
242
- style: { ...transitions.styles, left: x, top: y ?? 0, position: strategy, height: "auto" },
243
- })} initial={false} data-floating="true" animate={{ height: isEmpty ? "auto" : h }} className={css("shadow-floating isolate z-floating m-0 max-h-80 origin-[top_center] list-none overscroll-contain rounded-b-lg rounded-t-lg border border-floating-border bg-floating-background p-0 text-foreground ease-in-out", isTopPlacement ? "origin-[bottom_center]" : "origin-[top_center]")} onAnimationComplete={() => {
244
- if (!open)
245
- return setH(0);
246
- const ul = refs.floating.current;
247
- const li = ul.querySelectorAll("li").item(0);
248
- const sum = (li ? li.getBoundingClientRect().height : MIN_SIZE) * displayList.length;
249
- return flushSync(() => setH(sum + 2));
250
- }}>
251
- {isEmpty ? (<div role="option" className="w-full border-b border-tooltip-border">
252
- <span className="flex w-full justify-between p-2 text-left text-disabled">
253
- {emptyMessage || translation.autocompleteEmpty}
254
- </span>
255
- </div>) : null}
256
- <Virtuoso overscan={40} ref={virtuoso} hidden={isEmpty} data={displayList} style={{ height: h }} defaultItemHeight={MIN_SIZE} components={components} scrollerRef={(e) => void (scroller.current = e)} className="border-floating max-h-full overscroll-contain rounded-lg bg-floating-background p-0 text-foreground" itemContent={(i, option) => {
257
- const Label = option.Render ?? Frag;
258
- const active = value === option.value || value === option.label;
259
- const selected = index === i;
260
- const children = option.label ?? option.value;
261
- return (<button data-value={option.value} {...getItemProps({
262
- ref: (node) => void (listRef.current[i] = node),
263
- role: "option",
264
- type: "button",
265
- "aria-checked": active,
266
- "aria-current": active,
267
- "aria-selected": active,
268
- "aria-busy": option.disabled,
269
- onClick: () => onSelect(option, i),
270
- className: `cursor-pointer min-h-10 hover:bg-floating-hover w-full p-2 text-left ${active ? "bg-primary-hover text-primary-foreground" : ""} ${selected ? "bg-floating-hover text-floating-foreground" : ""}`,
271
- })}>
272
- <Label {...props} label={option.label} value={option.value} children={children}/>
273
- </button>);
274
- }}/>
275
- </motion.div>
276
- </FloatingFocusManager>) : null}
277
- </FloatingPortal>
278
- </InputField>);
279
- });
@@ -1,12 +0,0 @@
1
- import React, { forwardRef } from "react";
2
- import { css } from "../../lib/dom";
3
- export const Checkbox = forwardRef(({ children, asTask = false, labelClassName, loading, error, className = "", size, container, ...props }, ref) => {
4
- const d = props.disabled || loading;
5
- return (<label aria-disabled={d} data-disabled={d} data-task={asTask} data-component="checkbox" className={css("group flex w-fit flex-wrap items-center font-normal data-[disabled=true]:cursor-not-allowed", asTask ? "group-checkbox-checked:line-through" : "", container)}>
6
- <input {...props} ref={ref} disabled={d} type="checkbox" data-task={asTask} className={css("form-checkbox mr-2 inline-block size-4 appearance-none rounded border-card-border bg-origin-border text-primary focus:ring-primary disabled:opacity-70 group-aria-disabled:cursor-not-allowed", className)}/>
7
- {children}
8
- <span data-name="checkbox-label" className={css("min-w-full flex-1 text-xs text-danger empty:mt-0 empty:hidden", labelClassName)}>
9
- {error}
10
- </span>
11
- </label>);
12
- });
@@ -1,115 +0,0 @@
1
- "use client";
2
- import { format, isValid, parse, startOfDay } from "date-fns";
3
- import { CalendarIcon } from "lucide-react";
4
- import React, { forwardRef, Fragment, useEffect, useId, useMemo, useState } from "react";
5
- import { Is } from "sidekicker";
6
- import { useLocale } from "../../hooks/use-locale";
7
- import { useTranslations } from "../../hooks/use-translations";
8
- import { Calendar } from "../display/calendar";
9
- import { Dropdown } from "../floating/dropdown";
10
- import { Input } from "./input";
11
- const fixedDate = new Date(1970, 11, 31);
12
- const parts = {
13
- year: () => [/\d/, /\d/, /\d/, /\d/],
14
- month: () => [/\d/, /\d/],
15
- day: () => [/\d/, /\d/],
16
- hour: () => [/\d/, /\d/],
17
- minute: () => [/\d/, /\d/],
18
- literal: (str) => str.split(""),
19
- };
20
- const placeholders = {
21
- day: () => "dd",
22
- hour: () => "HH",
23
- month: () => "MM",
24
- minute: () => "mm",
25
- year: () => "yyyy",
26
- literal: (str) => str,
27
- };
28
- const partValues = {
29
- literal: (_, str) => str,
30
- year: (date) => date.getFullYear().toString(),
31
- day: (date) => date.getDate().toString().padStart(2, "0"),
32
- hour: (date) => date.getHours().toString().padStart(2, "0"),
33
- minute: (date) => date.getMinutes().toString().padStart(2, "0"),
34
- month: (date) => (date.getMonth() + 1).toString().padStart(2, "0"),
35
- };
36
- const formatParts = (datetimeFormat, date) => {
37
- try {
38
- return datetimeFormat.formatToParts(date).map((x) => {
39
- if (x.type === "literal" && x.value === ", ") {
40
- return { type: x.type, value: " " };
41
- }
42
- return x;
43
- });
44
- }
45
- catch (e) {
46
- return [];
47
- }
48
- };
49
- const DATE_TIME_FORMAT = { day: "numeric", month: "numeric", year: "numeric", hour: "numeric", minute: "numeric" };
50
- const DATE_FORMAT = { day: "numeric", month: "numeric", year: "numeric" };
51
- export const DatePicker = forwardRef(({ date, locale: inputLocal, disabledDate, onChange, markToday, clickToClose, floating = true, type, ...props }, externalRef) => {
52
- const locale = useLocale(inputLocal);
53
- const labelId = useId();
54
- const translation = useTranslations();
55
- const datetimeFormat = useMemo(() => new Intl.DateTimeFormat(locale, type === "datetime" ? DATE_TIME_FORMAT : DATE_FORMAT), [locale, type]);
56
- const [innerDate, setInnerDate] = useState(date || undefined);
57
- const [open, setOpen] = useState(false);
58
- const mask = formatParts(datetimeFormat, fixedDate).flatMap((x) => (Is.keyof(parts, x.type) ? parts[x.type](x.value) : []));
59
- const placeholder = useMemo(() => {
60
- return formatParts(datetimeFormat, fixedDate).reduce((acc, x) => acc + (Is.keyof(placeholders, x.type) ? placeholders[x.type](x.value) : ""), "");
61
- }, [datetimeFormat]);
62
- const isoDateEffect = date?.toISOString();
63
- const [value, setValue] = useState(!innerDate
64
- ? ""
65
- : formatParts(datetimeFormat, innerDate).reduce((acc, x) => acc + (Is.keyof(parts, x.type) ? partValues[x.type](innerDate, x.value) : ""), ""));
66
- const onChangeDateInput = (e) => {
67
- const v = e.target.value;
68
- setValue(v);
69
- if (mask.length === v.length) {
70
- const matches = mask.every((x, i) => {
71
- const c = v.charAt(i);
72
- return typeof x === "string" ? c === x : x.test(c);
73
- });
74
- if (matches) {
75
- const parsed = parse(v, placeholder, new Date());
76
- const d = type === "datetime" ? parsed : startOfDay(parsed);
77
- setInnerDate(d);
78
- return onChange?.(d);
79
- }
80
- }
81
- setInnerDate(undefined);
82
- return onChange?.(undefined);
83
- };
84
- useEffect(() => {
85
- if (isValid(date)) {
86
- setInnerDate(date);
87
- setValue(format(date, placeholder));
88
- }
89
- }, [isoDateEffect, placeholder]);
90
- const onChangeDate = (d) => {
91
- setInnerDate(d);
92
- onChange?.(d);
93
- if (clickToClose)
94
- setOpen(false);
95
- if (d)
96
- return setValue(format(d, placeholder));
97
- return setValue("");
98
- };
99
- const validDate = isValid(innerDate);
100
- const htmlValue = validDate ? innerDate.toISOString() : undefined;
101
- const CalendarComponent = (<Calendar {...props} type={type} locale={locale} changeOnlyOnClick markToday={markToday} onChange={onChangeDate} disabledDate={disabledDate} date={validDate ? innerDate : undefined}/>);
102
- return (<Fragment>
103
- <Input {...props} mask={mask} value={value} id={undefined} name={undefined} data-value={htmlValue} formNoValidate={!open} data-target={props.name} data-component="date-picker" onChange={onChangeDateInput} required={props.required ?? true} error={open ? undefined : props.error} placeholder={props.placeholder || translation.datepickerPlaceholder(placeholder)} right={floating ? (<Fragment>
104
- <input data-origin={props.name} defaultValue={htmlValue} form={props.form} hidden id={props.name} name={props.name} ref={externalRef} type="date"/>
105
- <Dropdown open={open} onChange={setOpen} buttonProps={{ "aria-describedby": labelId }} trigger={<span aria-labelledby={labelId}>
106
- <span id={labelId} className="sr-only">
107
- {translation.datePickerCalendarButtonLabel}
108
- </span>
109
- <CalendarIcon />
110
- </span>}>
111
- {CalendarComponent}
112
- </Dropdown>
113
- </Fragment>) : null}/>
114
- </Fragment>);
115
- });