@godxjp/ui 31.5.0 → 31.7.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/agent/START-HERE.md +5 -5
- package/agent/components/BranchScopePicker.json +5 -0
- package/agent/components/Breadcrumb.json +1 -1
- package/agent/components/Cascader.json +1 -1
- package/agent/components/DataTable.json +2 -2
- package/agent/components/InfiniteQueryState.json +6 -1
- package/agent/components/PageContainer.json +1 -1
- package/agent/components/Progress.json +12 -1
- package/agent/components/RangeTimeline.json +6 -0
- package/agent/components/RecordPicker.json +10 -0
- package/agent/components/Text.json +1 -1
- package/agent/components/Transfer.json +5 -0
- package/agent/components/Tree.json +21 -4
- package/agent/components/TreeSelect.json +1 -1
- package/agent/components.json +72 -13
- package/agent/index.json +5 -5
- package/agent/llms.txt +6 -6
- package/agent/tokens.json +12 -0
- package/dist/components/data-display/data-table.d.ts +3 -0
- package/dist/components/data-display/data-table.js +415 -370
- package/dist/components/data-display/progress.d.ts +16 -0
- package/dist/components/data-display/progress.js +17 -3
- package/dist/components/data-display/range-timeline.d.ts +20 -0
- package/dist/components/data-display/range-timeline.js +217 -197
- package/dist/components/data-display/tree.js +179 -23
- package/dist/components/data-entry/branch-scope-picker.d.ts +1 -0
- package/dist/components/data-entry/branch-scope-picker.js +2 -1
- package/dist/components/data-entry/cascader.js +4 -5
- package/dist/components/data-entry/record-picker.d.ts +2 -0
- package/dist/components/data-entry/record-picker.js +22 -3
- package/dist/components/data-entry/transfer.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +5 -2
- package/dist/components/data-entry/tree-select.js +14 -5
- package/dist/components/feedback/tooltip.d.ts +21 -0
- package/dist/components/feedback/tooltip.js +101 -0
- package/dist/components/general/typography.js +30 -11
- package/dist/components/layout/breadcrumb-ellipsis.d.ts +16 -0
- package/dist/components/layout/breadcrumb-ellipsis.js +28 -0
- package/dist/components/layout/breadcrumb.js +16 -7
- package/dist/components/layout/page-container.js +29 -20
- package/dist/components/query/infinite-query-state.d.ts +1 -1
- package/dist/components/query/infinite-query-state.js +2 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +18 -3
- package/dist/i18n/messages/ja.json +9 -3
- package/dist/i18n/messages/vi.json +9 -3
- package/dist/lib/hooks.d.ts +8 -4
- package/dist/lib/hooks.js +5 -2
- package/dist/lib/tree.d.ts +23 -0
- package/dist/lib/tree.js +29 -0
- package/dist/props/components/data-display.prop.d.ts +21 -2
- package/dist/props/components/data-entry.prop.d.ts +31 -4
- package/dist/props/components/query.prop.d.ts +8 -1
- package/dist/props/registry.d.ts +29 -6
- package/dist/props/registry.js +46 -4
- package/dist/props/vocabulary/data.prop.d.ts +32 -2
- package/dist/props/vocabulary/index.d.ts +2 -2
- package/dist/props/vocabulary/navigation.prop.d.ts +14 -0
- package/dist/styles/data-display-layout.css +52 -0
- package/dist/styles/layers.json +3 -2
- package/dist/styles/layout.css +22 -0
- package/dist/styles/table-layout.css +24 -1
- package/dist/tokens/components/navigation.css +2 -0
- package/dist/tokens/components/tree.css +2 -0
- package/docs/data-display/data-table/examples/server-paged.tsx +23 -0
- package/docs/data-display/data-table/index.md +2 -0
- package/docs/data-display/progress.tsx +24 -6
- package/docs/data-display/timeline.tsx +33 -0
- package/docs/data-display/tree.tsx +154 -0
- package/docs/data-entry/branch-scope-picker.tsx +6 -1
- package/docs/data-entry/record-picker.tsx +1 -0
- package/docs/data-entry/transfer.tsx +1 -0
- package/docs/general/typography.tsx +84 -1
- package/docs/i18n/messages/en.json +48 -1
- package/docs/i18n/messages/ja.json +47 -1
- package/docs/i18n/messages/vi.json +47 -1
- package/docs/navigation/breadcrumb.tsx +24 -0
- package/docs/query/infinite-query-state.tsx +5 -1
- package/docs/roadmap/tree-components.md +2 -1
- package/package.json +2 -2
- package/scripts/ui-audit.mjs +15 -5
|
@@ -89,6 +89,22 @@ type ProgressMeterProps = ProgressBase & {
|
|
|
89
89
|
*/
|
|
90
90
|
type ProgressBreakdownProps = ProgressBase & {
|
|
91
91
|
segments: ProgressSegment[];
|
|
92
|
+
/**
|
|
93
|
+
* The WHOLE the slices are drawn against, in the same unit as their `value`s. Omit it and the
|
|
94
|
+
* whole is the sum of the slices (the bar is always full). Pass it when part of the whole has
|
|
95
|
+
* no state yet — 3 passed of 400 test cases — and the rest stays the TRACK, exactly as antd's
|
|
96
|
+
* `percent` leaves the unfilled track as the remainder of 100. A `total` below the sum is
|
|
97
|
+
* ignored (the sum wins), so the slices never overflow the bar.
|
|
98
|
+
*
|
|
99
|
+
* The remainder is spoken as part of the `role="img"` name, Intl-formatted in the active
|
|
100
|
+
* locale, under `remainderLabel`.
|
|
101
|
+
*/
|
|
102
|
+
total?: number;
|
|
103
|
+
/**
|
|
104
|
+
* What the remainder is called in the spoken breakdown (e.g. `未実施`). Defaults to the
|
|
105
|
+
* catalogue's "Remaining" / 残り / Còn lại. Only read when `total` is set.
|
|
106
|
+
*/
|
|
107
|
+
remainderLabel?: string;
|
|
92
108
|
value?: never;
|
|
93
109
|
tone?: never;
|
|
94
110
|
over?: never;
|
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
|
+
import { numberFormat } from "../../lib/intl-cache.js";
|
|
5
6
|
import { cn } from "../../lib/utils.js";
|
|
6
7
|
const RING_BOX = 40;
|
|
7
8
|
const RING_CENTRE = RING_BOX / 2;
|
|
8
9
|
const RING_RADIUS = 16;
|
|
9
10
|
const RING_ROTATION = `rotate(-90 ${RING_CENTRE} ${RING_CENTRE})`;
|
|
10
11
|
function Progress(props) {
|
|
11
|
-
const { t } = useTranslation();
|
|
12
|
+
const { t, locale } = useTranslation();
|
|
12
13
|
const labelId = React.useId();
|
|
13
14
|
const {
|
|
14
15
|
label,
|
|
15
16
|
className,
|
|
16
17
|
segments,
|
|
18
|
+
total: wholeTotal,
|
|
19
|
+
remainderLabel,
|
|
17
20
|
value,
|
|
18
21
|
tone,
|
|
19
22
|
size,
|
|
@@ -28,9 +31,20 @@ function Progress(props) {
|
|
|
28
31
|
const caption = label !== void 0 ? /* @__PURE__ */ jsx("div", { className: "ui-progress-label", id: labelId, children: label }) : null;
|
|
29
32
|
if (segments !== void 0) {
|
|
30
33
|
const amounts = segments.map((segment) => Math.max(0, segment.value));
|
|
31
|
-
const
|
|
34
|
+
const sliceSum = amounts.reduce((sum, amount) => sum + amount, 0);
|
|
35
|
+
const hasWhole = wholeTotal !== void 0;
|
|
36
|
+
const total = hasWhole ? Math.max(sliceSum, wholeTotal) : sliceSum;
|
|
37
|
+
const formatAmount = hasWhole ? (amount) => numberFormat(locale).format(amount) : (amount) => String(amount);
|
|
32
38
|
const separator = t("dataDisplay.progress.breakdownSeparator");
|
|
33
|
-
const
|
|
39
|
+
const parts = segments.map(
|
|
40
|
+
(segment, index) => `${segment.label} ${formatAmount(amounts[index])}`
|
|
41
|
+
);
|
|
42
|
+
if (hasWhole) {
|
|
43
|
+
parts.push(
|
|
44
|
+
`${remainderLabel ?? t("dataDisplay.progress.remainder")} ${formatAmount(total - sliceSum)}`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
const spoken = parts.join(separator);
|
|
34
48
|
return /* @__PURE__ */ jsxs(
|
|
35
49
|
"div",
|
|
36
50
|
{
|
|
@@ -53,6 +53,16 @@ export type RangeTimelineProps = React.HTMLAttributes<HTMLElement> & {
|
|
|
53
53
|
defaultExpandedValues?: readonly string[];
|
|
54
54
|
/** Fires with the next expanded parent ids, for controlled and uncontrolled timelines alike. */
|
|
55
55
|
onExpandedValuesChange?: (values: string[]) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Keep the axis header (bands + ticks) on screen while the PAGE scrolls a long schedule — antd
|
|
58
|
+
* Table `sticky`. `offsetHeader` is the distance in px from the top of the scrolling viewport,
|
|
59
|
+
* e.g. the height of a fixed app topbar. The header then scrolls horizontally with the body.
|
|
60
|
+
* Needs no clipping ancestor (e.g. `Card`, which is `overflow: hidden`) between it and the page
|
|
61
|
+
* scroller. antd's `offsetScroll` / `getContainer` (a sticky horizontal scrollbar) are not ported.
|
|
62
|
+
*/
|
|
63
|
+
sticky?: boolean | {
|
|
64
|
+
offsetHeader?: number;
|
|
65
|
+
};
|
|
56
66
|
};
|
|
57
67
|
/** A horizontal range axis. Units and labels are data; the design system owns all geometry. */
|
|
58
68
|
export declare const RangeTimeline: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
|
|
@@ -94,4 +104,14 @@ export declare const RangeTimeline: React.ForwardRefExoticComponent<React.HTMLAt
|
|
|
94
104
|
defaultExpandedValues?: readonly string[];
|
|
95
105
|
/** Fires with the next expanded parent ids, for controlled and uncontrolled timelines alike. */
|
|
96
106
|
onExpandedValuesChange?: (values: string[]) => void;
|
|
107
|
+
/**
|
|
108
|
+
* Keep the axis header (bands + ticks) on screen while the PAGE scrolls a long schedule — antd
|
|
109
|
+
* Table `sticky`. `offsetHeader` is the distance in px from the top of the scrolling viewport,
|
|
110
|
+
* e.g. the height of a fixed app topbar. The header then scrolls horizontally with the body.
|
|
111
|
+
* Needs no clipping ancestor (e.g. `Card`, which is `overflow: hidden`) between it and the page
|
|
112
|
+
* scroller. antd's `offsetScroll` / `getContainer` (a sticky horizontal scrollbar) are not ported.
|
|
113
|
+
*/
|
|
114
|
+
sticky?: boolean | {
|
|
115
|
+
offsetHeader?: number;
|
|
116
|
+
};
|
|
97
117
|
} & React.RefAttributes<HTMLElement>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
5
|
import { ChevronDown, ChevronLeft, ChevronRight, GripVertical } from "lucide-react";
|
|
@@ -19,6 +19,7 @@ const RangeTimeline = React.forwardRef(
|
|
|
19
19
|
expandedValues,
|
|
20
20
|
defaultExpandedValues,
|
|
21
21
|
onExpandedValuesChange,
|
|
22
|
+
sticky = false,
|
|
22
23
|
className,
|
|
23
24
|
...props
|
|
24
25
|
}, ref) {
|
|
@@ -69,6 +70,8 @@ const RangeTimeline = React.forwardRef(
|
|
|
69
70
|
columns.reduce((sum, column) => sum + column.units, 0)
|
|
70
71
|
);
|
|
71
72
|
const track = React.useRef(null);
|
|
73
|
+
const stickyHeader = React.useRef(null);
|
|
74
|
+
const bodyScroller = React.useRef(null);
|
|
72
75
|
const drag = React.useRef(null);
|
|
73
76
|
const [preview, setPreview] = React.useState(null);
|
|
74
77
|
const deltaAt = (x) => drag.current ? Math.round((x - drag.current.x) * units * drag.current.direction / drag.current.width) : 0;
|
|
@@ -86,213 +89,230 @@ const RangeTimeline = React.forwardRef(
|
|
|
86
89
|
const bounded = current.edge === "start" ? Math.min(delta, row.end - row.start) : Math.max(delta, row.start - row.end);
|
|
87
90
|
if (bounded) onRangeChange?.(row.id, current.edge, bounded);
|
|
88
91
|
};
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
const canvasStyle = {
|
|
93
|
+
"--range-timeline-columns": Math.max(1, columns.length),
|
|
94
|
+
"--range-timeline-units": units
|
|
95
|
+
};
|
|
96
|
+
const header = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
97
|
+
bands && bands.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-header", children: [
|
|
98
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", "aria-hidden": "true" }),
|
|
99
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-columns", children: bands.map((band, index) => /* @__PURE__ */ jsx(
|
|
100
|
+
"div",
|
|
101
|
+
{
|
|
102
|
+
className: "ui-range-timeline-column",
|
|
103
|
+
style: { gridColumn: `span ${band.units}` },
|
|
104
|
+
children: /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", children: band.label })
|
|
105
|
+
},
|
|
106
|
+
index
|
|
107
|
+
)) })
|
|
108
|
+
] }),
|
|
109
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-header", children: [
|
|
110
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", children: /* @__PURE__ */ jsx(Text, { weight: "bold", children: label }) }),
|
|
111
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-columns", ref: track, children: columns.map((column, index) => /* @__PURE__ */ jsx(
|
|
112
|
+
"div",
|
|
113
|
+
{
|
|
114
|
+
className: "ui-range-timeline-column",
|
|
115
|
+
style: { gridColumn: `span ${column.units}` },
|
|
116
|
+
children: /* @__PURE__ */ jsx(Text, { size: "xs", children: column.label })
|
|
117
|
+
},
|
|
118
|
+
index
|
|
119
|
+
)) })
|
|
120
|
+
] })
|
|
121
|
+
] });
|
|
122
|
+
const body = /* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-body", role: nested ? "list" : void 0, children: [
|
|
123
|
+
(bordered || columns.some((column) => column.muted)) && // Decorative: the same unit tracks as the header columns, laid once behind every row so
|
|
124
|
+
// each vertical rule runs the full body height exactly under its header column.
|
|
125
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-grid", "aria-hidden": "true", children: [
|
|
126
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
127
|
+
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-columns", children: columns.map((column, index) => /* @__PURE__ */ jsx(
|
|
128
|
+
"div",
|
|
129
|
+
{
|
|
130
|
+
className: "ui-range-timeline-grid-column",
|
|
131
|
+
"data-muted": column.muted ? "true" : void 0,
|
|
132
|
+
style: { gridColumn: `span ${column.units}` }
|
|
133
|
+
},
|
|
134
|
+
index
|
|
135
|
+
)) })
|
|
136
|
+
] }),
|
|
137
|
+
visibleRows.map((row, index) => {
|
|
138
|
+
const idBase = `${reactId}-row-${rows.indexOf(row)}`;
|
|
139
|
+
const delta = preview?.id === row.id ? preview.delta : 0;
|
|
140
|
+
const start = Math.min(row.end, row.start + (preview?.edge === "start" ? delta : 0));
|
|
141
|
+
const end = Math.max(row.start, row.end + (preview?.edge === "end" ? delta : 0));
|
|
142
|
+
const left = Math.max(0, start), right = Math.min(units, end + 1);
|
|
143
|
+
return /* @__PURE__ */ jsxs(
|
|
100
144
|
"div",
|
|
101
145
|
{
|
|
102
|
-
className: "ui-range-timeline-
|
|
103
|
-
|
|
104
|
-
"
|
|
105
|
-
"
|
|
146
|
+
className: "ui-range-timeline-row",
|
|
147
|
+
...nested && {
|
|
148
|
+
role: "listitem",
|
|
149
|
+
"aria-level": depthOf(row) + 1,
|
|
150
|
+
"aria-setsize": siblingsOf(index).size,
|
|
151
|
+
"aria-posinset": siblingsOf(index).position
|
|
106
152
|
},
|
|
107
153
|
children: [
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
},
|
|
129
|
-
index
|
|
130
|
-
)) })
|
|
131
|
-
] }),
|
|
132
|
-
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-body", role: nested ? "list" : void 0, children: [
|
|
133
|
-
(bordered || columns.some((column) => column.muted)) && // Decorative: the same unit tracks as the header columns, laid once behind every row so
|
|
134
|
-
// each vertical rule runs the full body height exactly under its header column.
|
|
135
|
-
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-grid", "aria-hidden": "true", children: [
|
|
136
|
-
/* @__PURE__ */ jsx("div", {}),
|
|
137
|
-
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-columns", children: columns.map((column, index) => /* @__PURE__ */ jsx(
|
|
138
|
-
"div",
|
|
139
|
-
{
|
|
140
|
-
className: "ui-range-timeline-grid-column",
|
|
141
|
-
"data-muted": column.muted ? "true" : void 0,
|
|
142
|
-
style: { gridColumn: `span ${column.units}` }
|
|
143
|
-
},
|
|
144
|
-
index
|
|
145
|
-
)) })
|
|
146
|
-
] }),
|
|
147
|
-
visibleRows.map((row, index) => {
|
|
148
|
-
const idBase = `${reactId}-row-${rows.indexOf(row)}`;
|
|
149
|
-
const delta = preview?.id === row.id ? preview.delta : 0;
|
|
150
|
-
const start = Math.min(row.end, row.start + (preview?.edge === "start" ? delta : 0));
|
|
151
|
-
const end = Math.max(row.start, row.end + (preview?.edge === "end" ? delta : 0));
|
|
152
|
-
const left = Math.max(0, start), right = Math.min(units, end + 1);
|
|
153
|
-
return /* @__PURE__ */ jsxs(
|
|
154
|
-
"div",
|
|
155
|
-
{
|
|
156
|
-
className: "ui-range-timeline-row",
|
|
157
|
-
...nested && {
|
|
158
|
-
role: "listitem",
|
|
159
|
-
"aria-level": depthOf(row) + 1,
|
|
160
|
-
"aria-setsize": siblingsOf(index).size,
|
|
161
|
-
"aria-posinset": siblingsOf(index).position
|
|
162
|
-
},
|
|
163
|
-
children: [
|
|
164
|
-
nested ? /* @__PURE__ */ jsxs(
|
|
165
|
-
"div",
|
|
166
|
-
{
|
|
167
|
-
className: "ui-range-timeline-label",
|
|
168
|
-
"data-nested": "true",
|
|
169
|
-
style: { "--range-timeline-depth": depthOf(row) },
|
|
170
|
-
children: [
|
|
171
|
-
parents.includes(row.id) ? /* @__PURE__ */ jsxs(
|
|
172
|
-
Button,
|
|
173
|
-
{
|
|
174
|
-
variant: "ghost",
|
|
175
|
-
size: "icon-xs",
|
|
176
|
-
className: "ui-range-timeline-disclosure",
|
|
177
|
-
"aria-expanded": isExpanded(row.id),
|
|
178
|
-
"aria-labelledby": `${idBase}-toggle ${idBase}-label`,
|
|
179
|
-
onClick: () => toggleRow(row.id),
|
|
180
|
-
children: [
|
|
181
|
-
/* @__PURE__ */ jsx("span", { id: `${idBase}-toggle`, hidden: true, children: t("rangeTimeline.childRows") }),
|
|
182
|
-
isExpanded(row.id) ? /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(
|
|
183
|
-
ChevronRight,
|
|
184
|
-
{
|
|
185
|
-
"aria-hidden": "true",
|
|
186
|
-
className: "ui-range-timeline-disclosure-collapsed"
|
|
187
|
-
}
|
|
188
|
-
)
|
|
189
|
-
]
|
|
190
|
-
}
|
|
191
|
-
) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ui-range-timeline-disclosure-spacer" }),
|
|
192
|
-
/* @__PURE__ */ jsx("div", { id: `${idBase}-label`, className: "ui-range-timeline-label-content", children: row.label })
|
|
193
|
-
]
|
|
194
|
-
}
|
|
195
|
-
) : /* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", children: row.label }),
|
|
196
|
-
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-track", children: [
|
|
197
|
-
today != null && today >= 0 && today < units && /* @__PURE__ */ jsx(
|
|
198
|
-
"span",
|
|
154
|
+
nested ? /* @__PURE__ */ jsxs(
|
|
155
|
+
"div",
|
|
156
|
+
{
|
|
157
|
+
className: "ui-range-timeline-label",
|
|
158
|
+
"data-nested": "true",
|
|
159
|
+
style: { "--range-timeline-depth": depthOf(row) },
|
|
160
|
+
children: [
|
|
161
|
+
parents.includes(row.id) ? /* @__PURE__ */ jsxs(
|
|
162
|
+
Button,
|
|
163
|
+
{
|
|
164
|
+
variant: "ghost",
|
|
165
|
+
size: "icon-xs",
|
|
166
|
+
className: "ui-range-timeline-disclosure",
|
|
167
|
+
"aria-expanded": isExpanded(row.id),
|
|
168
|
+
"aria-labelledby": `${idBase}-toggle ${idBase}-label`,
|
|
169
|
+
onClick: () => toggleRow(row.id),
|
|
170
|
+
children: [
|
|
171
|
+
/* @__PURE__ */ jsx("span", { id: `${idBase}-toggle`, hidden: true, children: t("rangeTimeline.childRows") }),
|
|
172
|
+
isExpanded(row.id) ? /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(
|
|
173
|
+
ChevronRight,
|
|
199
174
|
{
|
|
200
175
|
"aria-hidden": "true",
|
|
201
|
-
className: "ui-range-timeline-
|
|
202
|
-
style: { insetInlineStart: `${(today + 0.5) / units * 100}%` }
|
|
203
|
-
}
|
|
204
|
-
),
|
|
205
|
-
right <= left && (end < 0 ? /* @__PURE__ */ jsxs("span", { className: "ui-range-timeline-outside", "data-direction": "before", children: [
|
|
206
|
-
/* @__PURE__ */ jsx(
|
|
207
|
-
ChevronLeft,
|
|
208
|
-
{
|
|
209
|
-
"aria-hidden": "true",
|
|
210
|
-
className: "ui-range-timeline-outside-icon"
|
|
211
|
-
}
|
|
212
|
-
),
|
|
213
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tone: "muted", children: t("rangeTimeline.outsideBefore") })
|
|
214
|
-
] }) : /* @__PURE__ */ jsxs("span", { className: "ui-range-timeline-outside", "data-direction": "after", children: [
|
|
215
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tone: "muted", children: t("rangeTimeline.outsideAfter") }),
|
|
216
|
-
/* @__PURE__ */ jsx(
|
|
217
|
-
ChevronRight,
|
|
218
|
-
{
|
|
219
|
-
"aria-hidden": "true",
|
|
220
|
-
className: "ui-range-timeline-outside-icon"
|
|
221
|
-
}
|
|
222
|
-
)
|
|
223
|
-
] })),
|
|
224
|
-
right > left && /* @__PURE__ */ jsx(
|
|
225
|
-
"div",
|
|
226
|
-
{
|
|
227
|
-
className: "ui-range-timeline-bar",
|
|
228
|
-
style: {
|
|
229
|
-
insetInlineStart: `${left / units * 100}%`,
|
|
230
|
-
inlineSize: `${(right - left) / units * 100}%`
|
|
231
|
-
},
|
|
232
|
-
children: onRangeChange && (right - left) * Math.max(1, columns.length) >= units && ["start", "end"].filter(
|
|
233
|
-
(edge) => edge === "start" ? start >= 0 && start < units : end >= 0 && end < units
|
|
234
|
-
).map((edge) => /* @__PURE__ */ jsx(
|
|
235
|
-
Button,
|
|
236
|
-
{
|
|
237
|
-
variant: "ghost",
|
|
238
|
-
size: "icon-xs",
|
|
239
|
-
className: "ui-range-timeline-handle",
|
|
240
|
-
"data-edge": edge,
|
|
241
|
-
"aria-label": edge === "start" ? row.startLabel : row.endLabel,
|
|
242
|
-
onPointerDown: (event) => {
|
|
243
|
-
const width = track.current?.getBoundingClientRect().width ?? 0;
|
|
244
|
-
if (!width || event.button !== 0) return;
|
|
245
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
246
|
-
drag.current = {
|
|
247
|
-
id: row.id,
|
|
248
|
-
edge,
|
|
249
|
-
x: event.clientX,
|
|
250
|
-
width,
|
|
251
|
-
direction: getComputedStyle(event.currentTarget).direction === "rtl" ? -1 : 1
|
|
252
|
-
};
|
|
253
|
-
},
|
|
254
|
-
onPointerMove: (event) => {
|
|
255
|
-
if (drag.current)
|
|
256
|
-
setPreview({
|
|
257
|
-
id: drag.current.id,
|
|
258
|
-
edge: drag.current.edge,
|
|
259
|
-
delta: deltaAt(event.clientX)
|
|
260
|
-
});
|
|
261
|
-
},
|
|
262
|
-
onPointerUp: complete,
|
|
263
|
-
onPointerCancel: cancel,
|
|
264
|
-
onLostPointerCapture: cancel,
|
|
265
|
-
onKeyDown: (event) => {
|
|
266
|
-
if (event.key === "Escape") {
|
|
267
|
-
cancel();
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
const step = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0;
|
|
271
|
-
if (!step) return;
|
|
272
|
-
event.preventDefault();
|
|
273
|
-
const direction = getComputedStyle(event.currentTarget).direction === "rtl" ? -1 : 1;
|
|
274
|
-
const delta2 = step * direction;
|
|
275
|
-
if (edge === "start" ? row.start + delta2 <= row.end : row.end + delta2 >= row.start)
|
|
276
|
-
onRangeChange(row.id, edge, delta2);
|
|
277
|
-
},
|
|
278
|
-
children: /* @__PURE__ */ jsx(GripVertical, { "aria-hidden": "true" })
|
|
279
|
-
},
|
|
280
|
-
edge
|
|
281
|
-
))
|
|
176
|
+
className: "ui-range-timeline-disclosure-collapsed"
|
|
282
177
|
}
|
|
283
178
|
)
|
|
284
|
-
]
|
|
285
|
-
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ui-range-timeline-disclosure-spacer" }),
|
|
182
|
+
/* @__PURE__ */ jsx("div", { id: `${idBase}-label`, className: "ui-range-timeline-label-content", children: row.label })
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
) : /* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", children: row.label }),
|
|
186
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-track", children: [
|
|
187
|
+
today != null && today >= 0 && today < units && /* @__PURE__ */ jsx(
|
|
188
|
+
"span",
|
|
189
|
+
{
|
|
190
|
+
"aria-hidden": "true",
|
|
191
|
+
className: "ui-range-timeline-today",
|
|
192
|
+
style: { insetInlineStart: `${(today + 0.5) / units * 100}%` }
|
|
193
|
+
}
|
|
194
|
+
),
|
|
195
|
+
right <= left && (end < 0 ? /* @__PURE__ */ jsxs("span", { className: "ui-range-timeline-outside", "data-direction": "before", children: [
|
|
196
|
+
/* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true", className: "ui-range-timeline-outside-icon" }),
|
|
197
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tone: "muted", children: t("rangeTimeline.outsideBefore") })
|
|
198
|
+
] }) : /* @__PURE__ */ jsxs("span", { className: "ui-range-timeline-outside", "data-direction": "after", children: [
|
|
199
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tone: "muted", children: t("rangeTimeline.outsideAfter") }),
|
|
200
|
+
/* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true", className: "ui-range-timeline-outside-icon" })
|
|
201
|
+
] })),
|
|
202
|
+
right > left && /* @__PURE__ */ jsx(
|
|
203
|
+
"div",
|
|
204
|
+
{
|
|
205
|
+
className: "ui-range-timeline-bar",
|
|
206
|
+
style: {
|
|
207
|
+
insetInlineStart: `${left / units * 100}%`,
|
|
208
|
+
inlineSize: `${(right - left) / units * 100}%`
|
|
286
209
|
},
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
210
|
+
children: onRangeChange && (right - left) * Math.max(1, columns.length) >= units && ["start", "end"].filter(
|
|
211
|
+
(edge) => edge === "start" ? start >= 0 && start < units : end >= 0 && end < units
|
|
212
|
+
).map((edge) => /* @__PURE__ */ jsx(
|
|
213
|
+
Button,
|
|
214
|
+
{
|
|
215
|
+
variant: "ghost",
|
|
216
|
+
size: "icon-xs",
|
|
217
|
+
className: "ui-range-timeline-handle",
|
|
218
|
+
"data-edge": edge,
|
|
219
|
+
"aria-label": edge === "start" ? row.startLabel : row.endLabel,
|
|
220
|
+
onPointerDown: (event) => {
|
|
221
|
+
const width = track.current?.getBoundingClientRect().width ?? 0;
|
|
222
|
+
if (!width || event.button !== 0) return;
|
|
223
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
224
|
+
drag.current = {
|
|
225
|
+
id: row.id,
|
|
226
|
+
edge,
|
|
227
|
+
x: event.clientX,
|
|
228
|
+
width,
|
|
229
|
+
direction: getComputedStyle(event.currentTarget).direction === "rtl" ? -1 : 1
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
onPointerMove: (event) => {
|
|
233
|
+
if (drag.current)
|
|
234
|
+
setPreview({
|
|
235
|
+
id: drag.current.id,
|
|
236
|
+
edge: drag.current.edge,
|
|
237
|
+
delta: deltaAt(event.clientX)
|
|
238
|
+
});
|
|
239
|
+
},
|
|
240
|
+
onPointerUp: complete,
|
|
241
|
+
onPointerCancel: cancel,
|
|
242
|
+
onLostPointerCapture: cancel,
|
|
243
|
+
onKeyDown: (event) => {
|
|
244
|
+
if (event.key === "Escape") {
|
|
245
|
+
cancel();
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const step = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0;
|
|
249
|
+
if (!step) return;
|
|
250
|
+
event.preventDefault();
|
|
251
|
+
const direction = getComputedStyle(event.currentTarget).direction === "rtl" ? -1 : 1;
|
|
252
|
+
const delta2 = step * direction;
|
|
253
|
+
if (edge === "start" ? row.start + delta2 <= row.end : row.end + delta2 >= row.start)
|
|
254
|
+
onRangeChange(row.id, edge, delta2);
|
|
255
|
+
},
|
|
256
|
+
children: /* @__PURE__ */ jsx(GripVertical, { "aria-hidden": "true" })
|
|
257
|
+
},
|
|
258
|
+
edge
|
|
259
|
+
))
|
|
260
|
+
}
|
|
261
|
+
)
|
|
290
262
|
] })
|
|
291
263
|
]
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
264
|
+
},
|
|
265
|
+
row.id
|
|
266
|
+
);
|
|
267
|
+
})
|
|
268
|
+
] });
|
|
269
|
+
const sectionProps = {
|
|
270
|
+
...props,
|
|
271
|
+
ref,
|
|
272
|
+
className: cn("ui-range-timeline", className),
|
|
273
|
+
"data-bordered": bordered ? "true" : void 0,
|
|
274
|
+
// Only a NON-default step scopes the unit-width knob, so a theme that narrows
|
|
275
|
+
// --range-timeline-unit-width globally still owns the default timeline (gh#730).
|
|
276
|
+
"data-density": density === "default" ? void 0 : density,
|
|
277
|
+
"aria-label": label
|
|
278
|
+
};
|
|
279
|
+
if (!sticky) {
|
|
280
|
+
return /* @__PURE__ */ jsx("section", { ...sectionProps, tabIndex: 0, children: /* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-canvas", style: canvasStyle, children: [
|
|
281
|
+
header,
|
|
282
|
+
body
|
|
283
|
+
] }) });
|
|
284
|
+
}
|
|
285
|
+
const offsetHeader = typeof sticky === "object" ? sticky.offsetHeader ?? 0 : 0;
|
|
286
|
+
return /* @__PURE__ */ jsxs("section", { ...sectionProps, "data-sticky": "true", children: [
|
|
287
|
+
/* @__PURE__ */ jsx(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
ref: stickyHeader,
|
|
291
|
+
className: "ui-range-timeline-sticky-header",
|
|
292
|
+
style: { "--range-timeline-sticky-offset": `${offsetHeader}px` },
|
|
293
|
+
onWheel: (event) => {
|
|
294
|
+
if (bodyScroller.current && event.deltaX)
|
|
295
|
+
bodyScroller.current.scrollLeft += event.deltaX;
|
|
296
|
+
},
|
|
297
|
+
children: /* @__PURE__ */ jsx("div", { className: "ui-range-timeline-canvas", style: canvasStyle, children: header })
|
|
298
|
+
}
|
|
299
|
+
),
|
|
300
|
+
/* @__PURE__ */ jsx(
|
|
301
|
+
"div",
|
|
302
|
+
{
|
|
303
|
+
ref: bodyScroller,
|
|
304
|
+
className: "ui-range-timeline-scroller",
|
|
305
|
+
role: "group",
|
|
306
|
+
"aria-label": label,
|
|
307
|
+
tabIndex: 0,
|
|
308
|
+
onScroll: (event) => {
|
|
309
|
+
if (stickyHeader.current)
|
|
310
|
+
stickyHeader.current.scrollLeft = event.currentTarget.scrollLeft;
|
|
311
|
+
},
|
|
312
|
+
children: /* @__PURE__ */ jsx("div", { className: "ui-range-timeline-canvas", style: canvasStyle, children: body })
|
|
313
|
+
}
|
|
314
|
+
)
|
|
315
|
+
] });
|
|
296
316
|
}
|
|
297
317
|
);
|
|
298
318
|
export {
|