@salemcobalt/ui 0.2.0-rc.23 → 0.2.0-rc.25
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 +2 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +182 -22
- package/dist/index.js.map +1 -1
- package/dist/styles.css +58 -6
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Styles ship as one stylesheet inside `@layer sc`, so an app's unlayered CSS alwa
|
|
|
33
33
|
| `Card` | `variant` outlined · elevated · filled · plain (a quiet row: no surface, a hover wash without border or shadow, selected is `accent.wash` with a 1px `accent.border`); `padding` none · sm · md · lg; `interactive`; `selected` (visual only: pair with `aria-pressed`/`aria-selected`/`aria-current`; also turns a Score inside solid); `as` or `render` to make it an `a`/`button`/`li`. |
|
|
34
34
|
| `Stack`, `Inline` | `gap` from the spacing scale (`none` … `4xl`); `align`; `justify`; `as`. `Inline` wraps unless `wrap={false}`. |
|
|
35
35
|
| `Kbd` | One key per `Kbd`; `Kbd.Group label="Command K"` groups a shortcut with a `+` (or `separator="space"`). |
|
|
36
|
-
| `Dialog` | `Root` (`open`, `defaultOpen`, `onOpenChange`, `dismissible`, `onRequestClose(reason)`: Esc, backdrop and every `Close` ask instead of closing; close by setting `open`), `Trigger`, `Content` (`size` sm · md · lg, every size clamps to the viewport minus a 16px gutter; `variant="sheet"` becomes a bottom sheet below 640px with a scrolling `Body`; `variant="fullscreen"` covers the viewport, inset 16px from 900px, with a scrolling `Body`), `Title`, `Description`, `Body`, `Actions`, `Close`. Menus, selects and tooltips opened inside render above it.
|
|
36
|
+
| `Dialog` | `Root` (`open`, `defaultOpen`, `onOpenChange`, `dismissible`, `onRequestClose(reason)`: Esc, backdrop and every `Close` ask instead of closing; close by setting `open`), `Trigger`, `Content` (`size` sm · md · lg, every size clamps to the viewport minus a 16px gutter; `variant="sheet"` becomes a bottom sheet below 640px with a scrolling `Body` and swipe-down-to-dismiss from its handle or header (top 64px, outside controls and `Body`; closes past 30% of its height or on a flick, otherwise springs back; the handle is a `Close` named "Dismiss"; `dismissOnSwipe={false}` where an accidental close loses work, also off when the Root is not `dismissible`); `variant="fullscreen"` covers the viewport, inset 16px from 900px, with a scrolling `Body`), `Title`, `Description`, `Body`, `Actions`, `Close`. Menus, selects and tooltips opened inside render above it. |
|
|
37
37
|
| `FullScreenFlow` | A multi-step takeover on `Dialog variant="fullscreen"` (docs/adr/0006). `Root` (`open` default `true`, required `onRequestClose(reason)` for Esc and the ×, `onNext`/`onBack` for Enter and the arrow keys outside controls, `decoration`), `Header` (`title` names the dialog, `logo`, `compactTitle` below 760px, `status`, `closeLabel`; children: `Progress`), `Progress` (`chapters` `{ label, steps }[]`, `step` counted from 1, `label`; current chapter `aria-current="step"`), `Body`, `Rail` (from 1000px, `footer`) › `RailGroup` (`label`) › `RailItem` (`current`, `done`, `disabled`, `adornment`), `Viewport` (`direction` forward · back; one keyed `Step`), `Step` (`title` an `<h2>` that takes focus, `eyebrow`, `description`, `announcement` for the live region), `Footer` (`back`, `hint`, children; 44px buttons). The app owns the step state; the flow owns motion, focus and announcements. |
|
|
38
38
|
| `Toolbar` | `Root` (required `aria-label`, `wrap`, `gap`), `Group` (`aria-label`, `gap`), `Separator`, `Spacer`, `Button` (`render={<IconButton … />}` or `render={<Menu.Trigger render={…} />}` so the control joins the roving focus: Tab enters, arrows move, Tab leaves), `Link` (an anchor in the same navigation; `render={<IconButton label render={<a href />} />}` for an icon link). |
|
|
39
39
|
| `Banner` | `tone` info (default) · success · warning · danger · neutral; `icon` (or `false`); `action` slot; `dismissible` + `onDismiss` (`open` to control); warning and danger are `role="alert"`, the rest `role="status"`. |
|
|
@@ -53,7 +53,7 @@ Styles ship as one stylesheet inside `@layer sc`, so an app's unlayered CSS alwa
|
|
|
53
53
|
| `SelectionBar` | Floating bulk-action bar on Toolbar, centred at the bottom of the viewport (content width up to 48rem, gutters and the safe area respected, full width between the gutters under 640px, fade and slide-up, none under reduced motion): `count` (hidden at 0), `onClear`, children are `Toolbar.Button`s, `aria-label` ("Bulk actions"), `countLabel`, `clearLabel`. Mount it at the end of the scrolling content: while open it leaves a spacer as tall as itself so the last rows scroll clear. A polite status region announces the count; focus returns to where it came from when the bar leaves. |
|
|
54
54
|
| `Toast` | `Toast.Provider` (`timeout` 6000, `limit` 3) near the root, `useToast().add({ title, description, tone, action: { label, onClick }, timeout, priority })` below it; Base UI Toast: polite region, paused on hover and focus, F6 to reach it, bottom-end at `--sc-z-toast`. |
|
|
55
55
|
| `PriorityNav` | Priority+ primary navigation (docs/adr/0005): required `aria-label`; `items` as `{ href, label, id?, current?, badge?, badgeLabel? }` in priority order; links that fit stay inline and the rest go into a "More" disclosure (APG disclosure navigation: a `button` with `aria-expanded`, not a menu; Esc, click outside and focus leaving close it). The `current` link is never collapsed. `moreLabel`, `moreCountLabel(n)` (announced only: "More, 3 links"), `renderLink={(props) => <Link {...props} />}` for a router. Server-renders every link on one clipped line (scrolls sideways without JS), measures widths once (again after web fonts load or when keys/string labels change) and re-renders only when the inline count changes. Takes the free space in a flex row (`flex: 1 1 0%`); in a grid use a `minmax(0, 1fr)` track. The open panel sits in the top layer (Popover API), anchored to the toggle with CSS anchor positioning (a JS fallback elsewhere) and capped to the viewport. `data-overflowing` + `onOverflowChange(boolean)` let a header make room, with `overflowHysteresis` (px) so it cannot oscillate. Under 400px wide (container query) More shows only an ellipsis. `badge` (a count, or `'dot'`; `0` shows nothing) draws an accent pill or dot after the label, decorative, with `badgeLabel` ("2 suggestions to review") appended to the link's name; while the item is collapsed, More shows the collapsed items' summed count (a dot when they only have dots) and adds their `badgeLabel`s to its name ("More, 3 links, 2 suggestions to review"). Icon-only, the badge sits on More's corner. No motion. |
|
|
56
|
-
| `Popover` | Non-modal panel on Base UI Popover: `Root` (`open`, `defaultOpen`, `onOpenChange`, `modal` default false), `Trigger` (secondary Button, or `render={<IconButton label dot />}`), `Content` (`side`, `align`, `sideOffset`, `arrow`; Menu's surface, `--sc-z-dropdown
|
|
56
|
+
| `Popover` | Non-modal panel on Base UI Popover: `Root` (`open`, `defaultOpen`, `onOpenChange`, `modal` default false), `Trigger` (secondary Button, or `render={<IconButton label dot />}`), `Content` (`side`, `align`, `sideOffset`, `arrow`, `anchor` to position against another element than the Trigger, e.g. a row's action button with a controlled `Root`; portaled to `document.body`; Menu's surface, `--sc-z-dropdown`, dropping to the backdrop layer while a Dialog opened from inside it is open, so the Dialog covers it), `Title` (names the dialog), `Description`, `Close` (the × with no children, or wraps a Button). Esc and focus return come from Base UI. |
|
|
57
57
|
| `BroomIcon` | Animated 24px-grid icon for "a sweep is running": `sweeping`, `size` (Icon sizes, default `lg`, or `display` 72px with a 1.75px stroke), `title`. Inline SVG; strokes stay 1.25px at any size; holds still with the dust shown under `prefers-reduced-motion`. Inside an IconButton it takes the next icon size up. |
|
|
58
58
|
| `Score` | A number on a tinted tile or in a ring: required `value` (a number, or `null` for not scored yet: a muted dash on the neutral tile or in an empty ring, no tone, no arc, read as "Fit score: not scored"), `max` (100), `tone` neutral · accent (default) · success · warning · danger (no thresholds inside: map value to tone in the app), `variant` tile · ring (64px, decorative SVG, arc animates only on change, none under reduced motion), `size` sm 40 · md 48 (tile), `caption`, `label` ("Fit score"), `valueText`, `selected`. Assistive tech reads one visually hidden sentence, "Fit score 94 out of 100"; the visible number is `aria-hidden`, no `aria-label`. A tile turns solid when `selected` or inside `.sc-card[data-selected]`, `[aria-pressed="true"]` or `[aria-selected="true"]`. |
|
|
59
59
|
| `ReasonList` | `ReasonList` (`ul`) + `ReasonList.Item` (`li`): required `tone` for (filled square) · against (bar) · gap (hollow circle), so the marker shape carries the meaning as well as the colour; `size` sm · md; `divider` (dashed rule above). Name it with a heading via `aria-labelledby`; `<strong>` inside picks out key words. |
|
package/dist/index.d.ts
CHANGED
|
@@ -738,13 +738,21 @@ interface DialogContentProps extends Omit<Dialog$1.Popup.Props, 'className'> {
|
|
|
738
738
|
* the Root when leaving needs a confirmation.
|
|
739
739
|
*/
|
|
740
740
|
variant?: DialogVariant | undefined;
|
|
741
|
+
/**
|
|
742
|
+
* `sheet` only. Below 640px a downward drag on the handle or the header (the top 64px, outside controls
|
|
743
|
+
* and `Dialog.Body`) moves the sheet; letting go past 30% of its height, or flicking down, closes it the
|
|
744
|
+
* way a press on the handle does (the handle is a `Dialog.Close` named "Dismiss"). Set `false` where an
|
|
745
|
+
* accidental close loses work; the handle then stays as decoration only. Off whenever the Root is not
|
|
746
|
+
* `dismissible`. Default `true`.
|
|
747
|
+
*/
|
|
748
|
+
dismissOnSwipe?: boolean | undefined;
|
|
741
749
|
className?: string | undefined;
|
|
742
750
|
}
|
|
743
751
|
/**
|
|
744
752
|
* Portal, backdrop and the popup. Focus moves inside on open and returns to the trigger on close.
|
|
745
753
|
* Menus, selects and tooltips opened from inside render above it (`--sc-z-dropdown` > `--sc-z-dialog`).
|
|
746
754
|
*/
|
|
747
|
-
declare function Content$2({ size, variant, className, children, ...rest }: DialogContentProps): react.JSX.Element;
|
|
755
|
+
declare function Content$2({ size, variant, dismissOnSwipe, className, children, ...rest }: DialogContentProps): react.JSX.Element;
|
|
748
756
|
interface DialogTitleProps extends Omit<Dialog$1.Title.Props, 'className'> {
|
|
749
757
|
className?: string | undefined;
|
|
750
758
|
}
|
|
@@ -2729,10 +2737,16 @@ interface PopoverContentProps extends Omit<Popover$1.Popup.Props, 'className'> {
|
|
|
2729
2737
|
sideOffset?: number | undefined;
|
|
2730
2738
|
/** Draws a tip pointing at the trigger. */
|
|
2731
2739
|
arrow?: boolean | undefined;
|
|
2740
|
+
/**
|
|
2741
|
+
* What to position against instead of the `Popover.Trigger`: an element, a ref to one, a virtual element or a
|
|
2742
|
+
* function returning either. For a popover opened from elsewhere (a menu item, a row action) with a controlled
|
|
2743
|
+
* `Popover.Root open`. The panel is still portaled to `document.body`.
|
|
2744
|
+
*/
|
|
2745
|
+
anchor?: Popover$1.Positioner.Props['anchor'];
|
|
2732
2746
|
className?: string | undefined;
|
|
2733
2747
|
}
|
|
2734
2748
|
/** Portal, positioner and the panel. Any content goes inside; name it with `Popover.Title`. */
|
|
2735
|
-
declare function Content({ side, align, sideOffset, arrow, className, children, ...rest }: PopoverContentProps): react.JSX.Element;
|
|
2749
|
+
declare function Content({ side, align, sideOffset, arrow, anchor, className, children, ...rest }: PopoverContentProps): react.JSX.Element;
|
|
2736
2750
|
interface PopoverTitleProps extends Omit<Popover$1.Title.Props, 'className'> {
|
|
2737
2751
|
className?: string | undefined;
|
|
2738
2752
|
}
|
package/dist/index.js
CHANGED
|
@@ -167,6 +167,141 @@ var Kbd = Object.assign(KbdBase, { Group: KbdGroup });
|
|
|
167
167
|
|
|
168
168
|
// src/components/Dialog/Dialog.tsx
|
|
169
169
|
import { Dialog as BaseDialog } from "@base-ui/react/dialog";
|
|
170
|
+
import { createContext, useCallback, useContext } from "react";
|
|
171
|
+
|
|
172
|
+
// src/components/Dialog/sheetSwipe.ts
|
|
173
|
+
var SHEET_SWIPE = {
|
|
174
|
+
/** Height in px, from the sheet's top edge, where a drag may start: the handle and the header. */
|
|
175
|
+
zone: 64,
|
|
176
|
+
/** Movement in px before a press becomes a drag, so taps stay taps. */
|
|
177
|
+
slop: 6,
|
|
178
|
+
/** Fraction of the sheet's height past which a release dismisses. */
|
|
179
|
+
distance: 0.3,
|
|
180
|
+
/** Release speed in px/ms: this fast downward dismisses at any distance, this fast upward keeps it open. */
|
|
181
|
+
velocity: 0.5,
|
|
182
|
+
/** Only samples this recent (ms) before the release count toward its speed. */
|
|
183
|
+
window: 100
|
|
184
|
+
};
|
|
185
|
+
function dragIntent(dx, dy, slop = SHEET_SWIPE.slop) {
|
|
186
|
+
if (Math.abs(dx) < slop && Math.abs(dy) < slop) return "pending";
|
|
187
|
+
return dy > 0 && dy >= Math.abs(dx) ? "drag" : "cancel";
|
|
188
|
+
}
|
|
189
|
+
function releaseVelocity(samples, window2 = SHEET_SWIPE.window) {
|
|
190
|
+
const last = samples[samples.length - 1];
|
|
191
|
+
if (!last) return 0;
|
|
192
|
+
const first = samples.find((s) => last.t - s.t <= window2) ?? last;
|
|
193
|
+
const dt = last.t - first.t;
|
|
194
|
+
return dt > 0 ? (last.y - first.y) / dt : 0;
|
|
195
|
+
}
|
|
196
|
+
function shouldDismissSheet({ offset, height, velocity }) {
|
|
197
|
+
if (offset <= 0 || height <= 0) return false;
|
|
198
|
+
if (velocity >= SHEET_SWIPE.velocity) return true;
|
|
199
|
+
if (velocity <= -SHEET_SWIPE.velocity) return false;
|
|
200
|
+
return offset >= height * SHEET_SWIPE.distance;
|
|
201
|
+
}
|
|
202
|
+
var IGNORE = 'a,button,input,select,textarea,label,[role="button"],[contenteditable]';
|
|
203
|
+
function attachSheetSwipe(handle) {
|
|
204
|
+
const popup = handle.parentElement;
|
|
205
|
+
if (!popup) return () => {
|
|
206
|
+
};
|
|
207
|
+
let press = null;
|
|
208
|
+
let dragging = false;
|
|
209
|
+
let height = 0;
|
|
210
|
+
let samples = [];
|
|
211
|
+
let suppressClick = false;
|
|
212
|
+
const startsDrag = (e) => {
|
|
213
|
+
if (!e.isPrimary || e.pointerType === "mouse" && e.button !== 0) return false;
|
|
214
|
+
if (handle.getClientRects().length === 0) return false;
|
|
215
|
+
const target = e.target instanceof Element ? e.target : null;
|
|
216
|
+
if (!target || handle.contains(target)) return true;
|
|
217
|
+
if (target.closest(IGNORE) || target.closest(".sc-dialog__body")) return false;
|
|
218
|
+
return e.clientY - popup.getBoundingClientRect().top <= SHEET_SWIPE.zone;
|
|
219
|
+
};
|
|
220
|
+
const settle = () => {
|
|
221
|
+
delete popup.dataset.swiping;
|
|
222
|
+
popup.style.removeProperty("transform");
|
|
223
|
+
};
|
|
224
|
+
const onDown = (e) => {
|
|
225
|
+
if (press || !startsDrag(e)) return;
|
|
226
|
+
press = { id: e.pointerId, x: e.clientX, y: e.clientY };
|
|
227
|
+
samples = [{ t: e.timeStamp, y: e.clientY }];
|
|
228
|
+
};
|
|
229
|
+
const onMove = (e) => {
|
|
230
|
+
if (!press || e.pointerId !== press.id) return;
|
|
231
|
+
const dy = e.clientY - press.y;
|
|
232
|
+
if (!dragging) {
|
|
233
|
+
const intent = dragIntent(e.clientX - press.x, dy);
|
|
234
|
+
if (intent === "pending") return;
|
|
235
|
+
if (intent === "cancel") {
|
|
236
|
+
press = null;
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
dragging = true;
|
|
240
|
+
height = popup.getBoundingClientRect().height;
|
|
241
|
+
popup.dataset.swiping = "";
|
|
242
|
+
popup.setPointerCapture?.(e.pointerId);
|
|
243
|
+
window.getSelection()?.removeAllRanges();
|
|
244
|
+
}
|
|
245
|
+
e.preventDefault();
|
|
246
|
+
samples.push({ t: e.timeStamp, y: e.clientY });
|
|
247
|
+
if (samples.length > 32) samples = samples.slice(-16);
|
|
248
|
+
popup.style.transform = `translateY(${Math.max(0, dy)}px)`;
|
|
249
|
+
};
|
|
250
|
+
const end = (e, cancelled) => {
|
|
251
|
+
if (!press || e.pointerId !== press.id) return;
|
|
252
|
+
const startY = press.y;
|
|
253
|
+
const wasDragging = dragging;
|
|
254
|
+
press = null;
|
|
255
|
+
dragging = false;
|
|
256
|
+
if (!wasDragging) return;
|
|
257
|
+
window.setTimeout(() => {
|
|
258
|
+
suppressClick = false;
|
|
259
|
+
}, 0);
|
|
260
|
+
if (cancelled) {
|
|
261
|
+
suppressClick = true;
|
|
262
|
+
settle();
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
samples.push({ t: e.timeStamp, y: e.clientY });
|
|
266
|
+
const release = {
|
|
267
|
+
offset: Math.max(0, e.clientY - startY),
|
|
268
|
+
height,
|
|
269
|
+
velocity: releaseVelocity(samples)
|
|
270
|
+
};
|
|
271
|
+
if (shouldDismissSheet(release)) {
|
|
272
|
+
delete popup.dataset.swiping;
|
|
273
|
+
handle.click();
|
|
274
|
+
suppressClick = true;
|
|
275
|
+
window.requestAnimationFrame(() => {
|
|
276
|
+
if (popup.isConnected && popup.hasAttribute("data-open")) settle();
|
|
277
|
+
});
|
|
278
|
+
} else {
|
|
279
|
+
suppressClick = true;
|
|
280
|
+
settle();
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
const onUp = (e) => end(e, false);
|
|
284
|
+
const onCancel = (e) => end(e, true);
|
|
285
|
+
const onClick = (e) => {
|
|
286
|
+
if (!suppressClick) return;
|
|
287
|
+
suppressClick = false;
|
|
288
|
+
e.preventDefault();
|
|
289
|
+
e.stopPropagation();
|
|
290
|
+
};
|
|
291
|
+
popup.addEventListener("pointerdown", onDown);
|
|
292
|
+
popup.addEventListener("pointermove", onMove);
|
|
293
|
+
popup.addEventListener("pointerup", onUp);
|
|
294
|
+
popup.addEventListener("pointercancel", onCancel);
|
|
295
|
+
popup.addEventListener("click", onClick, true);
|
|
296
|
+
return () => {
|
|
297
|
+
popup.removeEventListener("pointerdown", onDown);
|
|
298
|
+
popup.removeEventListener("pointermove", onMove);
|
|
299
|
+
popup.removeEventListener("pointerup", onUp);
|
|
300
|
+
popup.removeEventListener("pointercancel", onCancel);
|
|
301
|
+
popup.removeEventListener("click", onClick, true);
|
|
302
|
+
settle();
|
|
303
|
+
};
|
|
304
|
+
}
|
|
170
305
|
|
|
171
306
|
// src/components/Icon/Icon.tsx
|
|
172
307
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
@@ -447,6 +582,7 @@ var REQUESTABLE = /* @__PURE__ */ new Set([
|
|
|
447
582
|
"outside-press",
|
|
448
583
|
"close-press"
|
|
449
584
|
]);
|
|
585
|
+
var DismissibleContext = createContext(true);
|
|
450
586
|
function Root({
|
|
451
587
|
dismissible = true,
|
|
452
588
|
onOpenChange,
|
|
@@ -473,27 +609,49 @@ function Root({
|
|
|
473
609
|
}
|
|
474
610
|
onOpenChange?.(next);
|
|
475
611
|
},
|
|
476
|
-
children
|
|
612
|
+
children: /* @__PURE__ */ jsx6(DismissibleContext.Provider, { value: dismissible, children })
|
|
477
613
|
}
|
|
478
614
|
);
|
|
479
615
|
}
|
|
480
616
|
var Trigger = BaseDialog.Trigger;
|
|
481
|
-
function Content({
|
|
617
|
+
function Content({
|
|
618
|
+
size = "md",
|
|
619
|
+
variant = "dialog",
|
|
620
|
+
dismissOnSwipe = true,
|
|
621
|
+
className,
|
|
622
|
+
children,
|
|
623
|
+
...rest
|
|
624
|
+
}) {
|
|
625
|
+
const dismissible = useContext(DismissibleContext);
|
|
626
|
+
const isSheet = variant === "sheet";
|
|
627
|
+
const swipe = isSheet && dismissOnSwipe && dismissible;
|
|
482
628
|
return /* @__PURE__ */ jsxs5(BaseDialog.Portal, { children: [
|
|
483
629
|
/* @__PURE__ */ jsx6(BaseDialog.Backdrop, { className: "sc-dialog__backdrop" }),
|
|
484
|
-
/* @__PURE__ */
|
|
630
|
+
/* @__PURE__ */ jsxs5(
|
|
485
631
|
BaseDialog.Popup,
|
|
486
632
|
{
|
|
487
633
|
className: cx("sc-dialog__popup", className),
|
|
488
634
|
"data-size": size,
|
|
489
635
|
"data-variant": variant,
|
|
636
|
+
"data-swipe-dismiss": swipe ? "" : void 0,
|
|
490
637
|
"aria-modal": "true",
|
|
491
638
|
...rest,
|
|
492
|
-
children
|
|
639
|
+
children: [
|
|
640
|
+
isSheet && /* @__PURE__ */ jsx6(SheetHandle, { swipe }),
|
|
641
|
+
children
|
|
642
|
+
]
|
|
493
643
|
}
|
|
494
644
|
)
|
|
495
645
|
] });
|
|
496
646
|
}
|
|
647
|
+
function SheetHandle({ swipe }) {
|
|
648
|
+
const attach = useCallback(
|
|
649
|
+
(node) => node ? attachSheetSwipe(node) : void 0,
|
|
650
|
+
[]
|
|
651
|
+
);
|
|
652
|
+
if (!swipe) return /* @__PURE__ */ jsx6("div", { className: "sc-dialog__handle", "aria-hidden": "true" });
|
|
653
|
+
return /* @__PURE__ */ jsx6(BaseDialog.Close, { ref: attach, className: "sc-dialog__handle", "aria-label": "Dismiss" });
|
|
654
|
+
}
|
|
497
655
|
function Title({ className, ...rest }) {
|
|
498
656
|
return /* @__PURE__ */ jsx6(BaseDialog.Title, { className: cx("sc-dialog__title", className), ...rest });
|
|
499
657
|
}
|
|
@@ -1402,14 +1560,14 @@ function Text({
|
|
|
1402
1560
|
// src/components/Table/Table.tsx
|
|
1403
1561
|
import { Checkbox as BaseCheckbox2 } from "@base-ui/react/checkbox";
|
|
1404
1562
|
import {
|
|
1405
|
-
createContext,
|
|
1406
|
-
useContext
|
|
1563
|
+
createContext as createContext2,
|
|
1564
|
+
useContext as useContext2
|
|
1407
1565
|
} from "react";
|
|
1408
1566
|
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1409
|
-
var SelectionContext =
|
|
1410
|
-
var RowIdContext =
|
|
1567
|
+
var SelectionContext = createContext2(null);
|
|
1568
|
+
var RowIdContext = createContext2(void 0);
|
|
1411
1569
|
function useSelection(part) {
|
|
1412
|
-
const selection =
|
|
1570
|
+
const selection = useContext2(SelectionContext);
|
|
1413
1571
|
if (!selection) throw new Error(`${part} needs Table.Root selection={useRowSelection(ids)}`);
|
|
1414
1572
|
return selection;
|
|
1415
1573
|
}
|
|
@@ -1498,7 +1656,7 @@ function Row({
|
|
|
1498
1656
|
onMouseDown,
|
|
1499
1657
|
...rest
|
|
1500
1658
|
}) {
|
|
1501
|
-
const selection =
|
|
1659
|
+
const selection = useContext2(SelectionContext);
|
|
1502
1660
|
const selectable = selection !== null && selectionId !== void 0;
|
|
1503
1661
|
const isSelected = selected ?? (selectable && selection.isSelected(selectionId));
|
|
1504
1662
|
const row = /* @__PURE__ */ jsx21(
|
|
@@ -1571,7 +1729,7 @@ function SelectionHeader({
|
|
|
1571
1729
|
}
|
|
1572
1730
|
function SelectionCell({ label, className, onClick, onClickCapture, ...rest }) {
|
|
1573
1731
|
const selection = useSelection("Table.SelectionCell");
|
|
1574
|
-
const id =
|
|
1732
|
+
const id = useContext2(RowIdContext);
|
|
1575
1733
|
if (id === void 0) throw new Error("Table.SelectionCell goes inside a Table.Row with selectionId");
|
|
1576
1734
|
return /* @__PURE__ */ jsx21(
|
|
1577
1735
|
"td",
|
|
@@ -2255,9 +2413,9 @@ function fileTypeLabel(file) {
|
|
|
2255
2413
|
}
|
|
2256
2414
|
|
|
2257
2415
|
// src/utils/useMediaQuery.ts
|
|
2258
|
-
import { useCallback, useSyncExternalStore } from "react";
|
|
2416
|
+
import { useCallback as useCallback2, useSyncExternalStore } from "react";
|
|
2259
2417
|
function useMediaQuery(query) {
|
|
2260
|
-
const subscribe =
|
|
2418
|
+
const subscribe = useCallback2(
|
|
2261
2419
|
(onChange) => {
|
|
2262
2420
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {
|
|
2263
2421
|
};
|
|
@@ -3111,6 +3269,7 @@ function Content3({
|
|
|
3111
3269
|
align = "center",
|
|
3112
3270
|
sideOffset,
|
|
3113
3271
|
arrow = false,
|
|
3272
|
+
anchor,
|
|
3114
3273
|
className,
|
|
3115
3274
|
children,
|
|
3116
3275
|
...rest
|
|
@@ -3121,6 +3280,7 @@ function Content3({
|
|
|
3121
3280
|
side,
|
|
3122
3281
|
align,
|
|
3123
3282
|
sideOffset: sideOffset ?? (arrow ? 8 : 4),
|
|
3283
|
+
anchor,
|
|
3124
3284
|
className: "sc-popover__positioner",
|
|
3125
3285
|
children: /* @__PURE__ */ jsxs27(BasePopover.Popup, { className: cx("sc-popover", className), ...rest, children: [
|
|
3126
3286
|
arrow ? /* @__PURE__ */ jsx32(BasePopover.Arrow, { className: "sc-popover__arrow" }) : null,
|
|
@@ -3190,9 +3350,9 @@ function BroomIcon({ sweeping = false, size = "lg", title, className, ...rest })
|
|
|
3190
3350
|
// src/components/FullScreenFlow/FullScreenFlow.tsx
|
|
3191
3351
|
import {
|
|
3192
3352
|
Children as Children2,
|
|
3193
|
-
createContext as
|
|
3194
|
-
useCallback as
|
|
3195
|
-
useContext as
|
|
3353
|
+
createContext as createContext3,
|
|
3354
|
+
useCallback as useCallback3,
|
|
3355
|
+
useContext as useContext3,
|
|
3196
3356
|
useEffect as useEffect6,
|
|
3197
3357
|
useId as useId5,
|
|
3198
3358
|
useMemo as useMemo3,
|
|
@@ -3200,9 +3360,9 @@ import {
|
|
|
3200
3360
|
useState as useState8
|
|
3201
3361
|
} from "react";
|
|
3202
3362
|
import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
3203
|
-
var FlowContext =
|
|
3363
|
+
var FlowContext = createContext3({ announce: () => {
|
|
3204
3364
|
} });
|
|
3205
|
-
var FrameContext =
|
|
3365
|
+
var FrameContext = createContext3(void 0);
|
|
3206
3366
|
var ENTER_IGNORES = 'textarea, button, a[href], summary, select, [contenteditable], [role="combobox"], [data-flow-keys="local"]';
|
|
3207
3367
|
var ARROW_IGNORES = 'input, textarea, select, button, a[href], summary, [contenteditable], [role="radiogroup"], [role="slider"], [role="listbox"], [role="tablist"], [role="menu"], [role="grid"], [role="combobox"], [data-flow-keys="local"]';
|
|
3208
3368
|
function Root7({
|
|
@@ -3217,7 +3377,7 @@ function Root7({
|
|
|
3217
3377
|
const popupRef = useRef6(null);
|
|
3218
3378
|
const [message, setMessage] = useState8("");
|
|
3219
3379
|
const timer = useRef6(void 0);
|
|
3220
|
-
const announce =
|
|
3380
|
+
const announce = useCallback3((next) => {
|
|
3221
3381
|
setMessage("");
|
|
3222
3382
|
clearTimeout(timer.current);
|
|
3223
3383
|
timer.current = setTimeout(() => setMessage(next), 30);
|
|
@@ -3403,7 +3563,7 @@ function Viewport2({ direction = "forward", className, children, ...rest }) {
|
|
|
3403
3563
|
} else if (state.current.element !== element) {
|
|
3404
3564
|
setState((s) => ({ ...s, current: { ...s.current, element } }));
|
|
3405
3565
|
}
|
|
3406
|
-
const finishExit =
|
|
3566
|
+
const finishExit = useCallback3((leftKey) => {
|
|
3407
3567
|
setState((s) => s.leaving?.key === leftKey ? { ...s, leaving: null } : s);
|
|
3408
3568
|
}, []);
|
|
3409
3569
|
const ref = useRef6(null);
|
|
@@ -3472,8 +3632,8 @@ function Step({
|
|
|
3472
3632
|
}) {
|
|
3473
3633
|
const id = useId5();
|
|
3474
3634
|
const titleRef = useRef6(null);
|
|
3475
|
-
const phase =
|
|
3476
|
-
const { announce } =
|
|
3635
|
+
const phase = useContext3(FrameContext);
|
|
3636
|
+
const { announce } = useContext3(FlowContext);
|
|
3477
3637
|
const message = announcement ?? (typeof title === "string" ? title : void 0);
|
|
3478
3638
|
const latest = useRef6({ message, announce });
|
|
3479
3639
|
useEffect6(() => {
|