@hanzo/ui 8.0.66 → 8.0.69

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.
Files changed (200) hide show
  1. package/dist/backends/gui/accordion.cjs +69 -0
  2. package/dist/backends/gui/accordion.d.ts +57 -0
  3. package/dist/backends/gui/accordion.d.ts.map +1 -0
  4. package/dist/backends/gui/accordion.js +64 -0
  5. package/dist/backends/gui/accordion.js.map +1 -0
  6. package/dist/backends/gui/alert-dialog.cjs +91 -0
  7. package/dist/backends/gui/alert-dialog.d.ts +77 -0
  8. package/dist/backends/gui/alert-dialog.d.ts.map +1 -0
  9. package/dist/backends/gui/alert-dialog.js +79 -0
  10. package/dist/backends/gui/alert-dialog.js.map +1 -0
  11. package/dist/backends/gui/context-menu.cjs +189 -0
  12. package/dist/backends/gui/context-menu.d.ts +116 -0
  13. package/dist/backends/gui/context-menu.d.ts.map +1 -0
  14. package/dist/backends/gui/context-menu.js +140 -0
  15. package/dist/backends/gui/context-menu.js.map +1 -0
  16. package/dist/backends/gui/dropdown-menu.d.ts +1 -1
  17. package/dist/backends/gui/hover-card.cjs +76 -0
  18. package/dist/backends/gui/hover-card.d.ts +57 -0
  19. package/dist/backends/gui/hover-card.d.ts.map +1 -0
  20. package/dist/backends/gui/hover-card.js +72 -0
  21. package/dist/backends/gui/hover-card.js.map +1 -0
  22. package/dist/backends/gui/index.cjs +53 -3
  23. package/dist/backends/gui/index.d.ts +7 -1
  24. package/dist/backends/gui/index.d.ts.map +1 -1
  25. package/dist/backends/gui/index.js +12 -1
  26. package/dist/backends/gui/index.js.map +1 -1
  27. package/dist/backends/gui/layout.cjs +3 -2
  28. package/dist/backends/gui/layout.d.ts +1 -1
  29. package/dist/backends/gui/layout.d.ts.map +1 -1
  30. package/dist/backends/gui/layout.js +2 -2
  31. package/dist/backends/gui/layout.js.map +1 -1
  32. package/dist/backends/gui/radio-group.cjs +47 -0
  33. package/dist/backends/gui/radio-group.d.ts +36 -0
  34. package/dist/backends/gui/radio-group.d.ts.map +1 -0
  35. package/dist/backends/gui/radio-group.js +44 -0
  36. package/dist/backends/gui/radio-group.js.map +1 -0
  37. package/dist/backends/gui/toggle-group.cjs +114 -0
  38. package/dist/backends/gui/toggle-group.d.ts +57 -0
  39. package/dist/backends/gui/toggle-group.d.ts.map +1 -0
  40. package/dist/backends/gui/toggle-group.js +112 -0
  41. package/dist/backends/gui/toggle-group.js.map +1 -0
  42. package/dist/gallery.cjs +2 -2
  43. package/dist/gallery.d.ts.map +1 -1
  44. package/dist/gallery.js +3 -3
  45. package/dist/gallery.js.map +1 -1
  46. package/dist/glass.css +117 -0
  47. package/dist/gui-config.cjs +76 -43
  48. package/dist/gui-config.d.ts +204 -204
  49. package/dist/gui-config.d.ts.map +1 -1
  50. package/dist/gui-config.js +76 -43
  51. package/dist/gui-config.js.map +1 -1
  52. package/dist/index.cjs +57 -1
  53. package/dist/index.d.ts +3 -2
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +18 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/primitives/Accordion.cjs +8 -0
  58. package/dist/primitives/Accordion.d.ts +2 -0
  59. package/dist/primitives/Accordion.d.ts.map +1 -0
  60. package/dist/primitives/Accordion.js +5 -0
  61. package/dist/primitives/Accordion.js.map +1 -0
  62. package/dist/primitives/AccordionContent.cjs +8 -0
  63. package/dist/primitives/AccordionContent.d.ts +2 -0
  64. package/dist/primitives/AccordionContent.d.ts.map +1 -0
  65. package/dist/primitives/AccordionContent.js +5 -0
  66. package/dist/primitives/AccordionContent.js.map +1 -0
  67. package/dist/primitives/AccordionItem.cjs +8 -0
  68. package/dist/primitives/AccordionItem.d.ts +2 -0
  69. package/dist/primitives/AccordionItem.d.ts.map +1 -0
  70. package/dist/primitives/AccordionItem.js +5 -0
  71. package/dist/primitives/AccordionItem.js.map +1 -0
  72. package/dist/primitives/AccordionTrigger.cjs +8 -0
  73. package/dist/primitives/AccordionTrigger.d.ts +2 -0
  74. package/dist/primitives/AccordionTrigger.d.ts.map +1 -0
  75. package/dist/primitives/AccordionTrigger.js +5 -0
  76. package/dist/primitives/AccordionTrigger.js.map +1 -0
  77. package/dist/primitives/AlertDialog.cjs +8 -0
  78. package/dist/primitives/AlertDialog.d.ts +2 -0
  79. package/dist/primitives/AlertDialog.d.ts.map +1 -0
  80. package/dist/primitives/AlertDialog.js +5 -0
  81. package/dist/primitives/AlertDialog.js.map +1 -0
  82. package/dist/primitives/AlertDialogAction.cjs +8 -0
  83. package/dist/primitives/AlertDialogAction.d.ts +2 -0
  84. package/dist/primitives/AlertDialogAction.d.ts.map +1 -0
  85. package/dist/primitives/AlertDialogAction.js +5 -0
  86. package/dist/primitives/AlertDialogAction.js.map +1 -0
  87. package/dist/primitives/AlertDialogCancel.cjs +8 -0
  88. package/dist/primitives/AlertDialogCancel.d.ts +2 -0
  89. package/dist/primitives/AlertDialogCancel.d.ts.map +1 -0
  90. package/dist/primitives/AlertDialogCancel.js +5 -0
  91. package/dist/primitives/AlertDialogCancel.js.map +1 -0
  92. package/dist/primitives/AlertDialogContent.cjs +8 -0
  93. package/dist/primitives/AlertDialogContent.d.ts +2 -0
  94. package/dist/primitives/AlertDialogContent.d.ts.map +1 -0
  95. package/dist/primitives/AlertDialogContent.js +5 -0
  96. package/dist/primitives/AlertDialogContent.js.map +1 -0
  97. package/dist/primitives/AlertDialogDescription.cjs +8 -0
  98. package/dist/primitives/AlertDialogDescription.d.ts +2 -0
  99. package/dist/primitives/AlertDialogDescription.d.ts.map +1 -0
  100. package/dist/primitives/AlertDialogDescription.js +5 -0
  101. package/dist/primitives/AlertDialogDescription.js.map +1 -0
  102. package/dist/primitives/AlertDialogFooter.cjs +8 -0
  103. package/dist/primitives/AlertDialogFooter.d.ts +2 -0
  104. package/dist/primitives/AlertDialogFooter.d.ts.map +1 -0
  105. package/dist/primitives/AlertDialogFooter.js +5 -0
  106. package/dist/primitives/AlertDialogFooter.js.map +1 -0
  107. package/dist/primitives/AlertDialogHeader.cjs +8 -0
  108. package/dist/primitives/AlertDialogHeader.d.ts +2 -0
  109. package/dist/primitives/AlertDialogHeader.d.ts.map +1 -0
  110. package/dist/primitives/AlertDialogHeader.js +5 -0
  111. package/dist/primitives/AlertDialogHeader.js.map +1 -0
  112. package/dist/primitives/AlertDialogOverlay.cjs +8 -0
  113. package/dist/primitives/AlertDialogOverlay.d.ts +2 -0
  114. package/dist/primitives/AlertDialogOverlay.d.ts.map +1 -0
  115. package/dist/primitives/AlertDialogOverlay.js +5 -0
  116. package/dist/primitives/AlertDialogOverlay.js.map +1 -0
  117. package/dist/primitives/AlertDialogPortal.cjs +8 -0
  118. package/dist/primitives/AlertDialogPortal.d.ts +2 -0
  119. package/dist/primitives/AlertDialogPortal.d.ts.map +1 -0
  120. package/dist/primitives/AlertDialogPortal.js +5 -0
  121. package/dist/primitives/AlertDialogPortal.js.map +1 -0
  122. package/dist/primitives/AlertDialogTitle.cjs +8 -0
  123. package/dist/primitives/AlertDialogTitle.d.ts +2 -0
  124. package/dist/primitives/AlertDialogTitle.d.ts.map +1 -0
  125. package/dist/primitives/AlertDialogTitle.js +5 -0
  126. package/dist/primitives/AlertDialogTitle.js.map +1 -0
  127. package/dist/primitives/AlertDialogTrigger.cjs +8 -0
  128. package/dist/primitives/AlertDialogTrigger.d.ts +2 -0
  129. package/dist/primitives/AlertDialogTrigger.d.ts.map +1 -0
  130. package/dist/primitives/AlertDialogTrigger.js +5 -0
  131. package/dist/primitives/AlertDialogTrigger.js.map +1 -0
  132. package/dist/primitives/Anchor.cjs +8 -0
  133. package/dist/primitives/Anchor.d.ts +2 -0
  134. package/dist/primitives/Anchor.d.ts.map +1 -0
  135. package/dist/primitives/Anchor.js +5 -0
  136. package/dist/primitives/Anchor.js.map +1 -0
  137. package/dist/primitives/HoverCard.cjs +8 -0
  138. package/dist/primitives/HoverCard.d.ts +2 -0
  139. package/dist/primitives/HoverCard.d.ts.map +1 -0
  140. package/dist/primitives/HoverCard.js +5 -0
  141. package/dist/primitives/HoverCard.js.map +1 -0
  142. package/dist/primitives/HoverCardContent.cjs +8 -0
  143. package/dist/primitives/HoverCardContent.d.ts +2 -0
  144. package/dist/primitives/HoverCardContent.d.ts.map +1 -0
  145. package/dist/primitives/HoverCardContent.js +5 -0
  146. package/dist/primitives/HoverCardContent.js.map +1 -0
  147. package/dist/primitives/HoverCardTrigger.cjs +8 -0
  148. package/dist/primitives/HoverCardTrigger.d.ts +2 -0
  149. package/dist/primitives/HoverCardTrigger.d.ts.map +1 -0
  150. package/dist/primitives/HoverCardTrigger.js +5 -0
  151. package/dist/primitives/HoverCardTrigger.js.map +1 -0
  152. package/dist/primitives/RadioGroup.cjs +8 -0
  153. package/dist/primitives/RadioGroup.d.ts +2 -0
  154. package/dist/primitives/RadioGroup.d.ts.map +1 -0
  155. package/dist/primitives/RadioGroup.js +5 -0
  156. package/dist/primitives/RadioGroup.js.map +1 -0
  157. package/dist/primitives/RadioGroupItem.cjs +8 -0
  158. package/dist/primitives/RadioGroupItem.d.ts +2 -0
  159. package/dist/primitives/RadioGroupItem.d.ts.map +1 -0
  160. package/dist/primitives/RadioGroupItem.js +5 -0
  161. package/dist/primitives/RadioGroupItem.js.map +1 -0
  162. package/dist/primitives/ToggleGroup.cjs +8 -0
  163. package/dist/primitives/ToggleGroup.d.ts +2 -0
  164. package/dist/primitives/ToggleGroup.d.ts.map +1 -0
  165. package/dist/primitives/ToggleGroup.js +5 -0
  166. package/dist/primitives/ToggleGroup.js.map +1 -0
  167. package/dist/primitives/ToggleGroupItem.cjs +8 -0
  168. package/dist/primitives/ToggleGroupItem.d.ts +2 -0
  169. package/dist/primitives/ToggleGroupItem.d.ts.map +1 -0
  170. package/dist/primitives/ToggleGroupItem.js +5 -0
  171. package/dist/primitives/ToggleGroupItem.js.map +1 -0
  172. package/dist/product/AppHeader.cjs +3 -3
  173. package/dist/product/AppHeader.js +3 -3
  174. package/dist/product/CommerceResource.cjs +1 -1
  175. package/dist/product/CommerceResource.js +1 -1
  176. package/dist/product/ConfirmDelete.cjs +1 -1
  177. package/dist/product/ConfirmDelete.js +1 -1
  178. package/dist/product/EmptyState.cjs +1 -1
  179. package/dist/product/EmptyState.js +1 -1
  180. package/dist/product/Field.cjs +8 -3
  181. package/dist/product/Field.d.ts.map +1 -1
  182. package/dist/product/Field.js +8 -3
  183. package/dist/product/Field.js.map +1 -1
  184. package/dist/product/Filters.cjs +1 -1
  185. package/dist/product/Filters.js +1 -1
  186. package/dist/product/OrgSwitcher.cjs +2 -2
  187. package/dist/product/OrgSwitcher.js +2 -2
  188. package/dist/product/Pagination.cjs +1 -1
  189. package/dist/product/Pagination.js +1 -1
  190. package/dist/product/PrimaryButton.cjs +12 -0
  191. package/dist/product/PrimaryButton.d.ts.map +1 -1
  192. package/dist/product/PrimaryButton.js +12 -0
  193. package/dist/product/PrimaryButton.js.map +1 -1
  194. package/dist/product/UserMenu.cjs +1 -1
  195. package/dist/product/UserMenu.js +1 -1
  196. package/dist/product/social/PostCard.cjs +1 -1
  197. package/dist/product/social/PostCard.js +1 -1
  198. package/dist/styles.css +244 -45
  199. package/dist/theme.css +190 -41
  200. package/package.json +2 -2
