@godxjp/ui 20.0.0 → 20.2.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/README.md +8 -2
- package/dist/app/app-provider.js +37 -21
- package/dist/app/index.d.ts +2 -0
- package/dist/app/index.js +2 -0
- package/dist/app/storage.d.ts +17 -0
- package/dist/app/storage.js +28 -0
- package/dist/app/theme-axes.d.ts +2 -0
- package/dist/app/theme-axes.js +45 -0
- package/dist/components/charts/chart-cartesian.d.ts +2 -1
- package/dist/components/charts/chart-cartesian.js +52 -3
- package/dist/components/charts/chart-category-axis.d.ts +55 -0
- package/dist/components/charts/chart-category-axis.js +93 -0
- package/dist/components/charts/chart-frame.d.ts +10 -1
- package/dist/components/charts/chart-frame.js +19 -3
- package/dist/components/charts/compact-bar-trend.d.ts +1 -1
- package/dist/components/charts/compact-bar-trend.js +2 -0
- package/dist/components/charts/pie-chart.d.ts +1 -1
- package/dist/components/charts/pie-chart.js +12 -1
- package/dist/components/charts/recharts-peer.d.ts +49 -0
- package/dist/components/charts/recharts-peer.js +45 -0
- package/dist/components/data-display/card.d.ts +12 -1
- package/dist/components/data-display/card.js +22 -4
- package/dist/components/data-display/code-block.js +6 -2
- package/dist/components/data-display/data-table.d.ts +39 -4
- package/dist/components/data-display/data-table.js +802 -270
- package/dist/components/data-display/descriptions.d.ts +27 -6
- package/dist/components/data-display/descriptions.js +58 -17
- package/dist/components/data-display/index.d.ts +2 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/list-row.d.ts +10 -1
- package/dist/components/data-display/list-row.js +7 -1
- package/dist/components/data-display/popover.d.ts +9 -3
- package/dist/components/data-display/popover.js +65 -11
- package/dist/components/data-display/range-timeline.d.ts +38 -0
- package/dist/components/data-display/range-timeline.js +161 -0
- package/dist/components/data-display/scroll-area.js +13 -2
- package/dist/components/data-display/service-launcher-card.js +14 -12
- package/dist/components/data-display/table.d.ts +71 -3
- package/dist/components/data-display/table.js +56 -18
- package/dist/components/data-display/tree-list.js +4 -9
- package/dist/components/data-entry/calendar.d.ts +2 -2
- package/dist/components/data-entry/calendar.js +23 -3
- package/dist/components/data-entry/cascader.d.ts +1 -1
- package/dist/components/data-entry/cascader.js +188 -24
- package/dist/components/data-entry/color-picker.d.ts +1 -1
- package/dist/components/data-entry/color-picker.js +17 -5
- package/dist/components/data-entry/control-appearance.d.ts +64 -0
- package/dist/components/data-entry/control-appearance.js +39 -0
- package/dist/components/data-entry/control-surface.d.ts +61 -0
- package/dist/components/data-entry/control-surface.js +39 -0
- package/dist/components/data-entry/date-picker.d.ts +1 -1
- package/dist/components/data-entry/date-picker.js +344 -113
- package/dist/components/data-entry/date-range-picker.d.ts +1 -1
- package/dist/components/data-entry/date-range-picker.js +278 -140
- package/dist/components/data-entry/form-field.d.ts +1 -1
- package/dist/components/data-entry/form-field.js +39 -4
- package/dist/components/data-entry/form.d.ts +4 -0
- package/dist/components/data-entry/form.js +4 -2
- package/dist/components/data-entry/index.d.ts +7 -3
- package/dist/components/data-entry/index.js +10 -1
- package/dist/components/data-entry/input-otp.d.ts +1 -1
- package/dist/components/data-entry/input.d.ts +12 -34
- package/dist/components/data-entry/input.js +92 -24
- package/dist/components/data-entry/month-picker.d.ts +1 -1
- package/dist/components/data-entry/month-picker.js +47 -10
- package/dist/components/data-entry/month-range-picker.d.ts +1 -1
- package/dist/components/data-entry/month-range-picker.js +51 -11
- package/dist/components/data-entry/number-input.d.ts +7 -0
- package/dist/components/data-entry/number-input.js +147 -98
- package/dist/components/data-entry/password-input.d.ts +1 -1
- package/dist/components/data-entry/radio.d.ts +1 -1
- package/dist/components/data-entry/radio.js +61 -13
- package/dist/components/data-entry/search-input.d.ts +1 -1
- package/dist/components/data-entry/search-input.js +16 -2
- package/dist/components/data-entry/search-select.d.ts +2 -2
- package/dist/components/data-entry/search-select.js +209 -78
- package/dist/components/data-entry/select.d.ts +22 -4
- package/dist/components/data-entry/select.js +215 -163
- package/dist/components/data-entry/slider.d.ts +9 -1
- package/dist/components/data-entry/slider.js +87 -9
- package/dist/components/data-entry/switch.d.ts +3 -0
- package/dist/components/data-entry/switch.js +29 -3
- package/dist/components/data-entry/textarea.d.ts +14 -56
- package/dist/components/data-entry/textarea.js +80 -33
- package/dist/components/data-entry/time-picker.d.ts +2 -2
- package/dist/components/data-entry/time-picker.js +333 -109
- package/dist/components/data-entry/time-range-picker.d.ts +5 -0
- package/dist/components/data-entry/time-range-picker.js +89 -0
- package/dist/components/data-entry/transfer.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +86 -28
- package/dist/components/data-entry/tree-select.d.ts +1 -1
- package/dist/components/data-entry/tree-select.js +201 -113
- package/dist/components/data-entry/tree-utils.js +7 -14
- package/dist/components/data-entry/upload-files.d.ts +2 -0
- package/dist/components/data-entry/upload-files.js +31 -0
- package/dist/components/data-entry/upload-request.d.ts +4 -0
- package/dist/components/data-entry/upload-request.js +53 -0
- package/dist/components/data-entry/upload-types.d.ts +28 -0
- package/dist/components/data-entry/upload-types.js +2 -0
- package/dist/components/data-entry/upload.d.ts +2 -2
- package/dist/components/data-entry/upload.js +475 -115
- package/dist/components/feedback/dialog.js +19 -19
- package/dist/components/feedback/sheet.js +3 -0
- package/dist/components/feedback/tooltip.js +3 -0
- package/dist/components/general/button.d.ts +2 -1
- package/dist/components/general/button.js +7 -1
- package/dist/components/general/index.d.ts +1 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/general/typography.d.ts +3 -0
- package/dist/components/general/typography.js +15 -1
- package/dist/components/general/visually-hidden.d.ts +3 -0
- package/dist/components/general/visually-hidden.js +9 -0
- package/dist/components/layout/app-launcher.d.ts +34 -0
- package/dist/components/layout/app-launcher.js +261 -0
- package/dist/components/layout/app-shell.d.ts +3 -1
- package/dist/components/layout/app-shell.js +34 -14
- package/dist/components/layout/auth-shell.d.ts +1 -1
- package/dist/components/layout/auth-shell.js +2 -0
- package/dist/components/layout/breadcrumb.d.ts +14 -2
- package/dist/components/layout/breadcrumb.js +46 -4
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +23 -2
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.js +5 -1
- package/dist/components/layout/org-switcher.js +20 -1
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +5 -3
- package/dist/components/layout/responsive-grid.d.ts +16 -2
- package/dist/components/layout/responsive-grid.js +29 -2
- package/dist/components/layout/sidebar.js +2 -1
- package/dist/components/layout/topbar-item.d.ts +3 -0
- package/dist/components/layout/topbar-item.js +18 -3
- package/dist/components/layout/topbar.d.ts +1 -1
- package/dist/components/layout/topbar.js +27 -6
- package/dist/components/navigation/dropdown-menu.d.ts +30 -2
- package/dist/components/navigation/dropdown-menu.js +73 -11
- package/dist/components/navigation/pagination.d.ts +2 -2
- package/dist/components/navigation/pagination.js +155 -83
- package/dist/components/navigation/steps.d.ts +2 -2
- package/dist/components/navigation/steps.js +29 -4
- package/dist/components/navigation/tabs.d.ts +5 -33
- package/dist/components/navigation/tabs.js +232 -64
- package/dist/components/ui/hover-card.js +3 -0
- package/dist/components/ui/input-otp.d.ts +26 -28
- package/dist/components/ui/input-otp.js +50 -7
- package/dist/components/ui/password-input.d.ts +36 -2
- package/dist/components/ui/password-input.js +27 -7
- package/dist/components/ui/rating.d.ts +25 -0
- package/dist/components/ui/rating.js +67 -27
- package/dist/components/ui/segmented.d.ts +9 -0
- package/dist/components/ui/segmented.js +17 -2
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/separator.js +13 -0
- package/dist/components/ui/tag-input.d.ts +45 -0
- package/dist/components/ui/tag-input.js +109 -27
- package/dist/form/form-context.d.ts +29 -0
- package/dist/form/form-context.js +44 -4
- package/dist/form/form-field-array.d.ts +22 -0
- package/dist/form/form-field-array.js +50 -0
- package/dist/form/form-field-control.d.ts +2 -1
- package/dist/form/form-field-control.js +116 -40
- package/dist/form/form-root.d.ts +2 -1
- package/dist/form/form-root.js +142 -23
- package/dist/form/index.d.ts +3 -1
- package/dist/form/index.js +12 -1
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +3 -1
- package/dist/i18n/messages/en.json +59 -6
- package/dist/i18n/messages/ja.json +59 -6
- package/dist/i18n/messages/vi.json +59 -6
- package/dist/i18n/translate.d.ts +19 -0
- package/dist/i18n/translate.js +24 -0
- package/dist/inertia/index.d.ts +20 -0
- package/dist/inertia/index.js +60 -1
- package/dist/lib/control-styles.d.ts +25 -3
- package/dist/lib/control-styles.js +9 -3
- package/dist/lib/datetime/picker-format.d.ts +8 -0
- package/dist/lib/datetime/picker-format.js +54 -0
- package/dist/lib/overlay-portal.d.ts +18 -0
- package/dist/lib/overlay-portal.js +17 -0
- package/dist/props/components/app.prop.d.ts +13 -2
- package/dist/props/components/charts.prop.d.ts +21 -0
- package/dist/props/components/data-display.prop.d.ts +55 -4
- package/dist/props/components/data-entry.prop.d.ts +687 -43
- package/dist/props/components/form.prop.d.ts +142 -4
- package/dist/props/components/general.prop.d.ts +30 -1
- package/dist/props/components/index.d.ts +2 -2
- package/dist/props/components/layout.prop.d.ts +255 -8
- package/dist/props/components/navigation.prop.d.ts +113 -3
- package/dist/props/registry.d.ts +376 -10
- package/dist/props/registry.js +493 -9
- package/dist/props/vocabulary/data.prop.d.ts +179 -1
- package/dist/props/vocabulary/index.d.ts +4 -4
- package/dist/props/vocabulary/interaction.prop.d.ts +51 -2
- package/dist/props/vocabulary/navigation.prop.d.ts +40 -0
- package/dist/props/vocabulary/shared.prop.d.ts +33 -0
- package/dist/styles/badge-layout.css +2 -1
- package/dist/styles/card-layout.css +36 -5
- package/dist/styles/chart-layout.css +17 -1
- package/dist/styles/control.css +520 -14
- package/dist/styles/data-display-layout.css +248 -7
- package/dist/styles/data-entry-layout.css +13 -0
- package/dist/styles/layout.css +221 -4
- package/dist/styles/navigation-layout.css +230 -1
- package/dist/styles/shell-layout.css +690 -21
- package/dist/styles/table-layout.css +95 -6
- package/dist/styles/text-layout.css +5 -0
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/badge.css +1 -0
- package/dist/tokens/components/chart.css +6 -0
- package/dist/tokens/components/control.css +81 -3
- package/dist/tokens/components/data-display.css +9 -0
- package/dist/tokens/components/descriptions.css +11 -0
- package/dist/tokens/components/flex.css +8 -0
- package/dist/tokens/components/navigation.css +55 -0
- package/dist/tokens/components/shell.css +100 -5
- package/dist/tokens/components/table.css +14 -0
- package/dist/tokens/foundation.css +2 -0
- package/dist/tokens/semantic/layout.css +9 -0
- package/docs/CONSUMER-RULES.md +13 -0
- package/docs/DESIGN-AUTHORITY.md +43 -6
- package/docs/DEVELOPMENT.md +4 -3
- package/docs/FORMS.md +151 -6
- package/docs/FRAME-COVERAGE-REPORT.md +29 -16
- package/docs/README.md +1 -1
- package/docs/STANDARDS-vocabulary-tokens.md +1 -1
- package/docs/TESTING.md +15 -6
- package/docs/charts/cjk-category-axis.tsx +81 -0
- package/docs/data-display/card/index.tsx +22 -0
- package/docs/data-display/data-table/examples/antd-parity.tsx +257 -0
- package/docs/data-display/data-table/index.tsx +23 -0
- package/docs/data-display/descriptions.tsx +41 -0
- package/docs/data-display/list-row.tsx +6 -6
- package/docs/data-display/scroll-area.tsx +31 -25
- package/docs/data-display/table.tsx +104 -45
- package/docs/data-display/timeline.tsx +41 -0
- package/docs/data-entry/date-picker.tsx +85 -0
- package/docs/data-entry/date-range-picker.tsx +26 -0
- package/docs/data-entry/form-dynamic-fields.tsx +199 -0
- package/docs/data-entry/form.tsx +74 -4
- package/docs/data-entry/input-otp.tsx +24 -0
- package/docs/data-entry/input.tsx +46 -1
- package/docs/data-entry/month-range-picker.tsx +1 -1
- package/docs/data-entry/select.tsx +27 -0
- package/docs/data-entry/switch.tsx +41 -0
- package/docs/data-entry/textarea.tsx +38 -0
- package/docs/data-entry/time-picker.tsx +85 -1
- package/docs/data-entry/time-range-picker.tsx +55 -0
- package/docs/data-entry/transfer.tsx +17 -0
- package/docs/data-entry/upload.tsx +56 -12
- package/docs/feedback/tooltip.tsx +1 -1
- package/docs/general/activity.tsx +2 -2
- package/docs/general/button/index.tsx +14 -1
- package/docs/general/typography.tsx +14 -1
- package/docs/layout/app-launcher.tsx +195 -0
- package/docs/layout/app-shell-arrangements.tsx +5 -5
- package/docs/layout/app-shell.tsx +11 -0
- package/docs/layout/flex.tsx +50 -0
- package/docs/layout/responsive-grid.tsx +21 -1
- package/docs/layout/topbar.tsx +5 -9
- package/docs/navigation/app-setting-picker.tsx +11 -0
- package/docs/navigation/breadcrumb.tsx +48 -0
- package/docs/navigation/dropdown-menu.tsx +21 -0
- package/docs/navigation/pagination.tsx +52 -0
- package/docs/navigation/steps.tsx +37 -0
- package/docs/navigation/tabs.tsx +97 -1
- package/docs/query/button-refetch.tsx +1 -0
- package/docs/showcase/settings-security-mfa.tsx +3 -3
- package/package.json +24 -4
- package/scripts/_agent-setup.mjs +76 -9
- package/scripts/init-guinea-pig.mjs +26 -4
- package/scripts/ui-audit.mjs +243 -30
- package/scripts/visual-audit.mjs +45 -7
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { DescriptionsLayoutProp } from "../../props/vocabulary/interaction.prop.js";
|
|
3
|
+
import type { DescriptionsColumnProp, DescriptionsItemsProp, DescriptionsSpanProp } from "../../props/vocabulary/data.prop.js";
|
|
3
4
|
export type { DescriptionsLayoutProp };
|
|
4
5
|
export interface DescriptionsProps {
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Column count. A plain `1 | 2 | 3` keeps this library's own responsive ladder exactly as it
|
|
8
|
+
* was; any other number, or antd's `{ sm, md, lg, xl }` responsive object, drives the
|
|
9
|
+
* token-published grid instead (antd `column`).
|
|
10
|
+
*/
|
|
11
|
+
columns?: DescriptionsColumnProp;
|
|
6
12
|
/** Label placement within each item. Default `vertical` (label over value). */
|
|
7
13
|
layout?: DescriptionsLayoutProp;
|
|
8
14
|
/**
|
|
@@ -10,19 +16,34 @@ export interface DescriptionsProps {
|
|
|
10
16
|
* it there would read as a mistake, exactly like `Form`'s own contract.
|
|
11
17
|
*/
|
|
12
18
|
labelAlign?: "start" | "end";
|
|
19
|
+
/**
|
|
20
|
+
* Draw the grid as a bordered table (antd `bordered`): an outer frame, a rule between every
|
|
21
|
+
* cell, and a shaded label cell. Colour and rhythm come from the `--descriptions-*` tokens.
|
|
22
|
+
*/
|
|
23
|
+
bordered?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Declarative items (antd `items`) — an alternative to composing `Descriptions.Item` children.
|
|
26
|
+
* Both work; `items` renders first, then any children after it.
|
|
27
|
+
*/
|
|
28
|
+
items?: DescriptionsItemsProp;
|
|
13
29
|
className?: string;
|
|
14
|
-
children
|
|
30
|
+
children?: React.ReactNode;
|
|
15
31
|
}
|
|
16
|
-
export declare function Descriptions({ columns, layout, labelAlign, className, children, }: DescriptionsProps): React.JSX.Element;
|
|
32
|
+
export declare function Descriptions({ columns, layout, labelAlign, bordered, items, className, children, }: DescriptionsProps): React.JSX.Element;
|
|
17
33
|
export declare namespace Descriptions {
|
|
18
|
-
|
|
34
|
+
export { DescriptionsItem as Item };
|
|
19
35
|
}
|
|
20
36
|
export interface DescriptionsItemProps {
|
|
21
37
|
label: React.ReactNode;
|
|
22
38
|
/** Use mono spacing for IDs, paths, JSON. */
|
|
23
39
|
mono?: boolean;
|
|
24
|
-
/**
|
|
25
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Span full row(s) when the value is long. `2` / `3` keep the ladder they have always painted;
|
|
42
|
+
* `"filled"` takes the whole remaining row (antd), and a responsive `{ sm, md, lg, xl }` object
|
|
43
|
+
* spans a different number of columns per step.
|
|
44
|
+
*/
|
|
45
|
+
span?: DescriptionsSpanProp;
|
|
26
46
|
className?: string;
|
|
27
47
|
children: React.ReactNode;
|
|
28
48
|
}
|
|
49
|
+
declare function DescriptionsItem({ label, mono, span, className, children }: DescriptionsItemProps): React.JSX.Element;
|
|
@@ -4,45 +4,85 @@ import * as React from "react";
|
|
|
4
4
|
import { cn } from "../../lib/utils.js";
|
|
5
5
|
const DescriptionsLayoutContext = React.createContext({
|
|
6
6
|
layout: "vertical",
|
|
7
|
-
labelAlign: "start"
|
|
7
|
+
labelAlign: "start",
|
|
8
|
+
bordered: false
|
|
8
9
|
});
|
|
10
|
+
const BREAKPOINT_LADDER = ["sm", "md", "lg", "xl"];
|
|
11
|
+
function responsiveVars(name, base, steps) {
|
|
12
|
+
const vars = { [`${name}-base`]: base };
|
|
13
|
+
for (const step of BREAKPOINT_LADDER) {
|
|
14
|
+
const value = steps[step];
|
|
15
|
+
if (value !== void 0) vars[`${name}-${step}`] = value;
|
|
16
|
+
}
|
|
17
|
+
return vars;
|
|
18
|
+
}
|
|
19
|
+
const LEGACY_COLUMN_CLASS = {
|
|
20
|
+
1: "grid-cols-1",
|
|
21
|
+
2: "grid-cols-1 sm:grid-cols-2",
|
|
22
|
+
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
|
|
23
|
+
};
|
|
9
24
|
function Descriptions({
|
|
10
25
|
columns = 2,
|
|
11
26
|
layout = "vertical",
|
|
12
27
|
labelAlign = "start",
|
|
28
|
+
bordered = false,
|
|
29
|
+
items,
|
|
13
30
|
className,
|
|
14
31
|
children
|
|
15
32
|
}) {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
33
|
+
const legacyColumns = typeof columns === "number" ? LEGACY_COLUMN_CLASS[columns] : void 0;
|
|
34
|
+
const responsiveColumns = legacyColumns === void 0 ? typeof columns === "number" ? { sm: Math.min(columns, 2), lg: columns } : columns : void 0;
|
|
35
|
+
const context = React.useMemo(
|
|
36
|
+
() => ({ layout, labelAlign, bordered }),
|
|
37
|
+
[layout, labelAlign, bordered]
|
|
38
|
+
);
|
|
39
|
+
return /* @__PURE__ */ jsx(DescriptionsLayoutContext.Provider, { value: context, children: /* @__PURE__ */ jsxs(
|
|
19
40
|
"dl",
|
|
20
41
|
{
|
|
21
42
|
"data-slot": "descriptions",
|
|
22
|
-
"data-columns": columns,
|
|
43
|
+
"data-columns": typeof columns === "number" ? columns : void 0,
|
|
44
|
+
"data-columns-responsive": responsiveColumns ? "" : void 0,
|
|
45
|
+
"data-bordered": bordered ? "" : void 0,
|
|
46
|
+
style: responsiveColumns ? responsiveVars("--descriptions-column-count", 1, responsiveColumns) : void 0,
|
|
23
47
|
className: cn(
|
|
24
48
|
"grid gap-x-[var(--descriptions-column-gap)] gap-y-[var(--descriptions-row-gap)]",
|
|
25
|
-
|
|
49
|
+
legacyColumns,
|
|
26
50
|
className
|
|
27
51
|
),
|
|
28
|
-
children
|
|
52
|
+
children: [
|
|
53
|
+
items?.map((item, index) => /* @__PURE__ */ jsx(
|
|
54
|
+
DescriptionsItem,
|
|
55
|
+
{
|
|
56
|
+
label: item.label,
|
|
57
|
+
mono: item.mono,
|
|
58
|
+
span: item.span,
|
|
59
|
+
className: item.className,
|
|
60
|
+
children: item.children ?? item.value
|
|
61
|
+
},
|
|
62
|
+
item.key ?? index
|
|
63
|
+
)),
|
|
64
|
+
children
|
|
65
|
+
]
|
|
29
66
|
}
|
|
30
67
|
) });
|
|
31
68
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
children
|
|
38
|
-
}) {
|
|
69
|
+
const LEGACY_SPAN_CLASS = {
|
|
70
|
+
2: "sm:col-span-2",
|
|
71
|
+
3: "sm:col-span-2 lg:col-span-3"
|
|
72
|
+
};
|
|
73
|
+
function DescriptionsItem({ label, mono, span, className, children }) {
|
|
39
74
|
const { layout, labelAlign } = React.useContext(DescriptionsLayoutContext);
|
|
40
|
-
const
|
|
75
|
+
const legacySpan = typeof span === "number" ? LEGACY_SPAN_CLASS[span] : void 0;
|
|
76
|
+
const responsiveSpan = span !== void 0 && span !== "filled" && legacySpan === void 0 ? typeof span === "number" ? { sm: span } : span : void 0;
|
|
41
77
|
const endAlignedLabel = layout === "horizontal" && labelAlign === "end";
|
|
42
78
|
return /* @__PURE__ */ jsxs(
|
|
43
79
|
"div",
|
|
44
80
|
{
|
|
45
81
|
"data-slot": "descriptions-item",
|
|
82
|
+
"data-layout": layout,
|
|
83
|
+
"data-span": span === "filled" ? "filled" : void 0,
|
|
84
|
+
"data-span-responsive": responsiveSpan ? "" : void 0,
|
|
85
|
+
style: responsiveSpan ? responsiveVars("--descriptions-item-span", 1, responsiveSpan) : void 0,
|
|
46
86
|
className: cn(
|
|
47
87
|
layout === "horizontal" ? (
|
|
48
88
|
// Label beside value — a token-aligned label column so the values line up. The
|
|
@@ -54,7 +94,7 @@ Descriptions.Item = function DescriptionsItem({
|
|
|
54
94
|
// FormField / Form so the label→value gap is consistent everywhere.
|
|
55
95
|
"grid gap-[var(--field-label-gap)]"
|
|
56
96
|
),
|
|
57
|
-
|
|
97
|
+
legacySpan,
|
|
58
98
|
className
|
|
59
99
|
),
|
|
60
100
|
children: [
|
|
@@ -86,7 +126,8 @@ Descriptions.Item = function DescriptionsItem({
|
|
|
86
126
|
]
|
|
87
127
|
}
|
|
88
128
|
);
|
|
89
|
-
}
|
|
129
|
+
}
|
|
130
|
+
Descriptions.Item = DescriptionsItem;
|
|
90
131
|
export {
|
|
91
132
|
Descriptions
|
|
92
133
|
};
|
|
@@ -41,3 +41,5 @@ export { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious
|
|
|
41
41
|
export type { CarouselApi } from "./carousel.js";
|
|
42
42
|
export { PermissionMatrix } from "./permission-matrix.js";
|
|
43
43
|
export type { PermissionMatrixGrantsProp, PermissionMatrixPermissionProp, PermissionMatrixProp, PermissionMatrixProps, PermissionMatrixRoleProp, } from "./permission-matrix.js";
|
|
44
|
+
export { RangeTimeline } from "./range-timeline.js";
|
|
45
|
+
export type { RangeTimelineProps, RangeTimelineRow } from "./range-timeline.js";
|
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
useCarousel
|
|
55
55
|
} from "./carousel.js";
|
|
56
56
|
import { PermissionMatrix } from "./permission-matrix.js";
|
|
57
|
+
import { RangeTimeline } from "./range-timeline.js";
|
|
57
58
|
export {
|
|
58
59
|
Accordion,
|
|
59
60
|
AccordionContent,
|
|
@@ -102,6 +103,7 @@ export {
|
|
|
102
103
|
Progress,
|
|
103
104
|
Prose,
|
|
104
105
|
QrCode,
|
|
106
|
+
RangeTimeline,
|
|
105
107
|
ScrollArea,
|
|
106
108
|
ScrollBar,
|
|
107
109
|
ServiceCatalogCta,
|
|
@@ -13,7 +13,16 @@ export type ListRowDensity = ListRowDensityProp;
|
|
|
13
13
|
* justify-between border-b …">`.
|
|
14
14
|
*/
|
|
15
15
|
export interface ListRowProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Render element — `div` (default) or `li` when the parent is a `<ul>`/`<ol>`.
|
|
18
|
+
*
|
|
19
|
+
* With `asChild`, the child owns the row element, so `as` steps out and becomes the
|
|
20
|
+
* LIST ITEM around it: `<li data-slot="list-row-item"><a data-slot="list-row">`. That is
|
|
21
|
+
* the only reading under which both props can hold at once, and it is the shape a list
|
|
22
|
+
* of links needs — the alternative, wrapping the row yourself, moves every row into a
|
|
23
|
+
* wrapper of its own and the row-to-row divider (keyed on `:not(:last-child)` among
|
|
24
|
+
* siblings) stops matching entirely.
|
|
25
|
+
*/
|
|
17
26
|
as?: "div" | "li";
|
|
18
27
|
/** Use the supplied link as the entire row. Do not nest interactive trailing controls. */
|
|
19
28
|
asChild?: boolean;
|
|
@@ -22,6 +22,7 @@ const ListRow = React.forwardRef(
|
|
|
22
22
|
...props
|
|
23
23
|
}, ref) => {
|
|
24
24
|
const { t } = useTranslation();
|
|
25
|
+
const item = asChild && as !== "div" ? as : null;
|
|
25
26
|
const Comp = asChild ? Slot : as;
|
|
26
27
|
const truncate = overflow !== "wrap";
|
|
27
28
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -33,7 +34,7 @@ const ListRow = React.forwardRef(
|
|
|
33
34
|
] }),
|
|
34
35
|
trailing != null ? /* @__PURE__ */ jsx("span", { "data-slot": "list-row-trailing", children: trailing }) : null
|
|
35
36
|
] });
|
|
36
|
-
|
|
37
|
+
const row = /* @__PURE__ */ jsx(
|
|
37
38
|
Comp,
|
|
38
39
|
{
|
|
39
40
|
ref,
|
|
@@ -47,6 +48,11 @@ const ListRow = React.forwardRef(
|
|
|
47
48
|
children: asChild && React.isValidElement(children) ? React.cloneElement(children, void 0, content) : content
|
|
48
49
|
}
|
|
49
50
|
);
|
|
51
|
+
if (item === null) {
|
|
52
|
+
return row;
|
|
53
|
+
}
|
|
54
|
+
const Item = item;
|
|
55
|
+
return /* @__PURE__ */ jsx(Item, { "data-slot": "list-row-item", children: row });
|
|
50
56
|
}
|
|
51
57
|
);
|
|
52
58
|
ListRow.displayName = "ListRow";
|
|
@@ -34,6 +34,12 @@ type PopoverContentFlush = {
|
|
|
34
34
|
flush?: FlushProp;
|
|
35
35
|
};
|
|
36
36
|
interface PopoverContentProps extends React.ComponentPropsWithRef<"div">, PopoverContentFlush {
|
|
37
|
+
/**
|
|
38
|
+
* Render THIS panel somewhere other than the default. Almost always unnecessary: mounting the
|
|
39
|
+
* whole tree in a shadow root is what `OverlayPortalProvider` is for, and it moves every overlay
|
|
40
|
+
* at once. Reach for this only to place one panel differently from the rest.
|
|
41
|
+
*/
|
|
42
|
+
portalContainer?: Element;
|
|
37
43
|
/** Cạnh của trigger mà panel bám vào. */
|
|
38
44
|
side?: Side;
|
|
39
45
|
/** Canh panel theo cạnh của trigger. */
|
|
@@ -67,8 +73,8 @@ interface PopoverContentProps extends React.ComponentPropsWithRef<"div">, Popove
|
|
|
67
73
|
*/
|
|
68
74
|
onCloseAutoFocus?: (event: Event) => void;
|
|
69
75
|
}
|
|
70
|
-
export declare function PopoverContent({ className, style, children, ref, flush, side, align, sideOffset, alignOffset, avoidCollisions, collisionPadding, sticky: _sticky, hideWhenDetached: _hideWhenDetached, forceMount: _forceMount, onOpenAutoFocus, onCloseAutoFocus, ...props }: PopoverContentProps): React.JSX.Element;
|
|
76
|
+
export declare function PopoverContent({ className, style, children, ref, flush, side, align, sideOffset, alignOffset, avoidCollisions, collisionPadding, sticky: _sticky, hideWhenDetached: _hideWhenDetached, forceMount: _forceMount, onOpenAutoFocus, onCloseAutoFocus, portalContainer, ...props }: PopoverContentProps): React.JSX.Element;
|
|
71
77
|
export declare const PopoverHeader: ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => React.JSX.Element;
|
|
72
|
-
export declare const PopoverTitle: ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => React.JSX.Element;
|
|
73
|
-
export declare const PopoverDescription: ({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) => React.JSX.Element;
|
|
78
|
+
export declare const PopoverTitle: ({ className, id, ...props }: React.HTMLAttributes<HTMLDivElement>) => React.JSX.Element;
|
|
79
|
+
export declare const PopoverDescription: ({ className, id, ...props }: React.HTMLAttributes<HTMLParagraphElement>) => React.JSX.Element;
|
|
74
80
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useOverlayPortalContainer } from "../../lib/overlay-portal.js";
|
|
3
4
|
import * as React from "react";
|
|
4
5
|
import { chain, mergeRefs } from "@react-aria/utils";
|
|
5
6
|
import { Popover as AriaPopover } from "react-aria-components";
|
|
@@ -48,6 +49,11 @@ function Popover({
|
|
|
48
49
|
const triggerRef = React.useRef(null);
|
|
49
50
|
const anchorRef = React.useRef(null);
|
|
50
51
|
const contentId = React.useId();
|
|
52
|
+
const titleId = React.useId();
|
|
53
|
+
const descriptionId = React.useId();
|
|
54
|
+
const triggerId = React.useId();
|
|
55
|
+
const [hasTitle, registerTitle] = React.useState(false);
|
|
56
|
+
const [hasDescription, registerDescription] = React.useState(false);
|
|
51
57
|
const isOpen = open ?? uncontrolledOpen;
|
|
52
58
|
const setOpen = React.useCallback(
|
|
53
59
|
(next) => {
|
|
@@ -67,9 +73,27 @@ function Popover({
|
|
|
67
73
|
triggerRef,
|
|
68
74
|
anchorRef,
|
|
69
75
|
anchored,
|
|
70
|
-
setAnchored
|
|
76
|
+
setAnchored,
|
|
77
|
+
titleId,
|
|
78
|
+
descriptionId,
|
|
79
|
+
hasTitle,
|
|
80
|
+
hasDescription,
|
|
81
|
+
registerTitle,
|
|
82
|
+
registerDescription,
|
|
83
|
+
triggerId
|
|
71
84
|
}),
|
|
72
|
-
[
|
|
85
|
+
[
|
|
86
|
+
isOpen,
|
|
87
|
+
setOpen,
|
|
88
|
+
contentId,
|
|
89
|
+
modal,
|
|
90
|
+
anchored,
|
|
91
|
+
titleId,
|
|
92
|
+
descriptionId,
|
|
93
|
+
hasTitle,
|
|
94
|
+
hasDescription,
|
|
95
|
+
triggerId
|
|
96
|
+
]
|
|
73
97
|
);
|
|
74
98
|
return /* @__PURE__ */ jsx(PopoverRootContext.Provider, { value, children });
|
|
75
99
|
}
|
|
@@ -83,6 +107,7 @@ function PopoverTrigger({ asChild, onClick, ref, ...props }) {
|
|
|
83
107
|
"data-slot": "popover-trigger",
|
|
84
108
|
"aria-haspopup": "dialog",
|
|
85
109
|
"aria-expanded": root.open,
|
|
110
|
+
id: props.id ?? root.triggerId,
|
|
86
111
|
"aria-controls": root.open ? root.contentId : void 0,
|
|
87
112
|
"data-state": root.open ? "open" : "closed",
|
|
88
113
|
...props,
|
|
@@ -118,6 +143,7 @@ function PopoverContent({
|
|
|
118
143
|
forceMount: _forceMount,
|
|
119
144
|
onOpenAutoFocus,
|
|
120
145
|
onCloseAutoFocus,
|
|
146
|
+
portalContainer,
|
|
121
147
|
...props
|
|
122
148
|
}) {
|
|
123
149
|
const root = usePopoverRoot("PopoverContent");
|
|
@@ -152,9 +178,11 @@ function PopoverContent({
|
|
|
152
178
|
document.addEventListener("pointerdown", onPointerDown);
|
|
153
179
|
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
154
180
|
}, [open, setOpen, triggerRef]);
|
|
181
|
+
const overlayPortalContainer = useOverlayPortalContainer(portalContainer);
|
|
155
182
|
return /* @__PURE__ */ jsx(
|
|
156
183
|
AriaPopover,
|
|
157
184
|
{
|
|
185
|
+
UNSTABLE_portalContainer: overlayPortalContainer,
|
|
158
186
|
isOpen: root.open,
|
|
159
187
|
onOpenChange: root.setOpen,
|
|
160
188
|
isNonModal: root.isNonModal,
|
|
@@ -186,6 +214,8 @@ function PopoverContent({
|
|
|
186
214
|
"data-state": isExiting ? "closed" : "open",
|
|
187
215
|
"data-flush": flush ? "" : void 0,
|
|
188
216
|
...props,
|
|
217
|
+
"aria-labelledby": props["aria-labelledby"] ?? (props["aria-label"] ? void 0 : root.hasTitle ? root.titleId : root.triggerId),
|
|
218
|
+
"aria-describedby": props["aria-describedby"] ?? (root.hasDescription ? root.descriptionId : void 0),
|
|
189
219
|
ref: mergeRefs(ref, racRef, contentRef),
|
|
190
220
|
className: cn(
|
|
191
221
|
"ui-popover-content origin-[var(--radix-popover-content-transform-origin)]",
|
|
@@ -213,18 +243,42 @@ function PopoverContent({
|
|
|
213
243
|
);
|
|
214
244
|
}
|
|
215
245
|
const PopoverHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { "data-slot": "popover-header", className: cn("ui-popover-header", className), ...props });
|
|
216
|
-
const PopoverTitle = ({ className, ...props }) =>
|
|
246
|
+
const PopoverTitle = ({ className, id, ...props }) => {
|
|
247
|
+
const root = usePopoverRoot("PopoverTitle");
|
|
248
|
+
React.useEffect(() => {
|
|
249
|
+
root.registerTitle(true);
|
|
250
|
+
return () => root.registerTitle(false);
|
|
251
|
+
}, [root]);
|
|
252
|
+
return /* @__PURE__ */ jsx(
|
|
253
|
+
"div",
|
|
254
|
+
{
|
|
255
|
+
"data-slot": "popover-title",
|
|
256
|
+
id: id ?? root.titleId,
|
|
257
|
+
className: cn("font-medium", className),
|
|
258
|
+
...props
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
};
|
|
217
262
|
const PopoverDescription = ({
|
|
218
263
|
className,
|
|
264
|
+
id,
|
|
219
265
|
...props
|
|
220
|
-
}) =>
|
|
221
|
-
"
|
|
222
|
-
{
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
266
|
+
}) => {
|
|
267
|
+
const root = usePopoverRoot("PopoverDescription");
|
|
268
|
+
React.useEffect(() => {
|
|
269
|
+
root.registerDescription(true);
|
|
270
|
+
return () => root.registerDescription(false);
|
|
271
|
+
}, [root]);
|
|
272
|
+
return /* @__PURE__ */ jsx(
|
|
273
|
+
"p",
|
|
274
|
+
{
|
|
275
|
+
"data-slot": "popover-description",
|
|
276
|
+
id: id ?? root.descriptionId,
|
|
277
|
+
className: cn("text-muted-foreground", className),
|
|
278
|
+
...props
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
};
|
|
228
282
|
export {
|
|
229
283
|
Popover,
|
|
230
284
|
PopoverAnchor,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type RangeTimelineRow = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: React.ReactNode;
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
startLabel: string;
|
|
8
|
+
endLabel: string;
|
|
9
|
+
};
|
|
10
|
+
export type RangeTimelineProps = React.HTMLAttributes<HTMLElement> & {
|
|
11
|
+
label: string;
|
|
12
|
+
columns: {
|
|
13
|
+
label: string;
|
|
14
|
+
units: number;
|
|
15
|
+
}[];
|
|
16
|
+
bands?: {
|
|
17
|
+
label: string;
|
|
18
|
+
units: number;
|
|
19
|
+
}[];
|
|
20
|
+
rows: RangeTimelineRow[];
|
|
21
|
+
today?: number | null;
|
|
22
|
+
onRangeChange?: (id: string, edge: "start" | "end", delta: number) => void;
|
|
23
|
+
};
|
|
24
|
+
/** A horizontal range axis. Units and labels are data; the design system owns all geometry. */
|
|
25
|
+
export declare const RangeTimeline: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
|
|
26
|
+
label: string;
|
|
27
|
+
columns: {
|
|
28
|
+
label: string;
|
|
29
|
+
units: number;
|
|
30
|
+
}[];
|
|
31
|
+
bands?: {
|
|
32
|
+
label: string;
|
|
33
|
+
units: number;
|
|
34
|
+
}[];
|
|
35
|
+
rows: RangeTimelineRow[];
|
|
36
|
+
today?: number | null;
|
|
37
|
+
onRangeChange?: (id: string, edge: "start" | "end", delta: number) => void;
|
|
38
|
+
} & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
|
+
import { GripVertical } from "lucide-react";
|
|
6
|
+
import { Button } from "../general/button.js";
|
|
7
|
+
import { Text } from "../general/typography.js";
|
|
8
|
+
import { cn } from "../../lib/utils.js";
|
|
9
|
+
const RangeTimeline = React.forwardRef(
|
|
10
|
+
function RangeTimeline2({ label, columns, bands, rows, today, onRangeChange, className, ...props }, ref) {
|
|
11
|
+
const { t } = useTranslation();
|
|
12
|
+
const units = Math.max(
|
|
13
|
+
1,
|
|
14
|
+
columns.reduce((sum, column) => sum + column.units, 0)
|
|
15
|
+
);
|
|
16
|
+
const track = React.useRef(null);
|
|
17
|
+
const drag = React.useRef(null);
|
|
18
|
+
const [preview, setPreview] = React.useState(null);
|
|
19
|
+
const deltaAt = (x) => drag.current ? Math.round((x - drag.current.x) * units * drag.current.direction / drag.current.width) : 0;
|
|
20
|
+
const cancel = () => {
|
|
21
|
+
drag.current = null;
|
|
22
|
+
setPreview(null);
|
|
23
|
+
};
|
|
24
|
+
const complete = (event) => {
|
|
25
|
+
const current = drag.current;
|
|
26
|
+
if (!current) return;
|
|
27
|
+
const row = rows.find((row2) => row2.id === current.id);
|
|
28
|
+
const delta = deltaAt(event.clientX);
|
|
29
|
+
cancel();
|
|
30
|
+
if (!row) return;
|
|
31
|
+
const bounded = current.edge === "start" ? Math.min(delta, row.end - row.start) : Math.max(delta, row.start - row.end);
|
|
32
|
+
if (bounded) onRangeChange?.(row.id, current.edge, bounded);
|
|
33
|
+
};
|
|
34
|
+
return /* @__PURE__ */ jsx(
|
|
35
|
+
"section",
|
|
36
|
+
{
|
|
37
|
+
...props,
|
|
38
|
+
ref,
|
|
39
|
+
className: cn("ui-range-timeline", className),
|
|
40
|
+
"aria-label": label,
|
|
41
|
+
tabIndex: 0,
|
|
42
|
+
children: /* @__PURE__ */ jsxs(
|
|
43
|
+
"div",
|
|
44
|
+
{
|
|
45
|
+
className: "ui-range-timeline-canvas",
|
|
46
|
+
style: { "--range-timeline-columns": Math.max(1, columns.length) },
|
|
47
|
+
children: [
|
|
48
|
+
bands && bands.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-header", children: [
|
|
49
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", "aria-hidden": "true" }),
|
|
50
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-columns", children: bands.map((band, index) => /* @__PURE__ */ jsx(
|
|
51
|
+
"div",
|
|
52
|
+
{
|
|
53
|
+
className: "ui-range-timeline-column",
|
|
54
|
+
style: { flex: band.units },
|
|
55
|
+
children: /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", children: band.label })
|
|
56
|
+
},
|
|
57
|
+
index
|
|
58
|
+
)) })
|
|
59
|
+
] }),
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-header", children: [
|
|
61
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", children: /* @__PURE__ */ jsx(Text, { weight: "bold", children: label }) }),
|
|
62
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-columns", ref: track, children: columns.map((column, index) => /* @__PURE__ */ jsx(
|
|
63
|
+
"div",
|
|
64
|
+
{
|
|
65
|
+
className: "ui-range-timeline-column",
|
|
66
|
+
style: { flex: column.units },
|
|
67
|
+
children: /* @__PURE__ */ jsx(Text, { size: "xs", children: column.label })
|
|
68
|
+
},
|
|
69
|
+
index
|
|
70
|
+
)) })
|
|
71
|
+
] }),
|
|
72
|
+
rows.map((row) => {
|
|
73
|
+
const delta = preview?.id === row.id ? preview.delta : 0;
|
|
74
|
+
const start = Math.min(row.end, row.start + (preview?.edge === "start" ? delta : 0));
|
|
75
|
+
const end = Math.max(row.start, row.end + (preview?.edge === "end" ? delta : 0));
|
|
76
|
+
const left = Math.max(0, start), right = Math.min(units, end + 1);
|
|
77
|
+
return /* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-row", children: [
|
|
78
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", children: row.label }),
|
|
79
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-track", children: [
|
|
80
|
+
today != null && today >= 0 && today < units && /* @__PURE__ */ jsx(
|
|
81
|
+
"span",
|
|
82
|
+
{
|
|
83
|
+
"aria-hidden": "true",
|
|
84
|
+
className: "ui-range-timeline-today",
|
|
85
|
+
style: { insetInlineStart: `${(today + 0.5) / units * 100}%` }
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
right <= left && /* @__PURE__ */ jsx(Text, { tone: "muted", children: t("rangeTimeline.outsideRange") }),
|
|
89
|
+
right > left && /* @__PURE__ */ jsx(
|
|
90
|
+
"div",
|
|
91
|
+
{
|
|
92
|
+
className: "ui-range-timeline-bar",
|
|
93
|
+
style: {
|
|
94
|
+
insetInlineStart: `${left / units * 100}%`,
|
|
95
|
+
inlineSize: `${(right - left) / units * 100}%`
|
|
96
|
+
},
|
|
97
|
+
children: onRangeChange && (right - left) * Math.max(1, columns.length) >= units && ["start", "end"].filter(
|
|
98
|
+
(edge) => edge === "start" ? start >= 0 && start < units : end >= 0 && end < units
|
|
99
|
+
).map((edge) => /* @__PURE__ */ jsx(
|
|
100
|
+
Button,
|
|
101
|
+
{
|
|
102
|
+
variant: "ghost",
|
|
103
|
+
size: "icon-xs",
|
|
104
|
+
className: "ui-range-timeline-handle",
|
|
105
|
+
"data-edge": edge,
|
|
106
|
+
"aria-label": edge === "start" ? row.startLabel : row.endLabel,
|
|
107
|
+
onPointerDown: (event) => {
|
|
108
|
+
const width = track.current?.getBoundingClientRect().width ?? 0;
|
|
109
|
+
if (!width || event.button !== 0) return;
|
|
110
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
111
|
+
drag.current = {
|
|
112
|
+
id: row.id,
|
|
113
|
+
edge,
|
|
114
|
+
x: event.clientX,
|
|
115
|
+
width,
|
|
116
|
+
direction: getComputedStyle(event.currentTarget).direction === "rtl" ? -1 : 1
|
|
117
|
+
};
|
|
118
|
+
},
|
|
119
|
+
onPointerMove: (event) => {
|
|
120
|
+
if (drag.current)
|
|
121
|
+
setPreview({
|
|
122
|
+
id: drag.current.id,
|
|
123
|
+
edge: drag.current.edge,
|
|
124
|
+
delta: deltaAt(event.clientX)
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
onPointerUp: complete,
|
|
128
|
+
onPointerCancel: cancel,
|
|
129
|
+
onLostPointerCapture: cancel,
|
|
130
|
+
onKeyDown: (event) => {
|
|
131
|
+
if (event.key === "Escape") {
|
|
132
|
+
cancel();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const step = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0;
|
|
136
|
+
if (!step) return;
|
|
137
|
+
event.preventDefault();
|
|
138
|
+
const direction = getComputedStyle(event.currentTarget).direction === "rtl" ? -1 : 1;
|
|
139
|
+
const delta2 = step * direction;
|
|
140
|
+
if (edge === "start" ? row.start + delta2 <= row.end : row.end + delta2 >= row.start)
|
|
141
|
+
onRangeChange(row.id, edge, delta2);
|
|
142
|
+
},
|
|
143
|
+
children: /* @__PURE__ */ jsx(GripVertical, { "aria-hidden": "true" })
|
|
144
|
+
},
|
|
145
|
+
edge
|
|
146
|
+
))
|
|
147
|
+
}
|
|
148
|
+
)
|
|
149
|
+
] })
|
|
150
|
+
] }, row.id);
|
|
151
|
+
})
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
export {
|
|
160
|
+
RangeTimeline
|
|
161
|
+
};
|
|
@@ -113,7 +113,16 @@ function useBottomAnchor(viewport, enabled, offset, onAnchoredChange) {
|
|
|
113
113
|
}, [viewport, enabled, offset]);
|
|
114
114
|
}
|
|
115
115
|
const ScrollArea = React.forwardRef(
|
|
116
|
-
({
|
|
116
|
+
({
|
|
117
|
+
className,
|
|
118
|
+
children,
|
|
119
|
+
viewportRef,
|
|
120
|
+
anchor = "none",
|
|
121
|
+
anchorOffset,
|
|
122
|
+
onAnchoredChange,
|
|
123
|
+
orientation = "vertical",
|
|
124
|
+
...props
|
|
125
|
+
}, ref) => {
|
|
117
126
|
const [viewport, setViewport] = React.useState(null);
|
|
118
127
|
const attachViewport = React.useCallback(
|
|
119
128
|
(node) => {
|
|
@@ -139,11 +148,13 @@ const ScrollArea = React.forwardRef(
|
|
|
139
148
|
tabIndex: 0,
|
|
140
149
|
"data-slot": "scroll-area-viewport",
|
|
141
150
|
"data-anchor": anchor,
|
|
151
|
+
"data-orientation": orientation,
|
|
142
152
|
className: "size-full rounded-[inherit]",
|
|
143
153
|
children
|
|
144
154
|
}
|
|
145
155
|
),
|
|
146
|
-
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
156
|
+
orientation !== "horizontal" && /* @__PURE__ */ jsx(ScrollBar, { orientation: "vertical" }),
|
|
157
|
+
orientation !== "vertical" && /* @__PURE__ */ jsx(ScrollBar, { orientation: "horizontal" }),
|
|
147
158
|
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
|
|
148
159
|
]
|
|
149
160
|
}
|