@parallelworks/ui 0.88.1 → 0.89.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/dist/ai/components/ChatInput.js +2 -0
- package/dist/components/Combobox.js +15 -1
- package/dist/components/Provider.d.ts +4 -1
- package/dist/components/Provider.js +9 -1
- package/dist/components/ToggleGroup.d.ts +9 -1
- package/dist/components/ToggleGroup.js +9 -7
- package/dist/components/chart.d.ts +23 -8
- package/dist/components/chart.js +82 -25
- package/dist/index.d.ts +1 -1
- package/dist/list/ListFilterBar.d.ts +6 -2
- package/dist/list/ListFilterBar.js +235 -34
- package/dist/list/filterModel.d.ts +31 -2
- package/dist/list/filterModel.js +51 -24
- package/dist/list/index.d.ts +1 -1
- package/dist/list/listView.d.ts +5 -2
- package/dist/list/listView.js +3 -2
- package/dist/list/useListFilters.d.ts +6 -2
- package/dist/list/useListFilters.js +3 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -269,6 +269,8 @@ function ChatInput({ onSend, disabled = false, placeholder, conversationId, onEd
|
|
|
269
269
|
placeholder: effectivePlaceholder,
|
|
270
270
|
"aria-label": inputLabel ?? effectivePlaceholder,
|
|
271
271
|
disabled,
|
|
272
|
+
autoComplete: "off",
|
|
273
|
+
"data-1p-ignore": true,
|
|
272
274
|
rows: 1,
|
|
273
275
|
className: cx("theme-text block w-full resize-none overflow-hidden", "bg-transparent border-0 px-4", toolbar ? "pt-3.5 pb-1" : "pt-3 pb-1", "placeholder:text-(--theme-placeholder)", "focus:outline-none focus:ring-0", "disabled:opacity-50 disabled:cursor-not-allowed", "text-[1rem] leading-relaxed")
|
|
274
276
|
})
|
|
@@ -642,10 +642,14 @@ function VirtualList({ ref, statusGroups, query, tall, renderItem }) {
|
|
|
642
642
|
match
|
|
643
643
|
]);
|
|
644
644
|
const scroller = useRef(null);
|
|
645
|
+
const scrolledByHand = useRef(false);
|
|
646
|
+
useEffect(() => {
|
|
647
|
+
scrolledByHand.current = false;
|
|
648
|
+
}, [query]);
|
|
645
649
|
const virtualizer = useVirtualizer({
|
|
646
650
|
count: rows.length,
|
|
647
651
|
getScrollElement: () => scroller.current,
|
|
648
|
-
estimateSize: (i) => rows[i]?.kind === "group" ? 28 :
|
|
652
|
+
estimateSize: (i) => rows[i]?.kind === "group" ? 28 : 32,
|
|
649
653
|
overscan: 10,
|
|
650
654
|
paddingStart: 4,
|
|
651
655
|
paddingEnd: 4,
|
|
@@ -655,6 +659,7 @@ function VirtualList({ ref, statusGroups, query, tall, renderItem }) {
|
|
|
655
659
|
useImperativeHandle(ref, () => ({ reveal(index, reason) {
|
|
656
660
|
const row = index === void 0 ? void 0 : rowOfItem[index];
|
|
657
661
|
if (row === void 0 || reason === "pointer") return;
|
|
662
|
+
if (reason !== "keyboard" && scrolledByHand.current) return;
|
|
658
663
|
queueMicrotask(() => virtualizer.scrollToIndex(row, { align: "auto" }));
|
|
659
664
|
} }), [rowOfItem, virtualizer]);
|
|
660
665
|
const scrollerRef = useCallback((element) => {
|
|
@@ -666,6 +671,15 @@ function VirtualList({ ref, statusGroups, query, tall, renderItem }) {
|
|
|
666
671
|
return /* @__PURE__ */ jsx("div", {
|
|
667
672
|
role: "presentation",
|
|
668
673
|
ref: scrollerRef,
|
|
674
|
+
onWheel: () => {
|
|
675
|
+
scrolledByHand.current = true;
|
|
676
|
+
},
|
|
677
|
+
onTouchMove: () => {
|
|
678
|
+
scrolledByHand.current = true;
|
|
679
|
+
},
|
|
680
|
+
onPointerDown: (e) => {
|
|
681
|
+
if (e.target === e.currentTarget) scrolledByHand.current = true;
|
|
682
|
+
},
|
|
669
683
|
className: cx("overflow-auto overscroll-contain px-1", tall ? "max-h-full" : "max-h-[min(15rem,var(--available-height))]"),
|
|
670
684
|
style: { height: total },
|
|
671
685
|
children: /* @__PURE__ */ jsx("div", {
|
|
@@ -676,8 +676,11 @@ export interface UIStrings {
|
|
|
676
676
|
changeValue: (values: string) => string;
|
|
677
677
|
/** Joins the values a chip lists. */
|
|
678
678
|
list: (values: string[]) => string;
|
|
679
|
-
/** A relative date preset: `today`,
|
|
679
|
+
/** A relative date preset: `today`, `month` (so far), `year` (so far), `all` (every date),
|
|
680
|
+
* any `-Nd` (the last N days) or any `-Nh` (the last N hours). */
|
|
680
681
|
datePreset: (preset: string) => string;
|
|
682
|
+
/** At phone width, the toggle that shows a quick filter's other options: "+3 more". */
|
|
683
|
+
quickMore: (count: number) => string;
|
|
681
684
|
/** The date picker's entry that picks days on a calendar. */
|
|
682
685
|
customDate: string;
|
|
683
686
|
/** Two days a filter spans. */
|
|
@@ -647,9 +647,17 @@ var DEFAULTS = {
|
|
|
647
647
|
changeValue: (values) => `Value: ${values}`,
|
|
648
648
|
list: (values) => values.join(", "),
|
|
649
649
|
datePreset: (preset) => {
|
|
650
|
+
const named = {
|
|
651
|
+
today: "Today",
|
|
652
|
+
month: "This month",
|
|
653
|
+
year: "This year",
|
|
654
|
+
all: "All time"
|
|
655
|
+
};
|
|
650
656
|
const days = preset.match(/^-(\d+)d$/)?.[1];
|
|
651
|
-
|
|
657
|
+
const hours = preset.match(/^-(\d+)h$/)?.[1];
|
|
658
|
+
return named[preset] ?? (days ? `Last ${days} days` : hours ? `Last ${hours} hours` : preset);
|
|
652
659
|
},
|
|
660
|
+
quickMore: (count) => `+${count} more`,
|
|
653
661
|
customDate: "Custom…",
|
|
654
662
|
between: (from, to) => `${from} – ${to}`,
|
|
655
663
|
formatDate: (date, locale) => dayFormat(locale)[date.getFullYear() === (/* @__PURE__ */ new Date()).getFullYear() ? "short" : "medium"].format(date),
|
|
@@ -7,6 +7,9 @@ export interface ToggleGroupOption<T extends string> {
|
|
|
7
7
|
/** How many items the option matches, after the label. */
|
|
8
8
|
count?: number | undefined;
|
|
9
9
|
disabled?: boolean | undefined;
|
|
10
|
+
/** `warning`: an option asking to be looked at, such as "Needs attention", whose label takes
|
|
11
|
+
* the warning tone while it is off. */
|
|
12
|
+
tone?: 'warning' | undefined;
|
|
10
13
|
testId?: string;
|
|
11
14
|
}
|
|
12
15
|
export interface ToggleGroupProps<T extends string> {
|
|
@@ -33,6 +36,11 @@ export interface ToggleGroupProps<T extends string> {
|
|
|
33
36
|
* of what the filter lets through. */
|
|
34
37
|
'aria-describedby'?: string | undefined;
|
|
35
38
|
testId?: string;
|
|
39
|
+
className?: string | undefined;
|
|
40
|
+
/** Whether an option that's off dims its icon so the pressed ones lead (default true).
|
|
41
|
+
* `false` keeps icons whose color means something, such as status lamps, at full strength;
|
|
42
|
+
* the fill and check still say which are on. */
|
|
43
|
+
dimIcons?: boolean | undefined;
|
|
36
44
|
}
|
|
37
45
|
/** Options that narrow a list, such as run statuses or job states, as a row of
|
|
38
46
|
* toggle buttons that wraps on a narrow screen. Pressing one adds it to the
|
|
@@ -44,4 +52,4 @@ export interface ToggleGroupProps<T extends string> {
|
|
|
44
52
|
* value, such as a time range, what to group by, or which view of the same
|
|
45
53
|
* data to show. A filter that may be off, or takes several values, is a
|
|
46
54
|
* `ToggleGroup`. */
|
|
47
|
-
export declare function ToggleGroup<T extends string>({ label, options, value, onValueChange, multiple, all, allLabel, size, disabled, 'aria-describedby': describedBy, testId, }: ToggleGroupProps<T>): import("react").JSX.Element;
|
|
55
|
+
export declare function ToggleGroup<T extends string>({ label, options, value, onValueChange, multiple, all, allLabel, size, disabled, 'aria-describedby': describedBy, testId, className, dimIcons, }: ToggleGroupProps<T>): import("react").JSX.Element;
|
|
@@ -18,7 +18,7 @@ var ALL = "\0all";
|
|
|
18
18
|
* value, such as a time range, what to group by, or which view of the same
|
|
19
19
|
* data to show. A filter that may be off, or takes several values, is a
|
|
20
20
|
* `ToggleGroup`. */
|
|
21
|
-
function ToggleGroup$1({ label, options, value, onValueChange, multiple = true, all = false, allLabel, size = "sm", disabled = false, "aria-describedby": describedBy, testId }) {
|
|
21
|
+
function ToggleGroup$1({ label, options, value, onValueChange, multiple = true, all = false, allLabel, size = "sm", disabled = false, "aria-describedby": describedBy, testId, className, dimIcons = true }) {
|
|
22
22
|
const strings = useStrings();
|
|
23
23
|
const allCount = typeof all === "object" ? all.count : void 0;
|
|
24
24
|
const pressed = all && value.length === 0 ? [ALL] : value;
|
|
@@ -26,7 +26,7 @@ function ToggleGroup$1({ label, options, value, onValueChange, multiple = true,
|
|
|
26
26
|
"aria-label": label,
|
|
27
27
|
"aria-describedby": describedBy,
|
|
28
28
|
"data-testid": testId,
|
|
29
|
-
className: "flex flex-wrap items-center gap-1",
|
|
29
|
+
className: cx("flex flex-wrap items-center gap-1", className),
|
|
30
30
|
multiple,
|
|
31
31
|
disabled,
|
|
32
32
|
value: pressed,
|
|
@@ -42,7 +42,8 @@ function ToggleGroup$1({ label, options, value, onValueChange, multiple = true,
|
|
|
42
42
|
value: ALL,
|
|
43
43
|
label: allLabel ?? strings.common.all,
|
|
44
44
|
count: allCount,
|
|
45
|
-
size
|
|
45
|
+
size,
|
|
46
|
+
dimIcon: dimIcons
|
|
46
47
|
}),
|
|
47
48
|
all && options.length > 0 && /* @__PURE__ */ jsx("span", {
|
|
48
49
|
"aria-hidden": "true",
|
|
@@ -50,12 +51,13 @@ function ToggleGroup$1({ label, options, value, onValueChange, multiple = true,
|
|
|
50
51
|
}),
|
|
51
52
|
options.map((option) => /* @__PURE__ */ jsx(Chip, {
|
|
52
53
|
...option,
|
|
53
|
-
size
|
|
54
|
+
size,
|
|
55
|
+
dimIcon: dimIcons
|
|
54
56
|
}, option.value))
|
|
55
57
|
]
|
|
56
58
|
});
|
|
57
59
|
}
|
|
58
|
-
function Chip({ value, label, icon, count, disabled, testId, size }) {
|
|
60
|
+
function Chip({ value, label, icon, count, disabled, tone, testId, size, dimIcon }) {
|
|
59
61
|
const locale = useLocale();
|
|
60
62
|
return /* @__PURE__ */ jsxs(Toggle, {
|
|
61
63
|
value,
|
|
@@ -64,10 +66,10 @@ function Chip({ value, label, icon, count, disabled, testId, size }) {
|
|
|
64
66
|
className: cx(buttonClasses({
|
|
65
67
|
variant: "outline",
|
|
66
68
|
size
|
|
67
|
-
}), "group focus-visible:-outline-offset-2 aria-pressed:bg-(--theme-accent-subtle)"),
|
|
69
|
+
}), "group focus-visible:-outline-offset-2 aria-pressed:bg-(--theme-accent-subtle)", tone === "warning" && "not-aria-pressed:text-(--theme-warning-text)"),
|
|
68
70
|
children: [
|
|
69
71
|
icon && /* @__PURE__ */ jsx("span", {
|
|
70
|
-
className: "inline-flex shrink-0 transition-opacity group-not-aria-pressed:opacity-55",
|
|
72
|
+
className: cx("inline-flex shrink-0 transition-opacity", dimIcon && "group-not-aria-pressed:opacity-55"),
|
|
71
73
|
children: icon
|
|
72
74
|
}),
|
|
73
75
|
label,
|
|
@@ -58,13 +58,19 @@ export declare function ChartLegendList({ items, highlighted, onHighlight, shape
|
|
|
58
58
|
export interface ChartTooltipItem {
|
|
59
59
|
key: string;
|
|
60
60
|
name: ReactNode;
|
|
61
|
+
/** Detail under the name and value, such as what a ratio was measured from, in muted text.
|
|
62
|
+
* It wraps onto as many lines as it needs and is never cut. */
|
|
63
|
+
detail?: ReactNode;
|
|
61
64
|
value: number;
|
|
62
65
|
color: string;
|
|
63
66
|
}
|
|
67
|
+
/** How a reading lists its series: in the order given, which is the legend's, or largest
|
|
68
|
+
* first. */
|
|
69
|
+
export type ChartReadingOrder = 'series' | 'value';
|
|
64
70
|
/** What a chart's tooltip shows for a point: its label, then each series' swatch, name and
|
|
65
|
-
* value,
|
|
66
|
-
* A charting library's tooltip renders it as its content. */
|
|
67
|
-
export declare function ChartTooltipContent({ label, items, formatValue, total, highlighted, hideZero, sort, className, style, }: {
|
|
71
|
+
* value in the legend's order, zeros too, the series in focus in bold, and a total when there
|
|
72
|
+
* is more than one. A charting library's tooltip renders it as its content. */
|
|
73
|
+
export declare function ChartTooltipContent({ label, items, formatValue, total, highlighted, hideZero, order, sort, className, style, }: {
|
|
68
74
|
label?: ReactNode;
|
|
69
75
|
items: readonly ChartTooltipItem[];
|
|
70
76
|
/** Formats each value and the total, such as a currency; numbers in the host's locale
|
|
@@ -73,9 +79,12 @@ export declare function ChartTooltipContent({ label, items, formatValue, total,
|
|
|
73
79
|
/** Adds a total row; on by default when more than one series shows. */
|
|
74
80
|
total?: boolean | undefined;
|
|
75
81
|
highlighted?: string | null | undefined;
|
|
76
|
-
/** Leaves out series whose value is zero;
|
|
82
|
+
/** Leaves out series whose value is zero; off by default, since a zero is a reading too. */
|
|
77
83
|
hideZero?: boolean | undefined;
|
|
78
|
-
/**
|
|
84
|
+
/** `series` (the default) keeps the order of `items`, which is the legend's; `value` lists
|
|
85
|
+
* the largest first. */
|
|
86
|
+
order?: ChartReadingOrder | undefined;
|
|
87
|
+
/** @deprecated Use `order="value"`. */
|
|
79
88
|
sort?: boolean | undefined;
|
|
80
89
|
className?: string | undefined;
|
|
81
90
|
/** Places it; `ChartTooltipBeside` places it beside a crosshair. */
|
|
@@ -138,12 +147,18 @@ export interface ChartReading {
|
|
|
138
147
|
/** Adds the total; on by default when there is more than one series. */
|
|
139
148
|
total?: boolean | undefined;
|
|
140
149
|
highlighted?: string | null | undefined;
|
|
150
|
+
/** `series` (the default) lists the series in the order of `items`, the legend's; `value`
|
|
151
|
+
* lists the largest first. The tooltip and the readout both follow it. */
|
|
152
|
+
order?: ChartReadingOrder | undefined;
|
|
153
|
+
/** Leaves out series whose value is zero; off by default, since a zero is a reading too. */
|
|
154
|
+
hideZero?: boolean | undefined;
|
|
141
155
|
}
|
|
142
156
|
/** A point's reading docked above a chart's plot, for a chart too narrow for a tooltip beside
|
|
143
157
|
* its crosshair: the label and total on one line, then each series' swatch, name and value,
|
|
144
|
-
* in two columns as wide as their content when
|
|
145
|
-
* its
|
|
146
|
-
|
|
158
|
+
* in two columns as wide as their content when everything fits at full length, else one.
|
|
159
|
+
* By default every series keeps its place and its row, zero or not, so the readout keeps its
|
|
160
|
+
* height and order as the reading changes. */
|
|
161
|
+
export declare function ChartReadout({ label, items, formatValue, total, highlighted, order, hideZero, className, }: ChartReading & {
|
|
147
162
|
className?: string | undefined;
|
|
148
163
|
}): import("react").JSX.Element;
|
|
149
164
|
/** A chart's plot with its reading, placed for its width: on a wide chart a tooltip beside the
|
package/dist/components/chart.js
CHANGED
|
@@ -124,16 +124,30 @@ function ChartLegendList({ items, highlighted, onHighlight, shape, className })
|
|
|
124
124
|
})
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
|
+
var SWATCH_ON_LINE = "mt-[3px]";
|
|
128
|
+
/** A series' detail, on the lines under its name and value, in muted text: it wraps onto as
|
|
129
|
+
* many lines as it needs and is never cut. */
|
|
130
|
+
function SeriesDetail({ item, className }) {
|
|
131
|
+
if (item.detail == null || item.detail === "") return null;
|
|
132
|
+
return /* @__PURE__ */ jsx("span", {
|
|
133
|
+
className: cx("col-start-2 col-end-[-1] font-normal break-words text-(--theme-muted-text-color)", className),
|
|
134
|
+
children: item.detail
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/** A reading's rows: zeros left out when asked, and largest first when asked. */
|
|
138
|
+
function readingRows(items, order, hideZero) {
|
|
139
|
+
const rows = hideZero ? items.filter((item) => item.value !== 0) : [...items];
|
|
140
|
+
return order === "value" ? rows.sort((a, b) => b.value - a.value) : rows;
|
|
141
|
+
}
|
|
127
142
|
/** What a chart's tooltip shows for a point: its label, then each series' swatch, name and
|
|
128
|
-
* value,
|
|
129
|
-
* A charting library's tooltip renders it as its content. */
|
|
130
|
-
function ChartTooltipContent({ label, items, formatValue, total, highlighted, hideZero =
|
|
143
|
+
* value in the legend's order, zeros too, the series in focus in bold, and a total when there
|
|
144
|
+
* is more than one. A charting library's tooltip renders it as its content. */
|
|
145
|
+
function ChartTooltipContent({ label, items, formatValue, total, highlighted, hideZero = false, order, sort, className, style }) {
|
|
131
146
|
const { chart: t } = useStrings();
|
|
132
147
|
const locale = useLocale();
|
|
133
148
|
const number = useMemo(() => new Intl.NumberFormat(locale, { maximumFractionDigits: 2 }), [locale]);
|
|
134
149
|
const format = formatValue ?? ((n) => number.format(n));
|
|
135
|
-
|
|
136
|
-
if (sort) rows = [...rows].sort((a, b) => b.value - a.value);
|
|
150
|
+
const rows = readingRows(items, order ?? (sort ? "value" : "series"), hideZero);
|
|
137
151
|
const sum = rows.reduce((acc, item) => acc + item.value, 0);
|
|
138
152
|
const showTotal = total ?? rows.length > 1;
|
|
139
153
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -147,16 +161,23 @@ function ChartTooltipContent({ label, items, formatValue, total, highlighted, hi
|
|
|
147
161
|
/* @__PURE__ */ jsx("ul", {
|
|
148
162
|
className: "m-0 list-none space-y-1 p-0",
|
|
149
163
|
children: rows.map((item) => /* @__PURE__ */ jsxs("li", {
|
|
150
|
-
className: cx("
|
|
164
|
+
className: cx("grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-x-2", highlighted === item.key ? "font-semibold" : highlighted != null && "text-(--theme-muted-text-color)"),
|
|
151
165
|
children: [
|
|
152
|
-
/* @__PURE__ */ jsx(SeriesSwatch, {
|
|
166
|
+
/* @__PURE__ */ jsx(SeriesSwatch, {
|
|
167
|
+
color: item.color,
|
|
168
|
+
className: SWATCH_ON_LINE
|
|
169
|
+
}),
|
|
153
170
|
/* @__PURE__ */ jsx("span", {
|
|
154
|
-
className: "
|
|
171
|
+
className: "truncate",
|
|
155
172
|
children: item.name
|
|
156
173
|
}),
|
|
157
174
|
/* @__PURE__ */ jsx("span", {
|
|
158
175
|
className: "ml-2 tabular-nums",
|
|
159
176
|
children: format(item.value)
|
|
177
|
+
}),
|
|
178
|
+
/* @__PURE__ */ jsx(SeriesDetail, {
|
|
179
|
+
item,
|
|
180
|
+
className: "max-w-64"
|
|
160
181
|
})
|
|
161
182
|
]
|
|
162
183
|
}, item.key))
|
|
@@ -248,35 +269,64 @@ function ChartTooltipBeside({ x, top = 0, gap = 12, className, children }) {
|
|
|
248
269
|
});
|
|
249
270
|
}
|
|
250
271
|
var TWO_COLUMNS = "repeat(2, auto minmax(0, max-content) auto)";
|
|
251
|
-
|
|
252
|
-
|
|
272
|
+
/** The width an element's content needs, every line of it at full length: the widest of its
|
|
273
|
+
* own and its descendants' scroll widths, since a truncated line hides what overflows it. */
|
|
274
|
+
function fullWidth(el) {
|
|
275
|
+
if (!el) return 0;
|
|
276
|
+
let widest = el.scrollWidth;
|
|
277
|
+
for (const child of el.querySelectorAll("*")) widest = Math.max(widest, child.scrollWidth);
|
|
278
|
+
return widest;
|
|
279
|
+
}
|
|
280
|
+
var COLUMN_SPACE = 8;
|
|
281
|
+
var ONE_COLUMN = "auto minmax(0, max-content) auto 1fr";
|
|
253
282
|
/** A point's reading docked above a chart's plot, for a chart too narrow for a tooltip beside
|
|
254
283
|
* its crosshair: the label and total on one line, then each series' swatch, name and value,
|
|
255
|
-
* in two columns as wide as their content when
|
|
256
|
-
* its
|
|
257
|
-
|
|
284
|
+
* in two columns as wide as their content when everything fits at full length, else one.
|
|
285
|
+
* By default every series keeps its place and its row, zero or not, so the readout keeps its
|
|
286
|
+
* height and order as the reading changes. */
|
|
287
|
+
function ChartReadout({ label, items, formatValue, total, highlighted, order = "series", hideZero = false, className }) {
|
|
258
288
|
const { chart: t } = useStrings();
|
|
259
289
|
const locale = useLocale();
|
|
260
290
|
const number = useMemo(() => new Intl.NumberFormat(locale, { maximumFractionDigits: 2 }), [locale]);
|
|
261
291
|
const format = formatValue ?? ((n) => number.format(n));
|
|
262
|
-
const
|
|
263
|
-
const
|
|
292
|
+
const rows = readingRows(items, order, hideZero);
|
|
293
|
+
const sum = rows.reduce((acc, item) => acc + item.value, 0);
|
|
294
|
+
const showTotal = total ?? rows.length > 1;
|
|
264
295
|
const list = useRef(null);
|
|
265
296
|
const [columns, setColumns] = useState(2);
|
|
266
297
|
useLayoutEffect(() => {
|
|
267
298
|
const ul = list.current;
|
|
268
299
|
if (!ul) return;
|
|
269
300
|
const choose = () => {
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
301
|
+
const cols = [0, 1].map(() => ({
|
|
302
|
+
swatch: 0,
|
|
303
|
+
name: 0,
|
|
304
|
+
value: 0
|
|
305
|
+
}));
|
|
306
|
+
[...ul.children].forEach((li, i) => {
|
|
307
|
+
const [swatch, name, value] = [...li.children];
|
|
308
|
+
const col = cols[i % 2];
|
|
309
|
+
col.swatch = Math.max(col.swatch, swatch?.offsetWidth ?? 0);
|
|
310
|
+
col.name = Math.max(col.name, fullWidth(name));
|
|
311
|
+
col.value = Math.max(col.value, fullWidth(value));
|
|
312
|
+
});
|
|
313
|
+
const gap = Number.parseFloat(getComputedStyle(ul).columnGap) || 0;
|
|
314
|
+
const need = cols.reduce((sum, c) => sum + c.swatch + c.name + c.value, 0) + 5 * gap + COLUMN_SPACE;
|
|
315
|
+
const detailed = rows.some((item) => item.detail != null && item.detail !== "");
|
|
316
|
+
setColumns(rows.length > 1 && !detailed && need <= ul.clientWidth ? 2 : 1);
|
|
275
317
|
};
|
|
276
318
|
choose();
|
|
319
|
+
let live = true;
|
|
320
|
+
const fonts = typeof document === "undefined" ? void 0 : document.fonts;
|
|
321
|
+
fonts?.ready.then(() => live && choose());
|
|
322
|
+
fonts?.addEventListener?.("loadingdone", choose);
|
|
277
323
|
const observer = new ResizeObserver(choose);
|
|
278
324
|
observer.observe(ul);
|
|
279
|
-
return () =>
|
|
325
|
+
return () => {
|
|
326
|
+
live = false;
|
|
327
|
+
fonts?.removeEventListener?.("loadingdone", choose);
|
|
328
|
+
observer.disconnect();
|
|
329
|
+
};
|
|
280
330
|
});
|
|
281
331
|
return /* @__PURE__ */ jsxs("div", {
|
|
282
332
|
"data-chart-readout": "",
|
|
@@ -302,19 +352,26 @@ function ChartReadout({ label, items, formatValue, total, highlighted, className
|
|
|
302
352
|
})]
|
|
303
353
|
}), /* @__PURE__ */ jsx("ul", {
|
|
304
354
|
ref: list,
|
|
305
|
-
className: "m-0 grid list-none items-
|
|
355
|
+
className: "m-0 grid list-none items-start justify-start gap-x-1.5 gap-y-0.5 p-0",
|
|
306
356
|
style: { gridTemplateColumns: columns === 2 ? TWO_COLUMNS : ONE_COLUMN },
|
|
307
|
-
children:
|
|
357
|
+
children: rows.map((item, i) => /* @__PURE__ */ jsxs("li", {
|
|
308
358
|
className: cx("contents", highlighted === item.key ? "font-semibold" : highlighted != null && "text-(--theme-muted-text-color)"),
|
|
309
359
|
children: [
|
|
310
|
-
/* @__PURE__ */ jsx(SeriesSwatch, {
|
|
360
|
+
/* @__PURE__ */ jsx(SeriesSwatch, {
|
|
361
|
+
color: item.color,
|
|
362
|
+
className: cx(SWATCH_ON_LINE, columns === 1 && "col-start-1")
|
|
363
|
+
}),
|
|
311
364
|
/* @__PURE__ */ jsx("span", {
|
|
312
|
-
className: "
|
|
365
|
+
className: "truncate",
|
|
313
366
|
children: item.name
|
|
314
367
|
}),
|
|
315
368
|
/* @__PURE__ */ jsx("span", {
|
|
316
369
|
className: cx("text-end tabular-nums", columns === 2 && i % 2 === 0 && "me-2"),
|
|
317
370
|
children: format(item.value)
|
|
371
|
+
}),
|
|
372
|
+
/* @__PURE__ */ jsx(SeriesDetail, {
|
|
373
|
+
item,
|
|
374
|
+
className: "[contain:inline-size]"
|
|
318
375
|
})
|
|
319
376
|
]
|
|
320
377
|
}, item.key))
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { ContextMenuProvider, type MenuCloseTrigger, type MenuOpener, type OpenM
|
|
|
15
15
|
export { CopyButton, type CopyButtonProps, CopyCodeBlock, type CopyCodeBlockProps, } from './components/CopyButton.js';
|
|
16
16
|
export { CreateModal, CreateModalSelect, CreateModalSwitch, } from './components/CreateModal.js';
|
|
17
17
|
export { categoryClasses, categoryOf } from './components/category.js';
|
|
18
|
-
export { type ChartLegendItem, ChartLegendList, type ChartReading, ChartReadout, ChartTooltipBeside, ChartTooltipContent, ChartTooltipFrame, type ChartTooltipItem, type ChartTooltipPlacement, chartTooltipPlacement, foldSeries, OTHER_SERIES_COLOR, OTHER_SERIES_KEY, SERIES_LIMIT, SeriesSwatch, type SeriesSwatchShape, seriesColors, seriesOpacity, seriesSlotColor, useSeriesHighlight, } from './components/chart.js';
|
|
18
|
+
export { type ChartLegendItem, ChartLegendList, type ChartReading, type ChartReadingOrder, ChartReadout, ChartTooltipBeside, ChartTooltipContent, ChartTooltipFrame, type ChartTooltipItem, type ChartTooltipPlacement, chartTooltipPlacement, foldSeries, OTHER_SERIES_COLOR, OTHER_SERIES_KEY, SERIES_LIMIT, SeriesSwatch, type SeriesSwatchShape, seriesColors, seriesOpacity, seriesSlotColor, useSeriesHighlight, } from './components/chart.js';
|
|
19
19
|
export { Calendar, type CalendarProps, DatePicker, type DatePickerProps, } from './components/DatePicker.js';
|
|
20
20
|
export { DescriptionListGroup, DescriptionListItem, type DescriptionListItemProps, type DescriptionListProps, type DescriptionListSize, type DescriptionListVariant, default as DescriptionList, } from './components/DescriptionList.js';
|
|
21
21
|
export { collapsePanelClassName, Disclosure, DisclosurePanel, type DisclosureProps, } from './components/Disclosure.js';
|
|
@@ -37,6 +37,10 @@ export interface ListFilterBarProps {
|
|
|
37
37
|
/** The chips that say what narrows a list, under its toolbar: one per filter, each editable in
|
|
38
38
|
* place, then "+ Filter" and Clear (or Reset, where the page has default filters). It shows
|
|
39
39
|
* only while a filter is on or a field is required. At phone width it stops at two lines and
|
|
40
|
-
* a "+n filters" chip opens the rest in a sheet.
|
|
41
|
-
|
|
40
|
+
* a "+n filters" chip opens the rest in a sheet.
|
|
41
|
+
*
|
|
42
|
+
* The list's quick filters show above the chips as toggles, always, setting the same filters
|
|
43
|
+
* the chips edit. At phone width each keeps to one line, and "+n more" opens the rest in the
|
|
44
|
+
* same sheet. */
|
|
45
|
+
export declare function ListFilterBar({ filters, trailing, label, className }: ListFilterBarProps): false | import("react").JSX.Element | null;
|
|
42
46
|
export {};
|