@@ -0,0 +1,189 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.ContextMenuRadioGroup = exports.ContextMenuSubTrigger = exports.ContextMenuSubContent = exports.ContextMenuSub = exports.ContextMenuPortal = exports.ContextMenuGroup = exports.ContextMenuSeparator = exports.ContextMenuLabel = exports.ContextMenuRadioItem = exports.ContextMenuCheckboxItem = exports.ContextMenuItem = exports.ContextMenuContent = exports.ContextMenuTrigger = exports.ContextMenu = void 0;
38
+ exports.ContextMenuShortcut = ContextMenuShortcut;
39
+ const jsx_runtime_1 = require("react/jsx-runtime");
40
+ /**
41
+ * ContextMenu — the right-click menu, native to @hanzo/gui.
42
+ *
43
+ * `@hanzogui/context-menu` already ships the whole compound surface (Root/Trigger/
44
+ * Portal/Content/Group/Label/Item/CheckboxItem/RadioGroup/RadioItem/ItemIndicator/
45
+ * Separator/Sub/SubTrigger/SubContent) with the a11y (`role="menu"`,
46
+ * `menuitem`/`menuitemcheckbox`/`menuitemradio` + `aria-checked`, `aria-expanded`
47
+ * on a SubTrigger), the roving arrow-key focus, the typeahead, the cursor
48
+ * anchoring and the dismiss behaviour. It IS `Menu` with an `onContextMenu` (and
49
+ * a 700ms long-press on touch) trigger instead of a click one. This file only
50
+ * FLATTENS `ContextMenu.X` into the 15 `ContextMenuX` names and dresses them in
51
+ * the Hanzo tokens, so there is one menu design rather than two shapes of it.
52
+ *
53
+ * NO RENAMES. The API is @radix-ui/react-context-menu's, prop for prop — a
54
+ * consumer migrates by changing the import and nothing else. The `side`/`align`/
55
+ * `sideOffset` hoist that Popover and HoverCard need does not arise here: a
56
+ * context menu is anchored at the cursor, so Radix never put those on its
57
+ * Content either (gui `Omit`s them for the same reason).
58
+ *
59
+ * Cross-platform: gui style props only — no Tailwind class strings, no Radix, no
60
+ * DOM APIs. Rows are 32px tall (the design density) and `touch()` lifts the real
61
+ * tap target to 44px — on web and Tauri as well as native.
62
+ *
63
+ * `ContextMenuContent` mounts its OWN `ContextMenu.Portal`, so callers never wrap
64
+ * it — and re-applies the trigger's resolved theme inside the portal via
65
+ * `PortalTheme` (gui portals re-root the subtree, so React theme context does not
66
+ * flow).
67
+ *
68
+ * The geometry below is the SAME 32px row, 8px gutter, 44px tap and panel
69
+ * treatment as `dropdown-menu.tsx` — two menu geometries would be two design
70
+ * systems. It is restated rather than imported only because those constants are
71
+ * module-private there; hoist both onto one module when the barrel is wired.
72
+ */
73
+ const React = __importStar(require("react"));
74
+ const gui_1 = require("@hanzo/gui");
75
+ const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
76
+ const gesture_1 = require("./gesture.cjs");
77
+ const ink_1 = require("./ink.cjs");
78
+ const slot_1 = require("./slot.cjs");
79
+ const portal_theme_1 = require("../../product/menu/portal-theme.cjs");
80
+ // ── Geometry — literal px on the 8-grid; a 32px row expands to a 44px tap ──────
81
+ const ROW_H = 32;
82
+ const TAP_MIN = 44;
83
+ const ROW_PX = 8;
84
+ /** The one menu width floor — shared with DropdownMenu. */
85
+ const MIN_W = 200;
86
+ const INSET_PL = 32;
87
+ const INDICATOR_SLOT = 14;
88
+ const ICON = 16;
89
+ const panel = {
90
+ bg: '$color2',
91
+ borderColor: '$borderColor',
92
+ borderWidth: 1,
93
+ rounded: '$4',
94
+ p: 4,
95
+ minW: MIN_W,
96
+ overflow: 'hidden',
97
+ shadowColor: 'rgba(0,0,0,0.45)',
98
+ shadowRadius: 20,
99
+ shadowOffset: { width: 0, height: 10 },
100
+ };
101
+ const row = {
102
+ items: 'center',
103
+ gap: ROW_PX,
104
+ px: ROW_PX,
105
+ minH: ROW_H,
106
+ rounded: '$3',
107
+ select: 'none',
108
+ cursor: 'pointer',
109
+ ...(0, gesture_1.touch)(ROW_H, TAP_MIN, 'y'),
110
+ hoverStyle: { bg: '$color5' },
111
+ focusStyle: { bg: '$color5' },
112
+ pressStyle: { bg: '$color6' },
113
+ };
114
+ /** Row text style — free-form children go through `ink()` so a bare string renders on native. */
115
+ const label = { size: '$2', color: '$color12' };
116
+ /** Left indicator well shared by checkbox + radio rows. */
117
+ const Indicator = ({ children }) => ((0, jsx_runtime_1.jsx)(gui_1.XStack, { position: "absolute", l: ROW_PX, width: INDICATOR_SLOT, height: INDICATOR_SLOT, items: "center", justify: "center", pointerEvents: "none", children: (0, jsx_runtime_1.jsx)(gui_1.ContextMenu.ItemIndicator, { children: children }) }));
118
+ // ── Passthroughs — the gui part already IS the part ─────────────────────────────
119
+ const ContextMenu = gui_1.ContextMenu;
120
+ exports.ContextMenu = ContextMenu;
121
+ const ContextMenuTrigger = gui_1.ContextMenu.Trigger;
122
+ exports.ContextMenuTrigger = ContextMenuTrigger;
123
+ const ContextMenuGroup = gui_1.ContextMenu.Group;
124
+ exports.ContextMenuGroup = ContextMenuGroup;
125
+ const ContextMenuPortal = gui_1.ContextMenu.Portal;
126
+ exports.ContextMenuPortal = ContextMenuPortal;
127
+ const ContextMenuSub = gui_1.ContextMenu.Sub;
128
+ exports.ContextMenuSub = ContextMenuSub;
129
+ const ContextMenuRadioGroup = gui_1.ContextMenu.RadioGroup;
130
+ exports.ContextMenuRadioGroup = ContextMenuRadioGroup;
131
+ /**
132
+ * Both Content forwardRefs carry an EXPLICIT type. `tsc --noEmit` is happy without
133
+ * one; the build is not (TS2742). Declaration emit has to name the inferred type,
134
+ * and gui's context-menu types resolve through `@hanzogui/context-menu`'s own
135
+ * `createNonNativeContextMenu` plus `react-native` — paths reachable from gui but
136
+ * not from this package's `dist/`, so the emitted `.d.ts` referenced files a
137
+ * consumer does not have. Naming the props type (which is exported, hence
138
+ * portable) is what keeps the declaration self-contained. Only these two hit it:
139
+ * the row components are declared through `ContextMenuItemProps`, which is already
140
+ * a named export.
141
+ */
142
+ const ContextMenuContent = /* @__PURE__ */ React.forwardRef(function ContextMenuContent({ children, ...props }, ref) {
143
+ const themeName = (0, portal_theme_1.useThemeName)();
144
+ return ((0, jsx_runtime_1.jsx)(gui_1.ContextMenu.Portal, { children: (0, jsx_runtime_1.jsx)(portal_theme_1.PortalTheme, { name: themeName, children: (0, jsx_runtime_1.jsx)(gui_1.ContextMenu.Content, { ref: ref, ...(0, slot_1.slot)('context-menu-content'), ...panel, ...props, children: children }) }) }));
145
+ });
146
+ exports.ContextMenuContent = ContextMenuContent;
147
+ const ContextMenuSubContent = /* @__PURE__ */ React.forwardRef(function ContextMenuSubContent(props, ref) {
148
+ return ((0, jsx_runtime_1.jsx)(gui_1.ContextMenu.SubContent, { ref: ref, ...(0, slot_1.slot)('context-menu-sub-content'), ...panel, ...props }));
149
+ });
150
+ exports.ContextMenuSubContent = ContextMenuSubContent;
151
+ const ContextMenuItem = /* @__PURE__ */ React.forwardRef(function ContextMenuItem({ inset, variant = 'default', disabled, children, ...props }, ref) {
152
+ return ((0, jsx_runtime_1.jsx)(gui_1.ContextMenu.Item, { ref: ref, ...(0, slot_1.slot)('context-menu-item'), "data-inset": inset, "data-variant": variant, disabled: disabled, ...row, pl: inset ? INSET_PL : ROW_PX, theme: variant === 'destructive' ? 'red' : undefined, opacity: disabled ? 0.5 : 1, cursor: disabled ? 'default' : 'pointer', ...props, children: (0, ink_1.ink)(children, undefined, label) }));
153
+ });
154
+ exports.ContextMenuItem = ContextMenuItem;
155
+ const ContextMenuCheckboxItem = /* @__PURE__ */ React.forwardRef(function ContextMenuCheckboxItem({ children, checked, ...props }, ref) {
156
+ return ((0, jsx_runtime_1.jsxs)(gui_1.ContextMenu.CheckboxItem, { ref: ref, ...(0, slot_1.slot)('context-menu-checkbox-item'), checked: checked, ...row, pl: INSET_PL, ...props, children: [(0, jsx_runtime_1.jsx)(Indicator, { children: (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Check, { size: ICON }) }), (0, ink_1.ink)(children, undefined, label)] }));
157
+ });
158
+ exports.ContextMenuCheckboxItem = ContextMenuCheckboxItem;
159
+ const ContextMenuRadioItem = /* @__PURE__ */ React.forwardRef(function ContextMenuRadioItem({ children, value, ...props }, ref) {
160
+ return ((0, jsx_runtime_1.jsxs)(gui_1.ContextMenu.RadioItem, { ref: ref, ...(0, slot_1.slot)('context-menu-radio-item'),
161
+ // Named rather than left to the spread: gui's native-menu wrapper types the
162
+ // part as a UNION of prop shapes, and a rest spread cannot prove the
163
+ // required `value` survived it.
164
+ value: value, ...row, pl: INSET_PL, ...props, children: [(0, jsx_runtime_1.jsx)(Indicator, { children: (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Circle, { size: 8, fill: "currentColor" }) }), (0, ink_1.ink)(children, undefined, label)] }));
165
+ });
166
+ exports.ContextMenuRadioItem = ContextMenuRadioItem;
167
+ /**
168
+ * gui casts `SubTrigger` to a bare `React.FC` ("to avoid TS error", its words),
169
+ * which drops `ref` from the type while the runtime still forwards it. One cast,
170
+ * in one place, so the part keeps the ref every other row in this file has.
171
+ */
172
+ const SubTriggerBase = gui_1.ContextMenu.SubTrigger;
173
+ const ContextMenuSubTrigger = /* @__PURE__ */ React.forwardRef(function ContextMenuSubTrigger({ inset, children, ...props }, ref) {
174
+ return ((0, jsx_runtime_1.jsxs)(SubTriggerBase, { ref: ref, ...(0, slot_1.slot)('context-menu-sub-trigger'), "data-inset": inset, ...row, pl: inset ? INSET_PL : ROW_PX, ...props, children: [(0, ink_1.ink)(children, undefined, label), (0, jsx_runtime_1.jsx)(lucide_icons_2_1.ChevronRight, { size: ICON, ml: "auto", opacity: 0.6 })] }));
175
+ });
176
+ exports.ContextMenuSubTrigger = ContextMenuSubTrigger;
177
+ // ── Static rows ─────────────────────────────────────────────────────────────────
178
+ const ContextMenuLabel = /* @__PURE__ */ React.forwardRef(function ContextMenuLabel({ inset, ...props }, ref) {
179
+ return ((0, jsx_runtime_1.jsx)(gui_1.ContextMenu.Label, { ref: ref, ...(0, slot_1.slot)('context-menu-label'), "data-inset": inset, px: ROW_PX, py: 4, pl: inset ? INSET_PL : ROW_PX, fontSize: "$2", fontWeight: "500", color: "$color12", select: "none", ...props }));
180
+ });
181
+ exports.ContextMenuLabel = ContextMenuLabel;
182
+ const ContextMenuSeparator = /* @__PURE__ */ React.forwardRef(function ContextMenuSeparator(props, ref) {
183
+ return ((0, jsx_runtime_1.jsx)(gui_1.ContextMenu.Separator, { ref: ref, ...(0, slot_1.slot)('context-menu-separator'), height: 1, bg: "$borderColor", mx: 4, my: 4, ...props }));
184
+ });
185
+ exports.ContextMenuSeparator = ContextMenuSeparator;
186
+ /** Right-aligned shortcut hint. gui `Text`, not a raw `<span>`, so it renders on native. */
187
+ function ContextMenuShortcut(props) {
188
+ return ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('context-menu-shortcut'), ml: "auto", fontSize: "$1", letterSpacing: 1, color: "$color11", ...props }));
189
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * ContextMenu — the right-click menu, native to @hanzo/gui.
3
+ *
4
+ * `@hanzogui/context-menu` already ships the whole compound surface (Root/Trigger/
5
+ * Portal/Content/Group/Label/Item/CheckboxItem/RadioGroup/RadioItem/ItemIndicator/
6
+ * Separator/Sub/SubTrigger/SubContent) with the a11y (`role="menu"`,
7
+ * `menuitem`/`menuitemcheckbox`/`menuitemradio` + `aria-checked`, `aria-expanded`
8
+ * on a SubTrigger), the roving arrow-key focus, the typeahead, the cursor
9
+ * anchoring and the dismiss behaviour. It IS `Menu` with an `onContextMenu` (and
10
+ * a 700ms long-press on touch) trigger instead of a click one. This file only
11
+ * FLATTENS `ContextMenu.X` into the 15 `ContextMenuX` names and dresses them in
12
+ * the Hanzo tokens, so there is one menu design rather than two shapes of it.
13
+ *
14
+ * NO RENAMES. The API is @radix-ui/react-context-menu's, prop for prop — a
15
+ * consumer migrates by changing the import and nothing else. The `side`/`align`/
16
+ * `sideOffset` hoist that Popover and HoverCard need does not arise here: a
17
+ * context menu is anchored at the cursor, so Radix never put those on its
18
+ * Content either (gui `Omit`s them for the same reason).
19
+ *
20
+ * Cross-platform: gui style props only — no Tailwind class strings, no Radix, no
21
+ * DOM APIs. Rows are 32px tall (the design density) and `touch()` lifts the real
22
+ * tap target to 44px — on web and Tauri as well as native.
23
+ *
24
+ * `ContextMenuContent` mounts its OWN `ContextMenu.Portal`, so callers never wrap
25
+ * it — and re-applies the trigger's resolved theme inside the portal via
26
+ * `PortalTheme` (gui portals re-root the subtree, so React theme context does not
27
+ * flow).
28
+ *
29
+ * The geometry below is the SAME 32px row, 8px gutter, 44px tap and panel
30
+ * treatment as `dropdown-menu.tsx` — two menu geometries would be two design
31
+ * systems. It is restated rather than imported only because those constants are
32
+ * module-private there; hoist both onto one module when the barrel is wired.
33
+ */
34
+ import * as React from 'react';
35
+ import { ContextMenu as GuiContextMenu, Text, type GuiElement } from '@hanzo/gui';
36
+ declare const ContextMenu: typeof GuiContextMenu;
37
+ declare const ContextMenuTrigger: typeof GuiContextMenu.Trigger;
38
+ declare const ContextMenuGroup: typeof GuiContextMenu.Group;
39
+ declare const ContextMenuPortal: typeof GuiContextMenu.Portal;
40
+ declare const ContextMenuSub: typeof GuiContextMenu.Sub;
41
+ declare const ContextMenuRadioGroup: typeof GuiContextMenu.RadioGroup;
42
+ export type ContextMenuContentProps = React.ComponentProps<typeof GuiContextMenu.Content>;
43
+ export type ContextMenuSubContentProps = React.ComponentProps<typeof GuiContextMenu.SubContent>;
44
+ /**
45
+ * Both Content forwardRefs carry an EXPLICIT type. `tsc --noEmit` is happy without
46
+ * one; the build is not (TS2742). Declaration emit has to name the inferred type,
47
+ * and gui's context-menu types resolve through `@hanzogui/context-menu`'s own
48
+ * `createNonNativeContextMenu` plus `react-native` — paths reachable from gui but
49
+ * not from this package's `dist/`, so the emitted `.d.ts` referenced files a
50
+ * consumer does not have. Naming the props type (which is exported, hence
51
+ * portable) is what keeps the declaration self-contained. Only these two hit it:
52
+ * the row components are declared through `ContextMenuItemProps`, which is already
53
+ * a named export.
54
+ */
55
+ declare const ContextMenuContent: React.ForwardRefExoticComponent<ContextMenuContentProps & React.RefAttributes<GuiElement>>;
56
+ declare const ContextMenuSubContent: React.ForwardRefExoticComponent<ContextMenuSubContentProps & React.RefAttributes<GuiElement>>;
57
+ /**
58
+ * `inset` and `variant` are Radix's, and both are ALSO gui style props (`inset` is
59
+ * the CSS shorthand, `variant` a styled-component variant). Omitting them first is
60
+ * what makes `inset` a boolean flag again rather than an intersection with gui's
61
+ * type, under which the literal `true` does not typecheck.
62
+ */
63
+ export type ContextMenuItemProps = Omit<React.ComponentProps<typeof GuiContextMenu.Item>, 'inset' | 'variant'> & {
64
+ inset?: boolean;
65
+ variant?: 'default' | 'destructive';
66
+ };
67
+ declare const ContextMenuItem: React.ForwardRefExoticComponent<Omit<ContextMenuItemProps, "ref"> & React.RefAttributes<GuiElement>>;
68
+ declare const ContextMenuCheckboxItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@hanzogui/web").GetFinalProps<import("@hanzogui/web").StackNonStyleProps, import("@hanzogui/web").StackStyleBase, {
69
+ unstyled?: boolean | undefined;
70
+ }>, "scope" | keyof import("@hanzo/gui").MenuCheckboxItemProps> & import("@hanzo/gui").MenuCheckboxItemProps & {
71
+ scope?: string;
72
+ } & React.RefAttributes<GuiElement>, "ref"> & {
73
+ scope?: string;
74
+ } & React.RefAttributes<GuiElement> & Partial<Omit<Omit<import("@hanzo/gui").NativeMenuItemProps, "onSelect"> & {
75
+ checked?: boolean;
76
+ onCheckedChange?: (checked: boolean) => void;
77
+ value?: "mixed" | "on" | "off" | boolean;
78
+ onValueChange?: (state: "mixed" | "on" | "off", prevState: "mixed" | "on" | "off") => void;
79
+ key: string;
80
+ }, "scope" | keyof React.RefAttributes<GuiElement> | keyof import("@hanzo/gui").MenuCheckboxItemProps>>, "ref"> & React.RefAttributes<GuiElement>>;
81
+ declare const ContextMenuRadioItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@hanzogui/web").GetFinalProps<import("@hanzogui/web").StackNonStyleProps, import("@hanzogui/web").StackStyleBase, {
82
+ unstyled?: boolean | undefined;
83
+ }>, "scope" | keyof import("@hanzo/gui").MenuRadioItemProps> & import("@hanzo/gui").MenuRadioItemProps & {
84
+ scope?: string;
85
+ } & React.RefAttributes<GuiElement>, "ref"> & {
86
+ scope?: string;
87
+ } & React.RefAttributes<GuiElement> & Partial<Omit<any, "scope" | keyof React.RefAttributes<GuiElement> | keyof import("@hanzo/gui").MenuRadioItemProps>>, "ref"> & React.RefAttributes<GuiElement>>;
88
+ declare const ContextMenuSubTrigger: React.ForwardRefExoticComponent<Omit<Omit<import("@hanzo/gui").MenuSubTriggerProps & {
89
+ scope?: string;
90
+ } & React.RefAttributes<GuiElement>, "ref"> & {
91
+ children: React.ReactNode;
92
+ textValue?: string;
93
+ onSelect?: (event?: Event) => void;
94
+ } & {
95
+ disabled?: boolean;
96
+ hidden?: boolean;
97
+ destructive?: boolean;
98
+ key: string;
99
+ } & {
100
+ key: string;
101
+ }, "inset"> & {
102
+ inset?: boolean;
103
+ } & React.RefAttributes<GuiElement>>;
104
+ declare const ContextMenuLabel: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@hanzogui/web").GetFinalProps<import("@hanzogui/web").TextNonStyleProps, import("@hanzogui/web").TextStylePropsBase, {
105
+ unstyled?: boolean | undefined;
106
+ size?: import("@hanzogui/web").FontSizeTokens | undefined;
107
+ }>, keyof import("@hanzo/gui").MenuLabelProps> & import("@hanzo/gui").MenuLabelProps & React.RefAttributes<import("@hanzogui/web").GuiTextElement> & Partial<Omit<import("@hanzo/gui").NativeMenuLabelProps, "color" | "elevation" | "fontFamily" | "fontSize" | "fontStyle" | "fontVariant" | "fontWeight" | "letterSpacing" | "size" | "textAlign" | "lineHeight" | "textTransform" | "textShadowColor" | "allowFontScaling" | "ellipsizeMode" | "lineBreakMode" | "numberOfLines" | "maxFontSizeMultiplier" | "minimumFontScale" | "pressRetentionOffset" | "adjustsFontSizeToFit" | "dynamicTypeRamp" | "suppressHighlighting" | "lineBreakStrategyIOS" | "selectable" | "selectionColor" | "textBreakStrategy" | "dataDetectorType" | "android_hyphenationFrequency" | "textDecorationLine" | "textDecorationStyle" | "textDecorationColor" | "textShadowOffset" | "textShadowRadius" | "writingDirection" | "textAlignVertical" | "includeFontPadding" | "ellipsis" | "textDecorationDistance" | "textOverflow" | "whiteSpace" | "wordWrap" | "textShadow" | keyof React.RefAttributes<import("@hanzogui/web").GuiTextElement> | keyof import("@hanzo/gui").MenuLabelProps>>, "inset"> & {
108
+ inset?: boolean;
109
+ }, "ref"> & React.RefAttributes<GuiElement>>;
110
+ declare const ContextMenuSeparator: React.ForwardRefExoticComponent<Omit<Omit<import("@hanzogui/web").GetFinalProps<import("@hanzogui/web").StackNonStyleProps, import("@hanzogui/web").StackStyleBase, {
111
+ unstyled?: boolean | undefined;
112
+ }>, keyof import("@hanzo/gui").MenuSeparatorProps> & import("@hanzo/gui").MenuSeparatorProps & React.RefAttributes<GuiElement> & Partial<Omit<import("@hanzo/gui").NativeMenuSeparatorProps, keyof React.RefAttributes<GuiElement> | keyof import("@hanzo/gui").MenuSeparatorProps>>, "ref"> & React.RefAttributes<GuiElement>>;
113
+ /** Right-aligned shortcut hint. gui `Text`, not a raw `<span>`, so it renders on native. */
114
+ declare function ContextMenuShortcut(props: React.ComponentProps<typeof Text>): import("react/jsx-runtime").JSX.Element;
115
+ export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, };
116
+ //# sourceMappingURL=context-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/context-menu.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,WAAW,IAAI,cAAc,EAAE,IAAI,EAAU,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAgEzF,QAAA,MAAM,WAAW,EAAE,OAAO,cAA+B,CAAA;AACzD,QAAA,MAAM,kBAAkB,EAAE,OAAO,cAAc,CAAC,OAAgC,CAAA;AAChF,QAAA,MAAM,gBAAgB,EAAE,OAAO,cAAc,CAAC,KAA4B,CAAA;AAC1E,QAAA,MAAM,iBAAiB,EAAE,OAAO,cAAc,CAAC,MAA8B,CAAA;AAC7E,QAAA,MAAM,cAAc,EAAE,OAAO,cAAc,CAAC,GAAwB,CAAA;AACpE,QAAA,MAAM,qBAAqB,EAAE,OAAO,cAAc,CAAC,UAAsC,CAAA;AAGzF,MAAM,MAAM,uBAAuB,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,CAAA;AACzF,MAAM,MAAM,0BAA0B,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,UAAU,CAAC,CAAA;AAE/F;;;;;;;;;;GAUG;AACH,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,yBAAyB,CACvD,uBAAuB,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAc1D,CAAA;AAED,QAAA,MAAM,qBAAqB,EAAE,KAAK,CAAC,yBAAyB,CAC1D,0BAA0B,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAY7D,CAAA;AAGD;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,IAAI,CAAC,EAChD,OAAO,GAAG,SAAS,CACpB,GAAG;IACF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;CACpC,CAAA;AAED,QAAA,MAAM,eAAe,sGAoBpB,CAAA;AAED,QAAA,MAAM,uBAAuB;;;;;;;;;;;;kJAmB3B,CAAA;AAEF,QAAA,MAAM,oBAAoB;;;;;;oMAsBxB,CAAA;AAWF,QAAA,MAAM,qBAAqB;;;;;qBAyF0+yB,CAAC;;;;;;;;;YAvFl7yB,OAAO;oCAezF,CAAA;AAGF,QAAA,MAAM,gBAAgB;;;;YAEyD,OAAO;4CAiBpF,CAAA;AAEF,QAAA,MAAM,oBAAoB;;+TAexB,CAAA;AAEF,4FAA4F;AAC5F,iBAAS,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,2CAWpE;AAED,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACtB,CAAA"}
@@ -0,0 +1,140 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * ContextMenu — the right-click menu, native to @hanzo/gui.
5
+ *
6
+ * `@hanzogui/context-menu` already ships the whole compound surface (Root/Trigger/
7
+ * Portal/Content/Group/Label/Item/CheckboxItem/RadioGroup/RadioItem/ItemIndicator/
8
+ * Separator/Sub/SubTrigger/SubContent) with the a11y (`role="menu"`,
9
+ * `menuitem`/`menuitemcheckbox`/`menuitemradio` + `aria-checked`, `aria-expanded`
10
+ * on a SubTrigger), the roving arrow-key focus, the typeahead, the cursor
11
+ * anchoring and the dismiss behaviour. It IS `Menu` with an `onContextMenu` (and
12
+ * a 700ms long-press on touch) trigger instead of a click one. This file only
13
+ * FLATTENS `ContextMenu.X` into the 15 `ContextMenuX` names and dresses them in
14
+ * the Hanzo tokens, so there is one menu design rather than two shapes of it.
15
+ *
16
+ * NO RENAMES. The API is @radix-ui/react-context-menu's, prop for prop — a
17
+ * consumer migrates by changing the import and nothing else. The `side`/`align`/
18
+ * `sideOffset` hoist that Popover and HoverCard need does not arise here: a
19
+ * context menu is anchored at the cursor, so Radix never put those on its
20
+ * Content either (gui `Omit`s them for the same reason).
21
+ *
22
+ * Cross-platform: gui style props only — no Tailwind class strings, no Radix, no
23
+ * DOM APIs. Rows are 32px tall (the design density) and `touch()` lifts the real
24
+ * tap target to 44px — on web and Tauri as well as native.
25
+ *
26
+ * `ContextMenuContent` mounts its OWN `ContextMenu.Portal`, so callers never wrap
27
+ * it — and re-applies the trigger's resolved theme inside the portal via
28
+ * `PortalTheme` (gui portals re-root the subtree, so React theme context does not
29
+ * flow).
30
+ *
31
+ * The geometry below is the SAME 32px row, 8px gutter, 44px tap and panel
32
+ * treatment as `dropdown-menu.tsx` — two menu geometries would be two design
33
+ * systems. It is restated rather than imported only because those constants are
34
+ * module-private there; hoist both onto one module when the barrel is wired.
35
+ */
36
+ import * as React from 'react';
37
+ import { ContextMenu as GuiContextMenu, Text, XStack } from '@hanzo/gui';
38
+ import { Check, ChevronRight, Circle } from '@hanzogui/lucide-icons-2';
39
+ import { touch } from './gesture.js';
40
+ import { ink } from './ink.js';
41
+ import { slot } from './slot.js';
42
+ import { PortalTheme, useThemeName } from '../../product/menu/portal-theme.js';
43
+ // ── Geometry — literal px on the 8-grid; a 32px row expands to a 44px tap ──────
44
+ const ROW_H = 32;
45
+ const TAP_MIN = 44;
46
+ const ROW_PX = 8;
47
+ /** The one menu width floor — shared with DropdownMenu. */
48
+ const MIN_W = 200;
49
+ const INSET_PL = 32;
50
+ const INDICATOR_SLOT = 14;
51
+ const ICON = 16;
52
+ const panel = {
53
+ bg: '$color2',
54
+ borderColor: '$borderColor',
55
+ borderWidth: 1,
56
+ rounded: '$4',
57
+ p: 4,
58
+ minW: MIN_W,
59
+ overflow: 'hidden',
60
+ shadowColor: 'rgba(0,0,0,0.45)',
61
+ shadowRadius: 20,
62
+ shadowOffset: { width: 0, height: 10 },
63
+ };
64
+ const row = {
65
+ items: 'center',
66
+ gap: ROW_PX,
67
+ px: ROW_PX,
68
+ minH: ROW_H,
69
+ rounded: '$3',
70
+ select: 'none',
71
+ cursor: 'pointer',
72
+ ...touch(ROW_H, TAP_MIN, 'y'),
73
+ hoverStyle: { bg: '$color5' },
74
+ focusStyle: { bg: '$color5' },
75
+ pressStyle: { bg: '$color6' },
76
+ };
77
+ /** Row text style — free-form children go through `ink()` so a bare string renders on native. */
78
+ const label = { size: '$2', color: '$color12' };
79
+ /** Left indicator well shared by checkbox + radio rows. */
80
+ const Indicator = ({ children }) => (_jsx(XStack, { position: "absolute", l: ROW_PX, width: INDICATOR_SLOT, height: INDICATOR_SLOT, items: "center", justify: "center", pointerEvents: "none", children: _jsx(GuiContextMenu.ItemIndicator, { children: children }) }));
81
+ // ── Passthroughs — the gui part already IS the part ─────────────────────────────
82
+ const ContextMenu = GuiContextMenu;
83
+ const ContextMenuTrigger = GuiContextMenu.Trigger;
84
+ const ContextMenuGroup = GuiContextMenu.Group;
85
+ const ContextMenuPortal = GuiContextMenu.Portal;
86
+ const ContextMenuSub = GuiContextMenu.Sub;
87
+ const ContextMenuRadioGroup = GuiContextMenu.RadioGroup;
88
+ /**
89
+ * Both Content forwardRefs carry an EXPLICIT type. `tsc --noEmit` is happy without
90
+ * one; the build is not (TS2742). Declaration emit has to name the inferred type,
91
+ * and gui's context-menu types resolve through `@hanzogui/context-menu`'s own
92
+ * `createNonNativeContextMenu` plus `react-native` — paths reachable from gui but
93
+ * not from this package's `dist/`, so the emitted `.d.ts` referenced files a
94
+ * consumer does not have. Naming the props type (which is exported, hence
95
+ * portable) is what keeps the declaration self-contained. Only these two hit it:
96
+ * the row components are declared through `ContextMenuItemProps`, which is already
97
+ * a named export.
98
+ */
99
+ const ContextMenuContent = /* @__PURE__ */ React.forwardRef(function ContextMenuContent({ children, ...props }, ref) {
100
+ const themeName = useThemeName();
101
+ return (_jsx(GuiContextMenu.Portal, { children: _jsx(PortalTheme, { name: themeName, children: _jsx(GuiContextMenu.Content, { ref: ref, ...slot('context-menu-content'), ...panel, ...props, children: children }) }) }));
102
+ });
103
+ const ContextMenuSubContent = /* @__PURE__ */ React.forwardRef(function ContextMenuSubContent(props, ref) {
104
+ return (_jsx(GuiContextMenu.SubContent, { ref: ref, ...slot('context-menu-sub-content'), ...panel, ...props }));
105
+ });
106
+ const ContextMenuItem = /* @__PURE__ */ React.forwardRef(function ContextMenuItem({ inset, variant = 'default', disabled, children, ...props }, ref) {
107
+ return (_jsx(GuiContextMenu.Item, { ref: ref, ...slot('context-menu-item'), "data-inset": inset, "data-variant": variant, disabled: disabled, ...row, pl: inset ? INSET_PL : ROW_PX, theme: variant === 'destructive' ? 'red' : undefined, opacity: disabled ? 0.5 : 1, cursor: disabled ? 'default' : 'pointer', ...props, children: ink(children, undefined, label) }));
108
+ });
109
+ const ContextMenuCheckboxItem = /* @__PURE__ */ React.forwardRef(function ContextMenuCheckboxItem({ children, checked, ...props }, ref) {
110
+ return (_jsxs(GuiContextMenu.CheckboxItem, { ref: ref, ...slot('context-menu-checkbox-item'), checked: checked, ...row, pl: INSET_PL, ...props, children: [_jsx(Indicator, { children: _jsx(Check, { size: ICON }) }), ink(children, undefined, label)] }));
111
+ });
112
+ const ContextMenuRadioItem = /* @__PURE__ */ React.forwardRef(function ContextMenuRadioItem({ children, value, ...props }, ref) {
113
+ return (_jsxs(GuiContextMenu.RadioItem, { ref: ref, ...slot('context-menu-radio-item'),
114
+ // Named rather than left to the spread: gui's native-menu wrapper types the
115
+ // part as a UNION of prop shapes, and a rest spread cannot prove the
116
+ // required `value` survived it.
117
+ value: value, ...row, pl: INSET_PL, ...props, children: [_jsx(Indicator, { children: _jsx(Circle, { size: 8, fill: "currentColor" }) }), ink(children, undefined, label)] }));
118
+ });
119
+ /**
120
+ * gui casts `SubTrigger` to a bare `React.FC` ("to avoid TS error", its words),
121
+ * which drops `ref` from the type while the runtime still forwards it. One cast,
122
+ * in one place, so the part keeps the ref every other row in this file has.
123
+ */
124
+ const SubTriggerBase = GuiContextMenu.SubTrigger;
125
+ const ContextMenuSubTrigger = /* @__PURE__ */ React.forwardRef(function ContextMenuSubTrigger({ inset, children, ...props }, ref) {
126
+ return (_jsxs(SubTriggerBase, { ref: ref, ...slot('context-menu-sub-trigger'), "data-inset": inset, ...row, pl: inset ? INSET_PL : ROW_PX, ...props, children: [ink(children, undefined, label), _jsx(ChevronRight, { size: ICON, ml: "auto", opacity: 0.6 })] }));
127
+ });
128
+ // ── Static rows ─────────────────────────────────────────────────────────────────
129
+ const ContextMenuLabel = /* @__PURE__ */ React.forwardRef(function ContextMenuLabel({ inset, ...props }, ref) {
130
+ return (_jsx(GuiContextMenu.Label, { ref: ref, ...slot('context-menu-label'), "data-inset": inset, px: ROW_PX, py: 4, pl: inset ? INSET_PL : ROW_PX, fontSize: "$2", fontWeight: "500", color: "$color12", select: "none", ...props }));
131
+ });
132
+ const ContextMenuSeparator = /* @__PURE__ */ React.forwardRef(function ContextMenuSeparator(props, ref) {
133
+ return (_jsx(GuiContextMenu.Separator, { ref: ref, ...slot('context-menu-separator'), height: 1, bg: "$borderColor", mx: 4, my: 4, ...props }));
134
+ });
135
+ /** Right-aligned shortcut hint. gui `Text`, not a raw `<span>`, so it renders on native. */
136
+ function ContextMenuShortcut(props) {
137
+ return (_jsx(Text, { ...slot('context-menu-shortcut'), ml: "auto", fontSize: "$1", letterSpacing: 1, color: "$color11", ...props }));
138
+ }
139
+ export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, };
140
+ //# sourceMappingURL=context-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../../../src/backends/gui/context-menu.tsx"],"names":[],"mappings":"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"}
@@ -87,7 +87,7 @@ declare const DropdownMenuSubTrigger: React.ForwardRefExoticComponent<Omit<impor
87
87
  declare const DropdownMenuLabel: React.ForwardRefExoticComponent<Omit<Omit<import("@hanzogui/web").GetFinalProps<import("@hanzogui/web").TextNonStyleProps, import("@hanzogui/web").TextStylePropsBase, {
88
88
  unstyled?: boolean | undefined;
89
89
  size?: import("@hanzogui/web").FontSizeTokens | undefined;
90
- }>, keyof import("@hanzo/gui").MenuLabelProps> & import("@hanzo/gui").MenuLabelProps & React.RefAttributes<import("@hanzogui/web").GuiTextElement> & Partial<Omit<import("@hanzo/gui").NativeMenuLabelProps, "color" | "elevation" | "fontFamily" | "fontSize" | "fontStyle" | "fontVariant" | "fontWeight" | "letterSpacing" | "size" | "textAlign" | "lineHeight" | "textTransform" | "textShadowColor" | "allowFontScaling" | "ellipsizeMode" | "lineBreakMode" | "numberOfLines" | "maxFontSizeMultiplier" | "minimumFontScale" | "pressRetentionOffset" | "adjustsFontSizeToFit" | "dynamicTypeRamp" | "suppressHighlighting" | "lineBreakStrategyIOS" | "selectable" | "selectionColor" | "textBreakStrategy" | "dataDetectorType" | "android_hyphenationFrequency" | "textDecorationLine" | "textDecorationStyle" | "textDecorationColor" | "textShadowOffset" | "textShadowRadius" | "writingDirection" | "textAlignVertical" | "includeFontPadding" | "ellipsis" | "textDecorationDistance" | "textOverflow" | "whiteSpace" | "wordWrap" | "textShadow" | keyof import("@hanzo/gui").MenuLabelProps | keyof React.RefAttributes<import("@hanzogui/web").GuiTextElement>>> & {
90
+ }>, keyof import("@hanzo/gui").MenuLabelProps> & import("@hanzo/gui").MenuLabelProps & React.RefAttributes<import("@hanzogui/web").GuiTextElement> & Partial<Omit<import("@hanzo/gui").NativeMenuLabelProps, "color" | "elevation" | "fontFamily" | "fontSize" | "fontStyle" | "fontVariant" | "fontWeight" | "letterSpacing" | "size" | "textAlign" | "lineHeight" | "textTransform" | "textShadowColor" | "allowFontScaling" | "ellipsizeMode" | "lineBreakMode" | "numberOfLines" | "maxFontSizeMultiplier" | "minimumFontScale" | "pressRetentionOffset" | "adjustsFontSizeToFit" | "dynamicTypeRamp" | "suppressHighlighting" | "lineBreakStrategyIOS" | "selectable" | "selectionColor" | "textBreakStrategy" | "dataDetectorType" | "android_hyphenationFrequency" | "textDecorationLine" | "textDecorationStyle" | "textDecorationColor" | "textShadowOffset" | "textShadowRadius" | "writingDirection" | "textAlignVertical" | "includeFontPadding" | "ellipsis" | "textDecorationDistance" | "textOverflow" | "whiteSpace" | "wordWrap" | "textShadow" | keyof React.RefAttributes<import("@hanzogui/web").GuiTextElement> | keyof import("@hanzo/gui").MenuLabelProps>> & {
91
91
  inset?: boolean;
92
92
  }, "ref"> & React.RefAttributes<GuiElement>>;
