@jonmilner/ui 0.4.2 → 0.4.3
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/Menu/Menu.css +1 -1
- package/dist/Menu/client.d.mts +1 -0
- package/dist/Menu/client.mjs +91 -26
- package/dist/Menu/index.d.mts +1 -1
- package/dist/Menu/index.mjs +22 -25
- package/dist/docs/Menu.md +2 -2
- package/dist/docs/manifest.json +1 -1
- package/dist/popup/client.mjs +2 -1
- package/dist/theme/use-theme-container.mjs +2 -1
- package/package.json +2 -1
package/dist/Menu/Menu.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@layer tokens, reset, atoms, components.box, components.checkbox, components.clickable, components.icon, components.icon-button, components.inline, components.stack, components.text, components.badge, components.button, components.chip, components.field, components.heading, components.dialog, components.alert-dialog, components.menu, components.multiselect, components.search-field, components.tabs, components.tag, components.text-field, components.toast, components.visually-hidden;
|
|
2
|
-
@layer components.menu{
|
|
2
|
+
@layer components.menu{._393eil1{border:var(--space-1) solid var(--color-border);transform-origin:var(--transform-origin);transition:opacity var(--duration-fast) var(--easing-standard), scale var(--duration-fast) var(--easing-enter)}._393eil1:focus-visible{outline:var(--space-2) solid var(--color-focus);outline-offset:var(--space-2)}._393eil1[data-starting-style],._393eil1[data-ending-style]{opacity:0;scale:calc(1 - var(--scale-med))}._393eil2{cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}._393eil2:focus-visible{outline:var(--space-2) solid var(--color-focus);outline-offset:var(--space-2)}._393eil2[data-highlighted]{background-color:light-dark(var(--color-bg-muted),color-mix(in srgb, var(--color-fg) 10%, var(--color-bg-raised)))}._393eil2[aria-disabled=true]{color:var(--color-fg-muted);cursor:not-allowed}._393eil3{text-decoration:none}._393eil4{border-block-start:var(--space-1) solid var(--color-border)}@media (forced-colors:active){._393eil2[data-highlighted]:not([aria-disabled=true]){forced-color-adjust:none;color:highlighttext;background-color:highlight}._393eil2[aria-disabled=true]{color:graytext}}}
|
package/dist/Menu/client.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TriggerElementProps, TriggerLookProps } from "../popup/client.mjs";
|
|
2
|
+
import "./index.mjs";
|
|
2
3
|
import { Menu } from "@base-ui/react/menu";
|
|
3
4
|
//#region src/Menu/client.d.ts
|
|
4
5
|
type TriggerOwnProps = Omit<Menu.Trigger.Props, "render" | "className" | "style" | "nativeButton">;
|
package/dist/Menu/client.mjs
CHANGED
|
@@ -2,46 +2,111 @@
|
|
|
2
2
|
import { join as e } from "../styles/join.mjs";
|
|
3
3
|
import { splitStyleProps as t } from "../styles/split-style-props.mjs";
|
|
4
4
|
import { Box as n } from "../Box/index.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { positioner as
|
|
7
|
-
import { jsx as
|
|
8
|
-
import {
|
|
5
|
+
import { PopupScope as r, triggerElement as i, usePopupScope as a } from "../popup/client.mjs";
|
|
6
|
+
import { positioner as o } from "./Menu.css.mjs";
|
|
7
|
+
import { jsx as s } from "react/jsx-runtime";
|
|
8
|
+
import { createContext as c, use as l, useCallback as u, useLayoutEffect as d, useRef as f } from "react";
|
|
9
|
+
import { Menu as p } from "@base-ui/react/menu";
|
|
9
10
|
//#region src/Menu/client.tsx
|
|
10
|
-
function
|
|
11
|
-
let { ref:
|
|
12
|
-
return /* @__PURE__ */
|
|
11
|
+
function m({ disabled: e = !1, openOnHover: t, delay: n, closeDelay: r, handle: o, payload: c, ...l }) {
|
|
12
|
+
let { ref: u } = a();
|
|
13
|
+
return /* @__PURE__ */ s(p.Trigger, {
|
|
13
14
|
disabled: e,
|
|
14
15
|
openOnHover: t,
|
|
15
16
|
delay: n,
|
|
16
|
-
closeDelay:
|
|
17
|
-
handle:
|
|
18
|
-
payload:
|
|
19
|
-
ref:
|
|
20
|
-
render:
|
|
17
|
+
closeDelay: r,
|
|
18
|
+
handle: o,
|
|
19
|
+
payload: c,
|
|
20
|
+
ref: u,
|
|
21
|
+
render: i(l)
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
|
-
function
|
|
24
|
-
let { container: t } =
|
|
25
|
-
return /* @__PURE__ */
|
|
24
|
+
function h({ children: e }) {
|
|
25
|
+
let { container: t } = a();
|
|
26
|
+
return /* @__PURE__ */ s(p.Portal, {
|
|
26
27
|
container: t,
|
|
27
28
|
children: e
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
var g = c({ current: {
|
|
32
|
+
keyboard: !1,
|
|
33
|
+
opener: null
|
|
34
|
+
} });
|
|
35
|
+
function _({ onOpenChange: e, ...t }) {
|
|
36
|
+
let n = f({
|
|
37
|
+
keyboard: !1,
|
|
38
|
+
opener: null
|
|
39
|
+
});
|
|
40
|
+
return /* @__PURE__ */ s(r, { children: /* @__PURE__ */ s(g, {
|
|
41
|
+
value: n,
|
|
42
|
+
children: /* @__PURE__ */ s(p.Root, {
|
|
43
|
+
...t,
|
|
44
|
+
onOpenChange: (t, r) => {
|
|
45
|
+
n.current = t ? {
|
|
46
|
+
keyboard: !1,
|
|
47
|
+
opener: r.trigger ?? null
|
|
48
|
+
} : {
|
|
49
|
+
...n.current,
|
|
50
|
+
keyboard: r.event instanceof KeyboardEvent,
|
|
51
|
+
reason: r.reason
|
|
52
|
+
}, e?.(t, r);
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
}) });
|
|
56
|
+
}
|
|
57
|
+
function v({ finalFocus: e, ...n }) {
|
|
58
|
+
return /* @__PURE__ */ s(p.Positioner, {
|
|
59
|
+
...n,
|
|
33
60
|
collisionPadding: 8,
|
|
34
|
-
render: (
|
|
35
|
-
let [,
|
|
36
|
-
return /* @__PURE__ */
|
|
37
|
-
...
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
zIndex: "popover"
|
|
61
|
+
render: (n, { open: r }) => {
|
|
62
|
+
let [, i] = t(n);
|
|
63
|
+
return /* @__PURE__ */ s(b, {
|
|
64
|
+
...i,
|
|
65
|
+
finalFocus: e,
|
|
66
|
+
open: r
|
|
41
67
|
});
|
|
42
68
|
},
|
|
43
69
|
sideOffset: 4
|
|
44
70
|
});
|
|
45
71
|
}
|
|
72
|
+
var y = /* @__PURE__ */ new Set([
|
|
73
|
+
"trigger-hover",
|
|
74
|
+
"focus-out",
|
|
75
|
+
"outside-press"
|
|
76
|
+
]);
|
|
77
|
+
function b({ open: t, finalFocus: r, ref: i, className: c, ...p }) {
|
|
78
|
+
let { trigger: m } = a(), h = l(g), _ = f(null), v = u((e) => {
|
|
79
|
+
_.current = e;
|
|
80
|
+
let t = typeof i == "function" ? i(e) : void 0;
|
|
81
|
+
return i && typeof i != "function" && (i.current = e), () => {
|
|
82
|
+
_.current = null, typeof t == "function" ? t() : typeof i == "function" ? i(null) : i && (i.current = null);
|
|
83
|
+
};
|
|
84
|
+
}, [i]);
|
|
85
|
+
return d(() => {
|
|
86
|
+
let e = _.current;
|
|
87
|
+
if (!e) return;
|
|
88
|
+
if (t) {
|
|
89
|
+
e.inert = !1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
let { reason: n, keyboard: i, opener: a } = h.current, o = a?.isConnected ? a : m.current;
|
|
93
|
+
if (e.contains(e.ownerDocument.activeElement) && !r && !y.has(n ?? "") && o instanceof HTMLElement) {
|
|
94
|
+
let e = { preventScroll: !0 };
|
|
95
|
+
i && (e.focusVisible = !0), o.focus(e);
|
|
96
|
+
}
|
|
97
|
+
e.inert = !0;
|
|
98
|
+
}, [
|
|
99
|
+
t,
|
|
100
|
+
r,
|
|
101
|
+
h,
|
|
102
|
+
m
|
|
103
|
+
]), /* @__PURE__ */ s(n, {
|
|
104
|
+
...p,
|
|
105
|
+
"aria-hidden": !t || void 0,
|
|
106
|
+
className: e(o, c),
|
|
107
|
+
ref: v,
|
|
108
|
+
zIndex: "popover"
|
|
109
|
+
});
|
|
110
|
+
}
|
|
46
111
|
//#endregion
|
|
47
|
-
export {
|
|
112
|
+
export { h as MenuPortal, v as MenuPositioner, _ as MenuRootScope, m as MenuTrigger };
|
package/dist/Menu/index.d.mts
CHANGED
|
@@ -22,7 +22,7 @@ export type MenuSeparatorProps = PartProps<Menu$1.Separator.Props>;
|
|
|
22
22
|
export type MenuGroupProps = PartProps<Menu$1.Group.Props> & {
|
|
23
23
|
label: ReactNode;
|
|
24
24
|
};
|
|
25
|
-
declare function MenuRoot(
|
|
25
|
+
declare function MenuRoot(props: MenuProps): import("react").JSX.Element;
|
|
26
26
|
declare function MenuPopup({ side, align, backgroundColor, borderRadius, boxShadow, padding, className, style, ...props }: MenuPopupProps): import("react").JSX.Element;
|
|
27
27
|
declare function MenuItem({ variant, display, alignItems, gap, minBlockSize, paddingInline, borderRadius, color, className, style, children, ...props }: MenuItemProps): import("react").JSX.Element;
|
|
28
28
|
declare function MenuLinkItem({ href, disabled, closeOnClick, onClick, display, alignItems, gap, minBlockSize, paddingInline, borderRadius, color, className, style, children, ...props }: MenuLinkItemProps): import("react").JSX.Element;
|
package/dist/Menu/index.mjs
CHANGED
|
@@ -2,33 +2,30 @@ import { join as e } from "../styles/join.mjs";
|
|
|
2
2
|
import { splitStyleProps as t } from "../styles/split-style-props.mjs";
|
|
3
3
|
import { Box as n } from "../Box/index.mjs";
|
|
4
4
|
import { Text as r } from "../Text/index.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { MenuPortal as l, MenuPositioner as u, MenuTrigger as d } from "./client.mjs";
|
|
5
|
+
import { item as i, linkItem as a, popup as o, separator as s } from "./Menu.css.mjs";
|
|
6
|
+
import { MenuPortal as c, MenuPositioner as l, MenuRootScope as u, MenuTrigger as d } from "./client.mjs";
|
|
8
7
|
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
9
8
|
import { Children as m } from "react";
|
|
10
9
|
import { Menu as h } from "@base-ui/react/menu";
|
|
11
10
|
//#region src/Menu/index.tsx
|
|
12
|
-
function g(
|
|
13
|
-
return /* @__PURE__ */ f(
|
|
14
|
-
...t,
|
|
15
|
-
children: e
|
|
16
|
-
}) });
|
|
11
|
+
function g(e) {
|
|
12
|
+
return /* @__PURE__ */ f(u, { ...e });
|
|
17
13
|
}
|
|
18
|
-
function _({ side: r = "bottom", align: i = "start", backgroundColor: a = "bgRaised", borderRadius:
|
|
14
|
+
function _({ side: r = "bottom", align: i = "start", backgroundColor: a = "bgRaised", borderRadius: s = "med", boxShadow: u = "med", padding: d = "4", className: p, style: m, ...g }) {
|
|
19
15
|
let [_, v] = t(g);
|
|
20
|
-
return /* @__PURE__ */ f(
|
|
16
|
+
return /* @__PURE__ */ f(c, { children: /* @__PURE__ */ f(l, {
|
|
21
17
|
align: i,
|
|
18
|
+
finalFocus: v.finalFocus !== void 0 && v.finalFocus !== !0,
|
|
22
19
|
side: r,
|
|
23
20
|
children: /* @__PURE__ */ f(h.Popup, {
|
|
24
21
|
...v,
|
|
25
22
|
render: /* @__PURE__ */ f(n, {
|
|
26
23
|
backgroundColor: a,
|
|
27
|
-
borderRadius:
|
|
28
|
-
boxShadow:
|
|
24
|
+
borderRadius: s,
|
|
25
|
+
boxShadow: u,
|
|
29
26
|
padding: d,
|
|
30
27
|
..._,
|
|
31
|
-
className: e(
|
|
28
|
+
className: e(o, p),
|
|
32
29
|
style: m
|
|
33
30
|
})
|
|
34
31
|
})
|
|
@@ -42,12 +39,12 @@ function v(e) {
|
|
|
42
39
|
children: e
|
|
43
40
|
}) : e);
|
|
44
41
|
}
|
|
45
|
-
function y({ variant: r = "neutral", display:
|
|
42
|
+
function y({ variant: r = "neutral", display: a = "flex", alignItems: o = "center", gap: s = "8", minBlockSize: c = "sm", paddingInline: l = "12", borderRadius: u = "sm", color: d = r === "danger" ? "danger" : "fg", className: p, style: m, children: g, ..._ }) {
|
|
46
43
|
let [y, b] = t(_);
|
|
47
44
|
return /* @__PURE__ */ f(h.Item, {
|
|
48
45
|
...b,
|
|
49
46
|
render: /* @__PURE__ */ f(n, {
|
|
50
|
-
display:
|
|
47
|
+
display: a,
|
|
51
48
|
alignItems: o,
|
|
52
49
|
gap: s,
|
|
53
50
|
minBlockSize: c,
|
|
@@ -55,20 +52,20 @@ function y({ variant: r = "neutral", display: i = "flex", alignItems: o = "cente
|
|
|
55
52
|
borderRadius: u,
|
|
56
53
|
color: d,
|
|
57
54
|
...y,
|
|
58
|
-
className: e(
|
|
55
|
+
className: e(i, p),
|
|
59
56
|
style: m
|
|
60
57
|
}),
|
|
61
58
|
children: v(g)
|
|
62
59
|
});
|
|
63
60
|
}
|
|
64
|
-
function b({ href: r, disabled:
|
|
61
|
+
function b({ href: r, disabled: o = !1, closeOnClick: s = !0, onClick: c, display: l = "flex", alignItems: u = "center", gap: d = "8", minBlockSize: p = "sm", paddingInline: m = "12", borderRadius: g = "sm", color: _ = "fg", className: y, style: b, children: x, ...S }) {
|
|
65
62
|
let [C, w] = t(S);
|
|
66
63
|
return /* @__PURE__ */ f(h.LinkItem, {
|
|
67
64
|
...w,
|
|
68
|
-
"aria-disabled":
|
|
69
|
-
closeOnClick: !
|
|
70
|
-
href:
|
|
71
|
-
onClick:
|
|
65
|
+
"aria-disabled": o || void 0,
|
|
66
|
+
closeOnClick: !o && s,
|
|
67
|
+
href: o ? void 0 : r,
|
|
68
|
+
onClick: o ? void 0 : c,
|
|
72
69
|
render: /* @__PURE__ */ f(n, {
|
|
73
70
|
as: "a",
|
|
74
71
|
display: l,
|
|
@@ -79,21 +76,21 @@ function b({ href: r, disabled: i = !1, closeOnClick: s = !0, onClick: c, displa
|
|
|
79
76
|
borderRadius: g,
|
|
80
77
|
color: _,
|
|
81
78
|
...C,
|
|
82
|
-
className: e(
|
|
79
|
+
className: e(i, a, y),
|
|
83
80
|
style: b
|
|
84
81
|
}),
|
|
85
82
|
children: v(x)
|
|
86
83
|
});
|
|
87
84
|
}
|
|
88
|
-
function x({ marginBlock: r = "4", marginInline: i = "8", className: a, style: o, ...
|
|
89
|
-
let [l, u] = t(
|
|
85
|
+
function x({ marginBlock: r = "4", marginInline: i = "8", className: a, style: o, ...c }) {
|
|
86
|
+
let [l, u] = t(c);
|
|
90
87
|
return /* @__PURE__ */ f(h.Separator, {
|
|
91
88
|
...u,
|
|
92
89
|
render: /* @__PURE__ */ f(n, {
|
|
93
90
|
marginBlock: r,
|
|
94
91
|
marginInline: i,
|
|
95
92
|
...l,
|
|
96
|
-
className: e(
|
|
93
|
+
className: e(s, a),
|
|
97
94
|
style: o
|
|
98
95
|
})
|
|
99
96
|
});
|
package/dist/docs/Menu.md
CHANGED
|
@@ -113,8 +113,8 @@ A list of actions that opens from a button: a row's "Edit, Duplicate, Delete", a
|
|
|
113
113
|
## Accessibility
|
|
114
114
|
|
|
115
115
|
- The trigger has `aria-haspopup="menu"` and `aria-expanded`; the popup is `role="menu"` labelled by the trigger, items and link items are `role="menuitem"` (a link item is an `<a>` with an `href`, so the browser treats it as a link), groups are `role="group"` named by their label.
|
|
116
|
-
- Opening from the keyboard focuses the first item; from the pointer, the popup. Focus stays in the menu until it closes,
|
|
117
|
-
- A closed menu stays on the page while it fades out, but is `aria-hidden` from the moment it closes, so a menu opened during the fade (the next row's) is the only one a screen reader or a role query finds
|
|
116
|
+
- Opening from the keyboard focuses the first item; from the pointer, the popup. Focus stays in the menu until it closes. Closed by Esc, an item or `open={false}`, focus returns at once to the trigger that opened it, so a Tab pressed while it fades goes on to the control after the trigger. A press outside, a Tab out, a hover menu the pointer left, or a popup with `finalFocus` leaves focus to Base UI, which places it when the fade ends.
|
|
117
|
+
- A closed menu stays on the page while it fades out, but is `inert` and `aria-hidden` from the moment it closes, so a menu opened during the fade (the next row's) is the only one a screen reader or a role query finds, and nothing in the fading one takes focus or a click.
|
|
118
118
|
- The highlighted item gets a fill (`bgMuted` in light mode; in dark mode `bgRaised` with 10% `fg` mixed in, since `bgMuted` sits too close to the popup there), and the shared focus ring when reached from the keyboard. Under forced colors it is `Highlight` with `HighlightText`, disabled items are `GrayText` on the page's fill even when highlighted (`GrayText` pairs with `Canvas` only), and the popup keeps its border.
|
|
119
119
|
- The danger item's `danger` color passes 4.5:1 on the popup and on the highlight fill in every preset (`Menu.test.tsx` checks it, with `fg` and `fgMuted`); the word ("Delete") carries the meaning, not the color.
|
|
120
120
|
|
package/dist/docs/manifest.json
CHANGED
package/dist/popup/client.mjs
CHANGED
|
@@ -7,7 +7,8 @@ import { createContext as i, use as a } from "react";
|
|
|
7
7
|
//#region src/popup/client.tsx
|
|
8
8
|
var o = i({
|
|
9
9
|
container: { current: null },
|
|
10
|
-
ref: () => {}
|
|
10
|
+
ref: () => {},
|
|
11
|
+
trigger: { current: null }
|
|
11
12
|
});
|
|
12
13
|
function s({ children: e }) {
|
|
13
14
|
return /* @__PURE__ */ r(o, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jonmilner/ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"THIRD_PARTY_NOTICES.md"
|
|
@@ -166,6 +166,7 @@
|
|
|
166
166
|
"typecheck": "tsc -p tsconfig.json",
|
|
167
167
|
"test": "playwright install --only-shell chromium && vp test run",
|
|
168
168
|
"metrics": "node scripts/import-styles.ts",
|
|
169
|
+
"metrics:atoms": "node scripts/atoms-usage.ts",
|
|
169
170
|
"size": "size-limit",
|
|
170
171
|
"size:history": "node scripts/size-history.ts",
|
|
171
172
|
"check:publint": "publint --strict",
|