@tensor_1/react 2.48.0 → 2.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -1
- package/dist/components/Chip.d.ts +7 -3
- package/dist/components/Chip.js +2 -2
- package/dist/components/DashboardCanvas.js +14 -0
- package/dist/components/DataWorkspace.js +1 -4
- package/dist/components/FocusOnMount.d.ts +282 -0
- package/dist/components/FocusOnMount.js +12 -0
- package/dist/components/Kanban.d.ts +14 -3
- package/dist/components/Kanban.js +9 -4
- package/dist/components/MotionList.d.ts +303 -0
- package/dist/components/MotionList.js +175 -0
- package/dist/components/Popover.js +9 -0
- package/dist/components/RelationshipGraph.js +4 -1
- package/dist/components/RelationshipGraphLayered.js +107 -32
- package/dist/components/SearchSuggest.js +8 -1
- package/dist/components/Segmented.js +8 -2
- package/dist/components/Select.js +6 -0
- package/dist/components/SortableList.d.ts +2 -2
- package/dist/components/SortableList.js +16 -3
- package/dist/components/States.d.ts +33 -1
- package/dist/components/States.js +43 -1
- package/dist/components/Tabs.js +9 -2
- package/dist/components/Toast.d.ts +1 -1
- package/dist/components/Toast.js +106 -2
- package/dist/components/Tooltip.js +62 -7
- package/dist/emoji.cjs +115 -14
- package/dist/hooks/useAnchoredPosition.js +14 -2
- package/dist/hooks/useDeferredReorder.d.ts +32 -0
- package/dist/hooks/useDeferredReorder.js +47 -0
- package/dist/hooks/useDialog.js +15 -2
- package/dist/hooks/useKeyboardGrab.d.ts +58 -0
- package/dist/hooks/useKeyboardGrab.js +118 -0
- package/dist/hooks/useSlidingIndicator.d.ts +18 -0
- package/dist/hooks/useSlidingIndicator.js +80 -0
- package/dist/index.cjs +2203 -1373
- package/dist/index.d.cts +477 -13
- package/dist/index.d.ts +7 -3
- package/dist/index.js +14 -2
- package/dist/labels-context.d.ts +3 -0
- package/dist/motion.d.ts +11 -0
- package/dist/motion.js +35 -0
- package/dist/relationship-graph-model.d.ts +17 -3
- package/dist/relationship-graph-model.js +28 -16
- package/dist/rich-text.cjs +42 -2
- package/dist/toast-store.d.ts +5 -2
- package/dist/toast-store.js +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -192,7 +192,7 @@ Rules the component cannot enforce for you:
|
|
|
192
192
|
- **Dimming is not a signal.** `dimmedNodeIds` must be accompanied by text that says what is dimmed and why.
|
|
193
193
|
- **Localise everything.** Every visible and announced string comes from `labels`; the English defaults live in `DEFAULT_RELATIONSHIP_GRAPH_LABELS`.
|
|
194
194
|
|
|
195
|
-
**Map controls (`controls`, `initialView`).** The default `controls="full"` is the labelled toolbar above the map. `controls="compact"` is the map convention: an icon cluster in the map's bottom-right corner (zoom in, zoom out, fit, reset, full screen, each with a tooltip) and the zoom level beside it; drag pans, Ctrl/⌘ + wheel or a pinch zooms around the pointer, and a plain wheel keeps scrolling the page and briefly says how to zoom. The map itself takes keyboard focus: arrow keys pan (on an item they still move between items), `+` and `−` zoom, `0` resets and Escape leaves full screen. Full screen covers the page (the page behind does not scroll) and there a plain wheel zooms. `controls="none"` draws nothing; drag, pinch and Ctrl/⌘ + wheel still work. `initialView="fit"` opens with every item in view (down to the 40 % minimum) instead of the 75 % readability floor, and Reset returns to it.
|
|
195
|
+
**Map controls (`controls`, `initialView`).** The default `controls="full"` is the labelled toolbar above the map. `controls="compact"` is the map convention: an icon cluster in the map's bottom-right corner (zoom in, zoom out, fit, reset, full screen, each with a tooltip) and the zoom level beside it; drag pans, Ctrl/⌘ + wheel or a pinch zooms around the pointer, and a plain wheel keeps scrolling the page and briefly says how to zoom. The map itself takes keyboard focus: arrow keys pan (on an item they still move between items), `+` and `−` zoom, `0` resets and Escape leaves full screen. Full screen covers the page (the page behind does not scroll) and there a plain wheel zooms. `controls="none"` draws nothing; drag, pinch and Ctrl/⌘ + wheel still work. `initialView="fit"` opens with every item in view (down to the 40 % minimum) instead of the 75 % readability floor, and Reset returns to it. With `controls="compact"` the hint, the zoom level and the cluster sit in a band along the map's bottom edge; the map ends at the band, and fit, the first view and Reset leave its height free.
|
|
196
196
|
|
|
197
197
|
```tsx
|
|
198
198
|
<RelationshipGraph layout="layered" controls="compact" initialView="fit" height="clamp(24rem, 62vh, 44rem)" … />
|
|
@@ -285,6 +285,69 @@ const star = useOptimisticValue(view.starred, (next) => api.star(view.id, next),
|
|
|
285
285
|
</ChangeHighlight>
|
|
286
286
|
```
|
|
287
287
|
|
|
288
|
+
### Lists that move, the success outcome, sliding indicators (motion standard §2.5, §2.8)
|
|
289
|
+
|
|
290
|
+
- **`MotionList`** (`items`, `getKey`, `renderItem`, `as`): a new item rises 8 px and fades in;
|
|
291
|
+
a removed item stays in place (hidden from assistive tech, `inert`), fades out, and only then
|
|
292
|
+
leaves, so the items below glide up; a re-sort glides (FLIP, transform only). Nothing moves on
|
|
293
|
+
the first render. Focus stays on a moved item and goes to the next item when the focused one
|
|
294
|
+
leaves; focus outside the list is never pulled in. `renderItem` must pass unknown props to its
|
|
295
|
+
element (`<li>`, or a `Tr` with `as="tbody"`).
|
|
296
|
+
- **`useDeferredReorder(items, getKey)`**: never re-sort under the pointer. While a mouse is over
|
|
297
|
+
the list or keyboard focus is inside it, a new order waits (content still updates, new rows go
|
|
298
|
+
to the end); `held` says so; the order applies when they leave. Spread `listProps` on the list.
|
|
299
|
+
- **`SuccessState`** in `States`: the outcome of a rare journey (a request submitted): a mark
|
|
300
|
+
that draws once, the title (focused on mount for `page` and `full-page`), `reference`,
|
|
301
|
+
`next` (what happens next), `action`. Reduced motion shows the mark at once.
|
|
302
|
+
- **Tabs, Segmented**: the line underline, the pill and the lifted segment slide to the chosen
|
|
303
|
+
option on a click (160 ms); a keyboard change and reduced motion jump. Server HTML, forced
|
|
304
|
+
colours and Segmented's link mode keep each option's own mark. `useSlidingIndicator` is the
|
|
305
|
+
hook behind it.
|
|
306
|
+
- **CollapsibleSection** opening fades the body in and settles it 4 px (on `::details-content`,
|
|
307
|
+
where supported); an already open section, a keyboard open and closing are instant.
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
const queue = useDeferredReorder(rows, (row) => row.id);
|
|
311
|
+
<MotionList {...queue.listProps} as="tbody" items={queue.items} getKey={(row) => row.id}
|
|
312
|
+
renderItem={(row) => <Tr>…</Tr>} />
|
|
313
|
+
|
|
314
|
+
<SuccessState title={t('requestSubmitted')} reference={<>{req.number} <CopyButton … /></>}
|
|
315
|
+
next={[t('confirmationSent'), t('agentPicksUp')]} action={<ButtonLink href={`/requests/${req.id}`}>{t('viewRequest')}</ButtonLink>} />
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Drag affordances (motion standard §2.8)
|
|
319
|
+
|
|
320
|
+
One set of drag states for every draggable thing (`drag.css`), as attributes so any element can
|
|
321
|
+
carry them: `[data-uix-drag="lifted"]` (picked up by the pointer: a little larger, a deeper
|
|
322
|
+
shadow), `[data-uix-drag="grabbed"]` (picked up from the keyboard: a dashed ring, no motion),
|
|
323
|
+
`[data-uix-drop-target]` (the zone it would land in), `.uix-drop-line` (the gap it would drop
|
|
324
|
+
into) and `[data-uix-settle]` (the landing). Reduced motion keeps the states and drops the scale
|
|
325
|
+
and the landing.
|
|
326
|
+
|
|
327
|
+
- **SortableList** and **DashboardCanvas** lift and settle on their own.
|
|
328
|
+
- **Kanban**: `KanbanCard dragging`, `KanbanColumn dropTarget`, `<KanbanDropLine />` at the gap;
|
|
329
|
+
call `settleDrop(cardElement)` once the card is in its new place.
|
|
330
|
+
- **`useKeyboardGrab({ id, label, onMove, onDrop, onCancel, labels })`** for a draggable thing you
|
|
331
|
+
build: Space or Enter picks the focused item up, the arrows call `onMove(direction)` (return
|
|
332
|
+
what to say, e.g. "Position 3 of 8"), Space or Enter drops, Escape or leaving puts it back;
|
|
333
|
+
every step is said politely. Spread `itemProps` (it includes a `ref`) on the focusable item; the
|
|
334
|
+
picked-up state follows `id`, so an item moved into another list stays picked up and focused.
|
|
335
|
+
Words: `labels` or `UixLabelsProvider` `keyboardGrab`. The kit's lists have their own paths.
|
|
336
|
+
|
|
337
|
+
```tsx
|
|
338
|
+
<KanbanColumn title={t('doing')} dropTarget={drag?.column === 'doing'}>
|
|
339
|
+
{cards.map((card, i) => <Fragment key={card.id}>
|
|
340
|
+
{drag?.column === 'doing' && drag.index === i && <KanbanDropLine />}
|
|
341
|
+
<KanbanCard title={card.title} dragging={drag?.id === card.id} onMove={…} />
|
|
342
|
+
</Fragment>)}
|
|
343
|
+
{drag?.column === 'doing' && drag.index >= cards.length && <KanbanDropLine />}
|
|
344
|
+
</KanbanColumn>
|
|
345
|
+
|
|
346
|
+
// your own draggable list: the picked-up state follows the id, across lists too
|
|
347
|
+
const grab = useKeyboardGrab({ id: item.id, label: item.title, onMove: (dir) => move(item.id, dir), onCancel: restore });
|
|
348
|
+
<li tabIndex={0} {...grab.itemProps}>{item.title}</li>
|
|
349
|
+
```
|
|
350
|
+
|
|
288
351
|
### Scrolling tabs, toned stat tiles and copying
|
|
289
352
|
|
|
290
353
|
- **`Tabs overflow="scroll"`** keeps a long tab row on one line that scrolls sideways. The selected tab is always scrolled into view, and edge buttons appear only on the side that has hidden tabs. The buttons are pointer-only: keyboard users move with Arrow, Home and End. Combine it with `TabPanel keepMounted` on a record page with many sections.
|
|
@@ -1041,6 +1104,9 @@ const v = useVirtualRows(rows, { rowHeight: 44, estimatedViewportHeight: 600, en
|
|
|
1041
1104
|
- The ref is the body (the button, link or span that carries the chip's action), also on a
|
|
1042
1105
|
removable chip; `bodyProps` puts attributes there.
|
|
1043
1106
|
- `current` on a link chip: `aria-current="page"` and the filled look.
|
|
1107
|
+
- `onClick` gets the click event, so a chip can be a `Menu` trigger:
|
|
1108
|
+
`<Menu trigger={<Chip variant="add" icon={<PlusIcon />}>Filter</Chip>}>…</Menu>`. A handler that takes no
|
|
1109
|
+
argument still works.
|
|
1044
1110
|
|
|
1045
1111
|
#### FileUpload and Attachment
|
|
1046
1112
|
|
|
@@ -1591,6 +1657,9 @@ const [nav, setNav] = useState<ShellNav>('full');
|
|
|
1591
1657
|
|
|
1592
1658
|
- `Sidebar actions` sit beside the brand (hidden in the rail); `search` is a row that opens your search and shows
|
|
1593
1659
|
its keys (it does not bind them: your command palette listens); `footer` is pinned to the bottom.
|
|
1660
|
+
- Key caps are for a keyboard: on a touch phone or tablet (`(hover: none) and (pointer: coarse)`) the kit draws
|
|
1661
|
+
none, in the search row, Menu and CommandPalette rows, Tooltips, SearchSuggest and a Button's hint. What a
|
|
1662
|
+
screen reader hears is unchanged (`aria-keyshortcuts`, the spoken keys and descriptions stay).
|
|
1594
1663
|
- `AccountMenu`: avatar (photo, your node, or initials), name and a second line as a `Menu` trigger;
|
|
1595
1664
|
`collapsed` in the rail.
|
|
1596
1665
|
- `navHotkey` switches full ↔ rail instantly, never while typing; `navTierStorageKey` remembers the tier before
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode, MouseEvent } from 'react';
|
|
3
3
|
import { UixRenderLink } from '../link.js';
|
|
4
4
|
|
|
5
5
|
interface ChipProps extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
|
|
@@ -11,8 +11,12 @@ interface ChipProps extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
|
|
|
11
11
|
/** Toggle chip: `aria-pressed`, filled while on. Pair with `onPressedChange`. */
|
|
12
12
|
pressed?: boolean;
|
|
13
13
|
onPressedChange?: (pressed: boolean) => void;
|
|
14
|
-
/**
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* A chip that acts in place (e.g. opens the filter it shows for editing). Gets the click event,
|
|
16
|
+
* so a chip can be the `trigger` of a `Menu` (which reads `defaultPrevented`); a handler that
|
|
17
|
+
* takes no argument still works. Not called while `disabled`.
|
|
18
|
+
*/
|
|
19
|
+
onClick?: (event: MouseEvent<HTMLElement>) => void;
|
|
16
20
|
/** A link chip. */
|
|
17
21
|
href?: string;
|
|
18
22
|
renderLink?: UixRenderLink;
|
package/dist/components/Chip.js
CHANGED
|
@@ -30,10 +30,10 @@ const Chip = forwardRef(function Chip2({
|
|
|
30
30
|
/* @__PURE__ */ jsx("span", { className: "uix-chip__label", children }),
|
|
31
31
|
count != null && /* @__PURE__ */ jsx("span", { className: "uix-chip__count", children: count })
|
|
32
32
|
] });
|
|
33
|
-
const handleClick = () => {
|
|
33
|
+
const handleClick = (event) => {
|
|
34
34
|
if (disabled) return;
|
|
35
35
|
if (toggle) onPressedChange?.(!pressed);
|
|
36
|
-
onClick?.();
|
|
36
|
+
onClick?.(event);
|
|
37
37
|
};
|
|
38
38
|
const outer = cx(
|
|
39
39
|
"uix-chip",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { cx } from "../cx.js";
|
|
5
|
+
import { settleDrop } from "../hooks/useKeyboardGrab.js";
|
|
5
6
|
import { fillLabel } from "../fill-label.js";
|
|
6
7
|
import { GripVerticalIcon, Maximize2Icon } from "../icons/components.js";
|
|
7
8
|
import {
|
|
@@ -58,12 +59,25 @@ function DashboardCanvas({
|
|
|
58
59
|
const live = useRef({ layout, onLayoutChange, labels, itemLabel });
|
|
59
60
|
live.current = { layout, onLayoutChange, labels, itemLabel };
|
|
60
61
|
useEffect(() => () => dragRef.current?.stop(), []);
|
|
62
|
+
const settle = useRef(null);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const pending = settle.current;
|
|
65
|
+
if (!pending || preview) return;
|
|
66
|
+
const item = layout.find((entry) => entry.id === pending.id);
|
|
67
|
+
if (!item || item.col !== pending.col || item.row !== pending.row) {
|
|
68
|
+
if (layout !== pending.layout) settle.current = null;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
settle.current = null;
|
|
72
|
+
settleDrop(Array.from(gridRef.current?.children ?? []).find((el) => el.dataset.canvasId === pending.id));
|
|
73
|
+
});
|
|
61
74
|
const describe = (item, kind) => kind === "move" ? fillLabel(labels.moved, { label: itemLabel(item), col: item.col + 1, row: item.row + 1 }) : fillLabel(labels.resized, { label: itemLabel(item), w: item.w, h: item.h });
|
|
62
75
|
const commit = (id, placement, kind, source) => {
|
|
63
76
|
const state = live.current;
|
|
64
77
|
const next = placeCanvasItem(state.layout, id, placement);
|
|
65
78
|
const placed = next.find((item) => item.id === id);
|
|
66
79
|
if (!placed) return;
|
|
80
|
+
if (source === "pointer" && kind === "move") settle.current = { id, col: placed.col, row: placed.row, layout: state.layout };
|
|
67
81
|
state.onLayoutChange?.(next, { id, kind, source });
|
|
68
82
|
setAnnouncement(describe(placed, kind));
|
|
69
83
|
};
|
|
@@ -367,10 +367,7 @@ function FilterChips({ filters, labels, baseId }) {
|
|
|
367
367
|
children: /* @__PURE__ */ jsx(ChipSummary, { field, value: filters.values[field.id], options: filters.summary })
|
|
368
368
|
}
|
|
369
369
|
) }, field.id)),
|
|
370
|
-
unset.length > 0 && /* @__PURE__ */ jsx("span", { ref: addRef, children: /* @__PURE__ */ jsx(Menu, { trigger: /* @__PURE__ */
|
|
371
|
-
/* @__PURE__ */ jsx("span", { className: "uix-chip__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(PlusIcon, {}) }),
|
|
372
|
-
/* @__PURE__ */ jsx("span", { className: "uix-chip__label", children: labels.addFilter })
|
|
373
|
-
] }), children: unset.map((field) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => edit(field, addRef.current), children: field.label }, field.id)) }) }),
|
|
370
|
+
unset.length > 0 && /* @__PURE__ */ jsx("span", { ref: addRef, children: /* @__PURE__ */ jsx(Menu, { trigger: /* @__PURE__ */ jsx(Chip, { variant: "add", icon: /* @__PURE__ */ jsx(PlusIcon, {}), children: labels.addFilter }), children: unset.map((field) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => edit(field, addRef.current), children: field.label }, field.id)) }) }),
|
|
374
371
|
set.length > 0 && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "link", onClick: () => {
|
|
375
372
|
for (const f of set) filters.onChange(f.id, void 0);
|
|
376
373
|
}, children: labels.clearFilters }),
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, HTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A heading (or any element) that takes focus once, when it mounts — so a page that replaces
|
|
6
|
+
* a form with its outcome (SuccessState) reads the outcome first. `tabIndex={-1}`: focusable
|
|
7
|
+
* by script, not a tab stop. The client half of server-renderable states.
|
|
8
|
+
*/
|
|
9
|
+
declare function FocusOnMount({ as, enabled, children, ...props }: {
|
|
10
|
+
as: keyof HTMLElementTagNameMap;
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
} & HTMLAttributes<HTMLElement>): react.DetailedReactHTMLElement<{
|
|
14
|
+
ref: react.RefObject<HTMLElement>;
|
|
15
|
+
tabIndex: number;
|
|
16
|
+
defaultChecked?: boolean | undefined;
|
|
17
|
+
defaultValue?: string | number | readonly string[] | undefined;
|
|
18
|
+
suppressContentEditableWarning?: boolean | undefined;
|
|
19
|
+
suppressHydrationWarning?: boolean | undefined;
|
|
20
|
+
accessKey?: string | undefined;
|
|
21
|
+
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {});
|
|
22
|
+
autoFocus?: boolean | undefined;
|
|
23
|
+
className?: string | undefined;
|
|
24
|
+
contentEditable?: (boolean | "false" | "true") | "inherit" | "plaintext-only" | undefined;
|
|
25
|
+
contextMenu?: string | undefined;
|
|
26
|
+
dir?: string | undefined;
|
|
27
|
+
draggable?: (boolean | "false" | "true") | undefined;
|
|
28
|
+
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
|
|
29
|
+
hidden?: boolean | undefined;
|
|
30
|
+
id?: string | undefined;
|
|
31
|
+
lang?: string | undefined;
|
|
32
|
+
nonce?: string | undefined;
|
|
33
|
+
slot?: string | undefined;
|
|
34
|
+
spellCheck?: (boolean | "false" | "true") | undefined;
|
|
35
|
+
style?: react.CSSProperties | undefined;
|
|
36
|
+
title?: string | undefined;
|
|
37
|
+
translate?: "yes" | "no" | undefined;
|
|
38
|
+
radioGroup?: string | undefined;
|
|
39
|
+
role?: react.AriaRole | undefined;
|
|
40
|
+
about?: string | undefined;
|
|
41
|
+
content?: string | undefined;
|
|
42
|
+
datatype?: string | undefined;
|
|
43
|
+
inlist?: any;
|
|
44
|
+
prefix?: string | undefined;
|
|
45
|
+
property?: string | undefined;
|
|
46
|
+
rel?: string | undefined;
|
|
47
|
+
resource?: string | undefined;
|
|
48
|
+
rev?: string | undefined;
|
|
49
|
+
typeof?: string | undefined;
|
|
50
|
+
vocab?: string | undefined;
|
|
51
|
+
autoCorrect?: string | undefined;
|
|
52
|
+
autoSave?: string | undefined;
|
|
53
|
+
color?: string | undefined;
|
|
54
|
+
itemProp?: string | undefined;
|
|
55
|
+
itemScope?: boolean | undefined;
|
|
56
|
+
itemType?: string | undefined;
|
|
57
|
+
itemID?: string | undefined;
|
|
58
|
+
itemRef?: string | undefined;
|
|
59
|
+
results?: number | undefined;
|
|
60
|
+
security?: string | undefined;
|
|
61
|
+
unselectable?: "on" | "off" | undefined;
|
|
62
|
+
inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined;
|
|
63
|
+
is?: string | undefined;
|
|
64
|
+
exportparts?: string | undefined;
|
|
65
|
+
part?: string | undefined;
|
|
66
|
+
"aria-activedescendant"?: string | undefined;
|
|
67
|
+
"aria-atomic"?: (boolean | "false" | "true") | undefined;
|
|
68
|
+
"aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined;
|
|
69
|
+
"aria-braillelabel"?: string | undefined;
|
|
70
|
+
"aria-brailleroledescription"?: string | undefined;
|
|
71
|
+
"aria-busy"?: (boolean | "false" | "true") | undefined;
|
|
72
|
+
"aria-checked"?: boolean | "false" | "mixed" | "true" | undefined;
|
|
73
|
+
"aria-colcount"?: number | undefined;
|
|
74
|
+
"aria-colindex"?: number | undefined;
|
|
75
|
+
"aria-colindextext"?: string | undefined;
|
|
76
|
+
"aria-colspan"?: number | undefined;
|
|
77
|
+
"aria-controls"?: string | undefined;
|
|
78
|
+
"aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined;
|
|
79
|
+
"aria-describedby"?: string | undefined;
|
|
80
|
+
"aria-description"?: string | undefined;
|
|
81
|
+
"aria-details"?: string | undefined;
|
|
82
|
+
"aria-disabled"?: (boolean | "false" | "true") | undefined;
|
|
83
|
+
"aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined;
|
|
84
|
+
"aria-errormessage"?: string | undefined;
|
|
85
|
+
"aria-expanded"?: (boolean | "false" | "true") | undefined;
|
|
86
|
+
"aria-flowto"?: string | undefined;
|
|
87
|
+
"aria-grabbed"?: (boolean | "false" | "true") | undefined;
|
|
88
|
+
"aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined;
|
|
89
|
+
"aria-hidden"?: (boolean | "false" | "true") | undefined;
|
|
90
|
+
"aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined;
|
|
91
|
+
"aria-keyshortcuts"?: string | undefined;
|
|
92
|
+
"aria-label"?: string | undefined;
|
|
93
|
+
"aria-labelledby"?: string | undefined;
|
|
94
|
+
"aria-level"?: number | undefined;
|
|
95
|
+
"aria-live"?: "off" | "assertive" | "polite" | undefined;
|
|
96
|
+
"aria-modal"?: (boolean | "false" | "true") | undefined;
|
|
97
|
+
"aria-multiline"?: (boolean | "false" | "true") | undefined;
|
|
98
|
+
"aria-multiselectable"?: (boolean | "false" | "true") | undefined;
|
|
99
|
+
"aria-orientation"?: "horizontal" | "vertical" | undefined;
|
|
100
|
+
"aria-owns"?: string | undefined;
|
|
101
|
+
"aria-placeholder"?: string | undefined;
|
|
102
|
+
"aria-posinset"?: number | undefined;
|
|
103
|
+
"aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined;
|
|
104
|
+
"aria-readonly"?: (boolean | "false" | "true") | undefined;
|
|
105
|
+
"aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined;
|
|
106
|
+
"aria-required"?: (boolean | "false" | "true") | undefined;
|
|
107
|
+
"aria-roledescription"?: string | undefined;
|
|
108
|
+
"aria-rowcount"?: number | undefined;
|
|
109
|
+
"aria-rowindex"?: number | undefined;
|
|
110
|
+
"aria-rowindextext"?: string | undefined;
|
|
111
|
+
"aria-rowspan"?: number | undefined;
|
|
112
|
+
"aria-selected"?: (boolean | "false" | "true") | undefined;
|
|
113
|
+
"aria-setsize"?: number | undefined;
|
|
114
|
+
"aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined;
|
|
115
|
+
"aria-valuemax"?: number | undefined;
|
|
116
|
+
"aria-valuemin"?: number | undefined;
|
|
117
|
+
"aria-valuenow"?: number | undefined;
|
|
118
|
+
"aria-valuetext"?: string | undefined;
|
|
119
|
+
dangerouslySetInnerHTML?: {
|
|
120
|
+
__html: string | TrustedHTML;
|
|
121
|
+
} | undefined;
|
|
122
|
+
onCopy?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
123
|
+
onCopyCapture?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
124
|
+
onCut?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
125
|
+
onCutCapture?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
126
|
+
onPaste?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
127
|
+
onPasteCapture?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
128
|
+
onCompositionEnd?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
129
|
+
onCompositionEndCapture?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
130
|
+
onCompositionStart?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
131
|
+
onCompositionStartCapture?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
132
|
+
onCompositionUpdate?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
133
|
+
onCompositionUpdateCapture?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
134
|
+
onFocus?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
135
|
+
onFocusCapture?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
136
|
+
onBlur?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
137
|
+
onBlurCapture?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
138
|
+
onChange?: react.FormEventHandler<HTMLElement> | undefined;
|
|
139
|
+
onChangeCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
140
|
+
onBeforeInput?: react.InputEventHandler<HTMLElement> | undefined;
|
|
141
|
+
onBeforeInputCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
142
|
+
onInput?: react.FormEventHandler<HTMLElement> | undefined;
|
|
143
|
+
onInputCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
144
|
+
onReset?: react.FormEventHandler<HTMLElement> | undefined;
|
|
145
|
+
onResetCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
146
|
+
onSubmit?: react.FormEventHandler<HTMLElement> | undefined;
|
|
147
|
+
onSubmitCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
148
|
+
onInvalid?: react.FormEventHandler<HTMLElement> | undefined;
|
|
149
|
+
onInvalidCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
150
|
+
onLoad?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
151
|
+
onLoadCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
152
|
+
onError?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
153
|
+
onErrorCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
154
|
+
onKeyDown?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
155
|
+
onKeyDownCapture?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
156
|
+
onKeyPress?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
157
|
+
onKeyPressCapture?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
158
|
+
onKeyUp?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
159
|
+
onKeyUpCapture?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
160
|
+
onAbort?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
161
|
+
onAbortCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
162
|
+
onCanPlay?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
163
|
+
onCanPlayCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
164
|
+
onCanPlayThrough?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
165
|
+
onCanPlayThroughCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
166
|
+
onDurationChange?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
167
|
+
onDurationChangeCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
168
|
+
onEmptied?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
169
|
+
onEmptiedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
170
|
+
onEncrypted?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
171
|
+
onEncryptedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
172
|
+
onEnded?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
173
|
+
onEndedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
174
|
+
onLoadedData?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
175
|
+
onLoadedDataCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
176
|
+
onLoadedMetadata?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
177
|
+
onLoadedMetadataCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
178
|
+
onLoadStart?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
179
|
+
onLoadStartCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
180
|
+
onPause?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
181
|
+
onPauseCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
182
|
+
onPlay?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
183
|
+
onPlayCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
184
|
+
onPlaying?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
185
|
+
onPlayingCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
186
|
+
onProgress?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
187
|
+
onProgressCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
188
|
+
onRateChange?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
189
|
+
onRateChangeCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
190
|
+
onSeeked?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
191
|
+
onSeekedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
192
|
+
onSeeking?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
193
|
+
onSeekingCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
194
|
+
onStalled?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
195
|
+
onStalledCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
196
|
+
onSuspend?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
197
|
+
onSuspendCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
198
|
+
onTimeUpdate?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
199
|
+
onTimeUpdateCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
200
|
+
onVolumeChange?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
201
|
+
onVolumeChangeCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
202
|
+
onWaiting?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
203
|
+
onWaitingCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
204
|
+
onAuxClick?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
205
|
+
onAuxClickCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
206
|
+
onClick?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
207
|
+
onClickCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
208
|
+
onContextMenu?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
209
|
+
onContextMenuCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
210
|
+
onDoubleClick?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
211
|
+
onDoubleClickCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
212
|
+
onDrag?: react.DragEventHandler<HTMLElement> | undefined;
|
|
213
|
+
onDragCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
214
|
+
onDragEnd?: react.DragEventHandler<HTMLElement> | undefined;
|
|
215
|
+
onDragEndCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
216
|
+
onDragEnter?: react.DragEventHandler<HTMLElement> | undefined;
|
|
217
|
+
onDragEnterCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
218
|
+
onDragExit?: react.DragEventHandler<HTMLElement> | undefined;
|
|
219
|
+
onDragExitCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
220
|
+
onDragLeave?: react.DragEventHandler<HTMLElement> | undefined;
|
|
221
|
+
onDragLeaveCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
222
|
+
onDragOver?: react.DragEventHandler<HTMLElement> | undefined;
|
|
223
|
+
onDragOverCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
224
|
+
onDragStart?: react.DragEventHandler<HTMLElement> | undefined;
|
|
225
|
+
onDragStartCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
226
|
+
onDrop?: react.DragEventHandler<HTMLElement> | undefined;
|
|
227
|
+
onDropCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
228
|
+
onMouseDown?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
229
|
+
onMouseDownCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
230
|
+
onMouseEnter?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
231
|
+
onMouseLeave?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
232
|
+
onMouseMove?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
233
|
+
onMouseMoveCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
234
|
+
onMouseOut?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
235
|
+
onMouseOutCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
236
|
+
onMouseOver?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
237
|
+
onMouseOverCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
238
|
+
onMouseUp?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
239
|
+
onMouseUpCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
240
|
+
onSelect?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
241
|
+
onSelectCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
242
|
+
onTouchCancel?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
243
|
+
onTouchCancelCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
244
|
+
onTouchEnd?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
245
|
+
onTouchEndCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
246
|
+
onTouchMove?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
247
|
+
onTouchMoveCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
248
|
+
onTouchStart?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
249
|
+
onTouchStartCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
250
|
+
onPointerDown?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
251
|
+
onPointerDownCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
252
|
+
onPointerMove?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
253
|
+
onPointerMoveCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
254
|
+
onPointerUp?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
255
|
+
onPointerUpCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
256
|
+
onPointerCancel?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
257
|
+
onPointerCancelCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
258
|
+
onPointerEnter?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
259
|
+
onPointerLeave?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
260
|
+
onPointerOver?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
261
|
+
onPointerOverCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
262
|
+
onPointerOut?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
263
|
+
onPointerOutCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
264
|
+
onGotPointerCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
265
|
+
onGotPointerCaptureCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
266
|
+
onLostPointerCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
267
|
+
onLostPointerCaptureCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
268
|
+
onScroll?: react.UIEventHandler<HTMLElement> | undefined;
|
|
269
|
+
onScrollCapture?: react.UIEventHandler<HTMLElement> | undefined;
|
|
270
|
+
onWheel?: react.WheelEventHandler<HTMLElement> | undefined;
|
|
271
|
+
onWheelCapture?: react.WheelEventHandler<HTMLElement> | undefined;
|
|
272
|
+
onAnimationStart?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
273
|
+
onAnimationStartCapture?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
274
|
+
onAnimationEnd?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
275
|
+
onAnimationEndCapture?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
276
|
+
onAnimationIteration?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
277
|
+
onAnimationIterationCapture?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
278
|
+
onTransitionEnd?: react.TransitionEventHandler<HTMLElement> | undefined;
|
|
279
|
+
onTransitionEndCapture?: react.TransitionEventHandler<HTMLElement> | undefined;
|
|
280
|
+
}, HTMLElement>;
|
|
281
|
+
|
|
282
|
+
export { FocusOnMount };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createElement, useEffect, useRef } from "react";
|
|
3
|
+
function FocusOnMount({ as, enabled = true, children, ...props }) {
|
|
4
|
+
const ref = useRef(null);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (enabled) ref.current?.focus({ preventScroll: false });
|
|
7
|
+
}, [enabled]);
|
|
8
|
+
return createElement(as, { ...props, ref, tabIndex: -1 }, children);
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
FocusOnMount
|
|
12
|
+
};
|
|
@@ -13,9 +13,11 @@ declare function Kanban({ announcement, children, className, ...props }: KanbanP
|
|
|
13
13
|
interface KanbanColumnProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
14
14
|
title?: ReactNode;
|
|
15
15
|
count?: number;
|
|
16
|
+
/** A dragged card would land in this column: the column body is tinted and outlined (HAR-2590). */
|
|
17
|
+
dropTarget?: boolean;
|
|
16
18
|
children?: ReactNode;
|
|
17
19
|
}
|
|
18
|
-
declare function KanbanColumn({ title, count, children, className, ...props }: KanbanColumnProps): react.JSX.Element;
|
|
20
|
+
declare function KanbanColumn({ title, count, dropTarget, children, className, ...props }: KanbanColumnProps): react.JSX.Element;
|
|
19
21
|
type KanbanMoveDirection = 'up' | 'down' | 'left' | 'right';
|
|
20
22
|
interface KanbanCardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
21
23
|
title?: ReactNode;
|
|
@@ -26,8 +28,17 @@ interface KanbanCardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
|
|
|
26
28
|
* the board-level `announcement` so SR users hear the result.
|
|
27
29
|
*/
|
|
28
30
|
onMove?: (dir: KanbanMoveDirection) => void;
|
|
31
|
+
/** The card is being dragged with the pointer: it lifts (HAR-2590). Call `settleDrop(card)` when it lands. */
|
|
32
|
+
dragging?: boolean;
|
|
29
33
|
children?: ReactNode;
|
|
30
34
|
}
|
|
31
|
-
declare function KanbanCard({ title, meta, children, className, onMove, onKeyDown, ...props }: KanbanCardProps): react.JSX.Element;
|
|
35
|
+
declare function KanbanCard({ title, meta, children, className, onMove, onKeyDown, dragging, ...props }: KanbanCardProps): react.JSX.Element;
|
|
36
|
+
type KanbanDropLineProps = HTMLAttributes<HTMLDivElement>;
|
|
37
|
+
/**
|
|
38
|
+
* Where a dragged card would land between two cards (HAR-2590): an accent line with an end mark.
|
|
39
|
+
* Render it in the column at the insertion point while a drag is over it (also after the last
|
|
40
|
+
* card); it is decorative (the keyboard path and the board's `announcement` say where it goes).
|
|
41
|
+
*/
|
|
42
|
+
declare function KanbanDropLine({ className, ...props }: KanbanDropLineProps): react.JSX.Element;
|
|
32
43
|
|
|
33
|
-
export { Kanban, KanbanCard, type KanbanCardProps, KanbanColumn, type KanbanColumnProps, type KanbanMoveDirection, type KanbanProps };
|
|
44
|
+
export { Kanban, KanbanCard, type KanbanCardProps, KanbanColumn, type KanbanColumnProps, KanbanDropLine, type KanbanDropLineProps, type KanbanMoveDirection, type KanbanProps };
|
|
@@ -8,7 +8,7 @@ function Kanban({ announcement, children, className, ...props }) {
|
|
|
8
8
|
children
|
|
9
9
|
] });
|
|
10
10
|
}
|
|
11
|
-
function KanbanColumn({ title, count, children, className, ...props }) {
|
|
11
|
+
function KanbanColumn({ title, count, dropTarget, children, className, ...props }) {
|
|
12
12
|
const headId = useId();
|
|
13
13
|
const hasHead = title != null || count != null;
|
|
14
14
|
return /* @__PURE__ */ jsxs("div", { className: cx("uix-kanban__col", className), ...props, children: [
|
|
@@ -16,7 +16,7 @@ function KanbanColumn({ title, count, children, className, ...props }) {
|
|
|
16
16
|
title,
|
|
17
17
|
count != null && /* @__PURE__ */ jsx("span", { className: "uix-kanban__count", children: count })
|
|
18
18
|
] }),
|
|
19
|
-
/* @__PURE__ */ jsx("div", { className: "uix-kanban__body", role: "list", "aria-labelledby": hasHead ? headId : void 0, children })
|
|
19
|
+
/* @__PURE__ */ jsx("div", { className: "uix-kanban__body", role: "list", "aria-labelledby": hasHead ? headId : void 0, "data-uix-drop-target": dropTarget || void 0, children })
|
|
20
20
|
] });
|
|
21
21
|
}
|
|
22
22
|
const MOVE_KEYS = {
|
|
@@ -25,7 +25,7 @@ const MOVE_KEYS = {
|
|
|
25
25
|
ArrowLeft: "left",
|
|
26
26
|
ArrowRight: "right"
|
|
27
27
|
};
|
|
28
|
-
function KanbanCard({ title, meta, children, className, onMove, onKeyDown, ...props }) {
|
|
28
|
+
function KanbanCard({ title, meta, children, className, onMove, onKeyDown, dragging, ...props }) {
|
|
29
29
|
const handleKeyDown = (e) => {
|
|
30
30
|
onKeyDown?.(e);
|
|
31
31
|
if (!onMove || !e.altKey || e.defaultPrevented) return;
|
|
@@ -42,6 +42,7 @@ function KanbanCard({ title, meta, children, className, onMove, onKeyDown, ...pr
|
|
|
42
42
|
tabIndex: 0,
|
|
43
43
|
className: cx("uix-kanban__card", className),
|
|
44
44
|
onKeyDown: handleKeyDown,
|
|
45
|
+
"data-uix-drag": dragging ? "lifted" : void 0,
|
|
45
46
|
...props,
|
|
46
47
|
children: [
|
|
47
48
|
title && /* @__PURE__ */ jsx("div", { className: "uix-kanban__card-title", children: title }),
|
|
@@ -51,8 +52,12 @@ function KanbanCard({ title, meta, children, className, onMove, onKeyDown, ...pr
|
|
|
51
52
|
}
|
|
52
53
|
);
|
|
53
54
|
}
|
|
55
|
+
function KanbanDropLine({ className, ...props }) {
|
|
56
|
+
return /* @__PURE__ */ jsx("div", { ...props, className: cx("uix-drop-line", className), "aria-hidden": "true" });
|
|
57
|
+
}
|
|
54
58
|
export {
|
|
55
59
|
Kanban,
|
|
56
60
|
KanbanCard,
|
|
57
|
-
KanbanColumn
|
|
61
|
+
KanbanColumn,
|
|
62
|
+
KanbanDropLine
|
|
58
63
|
};
|