@aortl/admin-react 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AdminRoot.d.ts +1 -1
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/Button.d.ts +7 -6
- package/dist/Button.d.ts.map +1 -1
- package/dist/ButtonGroup.d.ts +7 -1
- package/dist/ButtonGroup.d.ts.map +1 -1
- package/dist/Input.d.ts +1 -1
- package/dist/Input.d.ts.map +1 -1
- package/dist/Link.d.ts +21 -0
- package/dist/Link.d.ts.map +1 -0
- package/dist/Textarea.d.ts +15 -2
- package/dist/Textarea.d.ts.map +1 -1
- package/dist/admin.scoped.css +121 -0
- package/dist/hotkey-parse.d.ts +9 -6
- package/dist/hotkey-parse.d.ts.map +1 -1
- package/dist/hotkey-registry.d.ts +5 -4
- package/dist/hotkey-registry.d.ts.map +1 -1
- package/dist/index.cjs +104 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +105 -29
- package/dist/index.mjs.map +1 -1
- package/dist/portal-context.d.ts +7 -4
- package/dist/portal-context.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/AdminRoot.d.ts
CHANGED
|
@@ -12,5 +12,5 @@ export interface AdminRootProps extends ComponentProps<"div"> {
|
|
|
12
12
|
*/
|
|
13
13
|
systemAccent?: string;
|
|
14
14
|
}
|
|
15
|
-
export declare function AdminRoot({ className, theme, systemAccent, style, ...rest }: AdminRootProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function AdminRoot({ className, theme, systemAccent, style, ref, ...rest }: AdminRootProps): import("react/jsx-runtime").JSX.Element;
|
|
16
16
|
//# sourceMappingURL=AdminRoot.d.ts.map
|
package/dist/AdminRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminRoot.d.ts","sourceRoot":"","sources":["../src/AdminRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"AdminRoot.d.ts","sourceRoot":"","sources":["../src/AdminRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAIrF,MAAM,WAAW,cAAe,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC3D;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,2CAgChG"}
|
package/dist/Button.d.ts
CHANGED
|
@@ -15,13 +15,14 @@ export interface ButtonProps extends ComponentProps<typeof BaseButton> {
|
|
|
15
15
|
/** Trailing icon. Pass a component (`iconTrailing={IconArrowRight}`) or an element. */
|
|
16
16
|
iconTrailing?: IconProp;
|
|
17
17
|
/**
|
|
18
|
-
* Keyboard shortcut bound to this button. Pressing the chord
|
|
19
|
-
*
|
|
20
|
-
* form
|
|
21
|
-
*
|
|
22
|
-
* alternatives — only the first is rendered as
|
|
18
|
+
* Keyboard shortcut bound to this button. Pressing the chord dispatches a
|
|
19
|
+
* native click on the underlying element, so `onClick` fires, `type="submit"`
|
|
20
|
+
* submits the form, and an anchor-rendered button (`render={<a href>}`)
|
|
21
|
+
* navigates — all the native side effects of a real click. Same syntax as
|
|
22
|
+
* `useHotkey`. Pass an array for alternatives — only the first is rendered as
|
|
23
|
+
* a visual chip.
|
|
23
24
|
*/
|
|
24
25
|
hotkey?: string | readonly string[];
|
|
25
26
|
}
|
|
26
|
-
export declare function Button({ variant, size, fullWidth, loading, icon, iconTrailing, hotkey, className, type, disabled, children, onClick, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export declare function Button({ variant, size, fullWidth, loading, icon, iconTrailing, hotkey, className, type, disabled, children, onClick, ref, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
27
28
|
//# sourceMappingURL=Button.d.ts.map
|
package/dist/Button.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAInD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AACvE,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,OAAO,UAAU,CAAC;IACpE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;uEACmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,uFAAuF;IACvF,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAmB,EACnB,IAAW,EACX,SAAS,EACT,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,SAAS,EACT,IAAe,EACf,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,GAAG,EACH,GAAG,IAAI,EACR,EAAE,WAAW,2CA+Cb"}
|
package/dist/ButtonGroup.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ import { ComponentProps } from 'react';
|
|
|
2
2
|
export type ButtonGroupOrientation = "horizontal" | "vertical";
|
|
3
3
|
export interface ButtonGroupProps extends ComponentProps<"div"> {
|
|
4
4
|
orientation?: ButtonGroupOrientation;
|
|
5
|
+
/**
|
|
6
|
+
* Stretch the group across its container. Horizontal groups split the row
|
|
7
|
+
* evenly so every button is the same width; vertical groups fill the
|
|
8
|
+
* container width.
|
|
9
|
+
*/
|
|
10
|
+
fullWidth?: boolean;
|
|
5
11
|
}
|
|
6
|
-
export declare function ButtonGroup({ orientation, role, className, ...rest }: ButtonGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function ButtonGroup({ orientation, fullWidth, role, className, ...rest }: ButtonGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
7
13
|
//# sourceMappingURL=ButtonGroup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.d.ts","sourceRoot":"","sources":["../src/ButtonGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,UAAU,CAAC;AAE/D,MAAM,WAAW,gBAAiB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC7D,WAAW,CAAC,EAAE,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ButtonGroup.d.ts","sourceRoot":"","sources":["../src/ButtonGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,UAAU,CAAC;AAE/D,MAAM,WAAW,gBAAiB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC7D,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAC1B,WAA0B,EAC1B,SAAiB,EACjB,IAAc,EACd,SAAS,EACT,GAAG,IAAI,EACR,EAAE,gBAAgB,2CAelB"}
|
package/dist/Input.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Input as BaseInput } from '@base-ui/react/input';
|
|
2
2
|
import { ComponentProps } from 'react';
|
|
3
|
-
export type InputVariant = "bordered" | "ghost" | "danger";
|
|
3
|
+
export type InputVariant = "bordered" | "ghost" | "danger" | "info" | "success" | "warning";
|
|
4
4
|
export type InputSize = "sm" | "md" | "lg";
|
|
5
5
|
type BaseInputProps = Omit<ComponentProps<typeof BaseInput>, "size">;
|
|
6
6
|
export interface InputProps extends BaseInputProps {
|
package/dist/Input.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAC5F,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,KAAK,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AAErE,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,wBAAgB,KAAK,CAAC,EACpB,OAAoB,EACpB,SAAgB,EAChB,SAAS,EACT,IAAa,EACb,GAAG,IAAI,EACR,EAAE,UAAU,2CAeZ"}
|
package/dist/Link.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentProps } from 'react';
|
|
2
|
+
import { IconProp } from './icon';
|
|
3
|
+
export interface LinkProps extends ComponentProps<"a"> {
|
|
4
|
+
/**
|
|
5
|
+
* Marks the link as leaving the app: renders a trailing ↗ affordance and
|
|
6
|
+
* defaults `target="_blank"` + `rel="noopener noreferrer"`. Explicit
|
|
7
|
+
* `target`/`rel` props win, so you can keep the icon while overriding either.
|
|
8
|
+
*/
|
|
9
|
+
external?: boolean;
|
|
10
|
+
/** Leading icon. Pass a component (`icon={IconHome}`) or an element. */
|
|
11
|
+
icon?: IconProp;
|
|
12
|
+
/** Trailing icon. Independent of `external`'s ↗ affordance. */
|
|
13
|
+
iconTrailing?: IconProp;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A text link — a plain `<a>` with the design system's link styling: primary
|
|
17
|
+
* color, hover shift, underline, and a focus-visible ring. Pass `external` for
|
|
18
|
+
* the new-tab affordance.
|
|
19
|
+
*/
|
|
20
|
+
export declare function Link({ external, icon, iconTrailing, className, target, rel, children, ...rest }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=Link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../src/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEnD,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,GAAG,CAAC;IACpD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wEAAwE;IACxE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,MAAM,EACN,GAAG,EACH,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,SAAS,2CAaX"}
|
package/dist/Textarea.d.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { ComponentProps } from 'react';
|
|
2
|
-
export type TextareaVariant = "bordered" | "ghost" | "danger";
|
|
2
|
+
export type TextareaVariant = "bordered" | "ghost" | "danger" | "info" | "success" | "warning";
|
|
3
3
|
export type TextareaSize = "sm" | "md" | "lg";
|
|
4
4
|
export interface TextareaProps extends Omit<ComponentProps<"textarea">, "size"> {
|
|
5
5
|
variant?: TextareaVariant;
|
|
6
6
|
textareaSize?: TextareaSize;
|
|
7
|
+
/**
|
|
8
|
+
* Height tracks content via CSS `field-sizing` (Chromium-only today; other
|
|
9
|
+
* browsers keep a fixed, resizable box). `rows`/min-height is the floor —
|
|
10
|
+
* set `max-height` via `className`/`style` for a ceiling.
|
|
11
|
+
*/
|
|
12
|
+
autoResize?: boolean;
|
|
7
13
|
}
|
|
8
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Multi-line text input. Rendered through Base UI's `Field.Control` with a
|
|
16
|
+
* `<textarea>` swapped in for the default `<input>`, so inside a `<Field>` it
|
|
17
|
+
* gets the same wiring as `<Input>`: a generated id, label `htmlFor`
|
|
18
|
+
* association, and validity-driven `:user-valid` / `<Field.Error>`. Works
|
|
19
|
+
* standalone too — `Field.Control` falls back to a default context.
|
|
20
|
+
*/
|
|
21
|
+
export declare function Textarea({ variant, textareaSize, autoResize, className, ...rest }: TextareaProps): import("react/jsx-runtime").JSX.Element;
|
|
9
22
|
//# sourceMappingURL=Textarea.d.ts.map
|
package/dist/Textarea.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.d.ts","sourceRoot":"","sources":["../src/Textarea.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Textarea.d.ts","sourceRoot":"","sources":["../src/Textarea.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAC/F,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7E,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAoB,EACpB,YAAmB,EACnB,UAAU,EACV,SAAS,EACT,GAAG,IAAI,EACR,EAAE,aAAa,2CAmBf"}
|
package/dist/admin.scoped.css
CHANGED
|
@@ -1617,6 +1617,57 @@
|
|
|
1617
1617
|
border-top-color: color-mix(in srgb, currentColor 25%, transparent);
|
|
1618
1618
|
}
|
|
1619
1619
|
}
|
|
1620
|
+
:scope._ao-btn-group-full-width:not(._ao-btn-group-vertical), :scope ._ao-btn-group-full-width:not(._ao-btn-group-vertical) {
|
|
1621
|
+
display: flex;
|
|
1622
|
+
width: 100%;
|
|
1623
|
+
}
|
|
1624
|
+
:scope._ao-btn-group-full-width:not(._ao-btn-group-vertical) > ._ao-btn, :scope ._ao-btn-group-full-width:not(._ao-btn-group-vertical) > ._ao-btn, :scope._ao-btn-group-full-width:not(._ao-btn-group-vertical) > ._ao-menu, :scope ._ao-btn-group-full-width:not(._ao-btn-group-vertical) > ._ao-menu {
|
|
1625
|
+
flex: 1;
|
|
1626
|
+
}
|
|
1627
|
+
:scope._ao-btn-group-full-width._ao-btn-group-vertical, :scope ._ao-btn-group-full-width._ao-btn-group-vertical {
|
|
1628
|
+
width: 100%;
|
|
1629
|
+
}
|
|
1630
|
+
:scope._ao-link, :scope ._ao-link {
|
|
1631
|
+
display: inline-flex;
|
|
1632
|
+
align-items: center;
|
|
1633
|
+
gap: calc(var(--spacing) * 1);
|
|
1634
|
+
border-radius: var(--radius-sm);
|
|
1635
|
+
color: var(--color-primary);
|
|
1636
|
+
text-decoration-line: underline;
|
|
1637
|
+
text-underline-offset: 2px;
|
|
1638
|
+
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
|
|
1639
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1640
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1641
|
+
--tw-duration: 150ms;
|
|
1642
|
+
transition-duration: 150ms;
|
|
1643
|
+
&:hover {
|
|
1644
|
+
@media (hover: hover) {
|
|
1645
|
+
color: var(--color-primary-hover);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
&:focus-visible {
|
|
1649
|
+
outline-style: var(--tw-outline-style);
|
|
1650
|
+
outline-width: 2px;
|
|
1651
|
+
}
|
|
1652
|
+
&:focus-visible {
|
|
1653
|
+
outline-offset: 2px;
|
|
1654
|
+
}
|
|
1655
|
+
&:focus-visible {
|
|
1656
|
+
outline-color: var(--color-primary);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
:scope._ao-link-external, :scope ._ao-link-external {
|
|
1660
|
+
--link-external-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17 7 7 17'/%3E%3Cpath d='M8 7h9v9'/%3E%3C/svg%3E");
|
|
1661
|
+
}
|
|
1662
|
+
:scope._ao-link-external::after, :scope ._ao-link-external::after {
|
|
1663
|
+
content: "";
|
|
1664
|
+
flex: none;
|
|
1665
|
+
width: 0.85em;
|
|
1666
|
+
height: 0.85em;
|
|
1667
|
+
background-color: currentColor;
|
|
1668
|
+
-webkit-mask: var(--link-external-arrow) center / contain no-repeat;
|
|
1669
|
+
mask: var(--link-external-arrow) center / contain no-repeat;
|
|
1670
|
+
}
|
|
1620
1671
|
:scope._ao-input, :scope ._ao-input {
|
|
1621
1672
|
display: inline-flex;
|
|
1622
1673
|
width: 100%;
|
|
@@ -1688,6 +1739,39 @@
|
|
|
1688
1739
|
outline-color: var(--color-danger);
|
|
1689
1740
|
}
|
|
1690
1741
|
}
|
|
1742
|
+
:scope._ao-input-info, :scope ._ao-input-info {
|
|
1743
|
+
border-color: var(--color-info);
|
|
1744
|
+
&:hover {
|
|
1745
|
+
@media (hover: hover) {
|
|
1746
|
+
border-color: var(--color-info);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
&:focus-visible {
|
|
1750
|
+
outline-color: var(--color-info);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
:scope._ao-input-success, :scope ._ao-input-success {
|
|
1754
|
+
border-color: var(--color-success);
|
|
1755
|
+
&:hover {
|
|
1756
|
+
@media (hover: hover) {
|
|
1757
|
+
border-color: var(--color-success);
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
&:focus-visible {
|
|
1761
|
+
outline-color: var(--color-success);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
:scope._ao-input-warning, :scope ._ao-input-warning {
|
|
1765
|
+
border-color: var(--color-warning);
|
|
1766
|
+
&:hover {
|
|
1767
|
+
@media (hover: hover) {
|
|
1768
|
+
border-color: var(--color-warning);
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
&:focus-visible {
|
|
1772
|
+
outline-color: var(--color-warning);
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1691
1775
|
:scope._ao-input-sm, :scope ._ao-input-sm {
|
|
1692
1776
|
padding-inline: calc(var(--spacing) * 2.5);
|
|
1693
1777
|
padding-block: calc(var(--spacing) * 1.5);
|
|
@@ -1816,6 +1900,43 @@
|
|
|
1816
1900
|
outline-color: var(--color-danger);
|
|
1817
1901
|
}
|
|
1818
1902
|
}
|
|
1903
|
+
:scope._ao-textarea-info, :scope ._ao-textarea-info {
|
|
1904
|
+
border-color: var(--color-info);
|
|
1905
|
+
&:hover {
|
|
1906
|
+
@media (hover: hover) {
|
|
1907
|
+
border-color: var(--color-info);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
&:focus-visible {
|
|
1911
|
+
outline-color: var(--color-info);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
:scope._ao-textarea-success, :scope ._ao-textarea-success {
|
|
1915
|
+
border-color: var(--color-success);
|
|
1916
|
+
&:hover {
|
|
1917
|
+
@media (hover: hover) {
|
|
1918
|
+
border-color: var(--color-success);
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
&:focus-visible {
|
|
1922
|
+
outline-color: var(--color-success);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
:scope._ao-textarea-warning, :scope ._ao-textarea-warning {
|
|
1926
|
+
border-color: var(--color-warning);
|
|
1927
|
+
&:hover {
|
|
1928
|
+
@media (hover: hover) {
|
|
1929
|
+
border-color: var(--color-warning);
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
&:focus-visible {
|
|
1933
|
+
outline-color: var(--color-warning);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
:scope._ao-textarea-autosize, :scope ._ao-textarea-autosize {
|
|
1937
|
+
field-sizing: content;
|
|
1938
|
+
resize: none;
|
|
1939
|
+
}
|
|
1819
1940
|
:scope._ao-textarea-sm, :scope ._ao-textarea-sm {
|
|
1820
1941
|
min-height: calc(var(--spacing) * 16);
|
|
1821
1942
|
padding-inline: calc(var(--spacing) * 2.5);
|
package/dist/hotkey-parse.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pure helpers for the hotkey system. Chord syntax: `<mod>+<mod>+…+<key>`
|
|
3
3
|
*
|
|
4
|
-
* Examples: `mod+s`,
|
|
4
|
+
* Examples: `mod+s`, `?`, `escape`, `mod+shift+k`, `arrowup`.
|
|
5
5
|
*
|
|
6
|
-
* Modifiers are case-insensitive. `mod`
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Modifiers are case-insensitive. `mod` resolves to the platform's primary
|
|
7
|
+
* command modifier — ⌘ (`meta`) on Apple platforms, `Ctrl` elsewhere — so
|
|
8
|
+
* `mod+s` fires on the OS-native gesture (Cmd+S on macOS, Ctrl+S otherwise)
|
|
9
|
+
* and the `<Kbd>` chip follows suit. The key is whatever
|
|
10
|
+
* `KeyboardEvent.key` produces, lowercased. A shifted printable symbol already
|
|
11
|
+
* encodes Shift in the character it produces, so bind `"?"` (not `"shift+?"`)
|
|
12
|
+
* to catch `shift+/`; `shift` stays explicit for letters and named keys, so
|
|
13
|
+
* `shift+a` and `shift+tab` remain distinct chords.
|
|
11
14
|
*/
|
|
12
15
|
export type Modifier = "ctrl" | "shift" | "alt" | "meta";
|
|
13
16
|
export interface ParsedChord {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hotkey-parse.d.ts","sourceRoot":"","sources":["../src/hotkey-parse.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hotkey-parse.d.ts","sourceRoot":"","sources":["../src/hotkey-parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAsCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CA2BrD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,WAAW,EAAE,CAGzE;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAOvD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAgB9D;AA4BD,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,CAcxD;AAkBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAEzE"}
|
|
@@ -4,11 +4,12 @@ import { RefObject } from 'react';
|
|
|
4
4
|
* attached on first registration and detached when the registry empties.
|
|
5
5
|
*
|
|
6
6
|
* On keydown:
|
|
7
|
-
* 1.
|
|
8
|
-
* 2.
|
|
9
|
-
* 3.
|
|
7
|
+
* 1. Ignore OS autorepeat (`e.repeat`) so a held chord fires once, not per tick.
|
|
8
|
+
* 2. Normalize the event to a canonical chord string.
|
|
9
|
+
* 3. Look up the bucket. Skip if empty.
|
|
10
|
+
* 4. Apply input suppression — bare-key chords are skipped while focus is
|
|
10
11
|
* in an editable element, except for `escape`.
|
|
11
|
-
*
|
|
12
|
+
* 5. `preventDefault()`, then invoke every surviving handler (bag semantics).
|
|
12
13
|
*/
|
|
13
14
|
export type HotkeyHandler = (e: KeyboardEvent) => void;
|
|
14
15
|
export interface HotkeyEntry {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hotkey-registry.d.ts","sourceRoot":"","sources":["../src/hotkey-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC
|
|
1
|
+
{"version":3,"file":"hotkey-registry.d.ts","sourceRoot":"","sources":["../src/hotkey-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;CACtC;AA6CD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,IAAI,CAmB3F;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,IAAI,IAAI,CAGtC"}
|
package/dist/index.cjs
CHANGED
|
@@ -4,12 +4,12 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
4
4
|
let react = require("react");
|
|
5
5
|
let _base_ui_react_button = require("@base-ui/react/button");
|
|
6
6
|
let _base_ui_react_input = require("@base-ui/react/input");
|
|
7
|
+
let _base_ui_react_field = require("@base-ui/react/field");
|
|
7
8
|
let _base_ui_react_checkbox = require("@base-ui/react/checkbox");
|
|
8
9
|
let _base_ui_react_radio = require("@base-ui/react/radio");
|
|
9
10
|
let _base_ui_react_radio_group = require("@base-ui/react/radio-group");
|
|
10
11
|
let _base_ui_react_switch = require("@base-ui/react/switch");
|
|
11
12
|
let _base_ui_react_select = require("@base-ui/react/select");
|
|
12
|
-
let _base_ui_react_field = require("@base-ui/react/field");
|
|
13
13
|
let _base_ui_react_tabs = require("@base-ui/react/tabs");
|
|
14
14
|
let _base_ui_react_tooltip = require("@base-ui/react/tooltip");
|
|
15
15
|
let _base_ui_react_dialog = require("@base-ui/react/dialog");
|
|
@@ -65,17 +65,40 @@ var Accordion = Object.assign(AccordionRoot, {
|
|
|
65
65
|
Content: AccordionContent
|
|
66
66
|
});
|
|
67
67
|
//#endregion
|
|
68
|
+
//#region src/portal-context.ts
|
|
69
|
+
/**
|
|
70
|
+
* Container that Base UI popups (Select, Tooltip, etc.) should portal into.
|
|
71
|
+
* `<AdminRoot>` publishes its own element here so popups render inside the
|
|
72
|
+
* scoped subtree and match the `@scope (._ao-admin-root)` CSS — without it
|
|
73
|
+
* they portal to `document.body`, outside the scope, and render unstyled. A
|
|
74
|
+
* `<Dialog>` ancestor overrides it with its own `<dialog>` element so popups
|
|
75
|
+
* join the top layer, painting above the backdrop and escaping its
|
|
76
|
+
* `overflow: hidden`. With no provider the context is null and popups fall
|
|
77
|
+
* back to `document.body`.
|
|
78
|
+
*/
|
|
79
|
+
var PortalContainerContext = (0, react.createContext)(null);
|
|
80
|
+
//#endregion
|
|
68
81
|
//#region src/AdminRoot.tsx
|
|
69
|
-
function AdminRoot({ className, theme, systemAccent, style, ...rest }) {
|
|
82
|
+
function AdminRoot({ className, theme, systemAccent, style, ref, ...rest }) {
|
|
70
83
|
const rootStyle = systemAccent !== void 0 ? {
|
|
71
84
|
...style,
|
|
72
85
|
"--color-system-accent": systemAccent
|
|
73
86
|
} : style;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
87
|
+
const portalRef = (0, react.useRef)(null);
|
|
88
|
+
const setRef = (0, react.useCallback)((node) => {
|
|
89
|
+
portalRef.current = node;
|
|
90
|
+
if (typeof ref === "function") ref(node);
|
|
91
|
+
else if (ref) ref.current = node;
|
|
92
|
+
}, [ref]);
|
|
93
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PortalContainerContext.Provider, {
|
|
94
|
+
value: portalRef,
|
|
95
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
96
|
+
ref: setRef,
|
|
97
|
+
className: cn("admin-root", className),
|
|
98
|
+
style: rootStyle,
|
|
99
|
+
...rest,
|
|
100
|
+
...theme !== void 0 && { "data-theme": theme }
|
|
101
|
+
})
|
|
79
102
|
});
|
|
80
103
|
}
|
|
81
104
|
//#endregion
|
|
@@ -208,9 +231,22 @@ var MOD_ORDER = [
|
|
|
208
231
|
"alt",
|
|
209
232
|
"meta"
|
|
210
233
|
];
|
|
234
|
+
/**
|
|
235
|
+
* Resolve the modifier `mod` aliases to. Apple platforms use ⌘ (`meta`) as the
|
|
236
|
+
* primary command modifier; everywhere else it's Ctrl. Detected once at module
|
|
237
|
+
* load (SSR-safe — the registry never dispatches server-side) and shared by the
|
|
238
|
+
* parse and display layers so the binding and its `<Kbd>` chip always agree.
|
|
239
|
+
*/
|
|
240
|
+
function detectApplePlatform() {
|
|
241
|
+
if (typeof navigator === "undefined") return false;
|
|
242
|
+
const platform = navigator.userAgentData?.platform || navigator.platform || "";
|
|
243
|
+
return /^(mac|iphone|ipad|ipod)/i.test(platform);
|
|
244
|
+
}
|
|
245
|
+
var IS_APPLE = detectApplePlatform();
|
|
246
|
+
var MOD_TARGET = IS_APPLE ? "meta" : "ctrl";
|
|
211
247
|
function tokenToMod(token) {
|
|
212
248
|
switch (token) {
|
|
213
|
-
case "mod":
|
|
249
|
+
case "mod": return MOD_TARGET;
|
|
214
250
|
case "ctrl":
|
|
215
251
|
case "control": return "ctrl";
|
|
216
252
|
case "shift": return "shift";
|
|
@@ -259,7 +295,7 @@ function normalizeEvent(e) {
|
|
|
259
295
|
if (key === "control" || key === "shift" || key === "alt" || key === "meta") return null;
|
|
260
296
|
const mods = /* @__PURE__ */ new Set();
|
|
261
297
|
if (e.ctrlKey) mods.add("ctrl");
|
|
262
|
-
if (e.shiftKey) mods.add("shift");
|
|
298
|
+
if (e.shiftKey && !isShiftedSymbol(key)) mods.add("shift");
|
|
263
299
|
if (e.altKey) mods.add("alt");
|
|
264
300
|
if (e.metaKey) mods.add("meta");
|
|
265
301
|
return canonicalize({
|
|
@@ -267,6 +303,10 @@ function normalizeEvent(e) {
|
|
|
267
303
|
key
|
|
268
304
|
});
|
|
269
305
|
}
|
|
306
|
+
/** A single printable symbol (`?`, `+`, `:`, …) — not a letter, digit, or named key. */
|
|
307
|
+
function isShiftedSymbol(key) {
|
|
308
|
+
return key.length === 1 && !/[a-z0-9]/.test(key);
|
|
309
|
+
}
|
|
270
310
|
var SPECIAL_KEY_LABELS = {
|
|
271
311
|
escape: "Esc",
|
|
272
312
|
esc: "Esc",
|
|
@@ -282,7 +322,12 @@ var SPECIAL_KEY_LABELS = {
|
|
|
282
322
|
backspace: "Backspace",
|
|
283
323
|
delete: "Del"
|
|
284
324
|
};
|
|
285
|
-
var MOD_LABELS = {
|
|
325
|
+
var MOD_LABELS = IS_APPLE ? {
|
|
326
|
+
ctrl: "⌃",
|
|
327
|
+
shift: "⇧",
|
|
328
|
+
alt: "⌥",
|
|
329
|
+
meta: "⌘"
|
|
330
|
+
} : {
|
|
286
331
|
ctrl: "Ctrl",
|
|
287
332
|
shift: "Shift",
|
|
288
333
|
alt: "Alt",
|
|
@@ -372,6 +417,7 @@ function isEditableTarget(target) {
|
|
|
372
417
|
return tag === "INPUT" || tag === "TEXTAREA";
|
|
373
418
|
}
|
|
374
419
|
function dispatch(e) {
|
|
420
|
+
if (e.repeat) return;
|
|
375
421
|
const chord = normalizeEvent(e);
|
|
376
422
|
if (chord === null) return;
|
|
377
423
|
const bucket = registry.get(chord);
|
|
@@ -447,10 +493,17 @@ function useHotkey(keys, handler, options) {
|
|
|
447
493
|
}
|
|
448
494
|
//#endregion
|
|
449
495
|
//#region src/Button.tsx
|
|
450
|
-
function Button({ variant = "default", size = "md", fullWidth, loading, icon, iconTrailing, hotkey, className, type = "button", disabled, children, onClick, ...rest }) {
|
|
451
|
-
const
|
|
496
|
+
function Button({ variant = "default", size = "md", fullWidth, loading, icon, iconTrailing, hotkey, className, type = "button", disabled, children, onClick, ref, ...rest }) {
|
|
497
|
+
const elementRef = (0, react.useRef)(null);
|
|
498
|
+
const setRef = (0, react.useCallback)((node) => {
|
|
499
|
+
elementRef.current = node;
|
|
500
|
+
if (typeof ref === "function") ref(node);
|
|
501
|
+
else if (ref) ref.current = node;
|
|
502
|
+
}, [ref]);
|
|
503
|
+
const { ariaKeyShortcuts, primaryChord } = useHotkey(hotkey, () => elementRef.current?.click(), { enabled: !disabled && !loading });
|
|
452
504
|
const iconOnly = children == null && (icon != null || iconTrailing != null);
|
|
453
505
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_base_ui_react_button.Button, {
|
|
506
|
+
ref: setRef,
|
|
454
507
|
onClick,
|
|
455
508
|
type,
|
|
456
509
|
disabled: disabled || loading,
|
|
@@ -475,10 +528,14 @@ function Button({ variant = "default", size = "md", fullWidth, loading, icon, ic
|
|
|
475
528
|
}
|
|
476
529
|
//#endregion
|
|
477
530
|
//#region src/ButtonGroup.tsx
|
|
478
|
-
function ButtonGroup({ orientation = "horizontal", role = "group", className, ...rest }) {
|
|
531
|
+
function ButtonGroup({ orientation = "horizontal", fullWidth = false, role = "group", className, ...rest }) {
|
|
479
532
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
480
533
|
role,
|
|
481
|
-
className: cn([
|
|
534
|
+
className: cn([
|
|
535
|
+
"btn-group",
|
|
536
|
+
orientation === "vertical" && "btn-group-vertical",
|
|
537
|
+
fullWidth && "btn-group-full-width"
|
|
538
|
+
], className),
|
|
482
539
|
...rest
|
|
483
540
|
});
|
|
484
541
|
}
|
|
@@ -598,6 +655,26 @@ function Indicator({ label, variant = "neutral", size = "sm", icon, placement =
|
|
|
598
655
|
});
|
|
599
656
|
}
|
|
600
657
|
//#endregion
|
|
658
|
+
//#region src/Link.tsx
|
|
659
|
+
/**
|
|
660
|
+
* A text link — a plain `<a>` with the design system's link styling: primary
|
|
661
|
+
* color, hover shift, underline, and a focus-visible ring. Pass `external` for
|
|
662
|
+
* the new-tab affordance.
|
|
663
|
+
*/
|
|
664
|
+
function Link({ external, icon, iconTrailing, className, target, rel, children, ...rest }) {
|
|
665
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
666
|
+
target: target ?? (external ? "_blank" : void 0),
|
|
667
|
+
rel: rel ?? (external ? "noopener noreferrer" : void 0),
|
|
668
|
+
className: cn(["link", external && "link-external"], className),
|
|
669
|
+
...rest,
|
|
670
|
+
children: [
|
|
671
|
+
renderIcon(icon),
|
|
672
|
+
children,
|
|
673
|
+
renderIcon(iconTrailing)
|
|
674
|
+
]
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
//#endregion
|
|
601
678
|
//#region src/Pagination.tsx
|
|
602
679
|
/**
|
|
603
680
|
* Compute the items to render for a given `page` / `total`. Always returns:
|
|
@@ -759,12 +836,21 @@ function defaultRender(item, onPageChange, prev, next) {
|
|
|
759
836
|
}
|
|
760
837
|
//#endregion
|
|
761
838
|
//#region src/Textarea.tsx
|
|
762
|
-
|
|
763
|
-
|
|
839
|
+
/**
|
|
840
|
+
* Multi-line text input. Rendered through Base UI's `Field.Control` with a
|
|
841
|
+
* `<textarea>` swapped in for the default `<input>`, so inside a `<Field>` it
|
|
842
|
+
* gets the same wiring as `<Input>`: a generated id, label `htmlFor`
|
|
843
|
+
* association, and validity-driven `:user-valid` / `<Field.Error>`. Works
|
|
844
|
+
* standalone too — `Field.Control` falls back to a default context.
|
|
845
|
+
*/
|
|
846
|
+
function Textarea({ variant = "bordered", textareaSize = "md", autoResize, className, ...rest }) {
|
|
847
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_field.Field.Control, {
|
|
848
|
+
render: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", { ...props }),
|
|
764
849
|
className: cn([
|
|
765
850
|
"textarea",
|
|
766
851
|
variant !== "bordered" && `textarea-${variant}`,
|
|
767
|
-
textareaSize !== "md" && `textarea-${textareaSize}
|
|
852
|
+
textareaSize !== "md" && `textarea-${textareaSize}`,
|
|
853
|
+
autoResize && "textarea-autosize"
|
|
768
854
|
], className),
|
|
769
855
|
...rest
|
|
770
856
|
});
|
|
@@ -861,16 +947,6 @@ function SwitchThumb({ className, ...rest }) {
|
|
|
861
947
|
}
|
|
862
948
|
var Switch = Object.assign(SwitchRoot, { Thumb: SwitchThumb });
|
|
863
949
|
//#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
|
|
874
950
|
//#region src/Select.tsx
|
|
875
951
|
function SelectRoot(props) {
|
|
876
952
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_select.Select.Root, { ...props });
|
|
@@ -1952,6 +2028,7 @@ exports.Indicator = Indicator;
|
|
|
1952
2028
|
exports.Input = Input;
|
|
1953
2029
|
exports.InputGroup = InputGroup;
|
|
1954
2030
|
exports.Kbd = Kbd;
|
|
2031
|
+
exports.Link = Link;
|
|
1955
2032
|
exports.Menu = Menu;
|
|
1956
2033
|
exports.Navbar = Navbar;
|
|
1957
2034
|
exports.Pagination = Pagination;
|