@setsquare/ui 0.12.0 → 0.13.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 +44 -0
- package/README.md +2 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/announce.d.ts +2 -0
- package/dist/lib/announce.d.ts.map +1 -0
- package/dist/lib/announce.js +38 -0
- package/dist/lib/announce.js.map +1 -0
- package/dist/lib/card-order.d.ts +21 -0
- package/dist/lib/card-order.d.ts.map +1 -0
- package/dist/lib/card-order.js +60 -0
- package/dist/lib/card-order.js.map +1 -0
- 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/styles/tokens.css +2 -0
- package/dist/tokens.json +10 -0
- package/dist/ui/drop-indicator.d.ts +5 -0
- package/dist/ui/drop-indicator.d.ts.map +1 -1
- package/dist/ui/drop-indicator.js +16 -2
- package/dist/ui/drop-indicator.js.map +1 -1
- package/dist/ui/grid-list.d.ts +74 -5
- package/dist/ui/grid-list.d.ts.map +1 -1
- package/dist/ui/grid-list.js +115 -3
- package/dist/ui/grid-list.js.map +1 -1
- package/dist/ui/timeline.d.ts.map +1 -1
- package/dist/ui/timeline.js +110 -55
- package/dist/ui/timeline.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/grid-list.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { useContext, useRef, useState } from 'react';
|
|
4
|
+
import { EllipsisVertical, GripVertical } from 'lucide-react';
|
|
5
|
+
import { Button as RACButton, GridList as RACGridList, GridListItem as RACGridListItem, useDragAndDrop, DragAndDropContext, } from 'react-aria-components';
|
|
6
|
+
import { announce } from '../lib/announce.js';
|
|
7
|
+
import { moveTarget } from '../lib/card-order.js';
|
|
5
8
|
import { cn } from '../lib/cn.js';
|
|
9
|
+
import { useLabels } from '../lib/locale.js';
|
|
10
|
+
import { withoutSoftHyphens } from '../lib/soft-hyphen.js';
|
|
11
|
+
import { useHyphenated } from '../lib/use-hyphenated.js';
|
|
6
12
|
import { SelectionCheckbox } from './checkbox.js';
|
|
13
|
+
import { DropIndicator, DropLayoutContext } from './drop-indicator.js';
|
|
14
|
+
import { Menu, MenuItem, MenuSection, MenuTrigger, Popover } from './menu.js';
|
|
7
15
|
/**
|
|
8
16
|
* A list of items people act on — members, files, integrations — where each row can hold its own buttons.
|
|
9
17
|
* ↑ ↓ move between rows and → through a row's own controls; Tab leaves the list. With
|
|
@@ -15,7 +23,14 @@ import { SelectionCheckbox } from './checkbox.js';
|
|
|
15
23
|
* button, which is how a keyboard or screen reader drag starts.
|
|
16
24
|
*/
|
|
17
25
|
export function GridList({ className, ...props }) {
|
|
18
|
-
|
|
26
|
+
const layout = props.layout ?? 'stack';
|
|
27
|
+
return (_jsx(DropLayoutContext.Provider, { value: layout, children: _jsx(RACGridList, { ...props, className: cn(layout === 'grid'
|
|
28
|
+
? // Cards in a wrapping row, as many as fit, `--card-gap` apart. A wrapping row rather than a CSS grid:
|
|
29
|
+
// while a drag is on, React Aria puts a drop indicator beside every card, and in a grid each would
|
|
30
|
+
// take a cell; in a row they take no room. No box of its own: the cards are boxes. Padding leaves
|
|
31
|
+
// room for a card's focus ring inside the scroller.
|
|
32
|
+
'relative flex max-h-[inherit] flex-wrap content-start gap-(--card-gap) overflow-auto p-2 text-sm outline-none data-focus-visible:focus-ring'
|
|
33
|
+
: 'relative flex max-h-[inherit] flex-col overflow-auto rounded-lg border border-border bg-card text-sm outline-none data-focus-visible:focus-ring', 'data-drop-target:bg-brand-subtle data-drop-target:outline-2 data-drop-target:outline-solid data-drop-target:outline-brand data-drop-target:-outline-offset-2', className) }) }));
|
|
19
34
|
}
|
|
20
35
|
/** Selected: brand-subtle, the 3px sidebar-primary marker and a ticked box — the same signals as a table row. */
|
|
21
36
|
export function GridListItem({ children, description, actions, dragLabel, className, ...props }) {
|
|
@@ -29,4 +44,101 @@ export function GridListItem({ children, description, actions, dragLabel, classN
|
|
|
29
44
|
// Forced colours drop the selected ground and the inset marker: draw the marker in Highlight instead.
|
|
30
45
|
"forced-colors:data-selected:before:absolute forced-colors:data-selected:before:inset-y-1 forced-colors:data-selected:before:start-0 forced-colors:data-selected:before:w-[3px] forced-colors:data-selected:before:bg-[Highlight] forced-colors:data-selected:before:forced-color-adjust-none forced-colors:data-selected:before:content-['']", className), children: ({ selectionMode, selectionBehavior, allowsDragging }) => (_jsxs(_Fragment, { children: [allowsDragging && (_jsx(RACButton, { slot: "drag", "aria-label": dragLabel, className: "group/grid-drag relative flex min-h-target min-w-target shrink-0 cursor-grab items-center justify-center outline-none", children: _jsx("span", { className: "flex size-control-sm items-center justify-center rounded-md text-muted-foreground group-data-focus-visible/grid-drag:focus-ring group-data-hovered/grid-drag:bg-muted group-data-hovered/grid-drag:text-foreground", children: _jsx(GripVertical, { "aria-hidden": "true", className: "size-4" }) }) })), selectionMode !== 'none' && selectionBehavior === 'toggle' && (_jsx(SelectionCheckbox, { className: "-ml-1" })), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "leading-5 font-medium text-foreground", children: children }), description && (_jsx("span", { className: "text-[13px] leading-5 text-muted-foreground", children: description }))] }), actions && _jsx("span", { className: "flex shrink-0 items-center gap-1", children: actions })] })) }));
|
|
31
46
|
}
|
|
47
|
+
export const gridListCardLabels = {
|
|
48
|
+
options: 'Options for {title}',
|
|
49
|
+
moveSection: 'Move',
|
|
50
|
+
moveFirst: 'Move to start',
|
|
51
|
+
moveEarlier: 'Move earlier',
|
|
52
|
+
moveLater: 'Move later',
|
|
53
|
+
moveLast: 'Move to end',
|
|
54
|
+
moved: '{title} moved to position {position} of {count}',
|
|
55
|
+
movedSeveral: '{moved, plural, one {# card} other {# cards}} moved, starting at position {position} of {count}',
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Reordering cards in a GridList, by drag and without: give `dragAndDropHooks` to the GridList and `order` to each
|
|
59
|
+
* GridListCard. Dragging a selected card drags the selected ones; a card's menu moves it (or the selection it's in)
|
|
60
|
+
* to the start, a place earlier, a place later or the end, which is the single-pointer way to reorder that 2.5.7
|
|
61
|
+
* asks for. Both call `onReorder` once per move.
|
|
62
|
+
*/
|
|
63
|
+
export function useCardOrder({ onReorder }) {
|
|
64
|
+
const { dragAndDropHooks } = useDragAndDrop({
|
|
65
|
+
getItems: (dragged) => [...dragged].map((key) => ({ 'text/plain': String(key) })),
|
|
66
|
+
onReorder: (e) => onReorder({
|
|
67
|
+
keys: [...e.keys],
|
|
68
|
+
target: e.target.key,
|
|
69
|
+
position: e.target.dropPosition === 'after' ? 'after' : 'before',
|
|
70
|
+
}),
|
|
71
|
+
renderDropIndicator: (target) => _jsx(DropIndicator, { target: target }),
|
|
72
|
+
});
|
|
73
|
+
return { dragAndDropHooks, reorder: onReorder };
|
|
74
|
+
}
|
|
75
|
+
const MOVES = ['first', 'earlier', 'later', 'last'];
|
|
76
|
+
const MOVE_LABEL = {
|
|
77
|
+
first: 'moveFirst',
|
|
78
|
+
earlier: 'moveEarlier',
|
|
79
|
+
later: 'moveLater',
|
|
80
|
+
last: 'moveLast',
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* A card in a GridList with `layout="grid"`: a picture, a title, a line and a status, then a footer with its drag
|
|
84
|
+
* button, its selection checkbox and its menu, in that order, each a target of its own, none over the picture. The
|
|
85
|
+
* card is the row: arrow keys move between cards, Tab through a card's own controls. Selected: the `brand-subtle`
|
|
86
|
+
* ground and a 2px `brand` ring, and a ticked box; in forced colours a `Highlight` ring.
|
|
87
|
+
*/
|
|
88
|
+
export function GridListCard({ id, title, media, description, status, menu, order, dragLabel, labels, className, ...props }) {
|
|
89
|
+
const t = useLabels('gridListCard', gridListCardLabels, labels);
|
|
90
|
+
const card = useRef(null);
|
|
91
|
+
const [shownTitle, titleRef] = useHyphenated(title);
|
|
92
|
+
const name = withoutSoftHyphens(title);
|
|
93
|
+
const hasMenu = !!menu || !!order;
|
|
94
|
+
return (_jsx(RACGridListItem, { ...props, id: id, ref: card, textValue: name, className: cn(
|
|
95
|
+
// Layer 1: the card is the target. Its width is the grid's, `--card-width`.
|
|
96
|
+
'group/card relative flex w-(--card-width) min-w-0 cursor-default flex-col overflow-hidden rounded-lg border border-border bg-card text-card-foreground outline-none', 'data-hovered:cursor-pointer data-disabled:cursor-not-allowed data-disabled:opacity-60', 'data-selected:border-brand data-selected:bg-brand-subtle data-selected:shadow-[0_0_0_1px_var(--brand)]', 'data-focus-visible:focus-ring data-dragging:opacity-50',
|
|
97
|
+
// Forced colours drop the ground and the shadow: a Highlight ring inside its edge instead.
|
|
98
|
+
"forced-colors:data-selected:after:pointer-events-none forced-colors:data-selected:after:absolute forced-colors:data-selected:after:inset-0 forced-colors:data-selected:after:rounded-lg forced-colors:data-selected:after:border-2 forced-colors:data-selected:after:border-[Highlight] forced-colors:data-selected:after:forced-color-adjust-none forced-colors:data-selected:after:content-['']", className), children: ({ selectionMode, selectionBehavior, allowsDragging }) => (_jsxs(_Fragment, { children: [media && (_jsx("span", { "aria-hidden": "true", className: "block aspect-video overflow-hidden bg-muted", children: media })), _jsxs("span", { className: "flex min-w-0 flex-col gap-0.5 px-3 pt-2", children: [_jsx("span", { className: "min-w-0 leading-5 font-semibold hyphens-auto text-foreground", children: _jsx("span", { ref: titleRef, className: "inline-block max-w-full", children: shownTitle }) }), description && (_jsx("span", { className: "text-[13px] leading-5 text-muted-foreground", children: description })), status && _jsx("span", { className: "flex flex-wrap items-center gap-1", children: status })] }), _jsxs("span", { className: "mt-auto flex items-center gap-1 px-1 pt-1 pb-1", children: [allowsDragging && (_jsx(RACButton, { slot: "drag", "aria-label": dragLabel, className: "group/card-drag relative flex min-h-target min-w-target shrink-0 cursor-grab items-center justify-center outline-none", children: _jsx("span", { className: "flex size-control-sm items-center justify-center rounded-md text-muted-foreground group-data-focus-visible/card-drag:focus-ring group-data-hovered/card-drag:bg-muted group-data-hovered/card-drag:text-foreground", children: _jsx(GripVertical, { "aria-hidden": "true", className: "size-4" }) }) })), selectionMode !== 'none' && selectionBehavior === 'toggle' && _jsx(SelectionCheckbox, {}), _jsx("span", { className: "flex-1" }), hasMenu && (_jsx(CardMenuButton, { id: id, name: name, menu: menu, order: order, card: card, t: t }))] })] })) }));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The card's menu button. Rendered inside the card as the list draws it, which is where the list can be read: a
|
|
102
|
+
* card's own body runs in React Aria's first, hidden pass, and React Aria gives an item no list state of its own (it
|
|
103
|
+
* clears ListStateContext there). Its drag state has the list's collection and selection, and is there whenever the
|
|
104
|
+
* cards can be reordered, which `useCardOrder` makes so.
|
|
105
|
+
*/
|
|
106
|
+
function CardMenuButton(props) {
|
|
107
|
+
const { dragState } = useContext(DragAndDropContext);
|
|
108
|
+
const state = dragState ?? null;
|
|
109
|
+
const [open, setOpen] = useState(false);
|
|
110
|
+
return (_jsxs(MenuTrigger, { isOpen: open, onOpenChange: setOpen, children: [_jsx(RACButton, { "aria-label": props.t('options', { title: props.name }), className: "group/card-menu relative flex min-h-target min-w-target shrink-0 cursor-pointer items-center justify-center outline-none", children: _jsx("span", { className: "flex size-control-sm items-center justify-center rounded-md text-muted-foreground group-data-focus-visible/card-menu:focus-ring group-data-hovered/card-menu:bg-muted group-data-hovered/card-menu:text-foreground group-data-pressed/card-menu:bg-muted", children: _jsx(EllipsisVertical, { "aria-hidden": "true", className: "size-4" }) }) }), _jsx(Popover, { placement: "bottom end", children: _jsx(CardMenu, { ...props, state: state }) })] }));
|
|
111
|
+
}
|
|
112
|
+
function CardMenu({ id, name, menu, order, card, t, state, }) {
|
|
113
|
+
const keys = state
|
|
114
|
+
? [...state.collection.getKeys()].filter((k) => state.collection.getItem(k)?.type === 'item')
|
|
115
|
+
: [id];
|
|
116
|
+
const selection = state?.selectionManager;
|
|
117
|
+
// The cards a move takes: the selection, when this card is in it, or this card alone.
|
|
118
|
+
const moving = !selection?.isSelected(id)
|
|
119
|
+
? [id]
|
|
120
|
+
: selection.isSelectAll
|
|
121
|
+
? keys
|
|
122
|
+
: keys.filter((k) => selection.selectedKeys.has(k));
|
|
123
|
+
const targets = Object.fromEntries(MOVES.map((m) => [m, order ? moveTarget(keys, moving, m) : null]));
|
|
124
|
+
const doMove = (move) => {
|
|
125
|
+
const reorder = targets[move];
|
|
126
|
+
if (!order || !reorder)
|
|
127
|
+
return;
|
|
128
|
+
order.reorder(reorder);
|
|
129
|
+
// Where the first moved card ends up, counted from 1.
|
|
130
|
+
const rest = keys.filter((k) => !reorder.keys.includes(k));
|
|
131
|
+
const at = rest.indexOf(reorder.target) + (reorder.position === 'after' ? 1 : 0);
|
|
132
|
+
announce(reorder.keys.length === 1
|
|
133
|
+
? t('moved', { title: name, position: at + 1, count: keys.length })
|
|
134
|
+
: t('movedSeveral', { moved: reorder.keys.length, position: at + 1, count: keys.length }));
|
|
135
|
+
// The card moved in the page: keep focus on it, after the menu has handed focus back.
|
|
136
|
+
requestAnimationFrame(() => requestAnimationFrame(() => card.current?.focus()));
|
|
137
|
+
};
|
|
138
|
+
return (_jsxs(Menu, { "aria-label": t('options', { title: name }), disabledKeys: MOVES.filter((m) => !targets[m]).map((m) => `move-${m}`), onAction: (key) => {
|
|
139
|
+
const move = String(key).replace(/^move-/, '');
|
|
140
|
+
if (MOVES.includes(move))
|
|
141
|
+
doMove(move);
|
|
142
|
+
}, children: [menu, order && (_jsx(MenuSection, { title: t('moveSection'), children: MOVES.map((m) => (_jsx(MenuItem, { id: `move-${m}`, children: t(MOVE_LABEL[m]) }, m))) }))] }));
|
|
143
|
+
}
|
|
32
144
|
//# sourceMappingURL=grid-list.js.map
|
package/dist/ui/grid-list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-list.js","sourceRoot":"","sources":["../../src/ui/grid-list.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;
|
|
1
|
+
{"version":3,"file":"grid-list.js","sourceRoot":"","sources":["../../src/ui/grid-list.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/ui/timeline.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/ui/timeline.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/timeline.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Children, createContext, isValidElement, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, } from 'react';
|
|
3
|
+
import { Children, createContext, isValidElement, memo, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, } from 'react';
|
|
4
4
|
import { ChevronRight, EllipsisVertical } from 'lucide-react';
|
|
5
5
|
import { Button as RACButton, Focusable, ToggleButton, Tree as RACTree, TreeItem as RACTreeItem, TreeItemContent, TooltipTrigger, useLocale, } from 'react-aria-components';
|
|
6
6
|
import { cn } from '../lib/cn.js';
|
|
@@ -29,6 +29,13 @@ export const timelineLabels = {
|
|
|
29
29
|
wasReset: '{label} reset to {time}',
|
|
30
30
|
};
|
|
31
31
|
const TimelineContext = createContext(null);
|
|
32
|
+
/**
|
|
33
|
+
* The playhead's time, on its own: it changes every frame while media plays, and only the playhead and its line
|
|
34
|
+
* read it, so lanes, items and markers don't render again with it.
|
|
35
|
+
*/
|
|
36
|
+
const TimeContext = createContext(undefined);
|
|
37
|
+
/** The part in view, for the ruler's ticks and the slots: it changes as the timeline scrolls. */
|
|
38
|
+
const ViewContext = createContext({ start: 0, end: 0 });
|
|
32
39
|
function useTimeline(part) {
|
|
33
40
|
const value = useContext(TimelineContext);
|
|
34
41
|
if (!value)
|
|
@@ -46,16 +53,21 @@ export function useTimelineMove() {
|
|
|
46
53
|
function useControlled(value, initial, onChange) {
|
|
47
54
|
const [own, setOwn] = useState(initial);
|
|
48
55
|
const controlled = value !== undefined;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
// The setter keeps its identity across renders, so the context it goes in can too.
|
|
57
|
+
const latest = useRef(onChange);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
latest.current = onChange;
|
|
60
|
+
});
|
|
61
|
+
const set = useCallback((next) => {
|
|
62
|
+
if (!controlled)
|
|
63
|
+
setOwn(next);
|
|
64
|
+
latest.current?.(next);
|
|
65
|
+
}, [controlled]);
|
|
66
|
+
return [controlled ? value : own, set];
|
|
57
67
|
}
|
|
58
68
|
const defaultStep = (format, fps) => format === 'frames' || format === 'timecode' ? 1 / fps : format === 'date' ? 900 : 0.1;
|
|
69
|
+
/** One empty list for every timeline without snap points: a new `[]` each render would change the context. */
|
|
70
|
+
const NO_POINTS = [];
|
|
59
71
|
/** AAA as products mark it and as the design-system artifact does. */
|
|
60
72
|
const AAA = '[data-conformance="aaa"], [data-theme$="-aaa"]';
|
|
61
73
|
/**
|
|
@@ -69,7 +81,7 @@ const AAA = '[data-conformance="aaa"], [data-theme$="-aaa"]';
|
|
|
69
81
|
* axis runs left to right; right-to-left layouts aren't supported yet. Under it, a line says what moving a marker
|
|
70
82
|
* did (snapped, picked up, put down), and is read out as it changes.
|
|
71
83
|
*/
|
|
72
|
-
export function Timeline({ duration, start = 0, format = 'seconds', fps = 25, timeZone, pxPerSecond: pps = 100, step: givenStep, time: givenTime, defaultTime, onTimeChange, snapPoints =
|
|
84
|
+
export function Timeline({ duration, start = 0, format = 'seconds', fps = 25, timeZone, pxPerSecond: pps = 100, step: givenStep, time: givenTime, defaultTime, onTimeChange, snapPoints = NO_POINTS, selectedItem: givenItem, defaultSelectedItem = null, onSelectedItemChange, labelWidth = 160, maxHeight, followPlayhead = true, labels, className, children, ...name }) {
|
|
73
85
|
const t = useLabels('timeline', timelineLabels, labels);
|
|
74
86
|
const { locale } = useLocale();
|
|
75
87
|
const end = start + duration;
|
|
@@ -85,37 +97,56 @@ export function Timeline({ duration, start = 0, format = 'seconds', fps = 25, ti
|
|
|
85
97
|
// Before the scroller is measured (and on the server), assume a wide screen's worth is in view.
|
|
86
98
|
const [scroll, setScroll] = useState({ left: 0, width: 1600 });
|
|
87
99
|
const scroller = useRef(null);
|
|
88
|
-
const
|
|
89
|
-
|
|
100
|
+
const seek = useCallback((s) => setTime(clampTime(s, start, end)), [setTime, start, end]);
|
|
101
|
+
// Everything but the playhead's time and the part in view, kept as one value while none of it changes: playback
|
|
102
|
+
// and scrolling don't render lanes, items and markers again.
|
|
103
|
+
const value = useMemo(() => {
|
|
104
|
+
const toX = (s) => (s - start) * pps;
|
|
105
|
+
return {
|
|
106
|
+
start,
|
|
107
|
+
end,
|
|
108
|
+
pps,
|
|
109
|
+
step,
|
|
110
|
+
trackWidth,
|
|
111
|
+
scale,
|
|
112
|
+
toX,
|
|
113
|
+
timeAt: (clientX, track) => clampTime(start + (clientX - track.getBoundingClientRect().left) / pps, start, end),
|
|
114
|
+
show: (s, shownStep = step) => formatTime(s, scale, shownStep),
|
|
115
|
+
speak: (s) => speakTime(s, scale, {
|
|
116
|
+
frames: (count) => t('frames', { count }),
|
|
117
|
+
frame: (frame) => t('frame', { frame }),
|
|
118
|
+
}),
|
|
119
|
+
t,
|
|
120
|
+
hasPlayhead,
|
|
121
|
+
seek,
|
|
122
|
+
snapPoints,
|
|
123
|
+
selectedItem,
|
|
124
|
+
selectItem,
|
|
125
|
+
announce: setStatus,
|
|
126
|
+
picked,
|
|
127
|
+
pick,
|
|
128
|
+
moving,
|
|
129
|
+
setMoving,
|
|
130
|
+
};
|
|
131
|
+
}, [
|
|
90
132
|
start,
|
|
91
133
|
end,
|
|
92
134
|
pps,
|
|
93
135
|
step,
|
|
94
136
|
trackWidth,
|
|
95
137
|
scale,
|
|
96
|
-
toX,
|
|
97
|
-
timeAt: (clientX, track) => clampTime(start + (clientX - track.getBoundingClientRect().left) / pps, start, end),
|
|
98
|
-
show: (s, shownStep = step) => formatTime(s, scale, shownStep),
|
|
99
|
-
speak: (s) => speakTime(s, scale, {
|
|
100
|
-
frames: (count) => t('frames', { count }),
|
|
101
|
-
frame: (frame) => t('frame', { frame }),
|
|
102
|
-
}),
|
|
103
138
|
t,
|
|
104
|
-
|
|
105
|
-
seek
|
|
139
|
+
hasPlayhead,
|
|
140
|
+
seek,
|
|
106
141
|
snapPoints,
|
|
107
142
|
selectedItem,
|
|
108
143
|
selectItem,
|
|
109
|
-
announce: setStatus,
|
|
110
144
|
picked,
|
|
111
|
-
pick,
|
|
112
145
|
moving,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
},
|
|
118
|
-
};
|
|
146
|
+
]);
|
|
147
|
+
const viewStart = clampTime(start + scroll.left / pps, start, end);
|
|
148
|
+
const viewEnd = clampTime(start + (scroll.left + scroll.width) / pps, start, end);
|
|
149
|
+
const view = useMemo(() => ({ start: viewStart, end: viewEnd }), [viewStart, viewEnd]);
|
|
119
150
|
// Track what's in view, for the ruler's ticks and the slots: on scroll, and as the scroller resizes.
|
|
120
151
|
useEffect(() => {
|
|
121
152
|
const el = scroller.current;
|
|
@@ -158,9 +189,9 @@ export function Timeline({ duration, start = 0, format = 'seconds', fps = 25, ti
|
|
|
158
189
|
picked.cancel();
|
|
159
190
|
}
|
|
160
191
|
};
|
|
161
|
-
return (_jsx(TimelineContext.Provider, { value: value, children: _jsxs("div", { role: "group", ...name, onKeyDownCapture: onKeyDownCapture, style: {
|
|
162
|
-
|
|
163
|
-
|
|
192
|
+
return (_jsx(TimelineContext.Provider, { value: value, children: _jsx(ViewContext.Provider, { value: view, children: _jsx(TimeContext.Provider, { value: hasPlayhead ? time : undefined, children: _jsxs("div", { role: "group", ...name, onKeyDownCapture: onKeyDownCapture, style: {
|
|
193
|
+
'--timeline-label-width': `${labelWidth}px`,
|
|
194
|
+
}, className: cn('relative flex flex-col overflow-hidden rounded-lg border border-border bg-background text-sm', className), children: [_jsx("div", { ref: scroller, "data-timeline-scroller": "", style: { maxHeight }, className: "relative overflow-auto overscroll-contain [scroll-padding-block-start:var(--lane-height)] [scroll-padding-inline-start:var(--timeline-label-width)]", children: _jsxs("div", { className: "relative", style: { width: `calc(var(--timeline-label-width) + ${trackWidth}px)` }, children: [children, playheadX !== null && (_jsx("div", { "aria-hidden": "true", "data-timeline-playhead-line": "", className: "pointer-events-none absolute inset-y-0 z-10 w-0.5 -translate-x-1/2 bg-primary forced-colors:bg-[Highlight] forced-colors:forced-color-adjust-none", style: { left: `calc(var(--timeline-label-width) + ${playheadX}px)` } }))] }) }), _jsx("p", { "aria-live": "polite", "aria-atomic": "true", "data-timeline-status": "", className: "border-t border-border px-3 py-1 text-[13px] leading-5 text-muted-foreground empty:border-0 empty:p-0", children: status })] }) }) }) }));
|
|
164
195
|
}
|
|
165
196
|
/** The label column's cell at the start of a row: it stays put while the track scrolls under it. */
|
|
166
197
|
function LabelCell({ className, style, children, }) {
|
|
@@ -177,7 +208,8 @@ function LabelCell({ className, style, children, }) {
|
|
|
177
208
|
*/
|
|
178
209
|
export function TimeRuler({ corner, className }) {
|
|
179
210
|
const tl = useTimeline('TimeRuler');
|
|
180
|
-
const
|
|
211
|
+
const view = useContext(ViewContext);
|
|
212
|
+
const { start, end, pps, scale, toX, show } = tl;
|
|
181
213
|
const [dragging, setDragging] = useState(false);
|
|
182
214
|
const thumb = useRef(null);
|
|
183
215
|
// A label is about as wide as its widest text at this step: 8.5px a character, and room either side.
|
|
@@ -193,7 +225,7 @@ export function TimeRuler({ corner, className }) {
|
|
|
193
225
|
tl.picked.put(at, e.altKey);
|
|
194
226
|
return;
|
|
195
227
|
}
|
|
196
|
-
if (
|
|
228
|
+
if (!tl.hasPlayhead)
|
|
197
229
|
return;
|
|
198
230
|
e.preventDefault();
|
|
199
231
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
@@ -208,16 +240,7 @@ export function TimeRuler({ corner, className }) {
|
|
|
208
240
|
tl.seek(place(at, { step: tl.step, origin: start, pxPerSecond: pps, free: e.altKey }).time);
|
|
209
241
|
};
|
|
210
242
|
const stop = () => setDragging(false);
|
|
211
|
-
|
|
212
|
-
if (time === undefined)
|
|
213
|
-
return;
|
|
214
|
-
const next = keyTime(e, time, tl);
|
|
215
|
-
if (next === null)
|
|
216
|
-
return;
|
|
217
|
-
e.preventDefault();
|
|
218
|
-
tl.seek(next);
|
|
219
|
-
};
|
|
220
|
-
return (_jsxs("div", { "data-timeline-ruler": "", className: cn('sticky top-0 z-30 flex h-lane min-h-target bg-background', className), children: [_jsx(LabelCell, { className: "justify-end shadow-[inset_0_-1px_0_var(--border)]", children: _jsx("span", { "aria-hidden": "true", className: "leading-5 font-semibold text-foreground tabular-nums", children: corner ?? (time !== undefined ? show(time) : null) }) }), _jsxs("div", { "data-timeline-ruler-track": "", onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: stop, onPointerCancel: stop, className: cn('relative shrink-0 touch-none shadow-[inset_0_-1px_0_var(--border)] select-none', time !== undefined || tl.picked ? 'cursor-pointer' : 'cursor-default'), style: { width: tl.trackWidth }, children: [marks.map((mark) => (_jsx("span", { "aria-hidden": "true", className: cn('absolute bottom-0 w-px bg-muted-foreground', mark.major ? 'h-2.5' : 'h-1.5'), style: { left: toX(mark.t) } }, mark.t))), marks
|
|
243
|
+
return (_jsxs("div", { "data-timeline-ruler": "", className: cn('sticky top-0 z-30 flex h-lane min-h-target bg-background', className), children: [_jsx(LabelCell, { className: "justify-end shadow-[inset_0_-1px_0_var(--border)]", children: _jsx("span", { "aria-hidden": "true", className: "leading-5 font-semibold text-foreground tabular-nums", children: corner ?? _jsx(PlayheadTime, {}) }) }), _jsxs("div", { "data-timeline-ruler-track": "", onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: stop, onPointerCancel: stop, className: cn('relative shrink-0 touch-none shadow-[inset_0_-1px_0_var(--border)] select-none', tl.hasPlayhead || tl.picked ? 'cursor-pointer' : 'cursor-default'), style: { width: tl.trackWidth }, children: [marks.map((mark) => (_jsx("span", { "aria-hidden": "true", className: cn('absolute bottom-0 w-px bg-muted-foreground', mark.major ? 'h-2.5' : 'h-1.5'), style: { left: toX(mark.t) } }, mark.t))), marks
|
|
221
244
|
.filter((mark) => mark.major)
|
|
222
245
|
.map((mark) => {
|
|
223
246
|
const x = toX(mark.t);
|
|
@@ -228,9 +251,30 @@ export function TimeRuler({ corner, className }) {
|
|
|
228
251
|
if (last && mark.t - major >= start && x - toX(mark.t - major) < labelPx * 2)
|
|
229
252
|
return null;
|
|
230
253
|
return (_jsx("span", { "aria-hidden": "true", className: "absolute top-0 text-sm leading-5 whitespace-nowrap text-muted-foreground tabular-nums", style: last ? { right: tl.trackWidth - x + 4 } : { left: x + 4 }, children: show(mark.t, major) }, mark.t));
|
|
231
|
-
}),
|
|
232
|
-
|
|
233
|
-
|
|
254
|
+
}), tl.hasPlayhead && _jsx(Playhead, { thumb: thumb, dragging: dragging })] })] }));
|
|
255
|
+
}
|
|
256
|
+
/** The playhead's time as the ruler shows it, for the corner: one of the few things that follows the time. */
|
|
257
|
+
function PlayheadTime() {
|
|
258
|
+
const tl = useTimeline('TimeRuler');
|
|
259
|
+
const time = useContext(TimeContext);
|
|
260
|
+
return time === undefined ? null : tl.show(time);
|
|
261
|
+
}
|
|
262
|
+
/** The playhead's slider. Its own component, so the ticks and labels don't render again as the time moves. */
|
|
263
|
+
function Playhead({ thumb, dragging, }) {
|
|
264
|
+
const tl = useTimeline('TimeRuler');
|
|
265
|
+
const time = useContext(TimeContext);
|
|
266
|
+
if (time === undefined)
|
|
267
|
+
return null;
|
|
268
|
+
const onKeyDown = (e) => {
|
|
269
|
+
const next = keyTime(e, time, tl);
|
|
270
|
+
if (next === null)
|
|
271
|
+
return;
|
|
272
|
+
e.preventDefault();
|
|
273
|
+
tl.seek(next);
|
|
274
|
+
};
|
|
275
|
+
return (_jsx("div", { ref: thumb, role: "slider", tabIndex: 0, "aria-label": tl.t('playhead'), "aria-orientation": "horizontal", "aria-valuemin": tl.start, "aria-valuemax": tl.end, "aria-valuenow": Math.round(time * 1000) / 1000, "aria-valuetext": tl.speak(time), "data-dragging": dragging || undefined, onKeyDown: onKeyDown,
|
|
276
|
+
// Layer 1: one target square, centred on the time. Dragged, so grab.
|
|
277
|
+
className: "group/playhead absolute top-0 z-10 flex h-full w-target -translate-x-1/2 cursor-grab justify-center outline-none data-dragging:cursor-grabbing", style: { left: tl.toX(time) }, children: _jsx("span", { "aria-hidden": "true", className: "mt-0.5 h-[calc(100%-4px)] w-2.5 rounded-sm bg-primary group-focus-visible/playhead:focus-ring forced-colors:bg-[Highlight] forced-colors:forced-color-adjust-none" }) }));
|
|
234
278
|
}
|
|
235
279
|
/** The time a key moves a slider on the timeline to, or null for a key it doesn't use. */
|
|
236
280
|
function keyTime(e, from, tl) {
|
|
@@ -254,11 +298,12 @@ function keyTime(e, from, tl) {
|
|
|
254
298
|
*/
|
|
255
299
|
export function TimelineSlot({ label, height = 48, 'aria-label': named, children, className, }) {
|
|
256
300
|
const tl = useTimeline('TimelineSlot');
|
|
301
|
+
const inView = useContext(ViewContext);
|
|
257
302
|
const view = {
|
|
258
303
|
start: tl.start,
|
|
259
304
|
end: tl.end,
|
|
260
|
-
visibleStart:
|
|
261
|
-
visibleEnd:
|
|
305
|
+
visibleStart: inView.start,
|
|
306
|
+
visibleEnd: inView.end,
|
|
262
307
|
pxPerSecond: tl.pps,
|
|
263
308
|
width: tl.trackWidth,
|
|
264
309
|
toX: tl.toX,
|
|
@@ -286,16 +331,26 @@ const itemTimes = (node) => {
|
|
|
286
331
|
* chevron to open it. Selected, it takes the `brand-subtle` ground and, in forced colours, a Highlight bar.
|
|
287
332
|
*/
|
|
288
333
|
export function TimelineLane({ id, label, items, children, className }) {
|
|
334
|
+
return (_jsxs(RACTreeItem, { id: id, textValue: label, className: cn('group/lane relative flex h-lane min-h-target cursor-default outline-none', 'data-hovered:cursor-pointer data-hovered:bg-accent data-selected:bg-brand-subtle data-focus-visible:focus-ring-inset', className), children: [_jsx(TreeItemContent, { children: ({ hasChildItems, level }) => (_jsxs(_Fragment, { children: [_jsxs(LabelCell, { style: { '--lane-indent': level - 1 }, className: cn('gap-0.5 ps-[calc(var(--lane-indent)*12px)] shadow-[inset_0_-1px_0_var(--border)] group-data-hovered/lane:bg-accent group-data-selected/lane:bg-brand-subtle',
|
|
335
|
+
// Forced colours drop the selected ground: a Highlight bar instead, on the cell that stays in view.
|
|
336
|
+
"forced-colors:group-data-selected/lane:before:absolute forced-colors:group-data-selected/lane:before:inset-y-0.5 forced-colors:group-data-selected/lane:before:start-0 forced-colors:group-data-selected/lane:before:w-[3px] forced-colors:group-data-selected/lane:before:bg-[Highlight] forced-colors:group-data-selected/lane:before:forced-color-adjust-none forced-colors:group-data-selected/lane:before:content-['']"), children: [hasChildItems ? (_jsx(RACButton, { slot: "chevron", className: "group/lane-chevron relative flex size-target shrink-0 cursor-pointer items-center justify-center outline-none", children: _jsx("span", { className: "flex size-5 items-center justify-center rounded-sm text-muted-foreground group-data-focus-visible/lane-chevron:focus-ring group-data-hovered/lane-chevron:bg-muted group-data-hovered/lane-chevron:text-foreground", children: _jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 group-data-expanded/lane:rotate-90" }) }) })) : (_jsx("span", { "aria-hidden": "true", className: "w-target shrink-0" })), _jsx("span", { className: "min-w-0 truncate leading-5 font-medium text-foreground group-data-selected/lane:font-semibold", children: label })] }), _jsx(LaneTrack, { items: items })] })) }), children] }));
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* A lane's track and its items, in time order. A component of its own, and memoised on `items`: React Aria renders a
|
|
340
|
+
* row again as its focus and hover change, and this keeps that from reaching the items, which render again only when
|
|
341
|
+
* the lane's items, the zoom, the selection or a move changes.
|
|
342
|
+
*/
|
|
343
|
+
const LaneTrack = memo(function LaneTrack({ items }) {
|
|
289
344
|
const tl = useTimeline('TimelineLane');
|
|
290
345
|
const sorted = Children.toArray(items)
|
|
291
346
|
.filter(isValidElement)
|
|
292
347
|
.sort((a, b) => itemTimes(a)[0] - itemTimes(b)[0]);
|
|
293
|
-
return (
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
348
|
+
return (_jsx("div", { className: "relative shrink-0 shadow-[inset_0_-1px_0_var(--border)]", style: { width: tl.trackWidth }, children: sorted.map((item, i) => (_jsx(Neighbours, { before: i > 0 ? tl.toX(itemTimes(sorted[i - 1])[1]) : -Infinity, after: i < sorted.length - 1 ? tl.toX(itemTimes(sorted[i + 1])[0]) : Infinity, children: item }, item.key ?? i))) }));
|
|
349
|
+
});
|
|
350
|
+
/** Where an item's neighbours are, kept as one value while they don't move. */
|
|
351
|
+
function Neighbours({ before, after, children }) {
|
|
352
|
+
const room = useMemo(() => ({ before, after }), [before, after]);
|
|
353
|
+
return _jsx(ItemRoomContext.Provider, { value: room, children: children });
|
|
299
354
|
}
|
|
300
355
|
// The badge's pairs, whose text the contrast audit promises against their ground; the edge is the text colour.
|
|
301
356
|
const tones = {
|