@cystackapp/ui 1.5.0 → 2.0.1

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 (170) 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/BadgeTestStory.d.ts +1 -1
  16. package/dist/components/badge/variants/BadgeMore.d.ts +1 -1
  17. package/dist/components/badge/variants/BadgeMoreTestStory.d.ts +1 -1
  18. package/dist/components/badge/variants/BadgeTag.d.ts +1 -1
  19. package/dist/components/banner/Banner.d.ts +9 -0
  20. package/dist/components/banner/Banner.js +21 -0
  21. package/dist/components/breadcrumb/Breadcrumb.d.ts +13 -0
  22. package/dist/components/breadcrumb/Breadcrumb.js +36 -0
  23. package/dist/components/button/ButtonLoader.d.ts +1 -1
  24. package/dist/components/button/ButtonTestStory.d.ts +5 -5
  25. package/dist/components/card/Card.d.ts +1 -1
  26. package/dist/components/card/Card.stories-ct.d.ts +1 -1
  27. package/dist/components/card/CardBody.d.ts +1 -1
  28. package/dist/components/card/CardHeader.d.ts +1 -1
  29. package/dist/components/chart/chart-legend/ChartLegend.d.ts +38 -0
  30. package/dist/components/chart/chart-legend/ChartLegend.js +57 -0
  31. package/dist/components/chart/chart-legend/ChartLegendItem.d.ts +19 -0
  32. package/dist/components/chart/chart-legend/ChartLegendItem.js +30 -0
  33. package/dist/components/chart/chart-legend/types.d.ts +49 -0
  34. package/dist/components/chart/donut-chart/DonutChart.d.ts +55 -0
  35. package/dist/components/chart/donut-chart/DonutChart.js +110 -0
  36. package/dist/components/chart/donut-chart/DonutSegments.d.ts +25 -0
  37. package/dist/components/chart/donut-chart/DonutSegments.js +51 -0
  38. package/dist/components/chart/donut-chart/donut-tooltip.d.ts +20 -0
  39. package/dist/components/chart/donut-chart/donut-tooltip.js +37 -0
  40. package/dist/components/chart/types.d.ts +8 -0
  41. package/dist/components/checkbox/CheckboxTestStory.d.ts +7 -7
  42. package/dist/components/collapsible/Collapsible.d.ts +1 -1
  43. package/dist/components/combobox/Combobox.d.ts +1 -1
  44. package/dist/components/divider/Divider.d.ts +9 -0
  45. package/dist/components/divider/Divider.js +28 -0
  46. package/dist/components/drawer/Drawer.d.ts +8 -0
  47. package/dist/components/drawer/Drawer.js +68 -0
  48. package/dist/components/dropdown/Dropdown.d.ts +45 -0
  49. package/dist/components/dropdown/Dropdown.js +133 -0
  50. package/dist/components/dropdown/DropdownMenu.d.ts +20 -0
  51. package/dist/components/dropdown/DropdownMenu.js +78 -0
  52. package/dist/components/dropdown/DropdownMenuItem.d.ts +13 -0
  53. package/dist/components/dropdown/DropdownMenuItem.js +49 -0
  54. package/dist/components/dropdown/DropdownTestStory.d.ts +5 -0
  55. package/dist/components/dropdown/dropdown-utils.d.ts +4 -0
  56. package/dist/components/dropdown/dropdown-utils.js +14 -0
  57. package/dist/components/dropdown/types.d.ts +48 -0
  58. package/dist/components/dropdown/use-dropdown-keyboard.d.ts +12 -0
  59. package/dist/components/dropdown/use-dropdown-keyboard.js +49 -0
  60. package/dist/components/empty-state/EmptyState.d.ts +26 -0
  61. package/dist/components/empty-state/EmptyState.js +36 -0
  62. package/dist/components/error-state/ErrorState.d.ts +1 -1
  63. package/dist/components/featured-icon/FeaturedIcon.d.ts +12 -0
  64. package/dist/components/featured-icon/FeaturedIcon.js +44 -0
  65. package/dist/components/form-field/FormField.d.ts +13 -0
  66. package/dist/components/form-field/FormField.js +21 -0
  67. package/dist/components/keyboard-shortcut-label/KeyboardShortcutLabel.d.ts +8 -0
  68. package/dist/components/keyboard-shortcut-label/KeyboardShortcutLabel.js +18 -0
  69. package/dist/components/loading-state/Loader.d.ts +20 -0
  70. package/dist/components/loading-state/Loader.js +38 -0
  71. package/dist/components/loading-state/LoadingState.d.ts +15 -0
  72. package/dist/components/loading-state/LoadingState.js +47 -0
  73. package/dist/components/loading-state/locale/en.json.d.ts +6 -0
  74. package/dist/components/loading-state/locale/en.json.js +7 -0
  75. package/dist/components/loading-state/locale/vi.json.d.ts +6 -0
  76. package/dist/components/loading-state/locale/vi.json.js +7 -0
  77. package/dist/components/media/Media.d.ts +7 -0
  78. package/dist/components/media/Media.js +25 -0
  79. package/dist/components/modal/helpers/HeaderIcon.d.ts +1 -1
  80. package/dist/components/modal/helpers/Title.d.ts +1 -1
  81. package/dist/components/notification/NotificationBanner.d.ts +9 -0
  82. package/dist/components/notification/NotificationBanner.js +97 -0
  83. package/dist/components/notification/icons.d.ts +5 -0
  84. package/dist/components/notification/icons.js +29 -0
  85. package/dist/components/notification/index.d.ts +4 -0
  86. package/dist/components/notification/index.js +26 -0
  87. package/dist/components/notification/locale/en.json.d.ts +8 -0
  88. package/dist/components/notification/locale/en.json.js +7 -0
  89. package/dist/components/notification/locale/vi.json.d.ts +8 -0
  90. package/dist/components/notification/locale/vi.json.js +7 -0
  91. package/dist/components/operating-system-icon/OperatingSystemIcon.d.ts +6 -0
  92. package/dist/components/operating-system-icon/OperatingSystemIcon.js +19 -0
  93. package/dist/components/operating-system-icon/assets/logo-android.svg.js +5 -0
  94. package/dist/components/operating-system-icon/assets/logo-apple.svg.js +5 -0
  95. package/dist/components/operating-system-icon/assets/logo-ubuntu.svg.js +5 -0
  96. package/dist/components/operating-system-icon/assets/logo-windows-10.svg.js +5 -0
  97. package/dist/components/page-title/PageTitle.d.ts +1 -1
  98. package/dist/components/popover/Popover.d.ts +1 -1
  99. package/dist/components/progress-bar/ProgressBar.d.ts +9 -0
  100. package/dist/components/progress-bar/ProgressBar.js +31 -0
  101. package/dist/components/radio/Radio.d.ts +4 -0
  102. package/dist/components/radio/Radio.js +55 -0
  103. package/dist/components/searchbox/Searchbox.d.ts +7 -0
  104. package/dist/components/searchbox/Searchbox.js +15 -0
  105. package/dist/components/select/Select.d.ts +11 -0
  106. package/dist/components/select/Select.js +44 -0
  107. package/dist/components/sidebar/SidebarSecondMenu.d.ts +38 -0
  108. package/dist/components/sidebar/SidebarSecondMenu.js +50 -0
  109. package/dist/components/skeleton/Skeleton.d.ts +14 -0
  110. package/dist/components/skeleton/Skeleton.js +12 -0
  111. package/dist/components/stat-banner-card/StatBannerCard.d.ts +24 -0
  112. package/dist/components/stat-banner-card/StatBannerCard.js +49 -0
  113. package/dist/components/switch/Switch.d.ts +1 -1
  114. package/dist/components/table/Table.d.ts +32 -0
  115. package/dist/components/table/Table.js +128 -0
  116. package/dist/components/table/TableActionButton.d.ts +15 -0
  117. package/dist/components/table/TableActionButton.js +50 -0
  118. package/dist/components/table/TableCell.d.ts +8 -0
  119. package/dist/components/table/TableCell.js +26 -0
  120. package/dist/components/table/TableHeader.d.ts +15 -0
  121. package/dist/components/table/TableHeader.js +36 -0
  122. package/dist/components/table/TableHeaderCell.d.ts +10 -0
  123. package/dist/components/table/TableHeaderCell.js +35 -0
  124. package/dist/components/table/TablePagination.d.ts +6 -0
  125. package/dist/components/table/TablePagination.js +69 -0
  126. package/dist/components/table/TableRow.d.ts +12 -0
  127. package/dist/components/table/TableRow.js +9 -0
  128. package/dist/components/table/expandable/ExpandableTable.d.ts +30 -0
  129. package/dist/components/table/expandable/ExpandableTable.js +156 -0
  130. package/dist/components/table/hooks/use-fit-page-height.d.ts +14 -0
  131. package/dist/components/table/hooks/use-fit-page-height.js +21 -0
  132. package/dist/components/table/hooks/use-row-selection.d.ts +27 -0
  133. package/dist/components/table/hooks/use-row-selection.js +35 -0
  134. package/dist/components/table/locale/en.json.d.ts +13 -0
  135. package/dist/components/table/locale/en.json.js +21 -0
  136. package/dist/components/table/locale/vi.json.d.ts +13 -0
  137. package/dist/components/table/locale/vi.json.js +21 -0
  138. package/dist/components/table/table-utils.d.ts +10 -0
  139. package/dist/components/table/table-utils.js +10 -0
  140. package/dist/components/table/types.d.ts +84 -0
  141. package/dist/components/tabs/Tabs.d.ts +27 -0
  142. package/dist/components/tabs/Tabs.js +75 -0
  143. package/dist/components/tabs/TabsTestStory.d.ts +4 -0
  144. package/dist/components/tags-input/TagsInput.d.ts +18 -0
  145. package/dist/components/tags-input/TagsInput.js +78 -0
  146. package/dist/components/tags-input/TagsInputTestStory.d.ts +3 -0
  147. package/dist/components/textarea/Textarea.d.ts +7 -0
  148. package/dist/components/textarea/Textarea.js +36 -0
  149. package/dist/components/toast/ToastSlice.d.ts +1 -1
  150. package/dist/components/toast/index.d.ts +1 -1
  151. package/dist/components/tooltip/Tooltip.d.ts +1 -1
  152. package/dist/filters/FilterDropdown.d.ts +9 -0
  153. package/dist/filters/FilterDropdown.js +57 -0
  154. package/dist/filters/types.d.ts +11 -0
  155. package/dist/filters/url-params.d.ts +5 -0
  156. package/dist/filters/url-params.js +20 -0
  157. package/dist/filters/use-filters.d.ts +13 -0
  158. package/dist/filters/use-filters.js +63 -0
  159. package/dist/hooks/use-countdown.d.ts +4 -0
  160. package/dist/hooks/use-countdown.js +18 -0
  161. package/dist/i18n/resources.js +23 -0
  162. package/dist/index.d.ts +56 -0
  163. package/dist/index.js +126 -40
  164. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +421 -350
  165. package/dist/utils/key-typeguard.d.ts +5 -0
  166. package/dist/utils/key-typeguard.js +6 -0
  167. package/dist/utils/use-debounce.d.ts +1 -0
  168. package/dist/utils/use-debounce.js +11 -0
  169. package/package.json +32 -10
  170. package/theme.css +4 -1
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ value: string;
3
+ onChange: (value: string) => void;
4
+ placeholder?: string;
5
+ }
6
+ export declare const Searchbox: ({ value, onChange, placeholder }: Props) => import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1,15 @@
1
+ import { jsx as r } from "react/jsx-runtime";
2
+ import { SearchLg as m } from "@untitled-ui/icons-react";
3
+ import { Input as p } from "../input/Input.js";
4
+ const s = ({ value: o, onChange: t, placeholder: e }) => /* @__PURE__ */ r(
5
+ p,
6
+ {
7
+ prefix: /* @__PURE__ */ r(m, { className: "h-4 w-4 shrink-0 text-gray-v2-400" }),
8
+ value: o,
9
+ onChange: (a) => t(a.target.value),
10
+ placeholder: e
11
+ }
12
+ );
13
+ export {
14
+ s as Searchbox
15
+ };
@@ -0,0 +1,11 @@
1
+ import { DropdownEntry, DropdownItem } from '../dropdown/types';
2
+ interface Props {
3
+ id?: string;
4
+ items: DropdownEntry[];
5
+ selected: string;
6
+ onSelect: (item: DropdownItem) => void;
7
+ placeholder?: string;
8
+ disabled?: boolean;
9
+ }
10
+ export declare const Select: ({ id, items, selected, onSelect, placeholder, disabled, }: Props) => import("react").JSX.Element;
11
+ export {};
@@ -0,0 +1,44 @@
1
+ import { jsx as e, jsxs as c } from "react/jsx-runtime";
2
+ import { ChevronDown as m } from "@untitled-ui/icons-react";
3
+ import { Dropdown as b } from "../dropdown/Dropdown.js";
4
+ import { flattenItems as u } from "../dropdown/dropdown-utils.js";
5
+ const x = ({
6
+ id: o,
7
+ items: r,
8
+ selected: a,
9
+ onSelect: s,
10
+ placeholder: i = "",
11
+ disabled: l = !1
12
+ }) => {
13
+ var n;
14
+ const t = (n = u(r).find(
15
+ (d) => d.id === a
16
+ )) == null ? void 0 : n.label;
17
+ return /* @__PURE__ */ e(
18
+ b,
19
+ {
20
+ items: r,
21
+ selected: a,
22
+ onSelect: s,
23
+ syncWidth: !0,
24
+ disabled: l,
25
+ className: "w-full",
26
+ children: /* @__PURE__ */ c(
27
+ "button",
28
+ {
29
+ id: o,
30
+ type: "button",
31
+ disabled: l,
32
+ className: "w-full 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-left text-gray-v2-700 shadow-xs transition-all outline-2 outline-transparent hover:bg-gray-v2-50 focus:outline-brand-v2-400 disabled:cursor-not-allowed disabled:bg-gray-v2-50 disabled:text-gray-v2-400 disabled:border-gray-v2-200",
33
+ children: [
34
+ t ? /* @__PURE__ */ e("span", { className: "truncate", title: t, children: t }) : /* @__PURE__ */ e("span", { className: "truncate text-gray-v2-400", children: i }),
35
+ /* @__PURE__ */ e(m, { className: "h-4 w-4 shrink-0 text-gray-v2-500" })
36
+ ]
37
+ }
38
+ )
39
+ }
40
+ );
41
+ };
42
+ export {
43
+ x as Select
44
+ };
@@ -0,0 +1,38 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SidebarSecondMenuItem {
3
+ key: string;
4
+ label: ReactNode;
5
+ to: string;
6
+ active?: boolean;
7
+ }
8
+ interface SidebarSecondMenuProps {
9
+ /** Where the back button navigates to (e.g. the product dashboard). */
10
+ backTo: string;
11
+ backLabel: ReactNode;
12
+ title: ReactNode;
13
+ items: SidebarSecondMenuItem[];
14
+ /** Called on every link click — lets a mobile drawer close on navigation. */
15
+ onNavigate?: () => void;
16
+ className?: string;
17
+ }
18
+ /**
19
+ * Contextual second-level sidebar panel — the settings-style menu used by the
20
+ * CyStack platform when entering an area with its own sub-navigation (account
21
+ * settings, workspace settings…). Renders a back link, a panel title and a
22
+ * vertical list of sub-pages. Pair it with a collapsed icon rail on the left.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <SidebarSecondMenu
27
+ * backTo="/"
28
+ * backLabel="Dashboard"
29
+ * title="Account settings"
30
+ * items={[
31
+ * { key: "profile", label: "Personal details", to: "/settings/account", active: true },
32
+ * { key: "security", label: "Security", to: "/settings/security" },
33
+ * ]}
34
+ * />
35
+ * ```
36
+ */
37
+ export declare const SidebarSecondMenu: ({ backTo, backLabel, title, items, onNavigate, className, }: SidebarSecondMenuProps) => import("react").JSX.Element;
38
+ export {};
@@ -0,0 +1,50 @@
1
+ import { jsxs as l, jsx as e } from "react/jsx-runtime";
2
+ import { FlipBackward as m } from "@untitled-ui/icons-react";
3
+ import { Link as r } from "react-router-dom";
4
+ import { cn as a } from "../../utils/cn.js";
5
+ const b = ({
6
+ backTo: n,
7
+ backLabel: d,
8
+ title: i,
9
+ items: s,
10
+ onNavigate: t,
11
+ className: c
12
+ }) => /* @__PURE__ */ l(
13
+ "div",
14
+ {
15
+ className: a(
16
+ "px-4 py-6 flex flex-col gap-4 w-full overflow-y-auto overflow-x-hidden",
17
+ c
18
+ ),
19
+ children: [
20
+ /* @__PURE__ */ e(r, { to: n, onClick: t, className: "no-underline", children: /* @__PURE__ */ l(
21
+ "button",
22
+ {
23
+ type: "button",
24
+ className: "flex items-center gap-2 w-fit rounded-lg font-semibold text-md text-brand-v2-700 hover:text-brand-v2-800 whitespace-nowrap",
25
+ children: [
26
+ /* @__PURE__ */ e(m, { className: "h-5 w-5 min-w-5" }),
27
+ d
28
+ ]
29
+ }
30
+ ) }),
31
+ /* @__PURE__ */ e("span", { className: "text-lg font-semibold text-gray-v2-900 whitespace-nowrap", children: i }),
32
+ /* @__PURE__ */ e("div", { className: "flex flex-col gap-0.5", children: s.map((o) => /* @__PURE__ */ e(
33
+ r,
34
+ {
35
+ to: o.to,
36
+ onClick: t,
37
+ className: a(
38
+ "py-2 pl-3 pr-3 my-0.5 no-underline text-md font-semibold rounded-md transition-all",
39
+ o.active ? "bg-brand-v2-50 text-brand-v2-700" : "hover:bg-gray-v2-50 text-gray-v2-700 hover:text-gray-v2-700"
40
+ ),
41
+ children: o.label
42
+ },
43
+ o.key
44
+ )) })
45
+ ]
46
+ }
47
+ );
48
+ export {
49
+ b as SidebarSecondMenu
50
+ };
@@ -0,0 +1,14 @@
1
+ interface Props {
2
+ className?: string;
3
+ }
4
+ /**
5
+ * Loading placeholder block. Size it with width/height utilities:
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * <Skeleton className="h-4 w-48" />
10
+ * <Skeleton className="size-10 rounded-full" />
11
+ * ```
12
+ */
13
+ export declare const Skeleton: ({ className }: Props) => import("react").JSX.Element;
14
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import { cn as r } from "../../utils/cn.js";
3
+ const n = ({ className: e }) => /* @__PURE__ */ o(
4
+ "span",
5
+ {
6
+ "aria-hidden": "true",
7
+ className: r("block animate-pulse rounded-md bg-gray-v2-100", e)
8
+ }
9
+ );
10
+ export {
11
+ n as Skeleton
12
+ };
@@ -0,0 +1,24 @@
1
+ import { ReactNode } from 'react';
2
+ export type StatBannerColor = "blue" | "success" | "warning" | "error";
3
+ interface StatBannerCardProps {
4
+ label: ReactNode;
5
+ /** `null` renders as "--" (no data). */
6
+ value: number | null;
7
+ color: StatBannerColor;
8
+ isPercentage?: boolean;
9
+ isLoading?: boolean;
10
+ className?: string;
11
+ }
12
+ /**
13
+ * Colored stat banner — the tinted hero card with a big number and a small
14
+ * accent marker on the right edge, used at the top of asset list pages on the
15
+ * CyStack platform (e.g. "Tổng số tên miền 1839").
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * <StatBannerCard label="Total domains" value={1839} color="blue" />
20
+ * <StatBannerCard label="Vulnerable" value={0} color="success" isPercentage />
21
+ * ```
22
+ */
23
+ export declare const StatBannerCard: ({ label, value, color, isPercentage, isLoading, className, }: StatBannerCardProps) => import("react").JSX.Element;
24
+ export {};
@@ -0,0 +1,49 @@
1
+ import { jsxs as n, jsx as e, Fragment as c } from "react/jsx-runtime";
2
+ import { cn as t } from "../../utils/cn.js";
3
+ import { Loader as m } from "../loading-state/Loader.js";
4
+ const d = {
5
+ blue: "bg-blue-v2-100",
6
+ success: "bg-success-v2-100",
7
+ warning: "bg-warning-v2-100",
8
+ error: "bg-error-v2-100"
9
+ }, g = {
10
+ blue: "bg-blue-v2",
11
+ success: "bg-success-v2",
12
+ warning: "bg-warning-v2",
13
+ error: "bg-error-v2"
14
+ }, x = ({
15
+ label: a,
16
+ value: s,
17
+ color: r,
18
+ isPercentage: l = !1,
19
+ isLoading: i = !1,
20
+ className: o
21
+ }) => /* @__PURE__ */ n(
22
+ "div",
23
+ {
24
+ className: t(
25
+ "flex items-center justify-between rounded-xl text-gray-v2-900 transition-colors shadow-xs overflow-hidden relative",
26
+ d[r],
27
+ o
28
+ ),
29
+ children: [
30
+ /* @__PURE__ */ e("span", { className: "px-3 lg:px-6 text-lg font-medium", children: a }),
31
+ /* @__PURE__ */ e("span", { className: "px-3 lg:px-6 py-3 text-display-sm font-semibold", children: i ? /* @__PURE__ */ e("span", { className: "h-9.5 w-9.5 min-w-9.5 flex items-center justify-center", children: /* @__PURE__ */ e(m, { baseSize: 1.25, particleCount: 24 }) }) : s === null ? "--" : /* @__PURE__ */ n(c, { children: [
32
+ s.toFixed(),
33
+ l ? /* @__PURE__ */ e("span", { className: "text-display-xs", children: "%" }) : null
34
+ ] }) }),
35
+ /* @__PURE__ */ e(
36
+ "span",
37
+ {
38
+ className: t(
39
+ "absolute right-0 top-0 bottom-0 my-auto h-10 w-1.5 rounded-l-full",
40
+ g[r]
41
+ )
42
+ }
43
+ )
44
+ ]
45
+ }
46
+ );
47
+ export {
48
+ x as StatBannerCard
49
+ };
@@ -3,5 +3,5 @@ interface Props extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type" | "
3
3
  checked?: boolean;
