@aortl/admin-react 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Button.d.ts +9 -1
- package/dist/Button.d.ts.map +1 -1
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Indicator.d.ts +32 -0
- package/dist/Indicator.d.ts.map +1 -0
- package/dist/Kbd.d.ts +25 -0
- package/dist/Kbd.d.ts.map +1 -0
- package/dist/Menu.d.ts +10 -2
- package/dist/Menu.d.ts.map +1 -1
- package/dist/PropertyList.d.ts +1 -4
- package/dist/PropertyList.d.ts.map +1 -1
- package/dist/Select.d.ts.map +1 -1
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/admin.scoped.css +209 -42
- package/dist/hotkey-parse.d.ts +34 -0
- package/dist/hotkey-parse.d.ts.map +1 -0
- package/dist/hotkey-registry.d.ts +25 -0
- package/dist/hotkey-registry.d.ts.map +1 -0
- package/dist/icon.d.ts +6 -4
- package/dist/icon.d.ts.map +1 -1
- package/dist/index.cjs +356 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +354 -35
- package/dist/index.mjs.map +1 -1
- package/dist/portal-context.d.ts +10 -0
- package/dist/portal-context.d.ts.map +1 -0
- package/dist/useHotkey.d.ts +34 -0
- package/dist/useHotkey.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/icon.d.ts
CHANGED
|
@@ -10,17 +10,19 @@ export interface IconRenderProps {
|
|
|
10
10
|
export type IconComponent = ComponentType<IconRenderProps>;
|
|
11
11
|
/**
|
|
12
12
|
* The value a component prop named `icon` will accept. Either:
|
|
13
|
-
* - a component reference (`icon={IconHome}`) — rendered with `size=
|
|
13
|
+
* - a component reference (`icon={IconHome}`) — rendered with `size="1em" aria-hidden`,
|
|
14
14
|
* - or an already-instantiated React element (`icon={<IconHome size={20} />}`) — rendered as-is.
|
|
15
15
|
*/
|
|
16
16
|
export type IconProp = IconComponent | ReactElement | null | undefined;
|
|
17
17
|
/**
|
|
18
|
-
* Render an `IconProp` to a React node, defaulting to `size=
|
|
19
|
-
* when given a component reference.
|
|
18
|
+
* Render an `IconProp` to a React node, defaulting to `size="1em" aria-hidden`
|
|
19
|
+
* when given a component reference. The `"1em"` default makes SVG icons inherit
|
|
20
|
+
* the host's `font-size`, matching how the Tabler webfont (`<i class="ti …">`)
|
|
21
|
+
* renders in the vanilla bundle — so both previews end up the same size.
|
|
20
22
|
*
|
|
21
23
|
* Anything that is not `null`/`undefined` and not already a React element is
|
|
22
24
|
* treated as a component type — `createElement` accepts function components,
|
|
23
25
|
* `forwardRef`s (e.g. `@tabler/icons-react`), `memo`, etc.
|
|
24
26
|
*/
|
|
25
|
-
export declare function renderIcon(icon: IconProp, size?: number): ReactNode;
|
|
27
|
+
export declare function renderIcon(icon: IconProp, size?: number | string): ReactNode;
|
|
26
28
|
//# sourceMappingURL=icon.d.ts.map
|
package/dist/icon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../src/icon.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;CAC5C;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC;AAEvE
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../src/icon.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;CAC5C;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC;AAEvE;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAE,MAAM,GAAG,MAAc,GAAG,SAAS,CAInF"}
|
package/dist/index.cjs
CHANGED
|
@@ -81,14 +81,16 @@ function AdminRoot({ className, theme, systemAccent, style, ...rest }) {
|
|
|
81
81
|
//#endregion
|
|
82
82
|
//#region src/icon.ts
|
|
83
83
|
/**
|
|
84
|
-
* Render an `IconProp` to a React node, defaulting to `size=
|
|
85
|
-
* when given a component reference.
|
|
84
|
+
* Render an `IconProp` to a React node, defaulting to `size="1em" aria-hidden`
|
|
85
|
+
* when given a component reference. The `"1em"` default makes SVG icons inherit
|
|
86
|
+
* the host's `font-size`, matching how the Tabler webfont (`<i class="ti …">`)
|
|
87
|
+
* renders in the vanilla bundle — so both previews end up the same size.
|
|
86
88
|
*
|
|
87
89
|
* Anything that is not `null`/`undefined` and not already a React element is
|
|
88
90
|
* treated as a component type — `createElement` accepts function components,
|
|
89
91
|
* `forwardRef`s (e.g. `@tabler/icons-react`), `memo`, etc.
|
|
90
92
|
*/
|
|
91
|
-
function renderIcon(icon, size =
|
|
93
|
+
function renderIcon(icon, size = "1em") {
|
|
92
94
|
if (icon == null) return null;
|
|
93
95
|
if ((0, react.isValidElement)(icon)) return icon;
|
|
94
96
|
return (0, react.createElement)(icon, {
|
|
@@ -199,13 +201,261 @@ function BrandTile({ monogram, icon, className, children, ...rest }) {
|
|
|
199
201
|
});
|
|
200
202
|
}
|
|
201
203
|
//#endregion
|
|
204
|
+
//#region src/hotkey-parse.ts
|
|
205
|
+
var MOD_ORDER = [
|
|
206
|
+
"ctrl",
|
|
207
|
+
"shift",
|
|
208
|
+
"alt",
|
|
209
|
+
"meta"
|
|
210
|
+
];
|
|
211
|
+
function tokenToMod(token) {
|
|
212
|
+
switch (token) {
|
|
213
|
+
case "mod":
|
|
214
|
+
case "ctrl":
|
|
215
|
+
case "control": return "ctrl";
|
|
216
|
+
case "shift": return "shift";
|
|
217
|
+
case "alt": return "alt";
|
|
218
|
+
case "meta": return "meta";
|
|
219
|
+
default: return null;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function parseChord(input) {
|
|
223
|
+
const tokens = input.trim().toLowerCase().split("+").map((t) => t.trim()).filter(Boolean);
|
|
224
|
+
if (tokens.length === 0) throw new Error(`Invalid hotkey: empty string`);
|
|
225
|
+
const mods = /* @__PURE__ */ new Set();
|
|
226
|
+
let key = null;
|
|
227
|
+
for (const token of tokens) {
|
|
228
|
+
const mod = tokenToMod(token);
|
|
229
|
+
if (mod !== null) {
|
|
230
|
+
mods.add(mod);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (key !== null) throw new Error(`Invalid hotkey "${input}": multiple non-modifier keys`);
|
|
234
|
+
key = token;
|
|
235
|
+
}
|
|
236
|
+
if (key === null) throw new Error(`Invalid hotkey "${input}": missing key`);
|
|
237
|
+
return {
|
|
238
|
+
mods,
|
|
239
|
+
key
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function parseKeys(keys) {
|
|
243
|
+
return (typeof keys === "string" ? [keys] : keys).map(parseChord);
|
|
244
|
+
}
|
|
245
|
+
/** Canonical wire form used as a map key in the registry. */
|
|
246
|
+
function canonicalize(chord) {
|
|
247
|
+
const parts = [];
|
|
248
|
+
for (const mod of MOD_ORDER) if (chord.mods.has(mod)) parts.push(mod);
|
|
249
|
+
parts.push(chord.key);
|
|
250
|
+
return parts.join("+");
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Normalize a keyboard event to its canonical chord string. Returns `null`
|
|
254
|
+
* if the event is a bare modifier press (`Shift` by itself, etc.) so callers
|
|
255
|
+
* can short-circuit before a map lookup.
|
|
256
|
+
*/
|
|
257
|
+
function normalizeEvent(e) {
|
|
258
|
+
const key = e.key.toLowerCase();
|
|
259
|
+
if (key === "control" || key === "shift" || key === "alt" || key === "meta") return null;
|
|
260
|
+
const mods = /* @__PURE__ */ new Set();
|
|
261
|
+
if (e.ctrlKey) mods.add("ctrl");
|
|
262
|
+
if (e.shiftKey) mods.add("shift");
|
|
263
|
+
if (e.altKey) mods.add("alt");
|
|
264
|
+
if (e.metaKey) mods.add("meta");
|
|
265
|
+
return canonicalize({
|
|
266
|
+
mods,
|
|
267
|
+
key
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
var SPECIAL_KEY_LABELS = {
|
|
271
|
+
escape: "Esc",
|
|
272
|
+
esc: "Esc",
|
|
273
|
+
enter: "Enter",
|
|
274
|
+
return: "Enter",
|
|
275
|
+
tab: "Tab",
|
|
276
|
+
" ": "Space",
|
|
277
|
+
space: "Space",
|
|
278
|
+
arrowup: "↑",
|
|
279
|
+
arrowdown: "↓",
|
|
280
|
+
arrowleft: "←",
|
|
281
|
+
arrowright: "→",
|
|
282
|
+
backspace: "Backspace",
|
|
283
|
+
delete: "Del"
|
|
284
|
+
};
|
|
285
|
+
var MOD_LABELS = {
|
|
286
|
+
ctrl: "Ctrl",
|
|
287
|
+
shift: "Shift",
|
|
288
|
+
alt: "Alt",
|
|
289
|
+
meta: "Meta"
|
|
290
|
+
};
|
|
291
|
+
/** Visual chips for a chord — one entry per modifier and the final key. */
|
|
292
|
+
function formatChord(chord) {
|
|
293
|
+
const parts = [];
|
|
294
|
+
for (const mod of MOD_ORDER) if (chord.mods.has(mod)) parts.push(MOD_LABELS[mod]);
|
|
295
|
+
const special = SPECIAL_KEY_LABELS[chord.key];
|
|
296
|
+
if (special !== void 0) parts.push(special);
|
|
297
|
+
else if (chord.key.length === 1) parts.push(chord.key.toUpperCase());
|
|
298
|
+
else parts.push(chord.key.charAt(0).toUpperCase() + chord.key.slice(1));
|
|
299
|
+
return parts;
|
|
300
|
+
}
|
|
301
|
+
var ARIA_MOD_LABELS = {
|
|
302
|
+
ctrl: "Control",
|
|
303
|
+
shift: "Shift",
|
|
304
|
+
alt: "Alt",
|
|
305
|
+
meta: "Meta"
|
|
306
|
+
};
|
|
307
|
+
function toAriaPart(chord) {
|
|
308
|
+
const parts = [];
|
|
309
|
+
for (const mod of MOD_ORDER) if (chord.mods.has(mod)) parts.push(ARIA_MOD_LABELS[mod]);
|
|
310
|
+
parts.push(chord.key.length === 1 ? chord.key.toUpperCase() : chord.key);
|
|
311
|
+
return parts.join("+");
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Serialize one or more chords to the `aria-keyshortcuts` format
|
|
315
|
+
* (space-separated alternatives, modifiers as `Control`/`Shift`/etc.).
|
|
316
|
+
*/
|
|
317
|
+
function toAriaKeyShortcuts(chords) {
|
|
318
|
+
return chords.map(toAriaPart).join(" ");
|
|
319
|
+
}
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/Kbd.tsx
|
|
322
|
+
/**
|
|
323
|
+
* Visual representation of a keyboard shortcut. Two shapes:
|
|
324
|
+
*
|
|
325
|
+
* ```tsx
|
|
326
|
+
* <Kbd keys="mod+s" /> // parsed: <Ctrl><S> in a .kbd-group
|
|
327
|
+
* <Kbd>Esc</Kbd> // literal: single <kbd>Esc</kbd>
|
|
328
|
+
* ```
|
|
329
|
+
*
|
|
330
|
+
* Render outside of action surfaces (tooltips, help dialogs) or inside them
|
|
331
|
+
* via the `hotkey` prop on `<Button>` / `<Menu.Item>`.
|
|
332
|
+
*/
|
|
333
|
+
function Kbd({ keys, children, className, ...rest }) {
|
|
334
|
+
if (keys != null) {
|
|
335
|
+
const chord = parseKeys(keys)[0];
|
|
336
|
+
if (!chord) return null;
|
|
337
|
+
const parts = formatChord(chord);
|
|
338
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
339
|
+
className: cn("kbd-group", className),
|
|
340
|
+
...rest,
|
|
341
|
+
children: parts.map((part, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("kbd", {
|
|
342
|
+
className: cn("kbd", void 0),
|
|
343
|
+
children: part
|
|
344
|
+
}, `${i}-${part}`))
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("kbd", {
|
|
348
|
+
className: cn("kbd", className),
|
|
349
|
+
...rest,
|
|
350
|
+
children
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region src/hotkey-registry.ts
|
|
355
|
+
var registry = /* @__PURE__ */ new Map();
|
|
356
|
+
var listenerAttached = false;
|
|
357
|
+
function ensureListener() {
|
|
358
|
+
if (listenerAttached || typeof window === "undefined") return;
|
|
359
|
+
window.addEventListener("keydown", dispatch);
|
|
360
|
+
listenerAttached = true;
|
|
361
|
+
}
|
|
362
|
+
function maybeDetachListener() {
|
|
363
|
+
if (!listenerAttached || typeof window === "undefined") return;
|
|
364
|
+
if (registry.size > 0) return;
|
|
365
|
+
window.removeEventListener("keydown", dispatch);
|
|
366
|
+
listenerAttached = false;
|
|
367
|
+
}
|
|
368
|
+
function isEditableTarget(target) {
|
|
369
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
370
|
+
if (target.isContentEditable) return true;
|
|
371
|
+
const tag = target.tagName;
|
|
372
|
+
return tag === "INPUT" || tag === "TEXTAREA";
|
|
373
|
+
}
|
|
374
|
+
function dispatch(e) {
|
|
375
|
+
const chord = normalizeEvent(e);
|
|
376
|
+
if (chord === null) return;
|
|
377
|
+
const bucket = registry.get(chord);
|
|
378
|
+
if (!bucket || bucket.size === 0) return;
|
|
379
|
+
if (isEditableTarget(e.target) && !chord.includes("+") && chord !== "escape") return;
|
|
380
|
+
e.preventDefault();
|
|
381
|
+
for (const entry of bucket) entry.handlerRef.current?.(e);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Register a hotkey entry under each of its canonical chord strings.
|
|
385
|
+
* Returns an unregister function that removes the entry from every bucket
|
|
386
|
+
* and detaches the listener if the registry is empty.
|
|
387
|
+
*/
|
|
388
|
+
function register(canonicalChords, entry) {
|
|
389
|
+
for (const chord of canonicalChords) {
|
|
390
|
+
let bucket = registry.get(chord);
|
|
391
|
+
if (!bucket) {
|
|
392
|
+
bucket = /* @__PURE__ */ new Set();
|
|
393
|
+
registry.set(chord, bucket);
|
|
394
|
+
}
|
|
395
|
+
bucket.add(entry);
|
|
396
|
+
}
|
|
397
|
+
ensureListener();
|
|
398
|
+
return () => {
|
|
399
|
+
for (const chord of canonicalChords) {
|
|
400
|
+
const bucket = registry.get(chord);
|
|
401
|
+
if (!bucket) continue;
|
|
402
|
+
bucket.delete(entry);
|
|
403
|
+
if (bucket.size === 0) registry.delete(chord);
|
|
404
|
+
}
|
|
405
|
+
maybeDetachListener();
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/useHotkey.ts
|
|
410
|
+
/**
|
|
411
|
+
* Register a keyboard shortcut. The handler is latched in a ref internally so
|
|
412
|
+
* callers don't need to memoize it. Passing nullish `keys` is a no-op, so
|
|
413
|
+
* the hook is safe to call unconditionally from components that may or may
|
|
414
|
+
* not have a binding (e.g. the `hotkey` prop on `<Button>`).
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* useHotkey("mod+s", save);
|
|
418
|
+
* useHotkey(["mod+s", "mod+enter"], save, { enabled: !isLoading });
|
|
419
|
+
*
|
|
420
|
+
* Returns derived strings for rendering — see {@link HotkeyInfo}.
|
|
421
|
+
*/
|
|
422
|
+
function useHotkey(keys, handler, options) {
|
|
423
|
+
const enabled = options?.enabled ?? true;
|
|
424
|
+
const handlerRef = (0, react.useRef)(handler);
|
|
425
|
+
handlerRef.current = handler;
|
|
426
|
+
const keyId = keys == null ? "" : Array.isArray(keys) ? keys.join("|") : keys;
|
|
427
|
+
const derived = (0, react.useMemo)(() => {
|
|
428
|
+
if (keyId === "") return {
|
|
429
|
+
canonicalChords: [],
|
|
430
|
+
ariaKeyShortcuts: void 0,
|
|
431
|
+
primaryChord: void 0
|
|
432
|
+
};
|
|
433
|
+
const parsed = parseKeys(keys);
|
|
434
|
+
const cans = parsed.map(canonicalize);
|
|
435
|
+
return {
|
|
436
|
+
canonicalChords: cans,
|
|
437
|
+
ariaKeyShortcuts: toAriaKeyShortcuts(parsed),
|
|
438
|
+
primaryChord: cans[0]
|
|
439
|
+
};
|
|
440
|
+
}, [keyId]);
|
|
441
|
+
(0, react.useEffect)(() => {
|
|
442
|
+
if (!enabled || derived.canonicalChords.length === 0) return;
|
|
443
|
+
const entry = { handlerRef };
|
|
444
|
+
return register(derived.canonicalChords, entry);
|
|
445
|
+
}, [derived, enabled]);
|
|
446
|
+
return derived;
|
|
447
|
+
}
|
|
448
|
+
//#endregion
|
|
202
449
|
//#region src/Button.tsx
|
|
203
|
-
function Button({ variant = "primary", size = "md", fullWidth, loading, icon, iconTrailing, className, type = "button", disabled, children, ...rest }) {
|
|
450
|
+
function Button({ variant = "primary", size = "md", fullWidth, loading, icon, iconTrailing, hotkey, className, type = "button", disabled, children, onClick, ...rest }) {
|
|
451
|
+
const { ariaKeyShortcuts, primaryChord } = useHotkey(hotkey, (e) => onClick?.(e), { enabled: !disabled && !loading });
|
|
204
452
|
const iconOnly = children == null && (icon != null || iconTrailing != null);
|
|
205
453
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_base_ui_react_button.Button, {
|
|
454
|
+
onClick,
|
|
206
455
|
type,
|
|
207
456
|
disabled: disabled || loading,
|
|
208
457
|
"aria-busy": loading || void 0,
|
|
458
|
+
"aria-keyshortcuts": ariaKeyShortcuts,
|
|
209
459
|
className: cn([
|
|
210
460
|
"btn",
|
|
211
461
|
`btn-${variant}`,
|
|
@@ -218,7 +468,8 @@ function Button({ variant = "primary", size = "md", fullWidth, loading, icon, ic
|
|
|
218
468
|
children: [
|
|
219
469
|
loading ? null : renderIcon(icon),
|
|
220
470
|
children,
|
|
221
|
-
renderIcon(iconTrailing)
|
|
471
|
+
renderIcon(iconTrailing),
|
|
472
|
+
primaryChord !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Kbd, { keys: primaryChord }) : null
|
|
222
473
|
]
|
|
223
474
|
});
|
|
224
475
|
}
|
|
@@ -315,6 +566,38 @@ function InputGroupAddon({ className, ...rest }) {
|
|
|
315
566
|
}
|
|
316
567
|
var InputGroup = Object.assign(InputGroupRoot, { Addon: InputGroupAddon });
|
|
317
568
|
//#endregion
|
|
569
|
+
//#region src/Indicator.tsx
|
|
570
|
+
function Indicator({ label, variant = "neutral", size = "sm", icon, placement = "top-end", offset, className, "aria-label": ariaLabel, children }) {
|
|
571
|
+
const [vertical, horizontal] = placement.split("-");
|
|
572
|
+
const placementClasses = [
|
|
573
|
+
"indicator-item",
|
|
574
|
+
vertical !== "top" && `indicator-${vertical}`,
|
|
575
|
+
horizontal !== "end" && `indicator-${horizontal}`
|
|
576
|
+
];
|
|
577
|
+
const hasContent = label !== void 0 || icon !== void 0;
|
|
578
|
+
const style = offset !== void 0 ? { "--indicator-offset": `${offset}px` } : void 0;
|
|
579
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
580
|
+
className: cn("indicator", className),
|
|
581
|
+
style,
|
|
582
|
+
children: [hasContent ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
|
|
583
|
+
className: cn(placementClasses, void 0),
|
|
584
|
+
variant,
|
|
585
|
+
size,
|
|
586
|
+
icon,
|
|
587
|
+
"aria-label": ariaLabel,
|
|
588
|
+
children: label
|
|
589
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
590
|
+
className: cn([
|
|
591
|
+
...placementClasses,
|
|
592
|
+
"indicator-dot",
|
|
593
|
+
variant !== "neutral" && `indicator-dot-${variant}`
|
|
594
|
+
], void 0),
|
|
595
|
+
role: ariaLabel !== void 0 ? "status" : void 0,
|
|
596
|
+
"aria-label": ariaLabel
|
|
597
|
+
}), children]
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
//#endregion
|
|
318
601
|
//#region src/Pagination.tsx
|
|
319
602
|
/**
|
|
320
603
|
* Compute the items to render for a given `page` / `total`. Always returns:
|
|
@@ -578,6 +861,16 @@ function SwitchThumb({ className, ...rest }) {
|
|
|
578
861
|
}
|
|
579
862
|
var Switch = Object.assign(SwitchRoot, { Thumb: SwitchThumb });
|
|
580
863
|
//#endregion
|
|
864
|
+
//#region src/portal-context.ts
|
|
865
|
+
/**
|
|
866
|
+
* Container that Base UI popups (Select, Tooltip, etc.) should portal into.
|
|
867
|
+
* When a `<Dialog>` ancestor publishes its `<dialog>` element through this
|
|
868
|
+
* context, popups render inside that top-layer dialog so they paint above
|
|
869
|
+
* the backdrop and escape its `overflow: hidden`. Outside a dialog the
|
|
870
|
+
* context is null and popups portal to `document.body` as before.
|
|
871
|
+
*/
|
|
872
|
+
var PortalContainerContext = (0, react.createContext)(null);
|
|
873
|
+
//#endregion
|
|
581
874
|
//#region src/Select.tsx
|
|
582
875
|
function SelectRoot(props) {
|
|
583
876
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_select.Select.Root, { ...props });
|
|
@@ -603,14 +896,19 @@ function SelectIcon({ className, children, ...rest }) {
|
|
|
603
896
|
});
|
|
604
897
|
}
|
|
605
898
|
function SelectPopup({ className, sideOffset = 4, children, ...rest }) {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
899
|
+
const portalContainer = (0, react.useContext)(PortalContainerContext);
|
|
900
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_select.Select.Portal, {
|
|
901
|
+
container: portalContainer ?? void 0,
|
|
902
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_select.Select.Positioner, {
|
|
903
|
+
sideOffset,
|
|
904
|
+
alignItemWithTrigger: false,
|
|
905
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_select.Select.Popup, {
|
|
906
|
+
className: cn("select-popup", className),
|
|
907
|
+
...rest,
|
|
908
|
+
children
|
|
909
|
+
})
|
|
612
910
|
})
|
|
613
|
-
})
|
|
911
|
+
});
|
|
614
912
|
}
|
|
615
913
|
function SelectItem({ className, ...rest }) {
|
|
616
914
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_select.Select.Item, {
|
|
@@ -802,12 +1100,15 @@ function DialogContainer({ open, onOpenChange, size = "md", closedby = "any", cl
|
|
|
802
1100
|
}, []);
|
|
803
1101
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DialogContext.Provider, {
|
|
804
1102
|
value: { close: () => ref.current?.close() },
|
|
805
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
806
|
-
ref,
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
1103
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PortalContainerContext.Provider, {
|
|
1104
|
+
value: ref,
|
|
1105
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dialog", {
|
|
1106
|
+
ref,
|
|
1107
|
+
className: cn(["dialog", size !== "md" && `dialog-${size}`], className),
|
|
1108
|
+
closedby,
|
|
1109
|
+
...rest,
|
|
1110
|
+
children
|
|
1111
|
+
})
|
|
811
1112
|
})
|
|
812
1113
|
});
|
|
813
1114
|
}
|
|
@@ -972,22 +1273,37 @@ function MenuPopup({ className, role = "menu", ...rest }) {
|
|
|
972
1273
|
});
|
|
973
1274
|
}
|
|
974
1275
|
function MenuItem(props) {
|
|
1276
|
+
const ref = (0, react.useRef)(null);
|
|
1277
|
+
const hotkey = props.hotkey;
|
|
1278
|
+
const { ariaKeyShortcuts, primaryChord } = useHotkey(hotkey, () => ref.current?.click(), { enabled: !("disabled" in props && props.disabled) });
|
|
975
1279
|
if (props.href !== void 0) {
|
|
976
|
-
const { className, role = "menuitem", icon, children, ...rest } = props;
|
|
1280
|
+
const { className, role = "menuitem", icon, children, hotkey: _hk, ...rest } = props;
|
|
977
1281
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
1282
|
+
ref,
|
|
978
1283
|
role,
|
|
1284
|
+
"aria-keyshortcuts": ariaKeyShortcuts,
|
|
979
1285
|
className: cn("menu-item", className),
|
|
980
1286
|
...rest,
|
|
981
|
-
children: [
|
|
1287
|
+
children: [
|
|
1288
|
+
renderIcon(icon),
|
|
1289
|
+
children,
|
|
1290
|
+
primaryChord !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Kbd, { keys: primaryChord }) : null
|
|
1291
|
+
]
|
|
982
1292
|
});
|
|
983
1293
|
}
|
|
984
|
-
const { className, type = "button", role = "menuitem", icon, children, ...rest } = props;
|
|
1294
|
+
const { className, type = "button", role = "menuitem", icon, children, hotkey: _hk, ...rest } = props;
|
|
985
1295
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1296
|
+
ref,
|
|
986
1297
|
type,
|
|
987
1298
|
role,
|
|
1299
|
+
"aria-keyshortcuts": ariaKeyShortcuts,
|
|
988
1300
|
className: cn("menu-item", className),
|
|
989
1301
|
...rest,
|
|
990
|
-
children: [
|
|
1302
|
+
children: [
|
|
1303
|
+
renderIcon(icon),
|
|
1304
|
+
children,
|
|
1305
|
+
primaryChord !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Kbd, { keys: primaryChord }) : null
|
|
1306
|
+
]
|
|
991
1307
|
});
|
|
992
1308
|
}
|
|
993
1309
|
function MenuSeparator({ className, ...rest }) {
|
|
@@ -1136,17 +1452,21 @@ function TooltipTrigger(props) {
|
|
|
1136
1452
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_tooltip.Tooltip.Trigger, { ...props });
|
|
1137
1453
|
}
|
|
1138
1454
|
function TooltipPopup({ size = "md", side = "top", align = "center", sideOffset = 6, role = "tooltip", className, children, ...rest }) {
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1455
|
+
const portalContainer = (0, react.useContext)(PortalContainerContext);
|
|
1456
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_tooltip.Tooltip.Portal, {
|
|
1457
|
+
container: portalContainer ?? void 0,
|
|
1458
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_tooltip.Tooltip.Positioner, {
|
|
1459
|
+
sideOffset,
|
|
1460
|
+
side,
|
|
1461
|
+
align,
|
|
1462
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_tooltip.Tooltip.Popup, {
|
|
1463
|
+
role,
|
|
1464
|
+
className: cn(["tooltip", size !== "md" && `tooltip-${size}`], className),
|
|
1465
|
+
...rest,
|
|
1466
|
+
children
|
|
1467
|
+
})
|
|
1148
1468
|
})
|
|
1149
|
-
})
|
|
1469
|
+
});
|
|
1150
1470
|
}
|
|
1151
1471
|
function TooltipShorthand({ content, side, align, sideOffset, size, children, ...rootProps }) {
|
|
1152
1472
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(TooltipRoot, {
|
|
@@ -1200,13 +1520,12 @@ function CheckGlyph({ className }) {
|
|
|
1200
1520
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M5 12l5 5l10 -10" })
|
|
1201
1521
|
});
|
|
1202
1522
|
}
|
|
1203
|
-
function PropertyListRoot({ striped, compact,
|
|
1523
|
+
function PropertyListRoot({ striped, compact, hideIfAllEmpty, title, className, children, ...rest }) {
|
|
1204
1524
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1205
1525
|
className: cn([
|
|
1206
1526
|
"property-list",
|
|
1207
1527
|
striped && "property-list-striped",
|
|
1208
1528
|
compact && "property-list-compact",
|
|
1209
|
-
copyable && "property-list-copyable",
|
|
1210
1529
|
hideIfAllEmpty && "property-list-hide-if-empty"
|
|
1211
1530
|
], className),
|
|
1212
1531
|
...rest,
|
|
@@ -1523,8 +1842,10 @@ exports.Dialog = Dialog;
|
|
|
1523
1842
|
exports.Field = Field;
|
|
1524
1843
|
exports.FileInput = FileInput;
|
|
1525
1844
|
exports.Footer = Footer;
|
|
1845
|
+
exports.Indicator = Indicator;
|
|
1526
1846
|
exports.Input = Input;
|
|
1527
1847
|
exports.InputGroup = InputGroup;
|
|
1848
|
+
exports.Kbd = Kbd;
|
|
1528
1849
|
exports.Menu = Menu;
|
|
1529
1850
|
exports.Navbar = Navbar;
|
|
1530
1851
|
exports.Pagination = Pagination;
|
|
@@ -1542,5 +1863,6 @@ exports.Textarea = Textarea;
|
|
|
1542
1863
|
exports.Tooltip = Tooltip;
|
|
1543
1864
|
exports.getPaginationItems = getPaginationItems;
|
|
1544
1865
|
exports.useAppShell = useAppShell;
|
|
1866
|
+
exports.useHotkey = useHotkey;
|
|
1545
1867
|
|
|
1546
1868
|
//# sourceMappingURL=index.cjs.map
|