93
93
  declare const DropdownMenuSeparator: React.ForwardRefExoticComponent<Omit<Omit<import("@hanzogui/web").GetFinalProps<import("@hanzogui/web").StackNonStyleProps, import("@hanzogui/web").StackStyleBase, {
@@ -0,0 +1,76 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.HoverCardContent = exports.HoverCardTrigger = void 0;
5
+ exports.HoverCard = HoverCard;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ /**
8
+ * HoverCard — the rich preview a pointer opens by resting on a trigger.
9
+ *
10
+ * gui ships no HoverCard primitive, but it ships the thing a hover card IS: a
11
+ * `Popover` in hover mode. `hoverable` puts floating-ui's `useHover` +
12
+ * `safePolygon` on the same popper the Popover already uses, so the cursor can
13
+ * travel the gap into the panel without it closing, and `useFocus` opens it from
14
+ * the keyboard. Nothing here re-implements hover timing, positioning or dismiss.
15
+ *
16
+ * TWO RENAMES, and they are the only two. Both are unavoidable — gui keeps on the
17
+ * popper ROOT what Radix put on the children — so both are absorbed HERE and the
18
+ * Radix call site is unchanged:
19
+ *
20
+ * 1. `openDelay` / `closeDelay` (root) -> one `hoverable={{ delay: {open, close} }}`.
21
+ * Radix's own defaults (700 / 300) are kept.
22
+ * 2. `side` + `align` + `sideOffset` (Content) -> ONE `placement` and one
23
+ * `offset` on the ROOT. Content still ACCEPTS all three and publishes them
24
+ * up through a context — the same idiom `popover.tsx` uses for `sideOffset`
25
+ * — so `<HoverCardContent side="left" align="start">` lands as
26
+ * `placement="left-start"` instead of being silently dropped, which is what
27
+ * `PopoverContent` does with `align` today. gui's popper and Radix agree on
28
+ * the default here (`bottom`/`center`), so nothing has to be written out.
29
+ *
30
+ * One deliberate a11y deviation from Radix, in the safer direction. Radix's hover
31
+ * card is sighted-user-only: its Content carries no role and its Trigger no aria
32
+ * state. Riding gui's popper gives the trigger `aria-expanded` and the panel
33
+ * `role="dialog"`, opens on keyboard FOCUS as well as hover, and closes on
34
+ * Escape through the dismissable layer. That is strictly more reachable than the
35
+ * component it replaces, so it is kept rather than suppressed.
36
+ *
37
+ * Press is NOT a trigger (`disablePressTrigger`): Radix's hover card never
38
+ * toggled on click, and its trigger is usually a link whose click must navigate.
39
+ *
40
+ * `HoverCardContent` re-applies the trigger's resolved theme inside the portal
41
+ * via `PortalTheme` — gui portals re-root the subtree, so theme context does not
42
+ * flow. `GuiPopover.Content` portals itself, so there is no `HoverCardPortal`,
43
+ * exactly as there is no `PopoverPortal`.
44
+ */
45
+ const gui_1 = require("@hanzo/gui");
46
+ const react_1 = require("react");
47
+ const ink_1 = require("./ink.cjs");
48
+ const slot_1 = require("./slot.cjs");
49
+ const portal_theme_1 = require("../../product/menu/portal-theme.cjs");
50
+ /** Radix's defaults, kept so a migrated call site behaves identically. */
51
+ const OPEN_DELAY = 700;
52
+ const CLOSE_DELAY = 300;
53
+ const DEFAULT_OFFSET = 4;
54
+ /** Radix/shadcn ship `w-64`. */
55
+ const WIDTH = 256;
56
+ /** Root-owned floating geometry. Content publishes into it; see rename 2 above. */
57
+ const FloatContext = /* @__PURE__ */ (0, react_1.createContext)(null);
58
+ function HoverCard({ openDelay = OPEN_DELAY, closeDelay = CLOSE_DELAY, ...props }) {
59
+ const [float, setFloat] = (0, react_1.useState)({
60
+ placement: 'bottom',
61
+ offset: DEFAULT_OFFSET,
62
+ });
63
+ // Identity-stable: an unchanged publish returns the same object, so Content's
64
+ // effect cannot drive a render loop.
65
+ const publish = (0, react_1.useCallback)((placement, offset) => setFloat((f) => (f.placement === placement && f.offset === offset ? f : { placement, offset })), []);
66
+ return ((0, jsx_runtime_1.jsx)(FloatContext.Provider, { value: publish, children: (0, jsx_runtime_1.jsx)(gui_1.Popover, { hoverable: { delay: { open: openDelay, close: closeDelay } }, placement: float.placement, offset: float.offset, ...props }) }));
67
+ }
68
+ const HoverCardTrigger = (props) => ((0, jsx_runtime_1.jsx)(gui_1.Popover.Trigger, { ...(0, slot_1.slot)('hover-card-trigger'), disablePressTrigger: true, ...props }));
69
+ exports.HoverCardTrigger = HoverCardTrigger;
70
+ const HoverCardContent = ({ side = 'bottom', align = 'center', sideOffset = DEFAULT_OFFSET, children, ...props }) => {
71
+ const themeName = (0, portal_theme_1.useThemeName)();
72
+ const publish = (0, react_1.useContext)(FloatContext);
73
+ (0, react_1.useEffect)(() => publish?.(align === 'center' ? side : `${side}-${align}`, sideOffset), [publish, side, align, sideOffset]);
74
+ return ((0, jsx_runtime_1.jsx)(portal_theme_1.PortalTheme, { name: themeName, children: (0, jsx_runtime_1.jsx)(gui_1.Popover.Content, { ...(0, slot_1.slot)('hover-card-content'), bg: "$color2", borderWidth: 1, borderColor: "$borderColor", rounded: "$4", p: "$4", width: WIDTH, ...props, children: (0, ink_1.ink)(children, undefined, { size: '$2' }) }) }));
75
+ };
76
+ exports.HoverCardContent = HoverCardContent;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * HoverCard — the rich preview a pointer opens by resting on a trigger.
3
+ *
4
+ * gui ships no HoverCard primitive, but it ships the thing a hover card IS: a
5
+ * `Popover` in hover mode. `hoverable` puts floating-ui's `useHover` +
6
+ * `safePolygon` on the same popper the Popover already uses, so the cursor can
7
+ * travel the gap into the panel without it closing, and `useFocus` opens it from
8
+ * the keyboard. Nothing here re-implements hover timing, positioning or dismiss.
9
+ *
10
+ * TWO RENAMES, and they are the only two. Both are unavoidable — gui keeps on the
11
+ * popper ROOT what Radix put on the children — so both are absorbed HERE and the
12
+ * Radix call site is unchanged:
13
+ *
14
+ * 1. `openDelay` / `closeDelay` (root) -> one `hoverable={{ delay: {open, close} }}`.
15
+ * Radix's own defaults (700 / 300) are kept.
16
+ * 2. `side` + `align` + `sideOffset` (Content) -> ONE `placement` and one
17
+ * `offset` on the ROOT. Content still ACCEPTS all three and publishes them
18
+ * up through a context — the same idiom `popover.tsx` uses for `sideOffset`
19
+ * — so `<HoverCardContent side="left" align="start">` lands as
20
+ * `placement="left-start"` instead of being silently dropped, which is what
21
+ * `PopoverContent` does with `align` today. gui's popper and Radix agree on
22
+ * the default here (`bottom`/`center`), so nothing has to be written out.
23
+ *
24
+ * One deliberate a11y deviation from Radix, in the safer direction. Radix's hover
25
+ * card is sighted-user-only: its Content carries no role and its Trigger no aria
26
+ * state. Riding gui's popper gives the trigger `aria-expanded` and the panel
27
+ * `role="dialog"`, opens on keyboard FOCUS as well as hover, and closes on
28
+ * Escape through the dismissable layer. That is strictly more reachable than the
29
+ * component it replaces, so it is kept rather than suppressed.
30
+ *
31
+ * Press is NOT a trigger (`disablePressTrigger`): Radix's hover card never
32
+ * toggled on click, and its trigger is usually a link whose click must navigate.
33
+ *
34
+ * `HoverCardContent` re-applies the trigger's resolved theme inside the portal
35
+ * via `PortalTheme` — gui portals re-root the subtree, so theme context does not
36
+ * flow. `GuiPopover.Content` portals itself, so there is no `HoverCardPortal`,
37
+ * exactly as there is no `PopoverPortal`.
38
+ */
39
+ import { Popover as GuiPopover } from '@hanzo/gui';
40
+ import { type ComponentProps } from 'react';
41
+ type Side = 'top' | 'right' | 'bottom' | 'left';
42
+ type Align = 'start' | 'center' | 'end';
43
+ export type HoverCardProps = Omit<ComponentProps<typeof GuiPopover>, 'hoverable' | 'placement' | 'offset'> & {
44
+ openDelay?: number;
45
+ closeDelay?: number;
46
+ };
47
+ declare function HoverCard({ openDelay, closeDelay, ...props }: HoverCardProps): import("react/jsx-runtime").JSX.Element;
48
+ export type HoverCardTriggerProps = ComponentProps<typeof GuiPopover.Trigger>;
49
+ declare const HoverCardTrigger: (props: HoverCardTriggerProps) => import("react/jsx-runtime").JSX.Element;
50
+ export type HoverCardContentProps = ComponentProps<typeof GuiPopover.Content> & {
51
+ side?: Side;
52
+ align?: Align;
53
+ sideOffset?: number;
54
+ };
55
+ declare const HoverCardContent: ({ side, align, sideOffset, children, ...props }: HoverCardContentProps) => import("react/jsx-runtime").JSX.Element;
56
+ export { HoverCard, HoverCardTrigger, HoverCardContent };
57
+ //# sourceMappingURL=hover-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover-card.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/hover-card.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,OAAO,CAAA;AAcd,KAAK,IAAI,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAC/C,KAAK,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;AAOvC,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,cAAc,CAAC,OAAO,UAAU,CAAC,EACjC,WAAW,GAAG,WAAW,GAAG,QAAQ,CACrC,GAAG;IACF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,iBAAS,SAAS,CAAC,EACjB,SAAsB,EACtB,UAAwB,EACxB,GAAG,KAAK,EACT,EAAE,cAAc,2CAsBhB;AAED,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAE7E,QAAA,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,4CAErD,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG;IAC9E,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,QAAA,MAAM,gBAAgB,GAAI,iDAMvB,qBAAqB,4CAuBvB,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}