@jonmilner/ui 0.4.2 → 0.4.4

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.
@@ -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{:where(._393eil0[data-closed])>[data-base-ui-focus-guard]{visibility:hidden}._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}}}
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}}}
@@ -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">;
@@ -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 { triggerElement as r, usePopupScope as i } from "../popup/client.mjs";
6
- import { positioner as a } from "./Menu.css.mjs";
7
- import { jsx as o } from "react/jsx-runtime";
8
- import { Menu as s } from "@base-ui/react/menu";
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 c({ disabled: e = !1, openOnHover: t, delay: n, closeDelay: a, handle: c, payload: l, ...u }) {
11
- let { ref: d } = i();
12
- return /* @__PURE__ */ o(s.Trigger, {
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: a,
17
- handle: c,
18
- payload: l,
19
- ref: d,
20
- render: r(u)
17
+ closeDelay: r,
18
+ handle: o,
19
+ payload: c,
20
+ ref: u,
21
+ render: i(l)
21
22
  });
22
23
  }
23
- function l({ children: e }) {
24
- let { container: t } = i();
25
- return /* @__PURE__ */ o(s.Portal, {
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
- function u(r) {
31
- return /* @__PURE__ */ o(s.Positioner, {
32
- ...r,
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: (r, { open: i }) => {
35
- let [, s] = t(r);
36
- return /* @__PURE__ */ o(n, {
37
- ...s,
38
- "aria-hidden": !i || void 0,
39
- className: e(a, s.className),
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 { l as MenuPortal, u as MenuPositioner, c as MenuTrigger };
112
+ export { h as MenuPortal, v as MenuPositioner, _ as MenuRootScope, m as MenuTrigger };
@@ -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({ children, ...props }: MenuProps): import("react").JSX.Element;
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;
@@ -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 { PopupScope as i } from "../popup/client.mjs";
6
- import { item as a, linkItem as o, popup as s, separator as c } from "./Menu.css.mjs";
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({ children: e, ...t }) {
13
- return /* @__PURE__ */ f(i, { children: /* @__PURE__ */ f(h.Root, {
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: o = "med", boxShadow: c = "med", padding: d = "4", className: p, style: m, ...g }) {
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(l, { children: /* @__PURE__ */ f(u, {
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: o,
28
- boxShadow: c,
24
+ borderRadius: s,
25
+ boxShadow: u,
29
26
  padding: d,
30
27
  ..._,
31
- className: e(s, p),
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: i = "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, ..._ }) {
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: i,
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(a, p),
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: i = !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 }) {
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": i || void 0,
69
- closeOnClick: !i && s,
70
- href: i ? void 0 : r,
71
- onClick: i ? void 0 : c,
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(a, o, y),
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, ...s }) {
89
- let [l, u] = t(s);
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(c, a),
93
+ className: e(s, a),
97
94
  style: o
98
95
  })
99
96
  });
package/dist/docs/Icon.md CHANGED
@@ -88,9 +88,12 @@ Generated from `src/icons/svg/` and exported from `@jonmilner/ui/icons`; each ta
88
88
  - `InboxIcon` (`inbox.svg`)
89
89
  - `InfoIcon` (`info.svg`)
90
90
  - `LoaderCircleIcon` (`loader-circle.svg`)
91
+ - `PencilIcon` (`pencil.svg`)
92
+ - `PlusIcon` (`plus.svg`)
91
93
  - `RefreshCwIcon` (`refresh-cw.svg`)
92
94
  - `SearchIcon` (`search.svg`)
93
95
  - `SettingsIcon` (`settings.svg`)
96
+ - `Trash2Icon` (`trash-2.svg`)
94
97
  - `XIcon` (`x.svg`)
95
98
 
96
99
  <!-- icons:end -->
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, then returns to the trigger.
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. Nothing in it is in the tab order. Focus stays in it until the fade ends, then returns to the trigger.
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
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "./manifest.schema.json",
3
3
  "package": "@jonmilner/ui",
4
- "version": "0.4.2",
4
+ "version": "0.4.4",
5
5
  "components": [
6
6
  {
7
7
  "name": "AlertDialog",
@@ -2759,9 +2759,12 @@
2759
2759
  "InboxIcon",
2760
2760
  "InfoIcon",
2761
2761
  "LoaderCircleIcon",
2762
+ "PencilIcon",
2763
+ "PlusIcon",
2762
2764
  "RefreshCwIcon",
2763
2765
  "SearchIcon",
2764
2766
  "SettingsIcon",
2767
+ "Trash2Icon",
2765
2768
  "XIcon"
2766
2769
  ],
2767
2770
  "tokens": {
@@ -0,0 +1,4 @@
1
+ import { IconProps } from "../Icon/index.mjs";
2
+ //#region src/icons/PencilIcon.d.ts
3
+ export declare function PencilIcon(props: Omit<IconProps, "children" | "viewBox">): import("react").JSX.Element;
4
+ //#endregion
@@ -0,0 +1,11 @@
1
+ import { Icon as e } from "../Icon/index.mjs";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ //#region src/icons/PencilIcon.tsx
4
+ function n(n) {
5
+ return /* @__PURE__ */ t(e, {
6
+ ...n,
7
+ children: /* @__PURE__ */ t("path", { d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497zM15 5l4 4" })
8
+ });
9
+ }
10
+ //#endregion
11
+ export { n as PencilIcon };
@@ -0,0 +1,4 @@
1
+ import { IconProps } from "../Icon/index.mjs";
2
+ //#region src/icons/PlusIcon.d.ts
3
+ export declare function PlusIcon(props: Omit<IconProps, "children" | "viewBox">): import("react").JSX.Element;
4
+ //#endregion
@@ -0,0 +1,11 @@
1
+ import { Icon as e } from "../Icon/index.mjs";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ //#region src/icons/PlusIcon.tsx
4
+ function n(n) {
5
+ return /* @__PURE__ */ t(e, {
6
+ ...n,
7
+ children: /* @__PURE__ */ t("path", { d: "M5 12h14M12 5v14" })
8
+ });
9
+ }
10
+ //#endregion
11
+ export { n as PlusIcon };
@@ -0,0 +1,4 @@
1
+ import { IconProps } from "../Icon/index.mjs";
2
+ //#region src/icons/Trash2Icon.d.ts
3
+ export declare function Trash2Icon(props: Omit<IconProps, "children" | "viewBox">): import("react").JSX.Element;
4
+ //#endregion
@@ -0,0 +1,11 @@
1
+ import { Icon as e } from "../Icon/index.mjs";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ //#region src/icons/Trash2Icon.tsx
4
+ function n(n) {
5
+ return /* @__PURE__ */ t(e, {
6
+ ...n,
7
+ children: /* @__PURE__ */ t("path", { d: "M10 11v6M14 11v6M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
8
+ });
9
+ }
10
+ //#endregion
11
+ export { n as Trash2Icon };
@@ -14,12 +14,15 @@ import { GitPullRequestDraftIcon } from "./GitPullRequestDraftIcon.mjs";
14
14
  import { GitPullRequestIcon } from "./GitPullRequestIcon.mjs";
15
15
  import { InboxIcon } from "./InboxIcon.mjs";
16
16
  import { LoaderCircleIcon } from "./LoaderCircleIcon.mjs";
17
+ import { PencilIcon } from "./PencilIcon.mjs";
18
+ import { PlusIcon } from "./PlusIcon.mjs";
17
19
  import { RefreshCwIcon } from "./RefreshCwIcon.mjs";
18
20
  import { SearchIcon } from "./SearchIcon.mjs";
19
21
  import { SettingsIcon } from "./SettingsIcon.mjs";
22
+ import { Trash2Icon } from "./Trash2Icon.mjs";
20
23
  import { XIcon } from "./XIcon.mjs";
21
24
  //#region src/icons/index.d.ts
22
- export declare const iconNames: readonly ["ArrowLeftIcon", "ArrowRightIcon", "CheckIcon", "ChevronDownIcon", "ChevronRightIcon", "CircleAlertIcon", "CircleCheckIcon", "CircleDotIcon", "CircleSlashIcon", "GitMergeIcon", "GitPullRequestClosedIcon", "GitPullRequestDraftIcon", "GitPullRequestIcon", "InboxIcon", "InfoIcon", "LoaderCircleIcon", "RefreshCwIcon", "SearchIcon", "SettingsIcon", "XIcon"];
25
+ export declare const iconNames: readonly ["ArrowLeftIcon", "ArrowRightIcon", "CheckIcon", "ChevronDownIcon", "ChevronRightIcon", "CircleAlertIcon", "CircleCheckIcon", "CircleDotIcon", "CircleSlashIcon", "GitMergeIcon", "GitPullRequestClosedIcon", "GitPullRequestDraftIcon", "GitPullRequestIcon", "InboxIcon", "InfoIcon", "LoaderCircleIcon", "PencilIcon", "PlusIcon", "RefreshCwIcon", "SearchIcon", "SettingsIcon", "Trash2Icon", "XIcon"];
23
26
  export type IconName = (typeof iconNames)[number];
24
27
  //#endregion
25
- export { ArrowLeftIcon, ArrowRightIcon, CheckIcon, ChevronDownIcon, ChevronRightIcon, CircleAlertIcon, CircleCheckIcon, CircleDotIcon, CircleSlashIcon, GitMergeIcon, GitPullRequestClosedIcon, GitPullRequestDraftIcon, GitPullRequestIcon, InboxIcon, InfoIcon, LoaderCircleIcon, RefreshCwIcon, SearchIcon, SettingsIcon, XIcon };
28
+ export { ArrowLeftIcon, ArrowRightIcon, CheckIcon, ChevronDownIcon, ChevronRightIcon, CircleAlertIcon, CircleCheckIcon, CircleDotIcon, CircleSlashIcon, GitMergeIcon, GitPullRequestClosedIcon, GitPullRequestDraftIcon, GitPullRequestIcon, InboxIcon, InfoIcon, LoaderCircleIcon, PencilIcon, PlusIcon, RefreshCwIcon, SearchIcon, SettingsIcon, Trash2Icon, XIcon };
@@ -16,10 +16,13 @@ import { GitPullRequestDraftIcon as m } from "./GitPullRequestDraftIcon.mjs";
16
16
  import { GitPullRequestIcon as h } from "./GitPullRequestIcon.mjs";
17
17
  import { InboxIcon as g } from "./InboxIcon.mjs";
18
18
  import { LoaderCircleIcon as _ } from "./LoaderCircleIcon.mjs";
19
- import { RefreshCwIcon as v } from "./RefreshCwIcon.mjs";
20
- import { SettingsIcon as y } from "./SettingsIcon.mjs";
19
+ import { PencilIcon as v } from "./PencilIcon.mjs";
20
+ import { PlusIcon as y } from "./PlusIcon.mjs";
21
+ import { RefreshCwIcon as b } from "./RefreshCwIcon.mjs";
22
+ import { SettingsIcon as x } from "./SettingsIcon.mjs";
23
+ import { Trash2Icon as S } from "./Trash2Icon.mjs";
21
24
  //#region src/icons/index.ts
22
- var b = [
25
+ var C = [
23
26
  "ArrowLeftIcon",
24
27
  "ArrowRightIcon",
25
28
  "CheckIcon",
@@ -36,10 +39,13 @@ var b = [
36
39
  "InboxIcon",
37
40
  "InfoIcon",
38
41
  "LoaderCircleIcon",
42
+ "PencilIcon",
43
+ "PlusIcon",
39
44
  "RefreshCwIcon",
40
45
  "SearchIcon",
41
46
  "SettingsIcon",
47
+ "Trash2Icon",
42
48
  "XIcon"
43
49
  ];
44
50
  //#endregion
45
- export { s as ArrowLeftIcon, c as ArrowRightIcon, e as CheckIcon, n as ChevronDownIcon, l as ChevronRightIcon, t as CircleAlertIcon, a as CircleCheckIcon, u as CircleDotIcon, d as CircleSlashIcon, f as GitMergeIcon, p as GitPullRequestClosedIcon, m as GitPullRequestDraftIcon, h as GitPullRequestIcon, g as InboxIcon, o as InfoIcon, _ as LoaderCircleIcon, v as RefreshCwIcon, r as SearchIcon, y as SettingsIcon, i as XIcon, b as iconNames };
51
+ export { s as ArrowLeftIcon, c as ArrowRightIcon, e as CheckIcon, n as ChevronDownIcon, l as ChevronRightIcon, t as CircleAlertIcon, a as CircleCheckIcon, u as CircleDotIcon, d as CircleSlashIcon, f as GitMergeIcon, p as GitPullRequestClosedIcon, m as GitPullRequestDraftIcon, h as GitPullRequestIcon, g as InboxIcon, o as InfoIcon, _ as LoaderCircleIcon, v as PencilIcon, y as PlusIcon, b as RefreshCwIcon, r as SearchIcon, x as SettingsIcon, S as Trash2Icon, i as XIcon, C as iconNames };
@@ -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, {
@@ -8,7 +8,8 @@ function r() {
8
8
  container: { get current() {
9
9
  return r.current?.closest("[data-brand]") ?? null;
10
10
  } },
11
- ref: i
11
+ ref: i,
12
+ trigger: r
12
13
  }), [i]);
13
14
  }
14
15
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jonmilner/ui",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
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",