@setsquare/ui 0.9.1 → 0.11.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/CHANGELOG.md +107 -0
- package/README.md +5 -2
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/cn.d.ts.map +1 -1
- package/dist/lib/cn.js +1 -0
- package/dist/lib/cn.js.map +1 -1
- package/dist/lib/english.d.ts.map +1 -1
- package/dist/lib/english.js +2 -0
- package/dist/lib/english.js.map +1 -1
- package/dist/lib/locale.d.ts +3 -0
- package/dist/lib/locale.d.ts.map +1 -1
- package/dist/lib/locale.js.map +1 -1
- package/dist/lib/timeline-scale.d.ts +106 -0
- package/dist/lib/timeline-scale.d.ts.map +1 -0
- package/dist/lib/timeline-scale.js +221 -0
- package/dist/lib/timeline-scale.js.map +1 -0
- package/dist/lib/use-scroll-tab-stop.d.ts +9 -0
- package/dist/lib/use-scroll-tab-stop.d.ts.map +1 -0
- package/dist/lib/use-scroll-tab-stop.js +46 -0
- package/dist/lib/use-scroll-tab-stop.js.map +1 -0
- package/dist/shell/dashboard-shell.d.ts +1 -0
- package/dist/shell/dashboard-shell.d.ts.map +1 -1
- package/dist/shell/dashboard-shell.js +2 -34
- package/dist/shell/dashboard-shell.js.map +1 -1
- package/dist/shell/page-header.d.ts +7 -1
- package/dist/shell/page-header.d.ts.map +1 -1
- package/dist/shell/page-header.js +3 -2
- package/dist/shell/page-header.js.map +1 -1
- package/dist/shell/right-panel.d.ts +29 -1
- package/dist/shell/right-panel.d.ts.map +1 -1
- package/dist/shell/right-panel.js +14 -5
- package/dist/shell/right-panel.js.map +1 -1
- package/dist/styles/theme.css +16 -0
- package/dist/styles/tokens.css +23 -0
- package/dist/tokens.json +95 -0
- package/dist/ui/button.d.ts +2 -1
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +9 -3
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/dialog.d.ts +14 -2
- package/dist/ui/dialog.d.ts.map +1 -1
- package/dist/ui/dialog.js +19 -4
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/disabled-reason.d.ts +36 -0
- package/dist/ui/disabled-reason.d.ts.map +1 -0
- package/dist/ui/disabled-reason.js +27 -0
- package/dist/ui/disabled-reason.js.map +1 -0
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js +10 -6
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/menu.d.ts +9 -3
- package/dist/ui/menu.d.ts.map +1 -1
- package/dist/ui/menu.js +22 -4
- package/dist/ui/menu.js.map +1 -1
- package/dist/ui/timeline.d.ts +231 -0
- package/dist/ui/timeline.d.ts.map +1 -0
- package/dist/ui/timeline.js +539 -0
- package/dist/ui/timeline.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time on a timeline: formats for the ruler and for screen readers, the ruler's tick steps at a zoom, snapping, and
|
|
3
|
+
* stacking flags that would overlap. Plain functions, so they are tested without a browser and a server can use them.
|
|
4
|
+
*
|
|
5
|
+
* Every time is a number of seconds. For `date`, it is seconds since the Unix epoch.
|
|
6
|
+
*/
|
|
7
|
+
const pad = (n, width = 2) => String(Math.floor(n)).padStart(width, '0');
|
|
8
|
+
const fpsOf = (o) => o.fps ?? 25;
|
|
9
|
+
/** The frame a time falls in, counting from 0. */
|
|
10
|
+
export const frameAt = (t, fps) => Math.round(t * fps + 1e-9);
|
|
11
|
+
/**
|
|
12
|
+
* A time as the ruler and a tooltip show it. `step` is the ruler's step, so a label says no more than the step can
|
|
13
|
+
* tell apart: 0:04 for whole seconds, 0:04.5 for tenths. For `date`, the step picks the parts (time of day, day,
|
|
14
|
+
* month).
|
|
15
|
+
*/
|
|
16
|
+
export function formatTime(t, options, step = 1) {
|
|
17
|
+
const fps = fpsOf(options);
|
|
18
|
+
switch (options.format) {
|
|
19
|
+
case 'frames':
|
|
20
|
+
return new Intl.NumberFormat(options.locale).format(frameAt(t, fps));
|
|
21
|
+
case 'timecode': {
|
|
22
|
+
const frames = frameAt(t, fps);
|
|
23
|
+
const whole = Math.floor(frames / fps);
|
|
24
|
+
return `${pad(whole / 3600)}:${pad((whole % 3600) / 60)}:${pad(whole % 60)}:${pad(frames % fps)}`;
|
|
25
|
+
}
|
|
26
|
+
case 'date': {
|
|
27
|
+
const date = new Date(t * 1000);
|
|
28
|
+
const zone = options.timeZone ? { timeZone: options.timeZone } : {};
|
|
29
|
+
const parts = step < 60
|
|
30
|
+
? { hour: 'numeric', minute: '2-digit', second: '2-digit' }
|
|
31
|
+
: step < 86400
|
|
32
|
+
? { hour: 'numeric', minute: '2-digit' }
|
|
33
|
+
: step < 28 * 86400
|
|
34
|
+
? { day: 'numeric', month: 'short' }
|
|
35
|
+
: { month: 'short', year: 'numeric' };
|
|
36
|
+
return new Intl.DateTimeFormat(options.locale, { ...parts, ...zone }).format(date);
|
|
37
|
+
}
|
|
38
|
+
default: {
|
|
39
|
+
const decimals = step >= 1 ? 0 : step >= 0.1 ? 1 : 2;
|
|
40
|
+
const sign = t < 0 ? '-' : '';
|
|
41
|
+
const abs = Math.abs(t);
|
|
42
|
+
const hours = Math.floor(abs / 3600);
|
|
43
|
+
const minutes = Math.floor((abs % 3600) / 60);
|
|
44
|
+
const seconds = abs % 60;
|
|
45
|
+
const secondsText = new Intl.NumberFormat(options.locale, {
|
|
46
|
+
minimumIntegerDigits: 2,
|
|
47
|
+
minimumFractionDigits: decimals,
|
|
48
|
+
maximumFractionDigits: decimals,
|
|
49
|
+
useGrouping: false,
|
|
50
|
+
}).format(Math.floor(seconds * 10 ** decimals + 1e-9) / 10 ** decimals);
|
|
51
|
+
return hours
|
|
52
|
+
? `${sign}${hours}:${pad(minutes)}:${secondsText}`
|
|
53
|
+
: `${sign}${minutes}:${secondsText}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A time in words, for a screen reader (a slider's aria-valuetext): "1 minute, 4.5 seconds", from the locale's own
|
|
59
|
+
* unit names and list pattern. `words.frames` names a count of frames, which Intl has no unit for ("12 frames"), and
|
|
60
|
+
* `words.frame` a frame number ("Frame 96"); both come from the component's labels.
|
|
61
|
+
*/
|
|
62
|
+
export function speakTime(t, options, words) {
|
|
63
|
+
const locale = options.locale;
|
|
64
|
+
const fps = fpsOf(options);
|
|
65
|
+
if (options.format === 'date') {
|
|
66
|
+
const zone = options.timeZone ? { timeZone: options.timeZone } : {};
|
|
67
|
+
return new Intl.DateTimeFormat(locale, {
|
|
68
|
+
dateStyle: 'medium',
|
|
69
|
+
timeStyle: 'short',
|
|
70
|
+
...zone,
|
|
71
|
+
}).format(new Date(t * 1000));
|
|
72
|
+
}
|
|
73
|
+
if (options.format === 'frames')
|
|
74
|
+
return words.frame(frameAt(t, fps));
|
|
75
|
+
const unit = (value, name, digits = 0) => new Intl.NumberFormat(locale, {
|
|
76
|
+
style: 'unit',
|
|
77
|
+
unit: name,
|
|
78
|
+
unitDisplay: 'long',
|
|
79
|
+
maximumFractionDigits: digits,
|
|
80
|
+
}).format(value);
|
|
81
|
+
const list = new Intl.ListFormat(locale, { style: 'long', type: 'unit' });
|
|
82
|
+
if (options.format === 'timecode') {
|
|
83
|
+
const frames = frameAt(t, fps);
|
|
84
|
+
const whole = Math.floor(frames / fps);
|
|
85
|
+
const parts = [
|
|
86
|
+
whole >= 3600 ? unit(Math.floor(whole / 3600), 'hour') : '',
|
|
87
|
+
whole >= 60 ? unit(Math.floor((whole % 3600) / 60), 'minute') : '',
|
|
88
|
+
unit(whole % 60, 'second'),
|
|
89
|
+
words.frames(frames % fps),
|
|
90
|
+
].filter(Boolean);
|
|
91
|
+
return list.format(parts);
|
|
92
|
+
}
|
|
93
|
+
const abs = Math.abs(t);
|
|
94
|
+
const hours = Math.floor(abs / 3600);
|
|
95
|
+
const minutes = Math.floor((abs % 3600) / 60);
|
|
96
|
+
const seconds = Math.round((abs % 60) * 100) / 100;
|
|
97
|
+
const parts = [
|
|
98
|
+
hours ? unit(hours, 'hour') : '',
|
|
99
|
+
minutes ? unit(minutes, 'minute') : '',
|
|
100
|
+
seconds || (!hours && !minutes) ? unit(seconds, 'second', 2) : '',
|
|
101
|
+
].filter(Boolean);
|
|
102
|
+
return list.format(parts);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The steps a ruler may label, in seconds, smallest first. Dates stop at a fortnight: months and years aren't a
|
|
106
|
+
* whole number of seconds, so a ruler that long needs calendar ticks, which this doesn't draw.
|
|
107
|
+
*/
|
|
108
|
+
function ladder(options) {
|
|
109
|
+
const fps = fpsOf(options);
|
|
110
|
+
const seconds = [
|
|
111
|
+
1, 2, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600, 7200, 10800, 21600, 43200,
|
|
112
|
+
];
|
|
113
|
+
switch (options.format) {
|
|
114
|
+
case 'frames':
|
|
115
|
+
case 'timecode':
|
|
116
|
+
return [...[1, 2, 5, 10].filter((f) => f < fps).map((f) => f / fps), ...seconds];
|
|
117
|
+
case 'date':
|
|
118
|
+
return [...seconds, 86400, 2 * 86400, 7 * 86400, 14 * 86400];
|
|
119
|
+
default:
|
|
120
|
+
return [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, ...seconds];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The ruler's steps at a zoom. `major` is the smallest labelled step whose labels are at least `minLabelPx` apart:
|
|
125
|
+
* a number, or a function of the step, since a label's width depends on what it shows (0:04 or 0:04.5, a time or a
|
|
126
|
+
* day). `minor` is the smallest step on the same ladder that divides `major` into at most ten, with ticks at least
|
|
127
|
+
* `minTickPx` apart, or null when there's no room for one.
|
|
128
|
+
*/
|
|
129
|
+
export function tickSteps(pxPerSecond, options, minLabelPx = 72, minTickPx = 8) {
|
|
130
|
+
const steps = ladder(options);
|
|
131
|
+
const need = typeof minLabelPx === 'number' ? () => minLabelPx : minLabelPx;
|
|
132
|
+
const major = steps.find((s) => s * pxPerSecond >= need(s)) ?? steps[steps.length - 1];
|
|
133
|
+
const divides = (s) => Math.abs(major / s - Math.round(major / s)) < 1e-6;
|
|
134
|
+
const minor = steps.find((s) => s < major && divides(s) && major / s <= 10 && s * pxPerSecond >= minTickPx) ??
|
|
135
|
+
null;
|
|
136
|
+
return { major, minor };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The ticks from `start` to `end`: every `step` counted from `origin`, each marked major when it is also a whole
|
|
140
|
+
* number of `major` steps from there. A date ruler counts from its own start (local midnight, say), not from the
|
|
141
|
+
* epoch, so its hours and days fall where the reader's do.
|
|
142
|
+
*/
|
|
143
|
+
export function ticks(start, end, step, major = step, origin = 0) {
|
|
144
|
+
const out = [];
|
|
145
|
+
const first = Math.ceil((start - origin) / step - 1e-9);
|
|
146
|
+
for (let i = first; i < first + 5000; i++) {
|
|
147
|
+
const t = Math.round((origin + i * step) * 1e6) / 1e6;
|
|
148
|
+
if (t > end + 1e-9)
|
|
149
|
+
break;
|
|
150
|
+
const n = (t - origin) / major;
|
|
151
|
+
out.push({ t, major: Math.abs(n - Math.round(n)) < 1e-6 });
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The nearest snap point within `thresholdPx` of `t` at this zoom, and the time to use: the point's, or `t` itself
|
|
157
|
+
* when none is close enough.
|
|
158
|
+
*/
|
|
159
|
+
export function snap(t, points, pxPerSecond, thresholdPx = 8) {
|
|
160
|
+
let best = null;
|
|
161
|
+
let distance = Infinity;
|
|
162
|
+
for (const point of points) {
|
|
163
|
+
const d = Math.abs(point.time - t) * pxPerSecond;
|
|
164
|
+
if (d <= thresholdPx && d < distance) {
|
|
165
|
+
best = point;
|
|
166
|
+
distance = d;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return { time: best ? best.time : t, point: best };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Where a pointer puts something: `raw` rounded to the nearest `step` from `origin` (a frame, say), then pulled to
|
|
173
|
+
* a snap point within `thresholdPx`, which wins over the step. `free` (Alt held) skips both.
|
|
174
|
+
*/
|
|
175
|
+
export function place(raw, options, thresholdPx = 8) {
|
|
176
|
+
if (options.free)
|
|
177
|
+
return { time: raw, point: null };
|
|
178
|
+
const origin = options.origin ?? 0;
|
|
179
|
+
const stepped = origin + Math.round((raw - origin) / options.step) * options.step;
|
|
180
|
+
const near = snap(raw, options.points ?? [], options.pxPerSecond, thresholdPx);
|
|
181
|
+
return near.point ? near : { time: Math.round(stepped * 1e6) / 1e6, point: null };
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Where a key press moves something: `delta` from `t`, caught by the first snap point it would cross or come
|
|
185
|
+
* within `thresholdPx` of. Only points beyond `t` count, so the next press moves on from a point rather than
|
|
186
|
+
* sticking to it. `free` (Alt held) moves by `delta` alone.
|
|
187
|
+
*/
|
|
188
|
+
export function nudge(t, delta, options, thresholdPx = 8) {
|
|
189
|
+
const next = Math.round((t + delta) * 1e6) / 1e6;
|
|
190
|
+
if (options.free || !options.points?.length)
|
|
191
|
+
return { time: next, point: null };
|
|
192
|
+
const reach = thresholdPx / options.pxPerSecond;
|
|
193
|
+
const ahead = options.points.filter((p) => delta > 0
|
|
194
|
+
? p.time > t + 1e-9 && p.time <= next + reach
|
|
195
|
+
: p.time < t - 1e-9 && p.time >= next - reach);
|
|
196
|
+
if (!ahead.length)
|
|
197
|
+
return { time: next, point: null };
|
|
198
|
+
const point = ahead.reduce((a, b) => (Math.abs(b.time - t) < Math.abs(a.time - t) ? b : a));
|
|
199
|
+
return { time: point.time, point };
|
|
200
|
+
}
|
|
201
|
+
/** `t` kept between `min` and `max`. */
|
|
202
|
+
export const clampTime = (t, min, max) => Math.min(max, Math.max(min, t));
|
|
203
|
+
/**
|
|
204
|
+
* Stacks flags whose labels would overlap into tiers: each takes the lowest tier where nothing already there reaches
|
|
205
|
+
* its start (with `gap` px between). Given each flag's left and right edge in px; returns each one's tier, in the
|
|
206
|
+
* order given, and how many tiers there are.
|
|
207
|
+
*/
|
|
208
|
+
export function stackTiers(flags, gap = 4) {
|
|
209
|
+
const order = flags.map((f, i) => ({ ...f, i })).sort((a, b) => a.left - b.left || a.i - b.i);
|
|
210
|
+
const ends = [];
|
|
211
|
+
const tiers = new Array(flags.length).fill(0);
|
|
212
|
+
for (const flag of order) {
|
|
213
|
+
let tier = ends.findIndex((end) => end + gap <= flag.left);
|
|
214
|
+
if (tier === -1)
|
|
215
|
+
tier = ends.length;
|
|
216
|
+
ends[tier] = flag.right;
|
|
217
|
+
tiers[flag.i] = tier;
|
|
218
|
+
}
|
|
219
|
+
return { tiers, count: Math.max(1, ends.length) };
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=timeline-scale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline-scale.js","sourceRoot":"","sources":["../../src/lib/timeline-scale.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Whether a vertical scroller should be a tab stop: while it scrolls and holds nothing a keyboard can reach (prose
|
|
4
|
+
* with no links, a changelog), so Tab reaches it and the arrow keys scroll it. That is what Chrome (132 and later)
|
|
5
|
+
* does for any scroller with no tabindex and no focusable children; an explicit tabindex opts out of it, so this
|
|
6
|
+
* puts it back, in every browser. Measured again when the scroller or its content resizes or changes.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useScrollTabStop(ref: RefObject<HTMLElement | null>): boolean;
|
|
9
|
+
//# sourceMappingURL=use-scroll-tab-stop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-scroll-tab-stop.d.ts","sourceRoot":"","sources":["../../src/lib/use-scroll-tab-stop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAK5D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,OAAO,CAmC5E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), summary, iframe, [contenteditable]:not([contenteditable="false"]), [tabindex]:not([tabindex="-1"])';
|
|
4
|
+
/**
|
|
5
|
+
* Whether a vertical scroller should be a tab stop: while it scrolls and holds nothing a keyboard can reach (prose
|
|
6
|
+
* with no links, a changelog), so Tab reaches it and the arrow keys scroll it. That is what Chrome (132 and later)
|
|
7
|
+
* does for any scroller with no tabindex and no focusable children; an explicit tabindex opts out of it, so this
|
|
8
|
+
* puts it back, in every browser. Measured again when the scroller or its content resizes or changes.
|
|
9
|
+
*/
|
|
10
|
+
export function useScrollTabStop(ref) {
|
|
11
|
+
const [tabbable, setTabbable] = useState(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const el = ref.current;
|
|
14
|
+
if (!el)
|
|
15
|
+
return;
|
|
16
|
+
let frame = 0;
|
|
17
|
+
const resize = new ResizeObserver(() => measure());
|
|
18
|
+
const measure = () => {
|
|
19
|
+
cancelAnimationFrame(frame);
|
|
20
|
+
frame = requestAnimationFrame(() => {
|
|
21
|
+
// The content can grow without the scroller resizing, so watch what is in it too.
|
|
22
|
+
for (const child of el.children)
|
|
23
|
+
resize.observe(child);
|
|
24
|
+
const scrolls = el.scrollHeight > el.clientHeight + 1;
|
|
25
|
+
const reachable = [...el.querySelectorAll(FOCUSABLE)].some((child) => !child.closest('[inert]') && child.getClientRects().length > 0);
|
|
26
|
+
setTabbable(scrolls && !reachable);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
measure();
|
|
30
|
+
resize.observe(el);
|
|
31
|
+
const mutation = new MutationObserver(measure);
|
|
32
|
+
mutation.observe(el, {
|
|
33
|
+
childList: true,
|
|
34
|
+
subtree: true,
|
|
35
|
+
attributes: true,
|
|
36
|
+
attributeFilter: ['href', 'disabled', 'tabindex', 'inert', 'hidden', 'contenteditable'],
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
cancelAnimationFrame(frame);
|
|
40
|
+
resize.disconnect();
|
|
41
|
+
mutation.disconnect();
|
|
42
|
+
};
|
|
43
|
+
}, [ref]);
|
|
44
|
+
return tabbable;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=use-scroll-tab-stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-scroll-tab-stop.js","sourceRoot":"","sources":["../../src/lib/use-scroll-tab-stop.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAE5D,MAAM,SAAS,GACb,mOAAmO,CAAC;AAEtO;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAkC;IACjE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAC5B,KAAK,GAAG,qBAAqB,CAAC,GAAG,EAAE;gBACjC,kFAAkF;gBAClF,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,QAAQ;oBAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACvD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,GAAG,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC;gBACtD,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CACxD,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC,MAAM,GAAG,CAAC,CAC1E,CAAC;gBACF,WAAW,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QACF,OAAO,EAAE,CAAC;QACV,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACnB,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE;YACnB,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI;YAChB,eAAe,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,CAAC;SACxF,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAC5B,MAAM,CAAC,UAAU,EAAE,CAAC;YACpB,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACV,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -64,6 +64,7 @@ export declare function ShellBody({ children, className }: {
|
|
|
64
64
|
children: ReactNode;
|
|
65
65
|
className?: string;
|
|
66
66
|
}): import("react").JSX.Element;
|
|
67
|
+
/** Content a keyboard can already reach inside a scroller, which then needs no tab stop of its own. */
|
|
67
68
|
/**
|
|
68
69
|
* The main landmark and scroll container; the skip link lands here. `relative` so anything absolutely positioned
|
|
69
70
|
* inside (sr-only text, React Aria's hidden inputs) scrolls with the page instead of being placed against the shell.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-shell.d.ts","sourceRoot":"","sources":["../../src/shell/dashboard-shell.tsx"],"names":[],"mappings":"AAEA,OAAO,EASL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"dashboard-shell.d.ts","sourceRoot":"","sources":["../../src/shell/dashboard-shell.tsx"],"names":[],"mappings":"AAEA,OAAO,EASL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE5D,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AACnE,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC3C,iFAAiF;AACjF,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,UAAU,EAAE,eAAe,CAAC;IAC5B,4EAA4E;IAC5E,YAAY,EAAE,OAAO,CAAC;CACvB;AAID,wBAAgB,QAAQ,IAAI,iBAAiB,CAI5C;AACD,wFAAwF;AACxF,wBAAgB,gBAAgB,IAAI,iBAAiB,GAAG,IAAI,CAE3D;AAeD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB,wFAAwF;IACxF,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kFAAkF;IAClF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,oBAA4B,EAC5B,uBAAuB,EACvB,IAAI,EAAE,UAAU,EAChB,UAAsB,EACtB,aAAa,EACb,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,mBAAmB,+BA8FrB;AAED,sGAAsG;AACtG,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAY9F;AAED,6DAA6D;AAC7D,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE7F;AAED,uGAAuG;AACvG;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,SAAS,EACT,iBAAiB,EAAE,UAAU,GAC9B,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,+BAsBA"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
4
4
|
import { cn } from '../lib/cn.js';
|
|
5
|
+
import { useScrollTabStop } from '../lib/use-scroll-tab-stop.js';
|
|
5
6
|
import { SkipLink } from './landmarks.js';
|
|
6
7
|
const ShellContext = createContext(null);
|
|
7
8
|
export function useShell() {
|
|
@@ -113,7 +114,6 @@ export function ShellBody({ children, className }) {
|
|
|
113
114
|
return _jsx("div", { className: cn('flex min-h-0 flex-1', className), children: children });
|
|
114
115
|
}
|
|
115
116
|
/** Content a keyboard can already reach inside a scroller, which then needs no tab stop of its own. */
|
|
116
|
-
const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), summary, iframe, [contenteditable]:not([contenteditable="false"]), [tabindex]:not([tabindex="-1"])';
|
|
117
117
|
/**
|
|
118
118
|
* The main landmark and scroll container; the skip link lands here. `relative` so anything absolutely positioned
|
|
119
119
|
* inside (sr-only text, React Aria's hidden inputs) scrolls with the page instead of being placed against the shell.
|
|
@@ -125,39 +125,7 @@ const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]):not([t
|
|
|
125
125
|
*/
|
|
126
126
|
export function ShellMain({ children, className, 'aria-labelledby': labelledBy, }) {
|
|
127
127
|
const ref = useRef(null);
|
|
128
|
-
const
|
|
129
|
-
useEffect(() => {
|
|
130
|
-
const main = ref.current;
|
|
131
|
-
if (!main)
|
|
132
|
-
return;
|
|
133
|
-
let frame = 0;
|
|
134
|
-
const resize = new ResizeObserver(() => measure());
|
|
135
|
-
const measure = () => {
|
|
136
|
-
cancelAnimationFrame(frame);
|
|
137
|
-
frame = requestAnimationFrame(() => {
|
|
138
|
-
// The content can grow without main resizing, so watch what is in it too.
|
|
139
|
-
for (const child of main.children)
|
|
140
|
-
resize.observe(child);
|
|
141
|
-
const scrolls = main.scrollHeight > main.clientHeight + 1;
|
|
142
|
-
const reachable = [...main.querySelectorAll(FOCUSABLE)].some((el) => !el.closest('[inert]') && el.getClientRects().length > 0);
|
|
143
|
-
setTabbable(scrolls && !reachable);
|
|
144
|
-
});
|
|
145
|
-
};
|
|
146
|
-
measure();
|
|
147
|
-
resize.observe(main);
|
|
148
|
-
const mutation = new MutationObserver(measure);
|
|
149
|
-
mutation.observe(main, {
|
|
150
|
-
childList: true,
|
|
151
|
-
subtree: true,
|
|
152
|
-
attributes: true,
|
|
153
|
-
attributeFilter: ['href', 'disabled', 'tabindex', 'inert', 'hidden', 'contenteditable'],
|
|
154
|
-
});
|
|
155
|
-
return () => {
|
|
156
|
-
cancelAnimationFrame(frame);
|
|
157
|
-
resize.disconnect();
|
|
158
|
-
mutation.disconnect();
|
|
159
|
-
};
|
|
160
|
-
}, []);
|
|
128
|
+
const tabbable = useScrollTabStop(ref);
|
|
161
129
|
return (_jsx("main", { ref: ref, id: "main",
|
|
162
130
|
// A scroller with nothing focusable in it has to take focus itself, or a keyboard can't scroll it.
|
|
163
131
|
// oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-shell.js","sourceRoot":"","sources":["../../src/shell/dashboard-shell.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EACL,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,eAAe,EACf,OAAO,EACP,MAAM,EACN,QAAQ,GAIT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAoB,MAAM,gBAAgB,CAAC;AAwB5D,MAAM,YAAY,GAAG,aAAa,CAA2B,IAAI,CAAC,CAAC;AAEnE,MAAM,UAAU,QAAQ;IACtB,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC3E,OAAO,GAAG,CAAC;AACb,CAAC;AACD,wFAAwF;AACxF,MAAM,UAAU,gBAAgB;IAC9B,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC;AAED,6EAA6E;AAC7E,SAAS,eAAe,CAAC,EAAe;IACtC,MAAM,EAAE,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC;IACjG,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC;AACtF,CAAC;AACD,SAAS,OAAO,CAAC,KAAa,EAAE,EAA0C;IACxE,IAAI,KAAK,GAAG,EAAE,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC;IACnC,IAAI,KAAK,GAAG,EAAE,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC;IACnC,IAAI,KAAK,GAAG,EAAE,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC;IACnC,OAAO,SAAS,CAAC;AACnB,CAAC;AA0BD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,oBAAoB,GAAG,KAAK,EAC5B,uBAAuB,EACvB,IAAI,EAAE,UAAU,EAChB,UAAU,GAAG,SAAS,EACtB,aAAa,EACb,MAAM,EACN,SAAS,EACT,KAAK,GACe;IACpB,MAAM,GAAG,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,IAAI,CAAC,CAAC;IACjE,MAAM,IAAI,GAAc,UAAU,IAAI,QAAQ,IAAI,SAAS,CAAC;IAE5D,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,UAAU;YAAE,OAAO;QACvB,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACf,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,gEAAgE;IAChE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAChD,uBAAuB,IAAI,IAAI,CAChC,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAChD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC7C,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI;YAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACnF,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;IAC1B,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IACjC,MAAM,gBAAgB,GAAG,aAAa,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC;IACnF,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEjG,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAEzE,4GAA4G;IAC5G,2GAA2G;IAC3G,4GAA4G;IAC5G,2GAA2G;IAC3G,MAAM,SAAS,GAAc,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1F,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAA4C,IAAI,CAAC,CAAC;IAChG,MAAM,SAAS,GACb,WAAW,EAAE,IAAI,KAAK,SAAS;QAC7B,CAAC,CAAC,WAAW,CAAC,IAAI;QAClB,CAAC,CAAC,CAAC,gBAAgB,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC;IACnD,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,IAAa,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAC5D,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IAE9D,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,IAAI;QACJ,gBAAgB;QAChB,aAAa;QACb,aAAa;QACb,gBAAgB;QAChB,SAAS;QACT,YAAY;QACZ,SAAS;QACT,cAAc;QACd,WAAW;QACX,UAAU;QACV,YAAY,EAAE,CAAC,CAAC,UAAU;KAC3B,CAAC,EACF;QACE,IAAI;QACJ,gBAAgB;QAChB,aAAa;QACb,aAAa;QACb,SAAS;QACT,YAAY;QACZ,SAAS;QACT,WAAW;QACX,UAAU;QACV,UAAU;KACX,CACF,CAAC;IAEF,OAAO,CACL,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACjC,eACE,GAAG,EAAE,GAAG,eACG,IAAI,EACf,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,EAAE,CACX,gGAAgG,EAChG,SAAS,CACV,aAED,KAAC,QAAQ,IAAC,IAAI,EAAC,OAAO,EAAC,KAAK,EAAC,gBAAgB,EAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAI,EACrF,QAAQ,IACL,GACgB,CACzB,CAAC;AACJ,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IAC7F,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,2HAA2H,EAC3H,oFAAoF,EACpF,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IAC5F,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAO,CAAC;AAChF,CAAC;AAED,uGAAuG;AACvG
|
|
1
|
+
{"version":3,"file":"dashboard-shell.js","sourceRoot":"","sources":["../../src/shell/dashboard-shell.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
import { type IconProp } from '../ui/icon.js';
|
|
2
3
|
export interface PageHeaderProps {
|
|
3
4
|
title: string;
|
|
5
|
+
/**
|
|
6
|
+
* An icon before the title, drawn in `muted-foreground` and hidden from assistive technology, so the h1 is named
|
|
7
|
+
* by its words alone. A component, or an element when a server component passes it.
|
|
8
|
+
*/
|
|
9
|
+
icon?: IconProp;
|
|
4
10
|
description?: string;
|
|
5
11
|
/** Page actions: at most one primary. Wraps below the title when it runs out of room. */
|
|
6
12
|
actions?: ReactNode;
|
|
@@ -10,7 +16,7 @@ export interface PageHeaderProps {
|
|
|
10
16
|
className?: string;
|
|
11
17
|
}
|
|
12
18
|
/** The page's h1, one-line description and actions. */
|
|
13
|
-
export declare function PageHeader({ title, description, actions, breadcrumbs, titleId, className, }: PageHeaderProps): import("react").JSX.Element;
|
|
19
|
+
export declare function PageHeader({ title, icon, description, actions, breadcrumbs, titleId, className, }: PageHeaderProps): import("react").JSX.Element;
|
|
14
20
|
/** Padding for everything below the page header. */
|
|
15
21
|
export declare function PageContent({ children, className }: {
|
|
16
22
|
children: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-header.d.ts","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"page-header.d.ts","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yFAAyF;IACzF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,WAAW,EACX,OAAO,EACP,WAAW,EACX,OAAsB,EACtB,SAAS,GACV,EAAE,eAAe,+BAqBjB;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAM/F"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from '../lib/cn.js';
|
|
3
|
+
import { renderIcon } from '../ui/icon.js';
|
|
3
4
|
/** The page's h1, one-line description and actions. */
|
|
4
|
-
export function PageHeader({ title, description, actions, breadcrumbs, titleId = 'page-title', className, }) {
|
|
5
|
-
return (_jsxs("div", { className: cn('flex flex-wrap items-end justify-between gap-4 px-(--gutter) pt-5 pb-4 @max-[40rem]/main:px-4', className), children: [_jsxs("div", { className: "min-w-0 flex-[1_1_20rem]", children: [breadcrumbs && _jsx("div", { className: "mb-1", children: breadcrumbs }),
|
|
5
|
+
export function PageHeader({ title, icon, description, actions, breadcrumbs, titleId = 'page-title', className, }) {
|
|
6
|
+
return (_jsxs("div", { className: cn('flex flex-wrap items-end justify-between gap-4 px-(--gutter) pt-5 pb-4 @max-[40rem]/main:px-4', className), children: [_jsxs("div", { className: "min-w-0 flex-[1_1_20rem]", children: [breadcrumbs && _jsx("div", { className: "mb-1", children: breadcrumbs }), _jsxs("h1", { id: titleId, className: cn('text-title', icon && 'flex items-center gap-3'), children: [icon && renderIcon(icon, 'size-7 shrink-0 text-muted-foreground'), icon ? _jsx("span", { className: "min-w-0", children: title }) : title] }), description && (_jsx("p", { className: "mt-1 max-w-(--measure) text-sm text-muted-foreground", children: description }))] }), actions && _jsx("div", { className: "flex flex-wrap items-center gap-(--control-gap)", children: actions })] }));
|
|
6
7
|
}
|
|
7
8
|
/** Padding for everything below the page header. */
|
|
8
9
|
export function PageContent({ children, className }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-header.js","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"page-header.js","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,UAAU,EAAiB,MAAM,eAAe,CAAC;AAkB1D,uDAAuD;AACvD,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,WAAW,EACX,OAAO,EACP,WAAW,EACX,OAAO,GAAG,YAAY,EACtB,SAAS,GACO;IAChB,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,+FAA+F,EAC/F,SAAS,CACV,aAED,eAAK,SAAS,EAAC,0BAA0B,aACtC,WAAW,IAAI,cAAK,SAAS,EAAC,MAAM,YAAE,WAAW,GAAO,EACzD,cAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,IAAI,IAAI,yBAAyB,CAAC,aAC5E,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,uCAAuC,CAAC,EACjE,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,SAAS,YAAE,KAAK,GAAQ,CAAC,CAAC,CAAC,KAAK,IACrD,EACJ,WAAW,IAAI,CACd,YAAG,SAAS,EAAC,sDAAsD,YAAE,WAAW,GAAK,CACtF,IACG,EACL,OAAO,IAAI,cAAK,SAAS,EAAC,iDAAiD,YAAE,OAAO,GAAO,IACxF,CACP,CAAC;AACJ,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IAC9F,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,oDAAoD,EAAE,SAAS,CAAC,YAChF,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -13,6 +13,34 @@ export interface RightPanelProps {
|
|
|
13
13
|
children: ReactNode;
|
|
14
14
|
/** Actions pinned to the bottom. */
|
|
15
15
|
footer?: ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* How the content sits in the panel. `"sections"`, the default: padded, `PanelSection`s stacked 20px apart, and
|
|
18
|
+
* the body scrolls. `"fill"`: for content that lays itself out (a chat with its own header, a scrolling list
|
|
19
|
+
* and a composer), the body is a flex column with no padding or gap that doesn't scroll; the content fills it,
|
|
20
|
+
* and its own scrollers work, since the body is `min-h-0`. The same beside main and in the Sheet. The content's
|
|
21
|
+
* scrollers are the product's to make reachable by keyboard: a tab stop on any that holds nothing focusable.
|
|
22
|
+
*/
|
|
23
|
+
body?: 'sections' | 'fill';
|
|
24
|
+
/**
|
|
25
|
+
* Its width beside main: `"default"`, `--panel-width` (320px; 360px at AAA); `"wide"`, `--panel-width-wide` (512px;
|
|
26
|
+
* 560px at AAA), for a panel that is a working surface such as a chat; or a number of px, kept between
|
|
27
|
+
* `--panel-width` and the smaller of `--panel-width-max` (720px) and half the shell, for a product that lets people
|
|
28
|
+
* set it. As a Sheet, below 1024px, it is the Sheet's width whatever this says.
|
|
29
|
+
*/
|
|
30
|
+
width?: 'default' | 'wide' | number;
|
|
31
|
+
/**
|
|
32
|
+
* Hides the title bar beside main, for content with a header of its own (a chat's tabs and the scene's name). The
|
|
33
|
+
* panel stays named: by `title`, or by `aria-labelledby` pointing at that header's heading. As a Sheet the title
|
|
34
|
+
* bar stays, since it holds the Sheet's close button.
|
|
35
|
+
*/
|
|
36
|
+
hideTitleBar?: boolean;
|
|
37
|
+
/** The id of the content's own heading, which then names the panel instead of `title`. */
|
|
38
|
+
'aria-labelledby'?: string;
|
|
39
|
+
/**
|
|
40
|
+
* `false` for a panel that is the page's main working surface: beside main it has no close button and stays
|
|
41
|
+
* open. As a Sheet, below 1024px, it still opens and closes as before.
|
|
42
|
+
*/
|
|
43
|
+
isDismissable?: boolean;
|
|
16
44
|
labels?: Partial<RightPanelLabels>;
|
|
17
45
|
className?: string;
|
|
18
46
|
}
|
|
@@ -20,7 +48,7 @@ export interface RightPanelProps {
|
|
|
20
48
|
* Extra information about the current selection. An <aside> beside main on wide shells,
|
|
21
49
|
* a Sheet (modal dialog) on narrow ones. Closing returns focus to the PanelToggle.
|
|
22
50
|
*/
|
|
23
|
-
export declare function RightPanel({ title, children, footer, labels: given, className }: RightPanelProps): import("react").JSX.Element | null;
|
|
51
|
+
export declare function RightPanel({ title, children, footer, body: layout, width, hideTitleBar, 'aria-labelledby': labelledBy, isDismissable, labels: given, className, }: RightPanelProps): import("react").JSX.Element | null;
|
|
24
52
|
/** Shows and hides the right panel. Put it in the page actions. */
|
|
25
53
|
export declare function PanelToggle({ label, labels, }: {
|
|
26
54
|
/** @deprecated Use `labels.toggle`. Kept for one release. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"right-panel.d.ts","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,SAAS,EAAkB,MAAM,OAAO,CAAC;AAS9D,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAG9B,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"right-panel.d.ts","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,SAAS,EAAkB,MAAM,OAAO,CAAC;AAS9D,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAG9B,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EAAE,MAAmB,EACzB,KAAiB,EACjB,YAAY,EACZ,iBAAiB,EAAE,UAAU,EAC7B,aAAoB,EACpB,MAAM,EAAE,KAAK,EACb,SAAS,GACV,EAAE,eAAe,sCAiFjB;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,GACP,EAAE;IACD,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACpC,+BAcA;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAOA"}
|
|
@@ -12,26 +12,35 @@ export const rightPanelLabels = {
|
|
|
12
12
|
close: 'Close {title}',
|
|
13
13
|
toggle: 'Details panel',
|
|
14
14
|
};
|
|
15
|
+
const panelWidths = { default: 'w-panel', wide: 'w-(--panel-width-wide)' };
|
|
15
16
|
/**
|
|
16
17
|
* Extra information about the current selection. An <aside> beside main on wide shells,
|
|
17
18
|
* a Sheet (modal dialog) on narrow ones. Closing returns focus to the PanelToggle.
|
|
18
19
|
*/
|
|
19
|
-
export function RightPanel({ title, children, footer, labels: given, className }) {
|
|
20
|
+
export function RightPanel({ title, children, footer, body: layout = 'sections', width = 'default', hideTitleBar, 'aria-labelledby': labelledBy, isDismissable = true, labels: given, className, }) {
|
|
20
21
|
const t = useLabels('rightPanel', rightPanelLabels, given);
|
|
21
22
|
const close = t('close', { title });
|
|
22
23
|
const { panelOpen, setPanelOpen, panelMode, panelToggleRef, isSizeForced } = useShell();
|
|
23
24
|
const headingId = useId();
|
|
24
25
|
const foot = footer ? (_jsx("div", { className: "flex gap-(--control-gap) border-t border-border px-4 py-3 *:flex-1", children: footer })) : null;
|
|
25
|
-
|
|
26
|
+
// Positioned either way, so hidden inputs and text inside are placed against it (positioned-scroll-container).
|
|
27
|
+
const body = (_jsx("div", { "data-panel-body": layout, className: cn('relative flex min-h-0 flex-1 flex-col', layout === 'sections' && 'gap-5 overflow-y-auto p-4'), children: children }));
|
|
26
28
|
if (panelMode === 'sheet') {
|
|
27
29
|
return (_jsx(Sheet, { side: "right", title: title, labels: { close: literal(close) }, isOpen: panelOpen, onOpenChange: setPanelOpen, footer: foot, children: body }));
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
// A panel that can't be closed stays open beside main, whatever the toggle state says.
|
|
32
|
+
if (!panelOpen && isDismissable)
|
|
30
33
|
return null;
|
|
31
|
-
|
|
34
|
+
const named = labelledBy ?? (hideTitleBar ? undefined : headingId);
|
|
35
|
+
return (_jsxs("aside", { "aria-labelledby": named, "aria-label": named ? undefined : title, style: {
|
|
36
|
+
viewTransitionName: 'shell-panel',
|
|
37
|
+
...(typeof width === 'number' && {
|
|
38
|
+
width: `clamp(var(--panel-width), ${width}px, min(var(--panel-width-max), 50%))`,
|
|
39
|
+
}),
|
|
40
|
+
}, className: cn('flex shrink-0 flex-col border-l border-border bg-card text-card-foreground', typeof width === 'number' ? 'max-w-[50%]' : panelWidths[width], !isSizeForced && '@max-[64rem]/shell:hidden', className), children: [!hideTitleBar && (_jsxs("div", { className: "flex min-h-[calc(var(--control-height)+1rem)] items-center justify-between gap-2 border-b border-border py-2 pr-2 pl-4", children: [_jsx("h2", { id: headingId, className: "text-subheading", children: title }), isDismissable && (_jsx(IconButton, { label: close, icon: X, visualSize: "icon-sm", tooltip: false, className: "justify-end", onPress: () => {
|
|
32
41
|
setPanelOpen(false);
|
|
33
42
|
requestAnimationFrame(() => panelToggleRef.current?.focus());
|
|
34
|
-
} })] }), body, foot] }));
|
|
43
|
+
} }))] })), body, foot] }));
|
|
35
44
|
}
|
|
36
45
|
/** Shows and hides the right panel. Put it in the page actions. */
|
|
37
46
|
export function PanelToggle({ label, labels, }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"right-panel.js","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAAkC,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAUhD,MAAM,CAAC,MAAM,gBAAgB,GAAqB;IAChD,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,eAAe;CACxB,CAAC;
|
|
1
|
+
{"version":3,"file":"right-panel.js","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"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"}
|
package/dist/styles/theme.css
CHANGED
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
--container-site: var(--site-max);
|
|
72
72
|
--container-site-narrow: var(--site-max-narrow);
|
|
73
73
|
--spacing-nav-item: var(--nav-item-height);
|
|
74
|
+
--spacing-lane: var(--lane-height);
|
|
74
75
|
--spacing-header: var(--header-height);
|
|
75
76
|
--spacing-sidebar: var(--sidebar-width);
|
|
76
77
|
--spacing-sidebar-collapsed: var(--sidebar-width-collapsed);
|
|
@@ -1322,3 +1323,18 @@
|
|
|
1322
1323
|
@slot;
|
|
1323
1324
|
}
|
|
1324
1325
|
}
|
|
1326
|
+
/* data-density="compact" on a container: denser controls for a tool UI (a timeline, a transport bar), at AA only.
|
|
1327
|
+
Paint, padding, gaps and text tighten; every target stays at least --target-min (24px), and text at least 13px.
|
|
1328
|
+
At AAA it changes nothing: targets are 44px there, so smaller paint would leave the layout as it was. */
|
|
1329
|
+
/* AAA as products mark it (data-conformance) and as the design-system artifact does (data-theme). */
|
|
1330
|
+
:root:not([data-conformance="aaa"], [data-theme$="-aaa"]) [data-density="compact"] {
|
|
1331
|
+
--control-height: var(--control-height-compact);
|
|
1332
|
+
--control-height-sm: var(--control-height-sm-compact);
|
|
1333
|
+
--control-height-lg: var(--control-height-lg-compact);
|
|
1334
|
+
--control-pad-x: var(--control-pad-x-compact);
|
|
1335
|
+
--control-gap: var(--control-gap-compact);
|
|
1336
|
+
--nav-item-height: var(--nav-item-height-compact);
|
|
1337
|
+
--lane-height: var(--lane-height-compact);
|
|
1338
|
+
--field-gap: var(--field-gap-compact);
|
|
1339
|
+
--text-sm: var(--text-sm-compact);
|
|
1340
|
+
}
|