@cystackapp/ui 1.4.1 → 2.0.0

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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -47
  3. package/dist/assets/background-pattern-grid.svg.js +7 -0
  4. package/dist/assets/empty-cloud.svg.js +5 -0
  5. package/dist/components/accordion/Accordion.d.ts +20 -0
  6. package/dist/components/accordion/Accordion.js +36 -0
  7. package/dist/components/accordion/AccordionTestStory.d.ts +3 -0
  8. package/dist/components/alert/Alert.d.ts +15 -0
  9. package/dist/components/alert/Alert.js +54 -0
  10. package/dist/components/avatar/Avatar.d.ts +13 -0
  11. package/dist/components/avatar/Avatar.js +64 -0
  12. package/dist/components/background-pattern/BackgroundPatternGrid.d.ts +1 -0
  13. package/dist/components/background-pattern/BackgroundPatternGrid.js +6 -0
  14. package/dist/components/badge/Badge.d.ts +1 -1
  15. package/dist/components/badge/Badge.js +3 -3
  16. package/dist/components/badge/BadgeTestStory.d.ts +1 -1
  17. package/dist/components/badge/variants/BadgeMore.d.ts +1 -1
  18. package/dist/components/badge/variants/BadgeMoreTestStory.d.ts +1 -1
  19. package/dist/components/badge/variants/BadgeTag.d.ts +1 -1
  20. package/dist/components/badge/variants/BadgeTag.js +1 -1
  21. package/dist/components/banner/Banner.d.ts +9 -0
  22. package/dist/components/banner/Banner.js +21 -0
  23. package/dist/components/breadcrumb/Breadcrumb.d.ts +13 -0
  24. package/dist/components/breadcrumb/Breadcrumb.js +36 -0
  25. package/dist/components/button/Button.d.ts +21 -0
  26. package/dist/components/button/Button.js +49 -0
  27. package/dist/components/button/ButtonLoader.d.ts +7 -0
  28. package/dist/components/button/ButtonLoader.js +44 -0
  29. package/dist/components/button/ButtonTestStory.d.ts +5 -0
  30. package/dist/components/button/button-variants.d.ts +13 -0
  31. package/dist/components/button/button-variants.js +58 -0
  32. package/dist/components/card/Card.d.ts +91 -0
  33. package/dist/components/card/Card.js +56 -0
  34. package/dist/components/card/Card.stories-ct.d.ts +1 -0
  35. package/dist/components/card/CardBody.d.ts +9 -0
  36. package/dist/components/card/CardBody.js +16 -0
  37. package/dist/components/card/CardHeader.d.ts +15 -0
  38. package/dist/components/card/CardHeader.js +79 -0
  39. package/dist/components/card/types.d.ts +1 -0
  40. package/dist/components/chart/chart-legend/ChartLegend.d.ts +38 -0
  41. package/dist/components/chart/chart-legend/ChartLegend.js +57 -0
  42. package/dist/components/chart/chart-legend/ChartLegendItem.d.ts +19 -0
  43. package/dist/components/chart/chart-legend/ChartLegendItem.js +30 -0
  44. package/dist/components/chart/chart-legend/types.d.ts +49 -0
  45. package/dist/components/chart/donut-chart/DonutChart.d.ts +55 -0
  46. package/dist/components/chart/donut-chart/DonutChart.js +110 -0
  47. package/dist/components/chart/donut-chart/DonutSegments.d.ts +25 -0
  48. package/dist/components/chart/donut-chart/DonutSegments.js +51 -0
  49. package/dist/components/chart/donut-chart/donut-tooltip.d.ts +20 -0
  50. package/dist/components/chart/donut-chart/donut-tooltip.js +37 -0
  51. package/dist/components/chart/types.d.ts +8 -0
  52. package/dist/components/checkbox/Checkbox.d.ts +6 -0
  53. package/dist/components/checkbox/Checkbox.js +72 -0
  54. package/dist/components/checkbox/CheckboxTestStory.d.ts +7 -0
  55. package/dist/components/collapsible/Collapsible.d.ts +21 -0
  56. package/dist/components/collapsible/Collapsible.js +50 -0
  57. package/dist/components/combobox/Combobox.d.ts +1 -1
  58. package/dist/components/divider/Divider.d.ts +9 -0
  59. package/dist/components/divider/Divider.js +28 -0
  60. package/dist/components/drawer/Drawer.d.ts +8 -0
  61. package/dist/components/drawer/Drawer.js +68 -0
  62. package/dist/components/dropdown/Dropdown.d.ts +45 -0
  63. package/dist/components/dropdown/Dropdown.js +133 -0
  64. package/dist/components/dropdown/DropdownMenu.d.ts +20 -0
  65. package/dist/components/dropdown/DropdownMenu.js +78 -0
  66. package/dist/components/dropdown/DropdownMenuItem.d.ts +13 -0
  67. package/dist/components/dropdown/DropdownMenuItem.js +49 -0
  68. package/dist/components/dropdown/DropdownTestStory.d.ts +5 -0
  69. package/dist/components/dropdown/dropdown-utils.d.ts +4 -0
  70. package/dist/components/dropdown/dropdown-utils.js +14 -0
  71. package/dist/components/dropdown/types.d.ts +48 -0
  72. package/dist/components/dropdown/use-dropdown-keyboard.d.ts +12 -0
  73. package/dist/components/dropdown/use-dropdown-keyboard.js +49 -0
  74. package/dist/components/empty-state/EmptyState.d.ts +26 -0
  75. package/dist/components/empty-state/EmptyState.js +36 -0
  76. package/dist/components/error-state/ErrorState.d.ts +1 -1
  77. package/dist/components/featured-icon/FeaturedIcon.d.ts +12 -0
  78. package/dist/components/featured-icon/FeaturedIcon.js +44 -0
  79. package/dist/components/form-field/FormField.d.ts +13 -0
  80. package/dist/components/form-field/FormField.js +21 -0
  81. package/dist/components/input/Input.d.ts +11 -0
  82. package/dist/components/input/Input.js +39 -0
  83. package/dist/components/keyboard-shortcut-label/KeyboardShortcutLabel.d.ts +8 -0
  84. package/dist/components/keyboard-shortcut-label/KeyboardShortcutLabel.js +18 -0
  85. package/dist/components/loading-state/Loader.d.ts +20 -0
  86. package/dist/components/loading-state/Loader.js +38 -0
  87. package/dist/components/loading-state/LoadingState.d.ts +15 -0
  88. package/dist/components/loading-state/LoadingState.js +47 -0
  89. package/dist/components/loading-state/locale/en.json.d.ts +6 -0
  90. package/dist/components/loading-state/locale/en.json.js +7 -0
  91. package/dist/components/loading-state/locale/vi.json.d.ts +6 -0
  92. package/dist/components/loading-state/locale/vi.json.js +7 -0
  93. package/dist/components/media/Media.d.ts +7 -0
  94. package/dist/components/media/Media.js +25 -0
  95. package/dist/components/modal/Modal.d.ts +9 -0
  96. package/dist/components/modal/Modal.js +68 -0
  97. package/dist/components/modal/helpers/HeaderIcon.d.ts +8 -0
  98. package/dist/components/modal/helpers/HeaderIcon.js +32 -0
  99. package/dist/components/modal/helpers/Title.d.ts +6 -0
  100. package/dist/components/modal/helpers/Title.js +9 -0
  101. package/dist/components/modal/helpers/circles-sm.svg.js +5 -0
  102. package/dist/components/modal/modal-context.d.ts +2 -0
  103. package/dist/components/modal/modal-context.js +9 -0
  104. package/dist/components/modal/use-click-outside-modal.d.ts +2 -0
  105. package/dist/components/modal/use-click-outside-modal.js +15 -0
  106. package/dist/components/notification/NotificationBanner.d.ts +9 -0
  107. package/dist/components/notification/NotificationBanner.js +97 -0
  108. package/dist/components/notification/icons.d.ts +5 -0
  109. package/dist/components/notification/icons.js +29 -0
  110. package/dist/components/notification/index.d.ts +4 -0
  111. package/dist/components/notification/index.js +26 -0
  112. package/dist/components/notification/locale/en.json.d.ts +8 -0
  113. package/dist/components/notification/locale/en.json.js +7 -0
  114. package/dist/components/notification/locale/vi.json.d.ts +8 -0
  115. package/dist/components/notification/locale/vi.json.js +7 -0
  116. package/dist/components/operating-system-icon/OperatingSystemIcon.d.ts +6 -0
  117. package/dist/components/operating-system-icon/OperatingSystemIcon.js +19 -0
  118. package/dist/components/operating-system-icon/assets/logo-android.svg.js +5 -0
  119. package/dist/components/operating-system-icon/assets/logo-apple.svg.js +5 -0
  120. package/dist/components/operating-system-icon/assets/logo-ubuntu.svg.js +5 -0
  121. package/dist/components/operating-system-icon/assets/logo-windows-10.svg.js +5 -0
  122. package/dist/components/page-title/PageTitle.d.ts +1 -1
  123. package/dist/components/popover/Popover.d.ts +1 -1
  124. package/dist/components/progress-bar/ProgressBar.d.ts +9 -0
  125. package/dist/components/progress-bar/ProgressBar.js +31 -0
  126. package/dist/components/radio/Radio.d.ts +4 -0
  127. package/dist/components/radio/Radio.js +55 -0
  128. package/dist/components/searchbox/Searchbox.d.ts +7 -0
  129. package/dist/components/searchbox/Searchbox.js +15 -0
  130. package/dist/components/select/Select.d.ts +11 -0
  131. package/dist/components/select/Select.js +44 -0
  132. package/dist/components/skeleton/Skeleton.d.ts +14 -0
  133. package/dist/components/skeleton/Skeleton.js +12 -0
  134. package/dist/components/switch/Switch.d.ts +1 -1
  135. package/dist/components/table/Table.d.ts +32 -0
  136. package/dist/components/table/Table.js +128 -0
  137. package/dist/components/table/TableActionButton.d.ts +15 -0
  138. package/dist/components/table/TableActionButton.js +50 -0
  139. package/dist/components/table/TableCell.d.ts +8 -0
  140. package/dist/components/table/TableCell.js +26 -0
  141. package/dist/components/table/TableHeader.d.ts +15 -0
  142. package/dist/components/table/TableHeader.js +36 -0
  143. package/dist/components/table/TableHeaderCell.d.ts +10 -0
  144. package/dist/components/table/TableHeaderCell.js +35 -0
  145. package/dist/components/table/TablePagination.d.ts +6 -0
  146. package/dist/components/table/TablePagination.js +69 -0
  147. package/dist/components/table/TableRow.d.ts +12 -0
  148. package/dist/components/table/TableRow.js +9 -0
  149. package/dist/components/table/expandable/ExpandableTable.d.ts +30 -0
  150. package/dist/components/table/expandable/ExpandableTable.js +156 -0
  151. package/dist/components/table/hooks/use-fit-page-height.d.ts +14 -0
  152. package/dist/components/table/hooks/use-fit-page-height.js +21 -0
  153. package/dist/components/table/hooks/use-row-selection.d.ts +27 -0
  154. package/dist/components/table/hooks/use-row-selection.js +35 -0
  155. package/dist/components/table/locale/en.json.d.ts +13 -0
  156. package/dist/components/table/locale/en.json.js +21 -0
  157. package/dist/components/table/locale/vi.json.d.ts +13 -0
  158. package/dist/components/table/locale/vi.json.js +21 -0
  159. package/dist/components/table/table-utils.d.ts +10 -0
  160. package/dist/components/table/table-utils.js +10 -0
  161. package/dist/components/table/types.d.ts +84 -0
  162. package/dist/components/tabs/Tabs.d.ts +27 -0
  163. package/dist/components/tabs/Tabs.js +75 -0
  164. package/dist/components/tabs/TabsTestStory.d.ts +4 -0
  165. package/dist/components/tags-input/TagsInput.d.ts +18 -0
  166. package/dist/components/tags-input/TagsInput.js +78 -0
  167. package/dist/components/tags-input/TagsInputTestStory.d.ts +3 -0
  168. package/dist/components/textarea/Textarea.d.ts +7 -0
  169. package/dist/components/textarea/Textarea.js +36 -0
  170. package/dist/components/toast/ToastSlice.d.ts +11 -0
  171. package/dist/components/toast/ToastSlice.js +103 -0
  172. package/dist/components/toast/icons.d.ts +8 -0
  173. package/dist/components/toast/icons.js +19 -0
  174. package/dist/components/toast/index.d.ts +4 -0
  175. package/dist/components/toast/index.js +35 -0
  176. package/dist/components/toast/types.d.ts +14 -0
  177. package/dist/components/toast/use-toast-list.d.ts +4 -0
  178. package/dist/components/toast/use-toast-list.js +27 -0
  179. package/dist/components/tooltip/Tooltip.d.ts +1 -1
  180. package/dist/filters/FilterDropdown.d.ts +9 -0
  181. package/dist/filters/FilterDropdown.js +57 -0
  182. package/dist/filters/types.d.ts +11 -0
  183. package/dist/filters/url-params.d.ts +5 -0
  184. package/dist/filters/url-params.js +20 -0
  185. package/dist/filters/use-filters.d.ts +13 -0
  186. package/dist/filters/use-filters.js +63 -0
  187. package/dist/hooks/use-countdown.d.ts +4 -0
  188. package/dist/hooks/use-countdown.js +18 -0
  189. package/dist/i18n/resources.js +23 -0
  190. package/dist/index.d.ts +66 -0
  191. package/dist/index.js +141 -38
  192. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +421 -350
  193. package/dist/test-utils/expect-visibility.d.ts +45 -0
  194. package/dist/utils/key-typeguard.d.ts +5 -0
  195. package/dist/utils/key-typeguard.js +6 -0
  196. package/dist/utils/observable.d.ts +7 -0
  197. package/dist/utils/observable.js +22 -0
  198. package/dist/utils/use-debounce.d.ts +1 -0
  199. package/dist/utils/use-debounce.js +11 -0
  200. package/package.json +30 -7
  201. package/theme.css +7 -1
