@cystackapp/ui 1.5.0 → 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.
- package/LICENSE +21 -0
- package/README.md +77 -47
- package/dist/assets/background-pattern-grid.svg.js +7 -0
- package/dist/assets/empty-cloud.svg.js +5 -0
- package/dist/components/accordion/Accordion.d.ts +20 -0
- package/dist/components/accordion/Accordion.js +36 -0
- package/dist/components/accordion/AccordionTestStory.d.ts +3 -0
- package/dist/components/alert/Alert.d.ts +15 -0
- package/dist/components/alert/Alert.js +54 -0
- package/dist/components/avatar/Avatar.d.ts +13 -0
- package/dist/components/avatar/Avatar.js +64 -0
- package/dist/components/background-pattern/BackgroundPatternGrid.d.ts +1 -0
- package/dist/components/background-pattern/BackgroundPatternGrid.js +6 -0
- package/dist/components/badge/Badge.d.ts +1 -1
- package/dist/components/badge/BadgeTestStory.d.ts +1 -1
- package/dist/components/badge/variants/BadgeMore.d.ts +1 -1
- package/dist/components/badge/variants/BadgeMoreTestStory.d.ts +1 -1
- package/dist/components/badge/variants/BadgeTag.d.ts +1 -1
- package/dist/components/banner/Banner.d.ts +9 -0
- package/dist/components/banner/Banner.js +21 -0
- package/dist/components/breadcrumb/Breadcrumb.d.ts +13 -0
- package/dist/components/breadcrumb/Breadcrumb.js +36 -0
- package/dist/components/button/ButtonLoader.d.ts +1 -1
- package/dist/components/button/ButtonTestStory.d.ts +5 -5
- package/dist/components/card/Card.d.ts +1 -1
- package/dist/components/card/Card.stories-ct.d.ts +1 -1
- package/dist/components/card/CardBody.d.ts +1 -1
- package/dist/components/card/CardHeader.d.ts +1 -1
- package/dist/components/chart/chart-legend/ChartLegend.d.ts +38 -0
- package/dist/components/chart/chart-legend/ChartLegend.js +57 -0
- package/dist/components/chart/chart-legend/ChartLegendItem.d.ts +19 -0
- package/dist/components/chart/chart-legend/ChartLegendItem.js +30 -0
- package/dist/components/chart/chart-legend/types.d.ts +49 -0
- package/dist/components/chart/donut-chart/DonutChart.d.ts +55 -0
- package/dist/components/chart/donut-chart/DonutChart.js +110 -0
- package/dist/components/chart/donut-chart/DonutSegments.d.ts +25 -0
- package/dist/components/chart/donut-chart/DonutSegments.js +51 -0
- package/dist/components/chart/donut-chart/donut-tooltip.d.ts +20 -0
- package/dist/components/chart/donut-chart/donut-tooltip.js +37 -0
- package/dist/components/chart/types.d.ts +8 -0
- package/dist/components/checkbox/CheckboxTestStory.d.ts +7 -7
- package/dist/components/collapsible/Collapsible.d.ts +1 -1
- package/dist/components/combobox/Combobox.d.ts +1 -1
- package/dist/components/divider/Divider.d.ts +9 -0
- package/dist/components/divider/Divider.js +28 -0
- package/dist/components/drawer/Drawer.d.ts +8 -0
- package/dist/components/drawer/Drawer.js +68 -0
- package/dist/components/dropdown/Dropdown.d.ts +45 -0
- package/dist/components/dropdown/Dropdown.js +133 -0
- package/dist/components/dropdown/DropdownMenu.d.ts +20 -0
- package/dist/components/dropdown/DropdownMenu.js +78 -0
- package/dist/components/dropdown/DropdownMenuItem.d.ts +13 -0
- package/dist/components/dropdown/DropdownMenuItem.js +49 -0
- package/dist/components/dropdown/DropdownTestStory.d.ts +5 -0
- package/dist/components/dropdown/dropdown-utils.d.ts +4 -0
- package/dist/components/dropdown/dropdown-utils.js +14 -0
- package/dist/components/dropdown/types.d.ts +48 -0
- package/dist/components/dropdown/use-dropdown-keyboard.d.ts +12 -0
- package/dist/components/dropdown/use-dropdown-keyboard.js +49 -0
- package/dist/components/empty-state/EmptyState.d.ts +26 -0
- package/dist/components/empty-state/EmptyState.js +36 -0
- package/dist/components/error-state/ErrorState.d.ts +1 -1
- package/dist/components/featured-icon/FeaturedIcon.d.ts +12 -0
- package/dist/components/featured-icon/FeaturedIcon.js +44 -0
- package/dist/components/form-field/FormField.d.ts +13 -0
- package/dist/components/form-field/FormField.js +21 -0
- package/dist/components/keyboard-shortcut-label/KeyboardShortcutLabel.d.ts +8 -0
- package/dist/components/keyboard-shortcut-label/KeyboardShortcutLabel.js +18 -0
- package/dist/components/loading-state/Loader.d.ts +20 -0
- package/dist/components/loading-state/Loader.js +38 -0
- package/dist/components/loading-state/LoadingState.d.ts +15 -0
- package/dist/components/loading-state/LoadingState.js +47 -0
- package/dist/components/loading-state/locale/en.json.d.ts +6 -0
- package/dist/components/loading-state/locale/en.json.js +7 -0
- package/dist/components/loading-state/locale/vi.json.d.ts +6 -0
- package/dist/components/loading-state/locale/vi.json.js +7 -0
- package/dist/components/media/Media.d.ts +7 -0
- package/dist/components/media/Media.js +25 -0
- package/dist/components/modal/helpers/HeaderIcon.d.ts +1 -1
- package/dist/components/modal/helpers/Title.d.ts +1 -1
- package/dist/components/notification/NotificationBanner.d.ts +9 -0
- package/dist/components/notification/NotificationBanner.js +97 -0
- package/dist/components/notification/icons.d.ts +5 -0
- package/dist/components/notification/icons.js +29 -0
- package/dist/components/notification/index.d.ts +4 -0
- package/dist/components/notification/index.js +26 -0
- package/dist/components/notification/locale/en.json.d.ts +8 -0
- package/dist/components/notification/locale/en.json.js +7 -0
- package/dist/components/notification/locale/vi.json.d.ts +8 -0
- package/dist/components/notification/locale/vi.json.js +7 -0
- package/dist/components/operating-system-icon/OperatingSystemIcon.d.ts +6 -0
- package/dist/components/operating-system-icon/OperatingSystemIcon.js +19 -0
- package/dist/components/operating-system-icon/assets/logo-android.svg.js +5 -0
- package/dist/components/operating-system-icon/assets/logo-apple.svg.js +5 -0
- package/dist/components/operating-system-icon/assets/logo-ubuntu.svg.js +5 -0
- package/dist/components/operating-system-icon/assets/logo-windows-10.svg.js +5 -0
- package/dist/components/page-title/PageTitle.d.ts +1 -1
- package/dist/components/popover/Popover.d.ts +1 -1
- package/dist/components/progress-bar/ProgressBar.d.ts +9 -0
- package/dist/components/progress-bar/ProgressBar.js +31 -0
- package/dist/components/radio/Radio.d.ts +4 -0
- package/dist/components/radio/Radio.js +55 -0
- package/dist/components/searchbox/Searchbox.d.ts +7 -0
- package/dist/components/searchbox/Searchbox.js +15 -0
- package/dist/components/select/Select.d.ts +11 -0
- package/dist/components/select/Select.js +44 -0
- package/dist/components/skeleton/Skeleton.d.ts +14 -0
- package/dist/components/skeleton/Skeleton.js +12 -0
- package/dist/components/switch/Switch.d.ts +1 -1
- package/dist/components/table/Table.d.ts +32 -0
- package/dist/components/table/Table.js +128 -0
- package/dist/components/table/TableActionButton.d.ts +15 -0
- package/dist/components/table/TableActionButton.js +50 -0
- package/dist/components/table/TableCell.d.ts +8 -0
- package/dist/components/table/TableCell.js +26 -0
- package/dist/components/table/TableHeader.d.ts +15 -0
- package/dist/components/table/TableHeader.js +36 -0
- package/dist/components/table/TableHeaderCell.d.ts +10 -0
- package/dist/components/table/TableHeaderCell.js +35 -0
- package/dist/components/table/TablePagination.d.ts +6 -0
- package/dist/components/table/TablePagination.js +69 -0
- package/dist/components/table/TableRow.d.ts +12 -0
- package/dist/components/table/TableRow.js +9 -0
- package/dist/components/table/expandable/ExpandableTable.d.ts +30 -0
- package/dist/components/table/expandable/ExpandableTable.js +156 -0
- package/dist/components/table/hooks/use-fit-page-height.d.ts +14 -0
- package/dist/components/table/hooks/use-fit-page-height.js +21 -0
- package/dist/components/table/hooks/use-row-selection.d.ts +27 -0
- package/dist/components/table/hooks/use-row-selection.js +35 -0
- package/dist/components/table/locale/en.json.d.ts +13 -0
- package/dist/components/table/locale/en.json.js +21 -0
- package/dist/components/table/locale/vi.json.d.ts +13 -0
- package/dist/components/table/locale/vi.json.js +21 -0
- package/dist/components/table/table-utils.d.ts +10 -0
- package/dist/components/table/table-utils.js +10 -0
- package/dist/components/table/types.d.ts +84 -0
- package/dist/components/tabs/Tabs.d.ts +27 -0
- package/dist/components/tabs/Tabs.js +75 -0
- package/dist/components/tabs/TabsTestStory.d.ts +4 -0
- package/dist/components/tags-input/TagsInput.d.ts +18 -0
- package/dist/components/tags-input/TagsInput.js +78 -0
- package/dist/components/tags-input/TagsInputTestStory.d.ts +3 -0
- package/dist/components/textarea/Textarea.d.ts +7 -0
- package/dist/components/textarea/Textarea.js +36 -0
- package/dist/components/toast/ToastSlice.d.ts +1 -1
- package/dist/components/toast/index.d.ts +1 -1
- package/dist/components/tooltip/Tooltip.d.ts +1 -1
- package/dist/filters/FilterDropdown.d.ts +9 -0
- package/dist/filters/FilterDropdown.js +57 -0
- package/dist/filters/types.d.ts +11 -0
- package/dist/filters/url-params.d.ts +5 -0
- package/dist/filters/url-params.js +20 -0
- package/dist/filters/use-filters.d.ts +13 -0
- package/dist/filters/use-filters.js +63 -0
- package/dist/hooks/use-countdown.d.ts +4 -0
- package/dist/hooks/use-countdown.js +18 -0
- package/dist/i18n/resources.js +23 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +122 -40
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +421 -350
- package/dist/utils/key-typeguard.d.ts +5 -0
- package/dist/utils/key-typeguard.js +6 -0
- package/dist/utils/use-debounce.d.ts +1 -0
- package/dist/utils/use-debounce.js +11 -0
- package/package.json +28 -6
- package/theme.css +4 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ChartLegendProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Unified chart legend component.
|
|
4
|
+
*
|
|
5
|
+
* Renders a list of color-coded legend items with optional
|
|
6
|
+
* percentage, value, and unit display. Supports vertical,
|
|
7
|
+
* horizontal, and grid layouts.
|
|
8
|
+
*
|
|
9
|
+
* @example Vertical (default)
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <ChartLegend data={chartData} showPercentage />
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @example Horizontal
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <ChartLegend data={chartData} layout="horizontal" />
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example Grid (2-column)
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <ChartLegend data={chartData} layout="grid" columns={2} />
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example With unit
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <ChartLegend
|
|
27
|
+
* data={chartData}
|
|
28
|
+
* showPercentage
|
|
29
|
+
* getUnit={(n) => `${n} tickets`}
|
|
30
|
+
* />
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example Suppress empty state (parent handles it)
|
|
34
|
+
* ```tsx
|
|
35
|
+
* <ChartLegend data={chartData} emptyText={null} />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare const ChartLegend: import('react').ForwardRefExoticComponent<ChartLegendProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as v, useMemo as w } from "react";
|
|
3
|
+
import { cn as y } from "../../../utils/cn.js";
|
|
4
|
+
import { ChartLegendItem as C } from "./ChartLegendItem.js";
|
|
5
|
+
const N = {
|
|
6
|
+
vertical: "flex flex-col gap-1",
|
|
7
|
+
horizontal: "flex flex-row flex-wrap gap-x-3 gap-y-1",
|
|
8
|
+
// Grid base — column count is set via inline `gridTemplateColumns`.
|
|
9
|
+
grid: "grid gap-x-5 gap-y-1"
|
|
10
|
+
}, L = v(
|
|
11
|
+
({
|
|
12
|
+
data: a,
|
|
13
|
+
layout: l = "vertical",
|
|
14
|
+
columns: m = 2,
|
|
15
|
+
showPercentage: n = !1,
|
|
16
|
+
showValue: p = !1,
|
|
17
|
+
getUnit: i,
|
|
18
|
+
emptyText: o = "No data",
|
|
19
|
+
itemClassName: c,
|
|
20
|
+
className: d,
|
|
21
|
+
style: s,
|
|
22
|
+
...f
|
|
23
|
+
}, g) => {
|
|
24
|
+
const t = w(
|
|
25
|
+
() => a.reduce((e, h) => e + h.value, 0),
|
|
26
|
+
[a]
|
|
27
|
+
), x = t === 0, u = l === "grid" ? {
|
|
28
|
+
gridTemplateColumns: `repeat(${m}, minmax(0, 1fr))`,
|
|
29
|
+
...s
|
|
30
|
+
} : s;
|
|
31
|
+
return /* @__PURE__ */ r(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
ref: g,
|
|
35
|
+
className: y(N[l], d),
|
|
36
|
+
style: u,
|
|
37
|
+
...f,
|
|
38
|
+
children: x && o !== null ? /* @__PURE__ */ r("span", { className: "text-sm text-gray-v2-600 whitespace-nowrap col-span-full", children: o }) : a.map((e) => /* @__PURE__ */ r(
|
|
39
|
+
C,
|
|
40
|
+
{
|
|
41
|
+
item: e,
|
|
42
|
+
totalValue: t,
|
|
43
|
+
showPercentage: n,
|
|
44
|
+
showValue: p,
|
|
45
|
+
getUnit: i,
|
|
46
|
+
className: c
|
|
47
|
+
},
|
|
48
|
+
`legend-${e.id}`
|
|
49
|
+
))
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
L.displayName = "ChartLegend";
|
|
55
|
+
export {
|
|
56
|
+
L as ChartLegend
|
|
57
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ChartDataItem } from '../types';
|
|
2
|
+
interface Props {
|
|
3
|
+
item: ChartDataItem;
|
|
4
|
+
totalValue: number;
|
|
5
|
+
showPercentage: boolean;
|
|
6
|
+
showValue: boolean;
|
|
7
|
+
getUnit?: (count: number) => string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A single legend row: color indicator + label text.
|
|
12
|
+
*
|
|
13
|
+
* Display format (all options enabled):
|
|
14
|
+
* ```
|
|
15
|
+
* [●] 42% Critical · 12 tickets
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const ChartLegendItem: ({ item, totalValue, showPercentage, showValue, getUnit, className, }: Props) => import("react").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsxs as l, jsx as u } from "react/jsx-runtime";
|
|
2
|
+
import { cn as m } from "../../../utils/cn.js";
|
|
3
|
+
const i = ({
|
|
4
|
+
item: e,
|
|
5
|
+
totalValue: n,
|
|
6
|
+
showPercentage: c,
|
|
7
|
+
showValue: a,
|
|
8
|
+
getUnit: r,
|
|
9
|
+
className: o
|
|
10
|
+
}) => {
|
|
11
|
+
const d = n > 0 ? (e.value / n * 100).toFixed(0) : "0", s = r ? r(e.value) : null;
|
|
12
|
+
return /* @__PURE__ */ l("div", { className: m("flex items-center gap-1.5", o), children: [
|
|
13
|
+
/* @__PURE__ */ u(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
className: "w-2 h-2 min-w-2 shrink-0 rounded-full",
|
|
17
|
+
style: { backgroundColor: e.color }
|
|
18
|
+
}
|
|
19
|
+
),
|
|
20
|
+
/* @__PURE__ */ l("span", { className: "text-sm text-gray-v2-600 whitespace-nowrap", children: [
|
|
21
|
+
c && n > 0 ? `${d}% ` : null,
|
|
22
|
+
e.name,
|
|
23
|
+
a && n > 0 ? ` (${e.value})` : null,
|
|
24
|
+
s ? ` · ${s}` : null
|
|
25
|
+
] })
|
|
26
|
+
] });
|
|
27
|
+
};
|
|
28
|
+
export {
|
|
29
|
+
i as ChartLegendItem
|
|
30
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
import { ChartDataItem } from '../types';
|
|
3
|
+
/** Controls how legend items are arranged. */
|
|
4
|
+
export type ChartLegendLayout = "vertical" | "horizontal" | "grid";
|
|
5
|
+
/**
|
|
6
|
+
* Props for the `ChartLegend` component.
|
|
7
|
+
*
|
|
8
|
+
* At minimum, provide `data`. The component renders a vertical
|
|
9
|
+
* list of legend items by default.
|
|
10
|
+
*/
|
|
11
|
+
export interface ChartLegendProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
12
|
+
/** Chart data entries. Uses `ChartDataItem` from `DonutChart`. */
|
|
13
|
+
data: ChartDataItem[];
|
|
14
|
+
/**
|
|
15
|
+
* Layout direction.
|
|
16
|
+
* - `"vertical"` (default): single column, stacked top-to-bottom.
|
|
17
|
+
* - `"horizontal"`: items flow left-to-right with wrapping.
|
|
18
|
+
* - `"grid"`: CSS grid with configurable columns.
|
|
19
|
+
*/
|
|
20
|
+
layout?: ChartLegendLayout;
|
|
21
|
+
/**
|
|
22
|
+
* Number of columns when `layout="grid"`. Default: `2`.
|
|
23
|
+
* Ignored for other layouts.
|
|
24
|
+
*/
|
|
25
|
+
columns?: number;
|
|
26
|
+
/** Show the percentage of each item relative to the total. Default: `false`. */
|
|
27
|
+
showPercentage?: boolean;
|
|
28
|
+
/** Show the raw numeric value of each item. Default: `false`. */
|
|
29
|
+
showValue?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Format a unit label for each item's value.
|
|
32
|
+
* Receives the item's value and should return a formatted string.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* getUnit={(n) => `${n} tickets`}
|
|
37
|
+
* // item.value = 12 → "12 tickets"
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
getUnit?: (count: number) => string;
|
|
41
|
+
/**
|
|
42
|
+
* Text to display when all items have zero value (totalCount === 0).
|
|
43
|
+
* Pass `null` to suppress the empty state entirely.
|
|
44
|
+
* Default: `"No data"`.
|
|
45
|
+
*/
|
|
46
|
+
emptyText?: string | null;
|
|
47
|
+
/** Additional CSS classes applied to each legend item row. */
|
|
48
|
+
itemClassName?: string;
|
|
49
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ReactNode, SVGAttributes } from 'react';
|
|
2
|
+
import { DonutTooltipPayload } from './donut-tooltip';
|
|
3
|
+
import { ChartDataItem } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Props for the `DonutChart` component.
|
|
6
|
+
*
|
|
7
|
+
* At minimum, provide `data`. The chart renders a built-in tooltip by default;
|
|
8
|
+
* pass `tooltip` to override, or `tooltip={null}` to disable.
|
|
9
|
+
*/
|
|
10
|
+
interface DonutChartProps extends Omit<SVGAttributes<SVGSVGElement>, "viewBox"> {
|
|
11
|
+
/** Chart data slices. Zero-value items are filtered automatically. */
|
|
12
|
+
data: ChartDataItem[];
|
|
13
|
+
/**
|
|
14
|
+
* Custom tooltip renderer. Receives the hovered item, total value, and unit.
|
|
15
|
+
* - Omit to use the built-in tooltip.
|
|
16
|
+
* - Pass `null` to disable tooltips entirely.
|
|
17
|
+
*/
|
|
18
|
+
tooltip?: ((payload: DonutTooltipPayload) => ReactNode) | null;
|
|
19
|
+
/** Format unit label for tooltip display. Receives the hovered item's value. */
|
|
20
|
+
getUnit?: (count: number) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Ratio of the inner hole radius to the outer radius.
|
|
23
|
+
* - `0` renders a pie chart (no hole).
|
|
24
|
+
* - `0.56` is the default donut.
|
|
25
|
+
* - `1` is degenerate (invisible).
|
|
26
|
+
*/
|
|
27
|
+
holeRatio?: number;
|
|
28
|
+
/** Color of the empty-state placeholder ring. */
|
|
29
|
+
emptyColor?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* SVG donut chart with built-in tooltip.
|
|
33
|
+
*
|
|
34
|
+
* Use `className` to control the rendered size, e.g. `className="w-32 h-32"`.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // Minimal — tooltip works out of the box
|
|
39
|
+
* <DonutChart data={[
|
|
40
|
+
* { id: "a", name: "Critical", value: 12, color: "#e11d48" },
|
|
41
|
+
* { id: "b", name: "High", value: 25, color: "#f97316" },
|
|
42
|
+
* ]} />
|
|
43
|
+
*
|
|
44
|
+
* // Custom size via className
|
|
45
|
+
* <DonutChart data={chartData} className="w-40 h-40" />
|
|
46
|
+
*
|
|
47
|
+
* // Pie chart (no hole)
|
|
48
|
+
* <DonutChart data={chartData} holeRatio={0} />
|
|
49
|
+
*
|
|
50
|
+
* // Disable tooltip
|
|
51
|
+
* <DonutChart data={chartData} tooltip={null} />
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare const DonutChart: import('react').ForwardRefExoticComponent<DonutChartProps & import('react').RefAttributes<SVGSVGElement>>;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { jsxs as m, Fragment as E, jsx as d } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as C, useMemo as p, useState as A, useCallback as R } from "react";
|
|
3
|
+
import { computeSegments as w, DonutSegments as F } from "./DonutSegments.js";
|
|
4
|
+
import { defaultTooltipRenderer as I, renderTooltipPortal as j } from "./donut-tooltip.js";
|
|
5
|
+
const v = 200, N = 0.56, P = "var(--color-gray-v2-200)", n = v / 2, o = { x: n, y: n }, U = C(
|
|
6
|
+
({
|
|
7
|
+
data: s,
|
|
8
|
+
tooltip: y = I,
|
|
9
|
+
getUnit: a,
|
|
10
|
+
holeRatio: T = N,
|
|
11
|
+
emptyColor: D = P,
|
|
12
|
+
className: L,
|
|
13
|
+
...M
|
|
14
|
+
}, O) => {
|
|
15
|
+
const l = n * T, S = p(
|
|
16
|
+
() => s.filter((e) => e.value > 0),
|
|
17
|
+
[s]
|
|
18
|
+
), r = p(
|
|
19
|
+
() => s.reduce((e, u) => e + u.value, 0),
|
|
20
|
+
[s]
|
|
21
|
+
), [i, g] = A({ x: 0, y: 0, visible: !1, payload: null }), h = R(
|
|
22
|
+
(e, u, b) => {
|
|
23
|
+
g({
|
|
24
|
+
x: u + 8,
|
|
25
|
+
y: b + 8,
|
|
26
|
+
visible: !0,
|
|
27
|
+
payload: {
|
|
28
|
+
item: e,
|
|
29
|
+
totalValue: r,
|
|
30
|
+
unit: a ? a(e.value) : ""
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
[r, a]
|
|
35
|
+
), f = R(() => {
|
|
36
|
+
g((e) => ({ ...e, visible: !1, payload: null }));
|
|
37
|
+
}, []), t = p(
|
|
38
|
+
() => w(
|
|
39
|
+
S,
|
|
40
|
+
r,
|
|
41
|
+
n,
|
|
42
|
+
l,
|
|
43
|
+
o
|
|
44
|
+
),
|
|
45
|
+
[S, r, l]
|
|
46
|
+
), _ = t.length > 1, c = t.length === 1, x = t.length === 0;
|
|
47
|
+
return /* @__PURE__ */ m(E, { children: [
|
|
48
|
+
/* @__PURE__ */ m(
|
|
49
|
+
"svg",
|
|
50
|
+
{
|
|
51
|
+
ref: O,
|
|
52
|
+
className: L,
|
|
53
|
+
viewBox: `0 0 ${v} ${v}`,
|
|
54
|
+
...M,
|
|
55
|
+
children: [
|
|
56
|
+
_ && /* @__PURE__ */ d(
|
|
57
|
+
F,
|
|
58
|
+
{
|
|
59
|
+
segments: t,
|
|
60
|
+
outerRadius: n,
|
|
61
|
+
innerRadius: l,
|
|
62
|
+
center: o,
|
|
63
|
+
onSegmentEnter: h,
|
|
64
|
+
onSegmentLeave: f
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
(c || x) && /* @__PURE__ */ m(E, { children: [
|
|
68
|
+
/* @__PURE__ */ d(
|
|
69
|
+
"circle",
|
|
70
|
+
{
|
|
71
|
+
cx: o.x,
|
|
72
|
+
cy: o.y,
|
|
73
|
+
r: n,
|
|
74
|
+
fill: c ? t[0].item.color : D,
|
|
75
|
+
opacity: x ? 0.4 : 1,
|
|
76
|
+
onMouseMove: c ? (e) => h(
|
|
77
|
+
t[0].item,
|
|
78
|
+
e.clientX,
|
|
79
|
+
e.clientY
|
|
80
|
+
) : void 0,
|
|
81
|
+
onMouseOut: c ? f : void 0
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
l > 0 && /* @__PURE__ */ d(
|
|
85
|
+
"circle",
|
|
86
|
+
{
|
|
87
|
+
cx: o.x,
|
|
88
|
+
cy: o.y,
|
|
89
|
+
r: l,
|
|
90
|
+
fill: "white"
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
] })
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
),
|
|
97
|
+
y && j(
|
|
98
|
+
i.y,
|
|
99
|
+
i.x,
|
|
100
|
+
i.visible,
|
|
101
|
+
i.payload,
|
|
102
|
+
y
|
|
103
|
+
)
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
U.displayName = "DonutChart";
|
|
108
|
+
export {
|
|
109
|
+
U as DonutChart
|
|
110
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ChartDataItem } from '../types';
|
|
2
|
+
export interface Point {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}
|
|
6
|
+
/** Pre-computed geometry for a single donut segment. */
|
|
7
|
+
export interface DonutSegment {
|
|
8
|
+
item: ChartDataItem;
|
|
9
|
+
startAngle: number;
|
|
10
|
+
endAngle: number;
|
|
11
|
+
outerStart: Point;
|
|
12
|
+
outerEnd: Point;
|
|
13
|
+
innerEnd: Point;
|
|
14
|
+
}
|
|
15
|
+
export declare function computeSegments(data: ChartDataItem[], totalValue: number, outerRadius: number, innerRadius: number, center: Point): DonutSegment[];
|
|
16
|
+
interface Props {
|
|
17
|
+
segments: DonutSegment[];
|
|
18
|
+
outerRadius: number;
|
|
19
|
+
innerRadius: number;
|
|
20
|
+
center: Point;
|
|
21
|
+
onSegmentEnter: (item: ChartDataItem, x: number, y: number) => void;
|
|
22
|
+
onSegmentLeave: () => void;
|
|
23
|
+
}
|
|
24
|
+
export declare const DonutSegments: ({ segments, outerRadius, innerRadius, center, onSegmentEnter, onSegmentLeave, }: Props) => import("react").JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsx as $, Fragment as p } from "react/jsx-runtime";
|
|
2
|
+
function l(o, e, t) {
|
|
3
|
+
const r = o * Math.PI / 180;
|
|
4
|
+
return {
|
|
5
|
+
x: Math.sin(r) * e + t.x,
|
|
6
|
+
y: -Math.cos(r) * e + t.y
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function m(o, e, t, r) {
|
|
10
|
+
const c = Math.abs(t - e) % 360 > 180 ? 1 : 0, u = t >= e ? 1 : 0, n = l(t, o, r);
|
|
11
|
+
return `A ${o} ${o} 0 ${c} ${u} ${n.x} ${n.y}`;
|
|
12
|
+
}
|
|
13
|
+
function M(o, e, t, r) {
|
|
14
|
+
const { outerStart: c, innerEnd: u, startAngle: n, endAngle: i } = o, a = m(e, n, i, r), s = m(t, i, n, r);
|
|
15
|
+
return `M ${c.x} ${c.y} ${a} L ${u.x} ${u.y} ${s}`;
|
|
16
|
+
}
|
|
17
|
+
function h(o, e, t, r, c) {
|
|
18
|
+
let u = 0;
|
|
19
|
+
return o.map((n) => {
|
|
20
|
+
const i = n.value / e * 360, a = u, s = a + i;
|
|
21
|
+
return u = s, {
|
|
22
|
+
item: n,
|
|
23
|
+
startAngle: a,
|
|
24
|
+
endAngle: s,
|
|
25
|
+
outerStart: l(a, t, c),
|
|
26
|
+
outerEnd: l(s, t, c),
|
|
27
|
+
innerEnd: l(s, r, c)
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const x = ({
|
|
32
|
+
segments: o,
|
|
33
|
+
outerRadius: e,
|
|
34
|
+
innerRadius: t,
|
|
35
|
+
center: r,
|
|
36
|
+
onSegmentEnter: c,
|
|
37
|
+
onSegmentLeave: u
|
|
38
|
+
}) => /* @__PURE__ */ $(p, { children: o.map((n) => /* @__PURE__ */ $(
|
|
39
|
+
"path",
|
|
40
|
+
{
|
|
41
|
+
fill: n.item.color,
|
|
42
|
+
d: M(n, e, t, r),
|
|
43
|
+
onMouseMove: (i) => c(n.item, i.clientX, i.clientY),
|
|
44
|
+
onMouseOut: u
|
|
45
|
+
},
|
|
46
|
+
n.item.id
|
|
47
|
+
)) });
|
|
48
|
+
export {
|
|
49
|
+
x as DonutSegments,
|
|
50
|
+
h as computeSegments
|
|
51
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ChartDataItem } from '../types';
|
|
3
|
+
/** Payload passed to a custom tooltip renderer. */
|
|
4
|
+
export interface DonutTooltipPayload {
|
|
5
|
+
item: ChartDataItem;
|
|
6
|
+
totalValue: number;
|
|
7
|
+
/** Formatted unit label, e.g. "tickets". Empty string when `getUnit` is not provided. */
|
|
8
|
+
unit: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Built-in tooltip renderer.
|
|
12
|
+
* Shows the item name, value with unit, and percentage of total.
|
|
13
|
+
*/
|
|
14
|
+
export declare const defaultTooltipRenderer: ({ item, totalValue, unit, }: DonutTooltipPayload) => ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* Render the tooltip into `document.body` via a portal.
|
|
17
|
+
* This is a plain function (not a component) to avoid `ReactPortal` vs `ReactNode`
|
|
18
|
+
* type mismatch issues between `@types/react` and `@types/react-dom`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderTooltipPortal(top: number, left: number, visible: boolean, payload: DonutTooltipPayload | null, renderer: (payload: DonutTooltipPayload) => ReactNode): ReactNode;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsxs as t, jsx as d } from "react/jsx-runtime";
|
|
2
|
+
import { createPortal as c } from "react-dom";
|
|
3
|
+
const a = ({
|
|
4
|
+
item: e,
|
|
5
|
+
totalValue: r,
|
|
6
|
+
unit: n
|
|
7
|
+
}) => {
|
|
8
|
+
const o = r > 0 ? (e.value / r * 100).toFixed() : "0";
|
|
9
|
+
return /* @__PURE__ */ t(
|
|
10
|
+
"div",
|
|
11
|
+
{
|
|
12
|
+
style: { backgroundColor: e.color },
|
|
13
|
+
className: "rounded-md p-3 shadow-lg whitespace-pre text-white font-medium text-sm",
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ d("p", { children: e.name }),
|
|
16
|
+
/* @__PURE__ */ t("p", { children: [
|
|
17
|
+
e.value,
|
|
18
|
+
" ",
|
|
19
|
+
n,
|
|
20
|
+
" (",
|
|
21
|
+
o,
|
|
22
|
+
"%)"
|
|
23
|
+
] })
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
function p(e, r, n, o, l) {
|
|
29
|
+
return !n || !o ? null : c(
|
|
30
|
+
/* @__PURE__ */ d("div", { style: { top: e, left: r }, className: "fixed z-10 pointer-events-none", children: l(o) }),
|
|
31
|
+
document.body
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
a as defaultTooltipRenderer,
|
|
36
|
+
p as renderTooltipPortal
|
|
37
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export declare function CheckboxUnchecked(): import("react
|
|
2
|
-
export declare function CheckboxChecked(): import("react
|
|
3
|
-
export declare function CheckboxIndeterminate(): import("react
|
|
4
|
-
export declare function CheckboxCheckedAndIndeterminate(): import("react
|
|
5
|
-
export declare function CheckboxDisabled(): import("react
|
|
6
|
-
export declare function CheckboxDisabledChecked(): import("react
|
|
7
|
-
export declare function CheckboxWithClickCounter(): import("react
|
|
1
|
+
export declare function CheckboxUnchecked(): import("react").JSX.Element;
|
|
2
|
+
export declare function CheckboxChecked(): import("react").JSX.Element;
|
|
3
|
+
export declare function CheckboxIndeterminate(): import("react").JSX.Element;
|
|
4
|
+
export declare function CheckboxCheckedAndIndeterminate(): import("react").JSX.Element;
|
|
5
|
+
export declare function CheckboxDisabled(): import("react").JSX.Element;
|
|
6
|
+
export declare function CheckboxDisabledChecked(): import("react").JSX.Element;
|
|
7
|
+
export declare function CheckboxWithClickCounter(): import("react").JSX.Element;
|
|
@@ -17,5 +17,5 @@ interface Props {
|
|
|
17
17
|
* @param expanded - Whether the content is shown.
|
|
18
18
|
* @param duration - Transition duration in milliseconds (default: 300).
|
|
19
19
|
*/
|
|
20
|
-
export declare const Collapsible: ({ expanded, duration, className, children, }: Props) => import("react
|
|
20
|
+
export declare const Collapsible: ({ expanded, duration, className, children, }: Props) => import("react").JSX.Element;
|
|
21
21
|
export {};
|
|
@@ -92,5 +92,5 @@ interface Props {
|
|
|
92
92
|
*
|
|
93
93
|
* <Combobox value={value} onChange={handleChange} error={error} />
|
|
94
94
|
*/
|
|
95
|
-
export declare const Combobox: ({ id, value, onChange, onBlur, getSuggestions, delimiter, placeholder, error, disabled, getBadgeProps, getLabel, }: Props) => import("react
|
|
95
|
+
export declare const Combobox: ({ id, value, onChange, onBlur, getSuggestions, delimiter, placeholder, error, disabled, getBadgeProps, getLabel, }: Props) => import("react").JSX.Element;
|
|
96
96
|
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Optional content rendered in the middle of the divider. */
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
orientation?: "horizontal" | "vertical";
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const Divider: ({ children, orientation, className, }: Props) => import("react").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as r, jsxs as l } from "react/jsx-runtime";
|
|
2
|
+
import { cn as e } from "../../utils/cn.js";
|
|
3
|
+
const p = ({
|
|
4
|
+
children: t,
|
|
5
|
+
orientation: s = "horizontal",
|
|
6
|
+
className: a
|
|
7
|
+
}) => s === "vertical" ? /* @__PURE__ */ r(
|
|
8
|
+
"span",
|
|
9
|
+
{
|
|
10
|
+
role: "separator",
|
|
11
|
+
"aria-orientation": "vertical",
|
|
12
|
+
className: e("self-stretch w-px bg-gray-v2-200", a)
|
|
13
|
+
}
|
|
14
|
+
) : t ? /* @__PURE__ */ l(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
role: "separator",
|
|
18
|
+
className: e("flex items-center gap-3 w-full", a),
|
|
19
|
+
children: [
|
|
20
|
+
/* @__PURE__ */ r("span", { className: "flex-1 h-px bg-gray-v2-200" }),
|
|
21
|
+
/* @__PURE__ */ r("span", { className: "text-sm font-medium text-gray-v2-600 whitespace-nowrap", children: t }),
|
|
22
|
+
/* @__PURE__ */ r("span", { className: "flex-1 h-px bg-gray-v2-200" })
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
) : /* @__PURE__ */ r("hr", { className: e("w-full border-0 h-px bg-gray-v2-200", a) });
|
|
26
|
+
export {
|
|
27
|
+
p as Divider
|
|
28
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface DrawerProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
onOpenChange: (open: boolean) => void;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const Drawer: ({ isOpen, onOpenChange, children, className, }: DrawerProps) => import('react').ReactPortal;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as a, jsxs as v } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as f, useCallback as h, useEffect as x } from "react";
|
|
3
|
+
import { createPortal as g } from "react-dom";
|
|
4
|
+
import { XClose as p } from "@untitled-ui/icons-react";
|
|
5
|
+
import { Button as w } from "../button/Button.js";
|
|
6
|
+
import { cn as d } from "../../utils/cn.js";
|
|
7
|
+
import { useClickOutsideModal as E } from "../modal/use-click-outside-modal.js";
|
|
8
|
+
const k = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])', A = ({
|
|
9
|
+
isOpen: e,
|
|
10
|
+
onOpenChange: r,
|
|
11
|
+
children: u,
|
|
12
|
+
className: m
|
|
13
|
+
}) => {
|
|
14
|
+
const i = f(null), l = f(null), b = (t) => {
|
|
15
|
+
if (!(!e || l.current === null) && (t.key === "Escape" && r(!1), t.key === "Tab")) {
|
|
16
|
+
const o = Array.from(
|
|
17
|
+
l.current.querySelectorAll(k)
|
|
18
|
+
).filter((y) => !y.closest("[inert]"));
|
|
19
|
+
if (o.length === 0) return;
|
|
20
|
+
const s = o[0], c = o[o.length - 1];
|
|
21
|
+
t.shiftKey ? document.activeElement === s && (t.preventDefault(), c.focus()) : document.activeElement === c && (t.preventDefault(), s.focus());
|
|
22
|
+
}
|
|
23
|
+
}, n = h(() => r(!1), [r]);
|
|
24
|
+
return E(n, i, [l]), x(() => (document.body.classList.toggle("overflow-hidden", e), () => document.body.classList.remove("overflow-hidden")), [e]), g(
|
|
25
|
+
/* @__PURE__ */ a(
|
|
26
|
+
"div",
|
|
27
|
+
{
|
|
28
|
+
ref: i,
|
|
29
|
+
className: d(
|
|
30
|
+
"fixed inset-0 flex items-center justify-end z-10 transition-all duration-300 bg-gray-v2-950/48",
|
|
31
|
+
{ "invisible opacity-0": !e }
|
|
32
|
+
),
|
|
33
|
+
onKeyDown: b,
|
|
34
|
+
children: /* @__PURE__ */ v(
|
|
35
|
+
"div",
|
|
36
|
+
{
|
|
37
|
+
ref: l,
|
|
38
|
+
role: "dialog",
|
|
39
|
+
"aria-modal": "true",
|
|
40
|
+
className: d(
|
|
41
|
+
"relative h-full w-104 bg-white flex flex-col overflow-hidden transition-all duration-300",
|
|
42
|
+
{ "translate-x-full": !e },
|
|
43
|
+
m
|
|
44
|
+
),
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ a(
|
|
47
|
+
w,
|
|
48
|
+
{
|
|
49
|
+
variant: "tertiary",
|
|
50
|
+
color: "gray",
|
|
51
|
+
className: "absolute right-0 top-0 m-4",
|
|
52
|
+
onClick: n,
|
|
53
|
+
"aria-label": "Close",
|
|
54
|
+
children: /* @__PURE__ */ a(p, { className: "size-6 shrink-0 text-gray-v2-400" })
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
u
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
document.body
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
export {
|
|
67
|
+
A as Drawer
|
|
68
|
+
};
|