4
4
  onChange?: (checked: boolean) => void;
5
5
  }
6
- export declare const Switch: ({ checked, onChange, className, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export declare const Switch: ({ checked, onChange, className, ...rest }: Props) => import("react").JSX.Element;
7
7
  export {};
@@ -0,0 +1,32 @@
1
+ import { To } from 'react-router-dom';
2
+ import { ColumnDef, EmptyStateConfig, PaginationState, SelectionState, SortState } from './types';
3
+ interface TableProps<TData> {
4
+ data: TData[] | undefined;
5
+ columns: ColumnDef<TData>[];
6
+ /** Returns the unique key for a row. */
7
+ rowKey: (row: TData) => string;
8
+ isLoading?: boolean;
9
+ selection?: SelectionState;
10
+ sort?: SortState;
11
+ pagination?: PaginationState;
12
+ /** Click handler for an entire row. Mutually exclusive with `getRowHref`. */
13
+ onRowClick?: (row: TData) => void;
14
+ /** When provided, rows render as `<Link>` elements navigating to this URL. */
15
+ getRowHref?: (row: TData) => To;
16
+ /** Configures the empty-state view. Falls back to a generic message. */
17
+ emptyState?: EmptyStateConfig;
18
+ /**
19
+ * When true, the table body height is calculated so the table never causes
20
+ * the page to scroll — it fits exactly within the remaining viewport height.
21
+ */
22
+ fitPageHeight?: boolean;
23
+ className?: string;
24
+ }
25
+ /**
26
+ * Data table with optional sorting, row selection, pagination, and row linking.
27
+ *
28
+ * Pass `fitPageHeight` to make the body height fill the remaining viewport
29
+ * without causing the page to scroll.
30
+ */
31
+ export declare const Table: <TData>({ data, columns, rowKey, isLoading, selection, sort, pagination, onRowClick, getRowHref, emptyState, fitPageHeight, className, }: TableProps<TData>) => import("react").JSX.Element;
32
+ export {};
@@ -0,0 +1,128 @@
1
+ import { jsx as l, jsxs as f, Fragment as J } from "react/jsx-runtime";
2
+ import { useMemo as K } from "react";
3
+ import { useTranslation as L } from "react-i18next";
4
+ import { Checkbox as O } from "../checkbox/Checkbox.js";
5
+ import { EmptyState as Q } from "../empty-state/EmptyState.js";
6
+ import { LoadingState as U } from "../loading-state/LoadingState.js";
7
+ import { cn as p } from "../../utils/cn.js";
8
+ import { TableCell as T } from "./TableCell.js";
9
+ import { TableHeader as V } from "./TableHeader.js";
10
+ import { TablePagination as W } from "./TablePagination.js";
11
+ import { TableRow as X } from "./TableRow.js";
12
+ import { buildGridTemplate as Y } from "./table-utils.js";
13
+ import { useRowSelection as Z } from "./hooks/use-row-selection.js";
14
+ import { useFitPageHeight as _ } from "./hooks/use-fit-page-height.js";
15
+ const nr = ({
16
+ data: d = [],
17
+ columns: e,
18
+ rowKey: h,
19
+ isLoading: a,
20
+ selection: o,
21
+ sort: N,
22
+ pagination: v,
23
+ onRowClick: m,
24
+ getRowHref: s,
25
+ emptyState: r,
26
+ fitPageHeight: b,
27
+ className: t
28
+ }) => {
29
+ const { t: k } = L("components/table"), { bodyRef: C, paginationRef: j, maxHeight: A } = _(), { isSelected: F, toggleRow: E, selectAllProps: G } = Z({
30
+ selection: o,
31
+ data: d,
32
+ rowKey: h,
33
+ isLoading: a
34
+ }), M = K(
35
+ () => Y(e, { hasSelection: !!o }),
36
+ [e, o]
37
+ ), P = a || d.length === 0;
38
+ return /* @__PURE__ */ l(
39
+ "div",
40
+ {
41
+ className: p(
42
+ "bg-white border border-gray-v2-200 shadow-xs rounded-xl flex flex-col min-h-0 overflow-hidden",
43
+ t
44
+ ),
45
+ children: P ? /* @__PURE__ */ l("div", { className: "flex items-center justify-center", children: a ? /* @__PURE__ */ l(U, {}) : /* @__PURE__ */ l(
46
+ Q,
47
+ {
48
+ title: (r == null ? void 0 : r.title) ?? k("emptyState"),
49
+ supportingText: r == null ? void 0 : r.supportingText,
50
+ type: r == null ? void 0 : r.type,
51
+ buttons: r == null ? void 0 : r.actions
52
+ }
53
+ ) }) : /* @__PURE__ */ f(J, { children: [
54
+ /* @__PURE__ */ f(
55
+ "div",
56
+ {
57
+ className: "grid flex-1 min-h-0 overflow-x-auto",
58
+ style: { gridTemplateColumns: M },
59
+ children: [
60
+ /* @__PURE__ */ l(
61
+ V,
62
+ {
63
+ columns: e,
64
+ sort: N,
65
+ selectAll: G
66
+ }
67
+ ),
68
+ /* @__PURE__ */ l(
69
+ "div",
70
+ {
71
+ ref: b ? C : void 0,
72
+ className: "grid grid-cols-subgrid col-span-full overflow-x-hidden overflow-y-auto",
73
+ style: b ? { maxHeight: A } : void 0,
74
+ children: d.map((n, u) => {
75
+ var g;
76
+ const c = h(n), x = F(c), q = u === d.length - 1, z = !!m || !!s, B = (g = o == null ? void 0 : o.disabledKeys) == null ? void 0 : g.includes(c);
77
+ return /* @__PURE__ */ f(
78
+ X,
79
+ {
80
+ href: s == null ? void 0 : s(n),
81
+ onClick: m && !s ? () => m(n) : void 0,
82
+ className: p(
83
+ x && "bg-gray-v2-50",
84
+ !q && "border-b border-gray-v2-200",
85
+ z && "cursor-pointer"
86
+ ),
87
+ children: [
88
+ o ? /* @__PURE__ */ l(T, { align: "center", children: /* @__PURE__ */ l(
89
+ O,
90
+ {
91
+ checked: x,
92
+ disabled: B,
93
+ onClick: (i) => E(c, i)
94
+ }
95
+ ) }) : null,
96
+ e.map((i, D) => /* @__PURE__ */ l(
97
+ T,
98
+ {
99
+ align: i.align,
100
+ className: i.cellClassName,
101
+ children: i.cell(n, u)
102
+ },
103
+ i.id ? i.id : D
104
+ ))
105
+ ]
106
+ },
107
+ c
108
+ );
109
+ })
110
+ }
111
+ )
112
+ ]
113
+ }
114
+ ),
115
+ v ? /* @__PURE__ */ l(
116
+ W,
117
+ {
118
+ ref: b ? j : void 0,
119
+ pagination: v
120
+ }
121
+ ) : null
122
+ ] })
123
+ }
124
+ );
125
+ };
126
+ export {
127
+ nr as Table
128
+ };
@@ -0,0 +1,15 @@
1
+ import { ComponentType, SVGProps } from 'react';
2
+ export interface TableActionItem {
3
+ id: string;
4
+ label: string;
5
+ icon?: ComponentType<SVGProps<SVGSVGElement>>;
6
+ danger?: boolean;
7
+ disabled?: boolean;
8
+ onSelect: () => void;
9
+ }
10
+ interface Props {
11
+ items: TableActionItem[];
12
+ disabled?: boolean;
13
+ }
14
+ export declare const TableActionButton: ({ items, disabled }: Props) => import("react").JSX.Element | null;
15
+ export {};
@@ -0,0 +1,50 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { DotsVertical as i } from "@untitled-ui/icons-react";
3
+ import { cn as d } from "../../utils/cn.js";
4
+ import { Dropdown as c } from "../dropdown/Dropdown.js";
5
+ const u = ({ items: n, disabled: r = !1 }) => {
6
+ const l = n.map((o) => ({
7
+ id: o.id,
8
+ label: o.label,
9
+ icon: o.icon ? /* @__PURE__ */ e(o.icon, { className: "h-5 w-5" }) : void 0,
10
+ danger: o.danger,
11
+ disabled: o.disabled
12
+ }));
13
+ return n.length === 0 ? null : /* @__PURE__ */ e(
14
+ "div",
15
+ {
16
+ onClick: (o) => {
17
+ o.stopPropagation(), o.preventDefault();
18
+ },
19
+ children: /* @__PURE__ */ e(
20
+ c,
21
+ {
22
+ items: l,
23
+ onSelect: (o) => {
24
+ const t = n.find((a) => a.id === o.id);
25
+ t == null || t.onSelect();
26
+ },
27
+ placement: "bottomRight",
28
+ disabled: r,
29
+ children: /* @__PURE__ */ e(
30
+ "button",
31
+ {
32
+ "aria-label": "Actions",
33
+ disabled: r,
34
+ className: d(
35
+ "inline-flex items-center justify-center rounded-md p-2.5",
36
+ "text-gray-v2-400 hover:bg-gray-v2-50",
37
+ "focus:outline-2 focus:outline-brand-v2-400",
38
+ "disabled:text-gray-v2-300 disabled:cursor-not-allowed disabled:hover:bg-transparent"
39
+ ),
40
+ children: /* @__PURE__ */ e(i, { className: "h-5 w-5" })
41
+ }
42
+ )
43
+ }
44
+ )
45
+ }
46
+ );
47
+ };
48
+ export {
49
+ u as TableActionButton
50
+ };
@@ -0,0 +1,8 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ import { ColumnAlign } from './types';
3
+ interface Props extends HTMLAttributes<HTMLDivElement> {
4
+ align?: ColumnAlign;
5
+ children?: ReactNode;
6
+ }
7
+ export declare const TableCell: ({ align, className, children, ...props }: Props) => import("react").JSX.Element;
8
+ export {};
@@ -0,0 +1,26 @@
1
+ import { jsx as s } from "react/jsx-runtime";
2
+ import { cn as n } from "../../utils/cn.js";
3
+ const f = {
4
+ left: "justify-start text-left",
5
+ center: "justify-center text-center",
6
+ right: "justify-end text-right"
7
+ }, l = ({
8
+ align: t = "left",
9
+ className: e,
10
+ children: r,
11
+ ...i
12
+ }) => /* @__PURE__ */ s(
13
+ "div",
14
+ {
15
+ ...i,
16
+ className: n(
17
+ "bg-inherit p-3 text-sm text-gray-v2-600 flex items-center gap-x-2",
18
+ f[t],
19
+ e
20
+ ),
21
+ children: r
22
+ }
23
+ );
24
+ export {
25
+ l as TableCell
26
+ };
@@ -0,0 +1,15 @@
1
+ import { ColumnDef, SortState } from './types';
2
+ interface SelectAllProps {
3
+ checked: boolean;
4
+ ready: boolean;
5
+ onChange: () => void;
6
+ }
7
+ interface Props<TData> {
8
+ columns: ColumnDef<TData>[];
9
+ sort?: SortState;
10
+ selectAll?: SelectAllProps;
11
+ /** Number of empty leading cells to render before the select-all and data columns. */
12
+ leadingCells?: number;
13
+ }
14
+ export declare const TableHeader: <TData>({ columns, sort, selectAll, leadingCells, }: Props<TData>) => import("react").JSX.Element;
15
+ export {};
@@ -0,0 +1,36 @@
1
+ import { jsxs as g, jsx as d } from "react/jsx-runtime";
2
+ import { Checkbox as l } from "../checkbox/Checkbox.js";
3
+ import { TableHeaderCell as n } from "./TableHeaderCell.js";
4
+ const C = ({
5
+ columns: o,
6
+ sort: r,
7
+ selectAll: a,
8
+ leadingCells: h = 0
9
+ }) => /* @__PURE__ */ g("div", { className: "grid grid-cols-subgrid col-span-full rounded-t-xl overflow-hidden", children: [
10
+ Array.from({ length: h }).map((e, s) => /* @__PURE__ */ d(n, {}, `leading-${s}`)),
11
+ a ? /* @__PURE__ */ d(n, { align: "center", children: a.ready ? /* @__PURE__ */ d(
12
+ l,
13
+ {
14
+ checked: a.checked,
15
+ onClick: a.onChange
16
+ }
17
+ ) : null }) : null,
18
+ o.map((e, s) => {
19
+ const i = e.sortKeys && r ? e.sortKeys.asc === r.value ? 1 : e.sortKeys.desc === r.value ? -1 : 0 : void 0, t = () => {
20
+ !e.sortKeys || !r || (i === 0 ? r.onChange(e.sortKeys.asc) : i === 1 ? r.onChange(e.sortKeys.desc) : i === -1 && r.onChange(""));
21
+ };
22
+ return /* @__PURE__ */ d(
23
+ n,
24
+ {
25
+ align: e.align,
26
+ sort: i,
27
+ onClick: e.sortKeys && r ? t : void 0,
28
+ children: e.header
29
+ },
30
+ e.id ? e.id : s
31
+ );
32
+ })
33
+ ] });
34
+ export {
35
+ C as TableHeader
36
+ };
@@ -0,0 +1,10 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ import { ColumnAlign } from './types';
3
+ interface Props extends HTMLAttributes<HTMLDivElement> {
4
+ align?: ColumnAlign;
5
+ /** -1: desc, 0: not active, 1: asc, undefined: not sortable. */
6
+ sort?: -1 | 0 | 1;
7
+ children?: ReactNode;
8
+ }
9
+ export declare const TableHeaderCell: ({ align, sort, className, children, ...props }: Props) => import("react").JSX.Element;
10
+ export {};
@@ -0,0 +1,35 @@
1
+ import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
+ import { ChevronUp as c, ChevronDown as i, ChevronSelectorVertical as m } from "@untitled-ui/icons-react";
3
+ import { cn as f } from "../../utils/cn.js";
4
+ const x = {
5
+ left: "justify-start text-left",
6
+ center: "justify-center text-center",
7
+ right: "justify-end text-right"
8
+ }, v = ({
9
+ align: s = "left",
10
+ sort: t,
11
+ className: n,
12
+ children: l,
13
+ ...o
14
+ }) => {
15
+ const r = t !== void 0;
16
+ return /* @__PURE__ */ a(
17
+ "div",
18
+ {
19
+ ...o,
20
+ className: f(
21
+ "bg-white text-xs font-semibold text-gray-v2 border-b border-gray-v2-200 p-3 flex items-center gap-1",
22
+ x[s],
23
+ r && "cursor-pointer select-none",
24
+ n
25
+ ),
26
+ children: [
27
+ l,
28
+ r ? /* @__PURE__ */ e("span", { className: "flex items-center text-gray-v2-400", children: t === 1 ? /* @__PURE__ */ e(c, { className: "h-3.5 w-3.5" }) : t === -1 ? /* @__PURE__ */ e(i, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ e(m, { className: "h-3.5 w-3.5" }) }) : null
29
+ ]
30
+ }
31
+ );
32
+ };
33
+ export {
34
+ v as TableHeaderCell
35
+ };
@@ -0,0 +1,6 @@
1
+ import { PaginationState } from './types';
2
+ interface Props {
3
+ pagination: PaginationState;
4
+ }
5
+ export declare const TablePagination: import('react').ForwardRefExoticComponent<Props & import('react').RefAttributes<HTMLDivElement>>;
6
+ export {};