@@ -0,0 +1,18 @@
1
+ import { BadgeColor } from '../badge/badge-utils';
2
+ export interface TagsInputProps {
3
+ tags: string[];
4
+ onTagsChange: (tags: string[]) => void;
5
+ placeholder?: string;
6
+ disabled?: boolean;
7
+ /** Marks the field as in an error state — switches the focus ring to error-v2. */
8
+ invalid?: boolean;
9
+ /** Fixed badge color for every tag. Defaults to a per-tag auto color. */
10
+ color?: BadgeColor;
11
+ /** Controlled text of the inner input (e.g. to drive an external search). */
12
+ value?: string;
13
+ onValueChange?: (value: string) => void;
14
+ /** Overrides the default removal behavior for a single tag. */
15
+ onRemove?: (tag: string) => void;
16
+ className?: string;
17
+ }
18
+ export declare const TagsInput: ({ tags, onTagsChange, placeholder, disabled, invalid, color, value, onValueChange, onRemove, className, }: TagsInputProps) => import("react").JSX.Element;
@@ -0,0 +1,78 @@
1
+ import { jsxs as S, jsx as p } from "react/jsx-runtime";
2
+ import { useRef as T, useState as A } from "react";
3
+ import { cn as B } from "../../utils/cn.js";
4
+ import { Badge as D } from "../badge/Badge.js";
5
+ import { getBadgeAutoColor as E } from "../badge/variants/BadgeTag.js";
6
+ const l = {
7
+ default: "border-gray-v2-300 focus-within:border-brand-v2 focus-within:outline-brand-v2",
8
+ invalid: "border-error-v2-300 focus-within:border-error-v2 focus-within:outline-error-v2",
9
+ disabled: "bg-gray-v2-50 border-gray-v2-300 cursor-not-allowed"
10
+ }, _ = ({
11
+ tags: t,
12
+ onTagsChange: s,
13
+ placeholder: m,
14
+ disabled: o,
15
+ invalid: v,
16
+ color: h,
17
+ value: a,
18
+ onValueChange: n,
19
+ onRemove: c,
20
+ className: x
21
+ }) => {
22
+ const d = T(null), [g, w] = A(""), i = a !== void 0 ? a : g, u = (r) => {
23
+ w(r), n == null || n(r);
24
+ }, f = (r) => {
25
+ o || (c ? c(t[r]) : s(t.filter((e, k) => k !== r)));
26
+ }, y = (r) => {
27
+ var e;
28
+ r.target === r.currentTarget && ((e = d.current) == null || e.focus());
29
+ }, b = (r) => {
30
+ if (r.key === "Enter") {
31
+ r.preventDefault();
32
+ const e = i.trim();
33
+ if (e.length === 0) return;
34
+ s([...t, e]), u("");
35
+ }
36
+ r.key === "Backspace" && i.length === 0 && t.length > 0 && f(t.length - 1);
37
+ };
38
+ return /* @__PURE__ */ S(
39
+ "div",
40
+ {
41
+ onClick: y,
42
+ className: B(
43
+ "bg-white rounded-lg border shadow-xs flex flex-wrap items-center gap-1.5 px-3 py-2 min-h-10 text-md transition-all outline outline-transparent cursor-text",
44
+ v ? l.invalid : l.default,
45
+ { [l.disabled]: o },
46
+ x
47
+ ),
48
+ children: [
49
+ t.map((r, e) => /* @__PURE__ */ p(
50
+ D,
51
+ {
52
+ color: h ?? E(r),
53
+ size: "sm",
54
+ onClose: o ? void 0 : () => f(e),
55
+ children: r
56
+ },
57
+ `${r}-${e}`
58
+ )),
59
+ /* @__PURE__ */ p(
60
+ "input",
61
+ {
62
+ ref: d,
63
+ type: "text",
64
+ disabled: o,
65
+ value: i,
66
+ onChange: (r) => u(r.target.value),
67
+ onKeyDown: b,
68
+ placeholder: o ? void 0 : m,
69
+ className: "flex-1 min-w-16 bg-transparent outline-none text-gray-v2-900 placeholder:text-gray-v2-500 disabled:text-gray-v2-400 disabled:cursor-not-allowed"
70
+ }
71
+ )
72
+ ]
73
+ }
74
+ );
75
+ };
76
+ export {
77
+ _ as TagsInput
78
+ };
@@ -0,0 +1,3 @@
1
+ export declare function TagsInputBasic({ disabled }: {
2
+ disabled?: boolean;
3
+ }): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { TextareaHTMLAttributes } from 'react';
2
+ interface Props extends TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ /** Marks the textarea as in an error state — switches the focus ring to error-v2. */
4
+ invalid?: boolean;
5
+ }
6
+ export declare const Textarea: import('react').ForwardRefExoticComponent<Props & import('react').RefAttributes<HTMLTextAreaElement>>;
7
+ export {};
@@ -0,0 +1,36 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { forwardRef as l } from "react";
3
+ import { cn as s } from "../../utils/cn.js";
4
+ const e = {
5
+ default: "border-gray-v2-300 focus-within:border-brand-v2 focus-within:outline-brand-v2",
6
+ invalid: "border-error-v2-300 focus-within:border-error-v2 focus-within:outline-error-v2",
7
+ disabled: "bg-gray-v2-50 border-gray-v2-300 cursor-not-allowed"
8
+ }, c = l(
9
+ ({ invalid: a, className: i, disabled: r, rows: n = 4, ...o }, d) => /* @__PURE__ */ t(
10
+ "span",
11
+ {
12
+ className: s(
13
+ "bg-white rounded-lg border shadow-xs flex px-3 py-2.5 text-md transition-all outline outline-transparent",
14
+ a ? e.invalid : e.default,
15
+ { [e.disabled]: r },
16
+ i
17
+ ),
18
+ children: /* @__PURE__ */ t(
19
+ "textarea",
20
+ {
21
+ ref: d,
22
+ disabled: r,
23
+ "aria-invalid": a,
24
+ rows: n,
25
+ className: "flex-1 min-w-0 bg-transparent outline-none resize-y text-gray-v2-900 placeholder:text-gray-v2-500 disabled:text-gray-v2-400 disabled:cursor-not-allowed disabled:resize-none",
26
+ ...o,
27
+ placeholder: r ? void 0 : o.placeholder
28
+ }
29
+ )
30
+ }
31
+ )
32
+ );
33
+ c.displayName = "Textarea";
34
+ export {
35
+ c as Textarea
36
+ };
@@ -0,0 +1,11 @@
1
+ import { InternalToastProps } from './types';
2
+ import { Observable } from '../../utils/observable';
3
+ interface Props {
4
+ toast: InternalToastProps;
5
+ observable: Observable<InternalToastProps>;
6
+ }
7
+ /** A slice of toast. Freshly out of the toaster, crunchy on the outside, soft and tender on the inside.
8
+ * Or is it just notification's UI.
9
+ */
10
+ export declare const ToastSlice: ({ toast, observable }: Props) => import("react").JSX.Element;
11
+ export {};
@@ -0,0 +1,103 @@
1
+ import { jsxs as c, jsx as i } from "react/jsx-runtime";
2
+ import { useState as f, useRef as y, useMemo as T, useCallback as p, useEffect as l } from "react";
3
+ import { XClose as x } from "@untitled-ui/icons-react";
4
+ import { Button as w } from "../button/Button.js";
5
+ import { iconByToastType as B, styleToastType as N } from "./icons.js";
6
+ import { cn as m } from "../../utils/cn.js";
7
+ const k = 4e3, W = ({ toast: e, observable: r }) => {
8
+ var a, d;
9
+ const [h, g] = f(!1), n = y(null), o = T(() => ["peach"].includes(e.type) ? "gradient" : "normal", [e.type]), s = p(
10
+ (t) => {
11
+ r.notify({ ...t, status: "dismissed" });
12
+ },
13
+ [r]
14
+ ), u = p(
15
+ (t) => {
16
+ r.notify({ ...t, status: "destroyed" });
17
+ },
18
+ [r]
19
+ );
20
+ return l(() => {
21
+ g(!0);
22
+ }, []), l(() => {
23
+ const t = setTimeout(() => {
24
+ s(e);
25
+ }, k);
26
+ return () => clearTimeout(t);
27
+ }, [e, s]), /* @__PURE__ */ c(
28
+ "div",
29
+ {
30
+ ref: n,
31
+ style: h ? e.status === "dismissed" ? (
32
+ // The last state before toast is destroyed
33
+ {
34
+ height: 0,
35
+ minHeight: 0,
36
+ opacity: 0,
37
+ marginBottom: 0,
38
+ paddingTop: 0,
39
+ paddingBottom: 0,
40
+ borderWidth: 0
41
+ }
42
+ ) : (
43
+ // The stable state
44
+ {
45
+ height: (d = n.current) == null ? void 0 : d.offsetHeight,
46
+ marginBottom: "0.75rem",
47
+ paddingTop: "0.75rem",
48
+ paddingBottom: "0.75rem",
49
+ borderWidth: "1px"
50
+ }
51
+ ) : (
52
+ // The first state: before toast is mounted
53
+ {
54
+ transform: "translate(0, -100%)",
55
+ height: (a = n.current) == null ? void 0 : a.offsetHeight,
56
+ marginBottom: "0.75rem",
57
+ paddingTop: "0.75rem",
58
+ paddingBottom: "0.75rem",
59
+ borderWidth: "1px"
60
+ }
61
+ ),
62
+ className: m(
63
+ "px-6 flex items-center gap-3 rounded-md duration-300 ease-out shadow-sm-01 min-h-16 overflow-hidden",
64
+ N[e.type],
65
+ o === "gradient" && "text-white"
66
+ ),
67
+ onTransitionEnd: (t) => {
68
+ t.target === t.currentTarget && t.propertyName === "height" && u(e);
69
+ },
70
+ children: [
71
+ B[e.type],
72
+ /* @__PURE__ */ c("div", { className: "flex flex-col", children: [
73
+ /* @__PURE__ */ i("span", { className: "text-md font-medium w-80 min-h-[1em] wrap-break-words", children: e.message }),
74
+ e.detail ? /* @__PURE__ */ i(
75
+ "span",
76
+ {
77
+ className: m(
78
+ "text-sm w-80 min-h-[1em] wrap-break-words line-clamp-3",
79
+ o === "gradient" ? "text-white" : "text-gray-v2-500"
80
+ ),
81
+ children: e.detail
82
+ }
83
+ ) : null
84
+ ] }),
85
+ /* @__PURE__ */ i(
86
+ w,
87
+ {
88
+ variant: "tertiary",
89
+ color: "gray",
90
+ onClick: () => s(e),
91
+ className: m(
92
+ o === "gradient" && "text-white hover:bg-transparent"
93
+ ),
94
+ children: /* @__PURE__ */ i(x, { className: "size-5 shrink-0 text-gray-v2-400" })
95
+ }
96
+ )
97
+ ]
98
+ }
99
+ );
100
+ };
101
+ export {
102
+ W as ToastSlice
103
+ };
@@ -0,0 +1,8 @@
1
+ import { ReactNode } from 'react';
2
+ import { ToastType } from './types';
3
+ export declare const styleToastType: {
4
+ [T in ToastType]: string;
5
+ };
6
+ export declare const iconByToastType: {
7
+ [T in ToastType]: ReactNode;
8
+ };
@@ -0,0 +1,19 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { InfoCircle as r, XCircle as s, CheckCircle as i } from "@untitled-ui/icons-react";
3
+ const a = {
4
+ success: "bg-white border-success-v2-500",
5
+ error: "bg-white border-error-v2-500",
6
+ warning: "bg-white border-warning-v2-500",
7
+ info: "bg-white border-blue-v2-500",
8
+ peach: "bg-gradient-to-br from-[#d74874] to-[#da805f] border-transparent"
9
+ }, c = {
10
+ success: /* @__PURE__ */ e(i, { className: "text-success-v2-500 size-6 shrink-0" }),
11
+ error: /* @__PURE__ */ e(s, { className: "text-error-v2-500 size-6 shrink-0" }),
12
+ warning: /* @__PURE__ */ e(r, { className: "text-warning-v2-500 size-6 shrink-0" }),
13
+ info: /* @__PURE__ */ e(r, { className: "text-blue-v2-500 size-6 shrink-0" }),
14
+ peach: /* @__PURE__ */ e(r, { className: "text-white size-6 shrink-0" })
15
+ };
16
+ export {
17
+ c as iconByToastType,
18
+ a as styleToastType
19
+ };
@@ -0,0 +1,4 @@
1
+ import { WrittenOnTheToast } from './types';
2
+ /** Where we store the newly cooked toasts. When a toast is created, it will appear here. */
3
+ export declare const Toaster: () => import("react").JSX.Element;
4
+ export declare const createToast: (newToast: WrittenOnTheToast) => void;
@@ -0,0 +1,35 @@
1
+ import { jsx as r } from "react/jsx-runtime";
2
+ import { useEffect as a } from "react";
3
+ import { ToastSlice as n } from "./ToastSlice.js";
4
+ import { useToastList as i } from "./use-toast-list.js";
5
+ import { Observable as c } from "../../utils/observable.js";
6
+ const l = () => window.isSecureContext ? crypto.randomUUID() : crypto.getRandomValues(new Uint32Array(1))[0].toString(), e = new c(), s = /* @__PURE__ */ new Set(), b = () => {
7
+ const o = i(e);
8
+ return a(() => {
9
+ const t = Symbol();
10
+ return s.add(t), () => {
11
+ s.delete(t);
12
+ };
13
+ }, []), /* @__PURE__ */ r("div", { className: "flex flex-col", children: o.map((t) => /* @__PURE__ */ r(
14
+ n,
15
+ {
16
+ toast: t,
17
+ observable: e
18
+ },
19
+ `toast-${t.id}`
20
+ )) });
21
+ }, T = (o) => {
22
+ process.env.NODE_ENV !== "production" && s.size === 0 && console.warn(
23
+ "[Toaster] createToast was called but no <Toaster> is mounted. This toast will be lost."
24
+ );
25
+ const t = {
26
+ ...o,
27
+ id: l(),
28
+ status: "stable"
29
+ };
30
+ e.notify(t);
31
+ };
32
+ export {
33
+ b as Toaster,
34
+ T as createToast
35
+ };
@@ -0,0 +1,14 @@
1
+ import { ReactNode } from 'react';
2
+ export type ToastType = "error" | "warning" | "success" | "info" | "peach";
3
+ type ToastStatus = "stable" | "dismissed" | "destroyed";
4
+ /** The name is Bon, Jambon. */
5
+ export interface WrittenOnTheToast {
6
+ type: ToastType;
7
+ message: string;
8
+ detail?: ReactNode;
9
+ }
10
+ export interface InternalToastProps extends WrittenOnTheToast {
11
+ id: string;
12
+ status: ToastStatus;
13
+ }
14
+ export {};
@@ -0,0 +1,4 @@
1
+ import { InternalToastProps } from './types';
2
+ import { Observable } from '../../utils/observable';
3
+ /** Returns the list of current existing toasts. */
4
+ export declare const useToastList: (observable: Observable<InternalToastProps>) => InternalToastProps[];
@@ -0,0 +1,27 @@
1
+ import { useState as d, useEffect as f } from "react";
2
+ import { flushSync as m } from "react-dom";
3
+ const c = (i) => {
4
+ const [u, r] = d([]);
5
+ return f(() => i.subscribe((s) => {
6
+ if (s.status === "dismissed") {
7
+ r(
8
+ (t) => t.map(
9
+ (e) => e.id === s.id ? { ...e, status: "dismissed" } : e
10
+ )
11
+ );
12
+ return;
13
+ }
14
+ if (s.status === "destroyed") {
15
+ r((t) => t.filter((e) => e.id !== s.id));
16
+ return;
17
+ }
18
+ setTimeout(() => {
19
+ m(() => {
20
+ r((t) => [...t, s]);
21
+ });
22
+ });
23
+ }), [i]), u;
24
+ };
25
+ export {
26
+ c as useToastList
27
+ };
@@ -7,5 +7,5 @@ interface Props {
7
7
  disabled?: boolean;
8
8
  className?: string;
9
9
  }
10
- export declare const Tooltip: ({ content, children, position, disabled, className, }: Props) => import("react/jsx-runtime").JSX.Element;
10
+ export declare const Tooltip: ({ content, children, position, disabled, className, }: Props) => import("react").JSX.Element;
11
11
  export {};
@@ -0,0 +1,9 @@
1
+ import { FilterOption } from './types';
2
+ export interface FilterDropdownProps {
3
+ label: string;
4
+ value: string | undefined;
5
+ options: FilterOption[];
6
+ onChange: (value: string | undefined) => void;
7
+ disabled?: boolean;
8
+ }
9
+ export declare const FilterDropdown: ({ label, value, options, onChange, disabled, }: FilterDropdownProps) => import("react").JSX.Element;
@@ -0,0 +1,57 @@
1
+ import { jsx as r, jsxs as m } from "react/jsx-runtime";
2
+ import { XClose as b, ChevronDown as v } from "@untitled-ui/icons-react";
3
+ import { cn as g } from "../utils/cn.js";
4
+ import { Dropdown as p } from "../components/dropdown/Dropdown.js";
5
+ const u = ({
6
+ label: n,
7
+ value: t,
8
+ options: i,
9
+ onChange: a,
10
+ disabled: o = !1
11
+ }) => {
12
+ var s;
13
+ const c = i.map((e) => ({
14
+ id: e.value,
15
+ label: e.label,
16
+ icon: e.icon
17
+ })), d = ((s = i.find((e) => e.value === t)) == null ? void 0 : s.label) ?? t, l = t !== void 0;
18
+ return /* @__PURE__ */ r(
19
+ p,
20
+ {
21
+ items: c,
22
+ selected: t,
23
+ onSelect: (e) => a(e.id),
24
+ disabled: o,
25
+ children: /* @__PURE__ */ m(
26
+ "button",
27
+ {
28
+ type: "button",
29
+ disabled: o,
30
+ className: g(
31
+ "inline-flex items-center justify-between gap-2 min-h-10 rounded-lg border border-gray-v2-300 bg-white px-3 py-2 text-sm font-semibold text-gray-v2-700 shadow-xs transition-all outline-2 outline-transparent hover:bg-gray-v2-50 focus:outline-brand-v2-400",
32
+ o && "cursor-not-allowed bg-gray-v2-50 text-gray-v2-400 border-gray-v2-200"
33
+ ),
34
+ children: [
35
+ /* @__PURE__ */ r("span", { children: l ? `${n}: ${d}` : n }),
36
+ l ? /* @__PURE__ */ r(
37
+ "span",
38
+ {
39
+ role: "button",
40
+ "aria-label": "Clear filter",
41
+ tabIndex: -1,
42
+ onClick: (e) => {
43
+ e.stopPropagation(), a(void 0);
44
+ },
45
+ className: "inline-flex shrink-0 items-center rounded text-gray-v2-500 hover:text-gray-v2-700",
46
+ children: /* @__PURE__ */ r(b, { className: "h-5 w-5" })
47
+ }
48
+ ) : /* @__PURE__ */ r(v, { className: "h-5 w-5 shrink-0 text-gray-v2-500" })
49
+ ]
50
+ }
51
+ )
52
+ }
53
+ );
54
+ };
55
+ export {
56
+ u as FilterDropdown
57
+ };
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+ export interface FilterOption {
3
+ value: string;
4
+ label: string;
5
+ icon?: ReactNode;
6
+ }
7
+ export interface ParamCodec<T> {
8
+ serialize: (value: T) => string | null;
9
+ deserialize: (raw: string) => T;
10
+ debounceMs?: number;
11
+ }
@@ -0,0 +1,5 @@
1
+ import { ParamCodec } from './types';
2
+ export declare const stringCodec: ParamCodec<string | undefined>;
3
+ export declare const numberCodec: ParamCodec<number | undefined>;
4
+ export declare const csvCodec: ParamCodec<string[]>;
5
+ export declare const searchCodec: ParamCodec<string | undefined>;
@@ -0,0 +1,20 @@
1
+ const i = {
2
+ serialize: (e) => e !== void 0 ? e : null,
3
+ deserialize: (e) => e
4
+ }, s = {
5
+ serialize: (e) => e !== void 0 ? String(e) : null,
6
+ deserialize: (e) => Number(e)
7
+ }, l = {
8
+ serialize: (e) => e.length > 0 ? e.join(",") : null,
9
+ deserialize: (e) => e.split(",")
10
+ }, n = {
11
+ serialize: (e) => e || null,
12
+ deserialize: (e) => e,
13
+ debounceMs: 300
14
+ };
15
+ export {
16
+ l as csvCodec,
17
+ s as numberCodec,
18
+ n as searchCodec,
19
+ i as stringCodec
20
+ };
@@ -0,0 +1,13 @@
1
+ import { ParamCodec } from './types';
2
+ interface UseFiltersOptions<T extends Record<string, unknown>> {
3
+ urlSync?: {
4
+ [K in keyof T]?: ParamCodec<T[K]>;
5
+ };
6
+ }
7
+ export declare function useFilters<T extends Record<string, unknown>>(defaults: T, options?: UseFiltersOptions<T>): {
8
+ params: T;
9
+ debouncedParams: T;
10
+ setParam: <K extends keyof T>(key: K, value: T[K]) => void;
11
+ reset: (keys?: Array<keyof T>) => void;
12
+ };
13
+ export {};
@@ -0,0 +1,63 @@
1
+ import { useState as f, useRef as y } from "react";
2
+ function d(r, e, i) {
3
+ return e ? Object.fromEntries(
4
+ Object.keys(r).map((n) => {
5
+ const S = e[n], m = i.get(n), w = S && m !== null ? S.deserialize(m) : r[n];
6
+ return [n, w];
7
+ })
8
+ ) : r;
9
+ }
10
+ function h(r, e) {
11
+ const i = new URLSearchParams(window.location.search);
12
+ e !== null ? i.set(r, e) : i.delete(r);
13
+ const n = i.toString(), S = n ? `${window.location.pathname}?${n}` : window.location.pathname;
14
+ window.history.replaceState(null, "", S);
15
+ }
16
+ function R(r, e) {
17
+ const [i, n] = f(
18
+ () => d(
19
+ r,
20
+ e == null ? void 0 : e.urlSync,
21
+ new URLSearchParams(window.location.search)
22
+ )
23
+ ), [S, m] = f(
24
+ () => d(
25
+ r,
26
+ e == null ? void 0 : e.urlSync,
27
+ new URLSearchParams(window.location.search)
28
+ )
29
+ ), w = y({});
30
+ function b(l, s) {
31
+ var a;
32
+ n((o) => ({ ...o, [l]: s }));
33
+ const u = (a = e == null ? void 0 : e.urlSync) == null ? void 0 : a[l], c = u == null ? void 0 : u.debounceMs, t = String(l);
34
+ c !== void 0 ? (clearTimeout(w.current[t]), w.current[t] = setTimeout(() => {
35
+ m((o) => ({ ...o, [l]: s }));
36
+ }, c)) : m((o) => ({ ...o, [l]: s })), u && h(t, u.serialize(s));
37
+ }
38
+ function P(l) {
39
+ const s = l ?? Object.keys(r);
40
+ n((c) => {
41
+ const t = { ...c };
42
+ for (const a of s) t[a] = r[a];
43
+ return t;
44
+ }), m((c) => {
45
+ const t = { ...c };
46
+ for (const a of s) {
47
+ const o = String(a);
48
+ clearTimeout(w.current[o]), delete w.current[o], t[a] = r[a];
49
+ }
50
+ return t;
51
+ });
52
+ const u = e == null ? void 0 : e.urlSync;
53
+ if (u)
54
+ for (const c of s) {
55
+ const t = u[c];
56
+ t && h(String(c), t.serialize(r[c]));
57
+ }
58
+ }
59
+ return { params: i, debouncedParams: S, setParam: b, reset: P };
60
+ }
61
+ export {
62
+ R as useFilters
63
+ };
@@ -0,0 +1,4 @@
1
+ export declare function useCountdown(initialSeconds: number): {
2
+ secondsLeft: number;
3
+ reset: () => void;
4
+ };
@@ -0,0 +1,18 @@
1
+ import { useState as u, useEffect as c, useCallback as f } from "react";
2
+ function l(e) {
3
+ const [t, r] = u(e);
4
+ c(() => {
5
+ if (t === 0) return;
6
+ const n = setInterval(() => {
7
+ r((o) => o - 1);
8
+ }, 1e3);
9
+ return () => clearInterval(n);
10
+ }, [t]);
11
+ const s = f(() => {
12
+ r(e);
13
+ }, [e]);
14
+ return { secondsLeft: t, reset: s };
15
+ }
16
+ export {
17
+ l as useCountdown
18
+ };
@@ -0,0 +1,23 @@
1
+ import o from "../components/loading-state/locale/en.json.js";
2
+ import n from "../components/notification/locale/en.json.js";
3
+ import t from "../components/table/locale/en.json.js";
4
+ import e from "../components/loading-state/locale/vi.json.js";
5
+ import i from "../components/notification/locale/vi.json.js";
6
+ import m from "../components/table/locale/vi.json.js";
7
+ const l = {
8
+ en: {
9
+ // --- Flat namespace keys matching folder paths (for i18n-ally) ---
10
+ "components/loading-state": o,
11
+ "components/notification": n,
12
+ "components/table": t
13
+ },
14
+ vi: {
15
+ // --- Flat namespace keys matching folder paths (for i18n-ally) ---
16
+ "components/loading-state": e,
17
+ "components/notification": i,
18
+ "components/table": m
19
+ }
20
+ };
21
+ export {
22
+ l as resources
23
+ };