@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.
- package/dist/backends/gui/accordion.cjs +69 -0
- package/dist/backends/gui/accordion.d.ts +57 -0
- package/dist/backends/gui/accordion.d.ts.map +1 -0
- package/dist/backends/gui/accordion.js +64 -0
- package/dist/backends/gui/accordion.js.map +1 -0
- package/dist/backends/gui/alert-dialog.cjs +91 -0
- package/dist/backends/gui/alert-dialog.d.ts +77 -0
- package/dist/backends/gui/alert-dialog.d.ts.map +1 -0
- package/dist/backends/gui/alert-dialog.js +79 -0
- package/dist/backends/gui/alert-dialog.js.map +1 -0
- package/dist/backends/gui/context-menu.cjs +189 -0
- package/dist/backends/gui/context-menu.d.ts +116 -0
- package/dist/backends/gui/context-menu.d.ts.map +1 -0
- package/dist/backends/gui/context-menu.js +140 -0
- package/dist/backends/gui/context-menu.js.map +1 -0
- package/dist/backends/gui/dropdown-menu.d.ts +1 -1
- package/dist/backends/gui/hover-card.cjs +76 -0
- package/dist/backends/gui/hover-card.d.ts +57 -0
- package/dist/backends/gui/hover-card.d.ts.map +1 -0
- package/dist/backends/gui/hover-card.js +72 -0
- package/dist/backends/gui/hover-card.js.map +1 -0
- package/dist/backends/gui/index.cjs +53 -3
- package/dist/backends/gui/index.d.ts +7 -1
- package/dist/backends/gui/index.d.ts.map +1 -1
- package/dist/backends/gui/index.js +12 -1
- package/dist/backends/gui/index.js.map +1 -1
- package/dist/backends/gui/layout.cjs +3 -2
- package/dist/backends/gui/layout.d.ts +1 -1
- package/dist/backends/gui/layout.d.ts.map +1 -1
- package/dist/backends/gui/layout.js +2 -2
- package/dist/backends/gui/layout.js.map +1 -1
- package/dist/backends/gui/radio-group.cjs +47 -0
- package/dist/backends/gui/radio-group.d.ts +36 -0
- package/dist/backends/gui/radio-group.d.ts.map +1 -0
- package/dist/backends/gui/radio-group.js +44 -0
- package/dist/backends/gui/radio-group.js.map +1 -0
- package/dist/backends/gui/toggle-group.cjs +114 -0
- package/dist/backends/gui/toggle-group.d.ts +57 -0
- package/dist/backends/gui/toggle-group.d.ts.map +1 -0
- package/dist/backends/gui/toggle-group.js +112 -0
- package/dist/backends/gui/toggle-group.js.map +1 -0
- package/dist/gallery.cjs +2 -2
- package/dist/gallery.d.ts.map +1 -1
- package/dist/gallery.js +3 -3
- package/dist/gallery.js.map +1 -1
- package/dist/glass.css +117 -0
- package/dist/gui-config.cjs +76 -43
- package/dist/gui-config.d.ts +204 -204
- package/dist/gui-config.d.ts.map +1 -1
- package/dist/gui-config.js +76 -43
- package/dist/gui-config.js.map +1 -1
- package/dist/index.cjs +57 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/primitives/Accordion.cjs +8 -0
- package/dist/primitives/Accordion.d.ts +2 -0
- package/dist/primitives/Accordion.d.ts.map +1 -0
- package/dist/primitives/Accordion.js +5 -0
- package/dist/primitives/Accordion.js.map +1 -0
- package/dist/primitives/AccordionContent.cjs +8 -0
- package/dist/primitives/AccordionContent.d.ts +2 -0
- package/dist/primitives/AccordionContent.d.ts.map +1 -0
- package/dist/primitives/AccordionContent.js +5 -0
- package/dist/primitives/AccordionContent.js.map +1 -0
- package/dist/primitives/AccordionItem.cjs +8 -0
- package/dist/primitives/AccordionItem.d.ts +2 -0
- package/dist/primitives/AccordionItem.d.ts.map +1 -0
- package/dist/primitives/AccordionItem.js +5 -0
- package/dist/primitives/AccordionItem.js.map +1 -0
- package/dist/primitives/AccordionTrigger.cjs +8 -0
- package/dist/primitives/AccordionTrigger.d.ts +2 -0
- package/dist/primitives/AccordionTrigger.d.ts.map +1 -0
- package/dist/primitives/AccordionTrigger.js +5 -0
- package/dist/primitives/AccordionTrigger.js.map +1 -0
- package/dist/primitives/AlertDialog.cjs +8 -0
- package/dist/primitives/AlertDialog.d.ts +2 -0
- package/dist/primitives/AlertDialog.d.ts.map +1 -0
- package/dist/primitives/AlertDialog.js +5 -0
- package/dist/primitives/AlertDialog.js.map +1 -0
- package/dist/primitives/AlertDialogAction.cjs +8 -0
- package/dist/primitives/AlertDialogAction.d.ts +2 -0
- package/dist/primitives/AlertDialogAction.d.ts.map +1 -0
- package/dist/primitives/AlertDialogAction.js +5 -0
- package/dist/primitives/AlertDialogAction.js.map +1 -0
- package/dist/primitives/AlertDialogCancel.cjs +8 -0
- package/dist/primitives/AlertDialogCancel.d.ts +2 -0
- package/dist/primitives/AlertDialogCancel.d.ts.map +1 -0
- package/dist/primitives/AlertDialogCancel.js +5 -0
- package/dist/primitives/AlertDialogCancel.js.map +1 -0
- package/dist/primitives/AlertDialogContent.cjs +8 -0
- package/dist/primitives/AlertDialogContent.d.ts +2 -0
- package/dist/primitives/AlertDialogContent.d.ts.map +1 -0
- package/dist/primitives/AlertDialogContent.js +5 -0
- package/dist/primitives/AlertDialogContent.js.map +1 -0
- package/dist/primitives/AlertDialogDescription.cjs +8 -0
- package/dist/primitives/AlertDialogDescription.d.ts +2 -0
- package/dist/primitives/AlertDialogDescription.d.ts.map +1 -0
- package/dist/primitives/AlertDialogDescription.js +5 -0
- package/dist/primitives/AlertDialogDescription.js.map +1 -0
- package/dist/primitives/AlertDialogFooter.cjs +8 -0
- package/dist/primitives/AlertDialogFooter.d.ts +2 -0
- package/dist/primitives/AlertDialogFooter.d.ts.map +1 -0
- package/dist/primitives/AlertDialogFooter.js +5 -0
- package/dist/primitives/AlertDialogFooter.js.map +1 -0
- package/dist/primitives/AlertDialogHeader.cjs +8 -0
- package/dist/primitives/AlertDialogHeader.d.ts +2 -0
- package/dist/primitives/AlertDialogHeader.d.ts.map +1 -0
- package/dist/primitives/AlertDialogHeader.js +5 -0
- package/dist/primitives/AlertDialogHeader.js.map +1 -0
- package/dist/primitives/AlertDialogOverlay.cjs +8 -0
- package/dist/primitives/AlertDialogOverlay.d.ts +2 -0
- package/dist/primitives/AlertDialogOverlay.d.ts.map +1 -0
- package/dist/primitives/AlertDialogOverlay.js +5 -0
- package/dist/primitives/AlertDialogOverlay.js.map +1 -0
- package/dist/primitives/AlertDialogPortal.cjs +8 -0
- package/dist/primitives/AlertDialogPortal.d.ts +2 -0
- package/dist/primitives/AlertDialogPortal.d.ts.map +1 -0
- package/dist/primitives/AlertDialogPortal.js +5 -0
- package/dist/primitives/AlertDialogPortal.js.map +1 -0
- package/dist/primitives/AlertDialogTitle.cjs +8 -0
- package/dist/primitives/AlertDialogTitle.d.ts +2 -0
- package/dist/primitives/AlertDialogTitle.d.ts.map +1 -0
- package/dist/primitives/AlertDialogTitle.js +5 -0
- package/dist/primitives/AlertDialogTitle.js.map +1 -0
- package/dist/primitives/AlertDialogTrigger.cjs +8 -0
- package/dist/primitives/AlertDialogTrigger.d.ts +2 -0
- package/dist/primitives/AlertDialogTrigger.d.ts.map +1 -0
- package/dist/primitives/AlertDialogTrigger.js +5 -0
- package/dist/primitives/AlertDialogTrigger.js.map +1 -0
- package/dist/primitives/Anchor.cjs +8 -0
- package/dist/primitives/Anchor.d.ts +2 -0
- package/dist/primitives/Anchor.d.ts.map +1 -0
- package/dist/primitives/Anchor.js +5 -0
- package/dist/primitives/Anchor.js.map +1 -0
- package/dist/primitives/HoverCard.cjs +8 -0
- package/dist/primitives/HoverCard.d.ts +2 -0
- package/dist/primitives/HoverCard.d.ts.map +1 -0
- package/dist/primitives/HoverCard.js +5 -0
- package/dist/primitives/HoverCard.js.map +1 -0
- package/dist/primitives/HoverCardContent.cjs +8 -0
- package/dist/primitives/HoverCardContent.d.ts +2 -0
- package/dist/primitives/HoverCardContent.d.ts.map +1 -0
- package/dist/primitives/HoverCardContent.js +5 -0
- package/dist/primitives/HoverCardContent.js.map +1 -0
- package/dist/primitives/HoverCardTrigger.cjs +8 -0
- package/dist/primitives/HoverCardTrigger.d.ts +2 -0
- package/dist/primitives/HoverCardTrigger.d.ts.map +1 -0
- package/dist/primitives/HoverCardTrigger.js +5 -0
- package/dist/primitives/HoverCardTrigger.js.map +1 -0
- package/dist/primitives/RadioGroup.cjs +8 -0
- package/dist/primitives/RadioGroup.d.ts +2 -0
- package/dist/primitives/RadioGroup.d.ts.map +1 -0
- package/dist/primitives/RadioGroup.js +5 -0
- package/dist/primitives/RadioGroup.js.map +1 -0
- package/dist/primitives/RadioGroupItem.cjs +8 -0
- package/dist/primitives/RadioGroupItem.d.ts +2 -0
- package/dist/primitives/RadioGroupItem.d.ts.map +1 -0
- package/dist/primitives/RadioGroupItem.js +5 -0
- package/dist/primitives/RadioGroupItem.js.map +1 -0
- package/dist/primitives/ToggleGroup.cjs +8 -0
- package/dist/primitives/ToggleGroup.d.ts +2 -0
- package/dist/primitives/ToggleGroup.d.ts.map +1 -0
- package/dist/primitives/ToggleGroup.js +5 -0
- package/dist/primitives/ToggleGroup.js.map +1 -0
- package/dist/primitives/ToggleGroupItem.cjs +8 -0
- package/dist/primitives/ToggleGroupItem.d.ts +2 -0
- package/dist/primitives/ToggleGroupItem.d.ts.map +1 -0
- package/dist/primitives/ToggleGroupItem.js +5 -0
- package/dist/primitives/ToggleGroupItem.js.map +1 -0
- package/dist/product/AppHeader.cjs +3 -3
- package/dist/product/AppHeader.js +3 -3
- package/dist/product/CommerceResource.cjs +1 -1
- package/dist/product/CommerceResource.js +1 -1
- package/dist/product/ConfirmDelete.cjs +1 -1
- package/dist/product/ConfirmDelete.js +1 -1
- package/dist/product/EmptyState.cjs +1 -1
- package/dist/product/EmptyState.js +1 -1
- package/dist/product/Field.cjs +8 -3
- package/dist/product/Field.d.ts.map +1 -1
- package/dist/product/Field.js +8 -3
- package/dist/product/Field.js.map +1 -1
- package/dist/product/Filters.cjs +1 -1
- package/dist/product/Filters.js +1 -1
- package/dist/product/OrgSwitcher.cjs +2 -2
- package/dist/product/OrgSwitcher.js +2 -2
- package/dist/product/Pagination.cjs +1 -1
- package/dist/product/Pagination.js +1 -1
- package/dist/product/PrimaryButton.cjs +12 -0
- package/dist/product/PrimaryButton.d.ts.map +1 -1
- package/dist/product/PrimaryButton.js +12 -0
- package/dist/product/PrimaryButton.js.map +1 -1
- package/dist/product/UserMenu.cjs +1 -1
- package/dist/product/UserMenu.js +1 -1
- package/dist/product/social/PostCard.cjs +1 -1
- package/dist/product/social/PostCard.js +1 -1
- package/dist/styles.css +244 -45
- package/dist/theme.css +190 -41
- 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":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,WAAW,IAAI,cAAc,EAAE,IAAI,EAAE,MAAM,EAAmB,MAAM,YAAY,CAAA;AACzF,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAE3E,kFAAkF;AAClF,MAAM,KAAK,GAAG,EAAE,CAAA;AAChB,MAAM,OAAO,GAAG,EAAE,CAAA;AAClB,MAAM,MAAM,GAAG,CAAC,CAAA;AAChB,2DAA2D;AAC3D,MAAM,KAAK,GAAG,GAAG,CAAA;AACjB,MAAM,QAAQ,GAAG,EAAE,CAAA;AACnB,MAAM,cAAc,GAAG,EAAE,CAAA;AACzB,MAAM,IAAI,GAAG,EAAE,CAAA;AAEf,MAAM,KAAK,GAAG;IACZ,EAAE,EAAE,SAAS;IACb,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,CAAC;IACd,OAAO,EAAE,IAAI;IACb,CAAC,EAAE,CAAC;IACJ,IAAI,EAAE,KAAK;IACX,QAAQ,EAAE,QAAQ;IAClB,WAAW,EAAE,kBAAkB;IAC/B,YAAY,EAAE,EAAE;IAChB,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;CAC9B,CAAA;AAEV,MAAM,GAAG,GAAG;IACV,KAAK,EAAE,QAAQ;IACf,GAAG,EAAE,MAAM;IACX,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,SAAS;IACjB,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC;IAC7B,UAAU,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;IAC7B,UAAU,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;IAC7B,UAAU,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;CACrB,CAAA;AAEV,iGAAiG;AACjG,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAW,CAAA;AAExD,2DAA2D;AAC3D,MAAM,SAAS,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CACjE,KAAC,MAAM,IACL,QAAQ,EAAC,UAAU,EACnB,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,cAAc,EACtB,KAAK,EAAC,QAAQ,EACd,OAAO,EAAC,QAAQ,EAChB,aAAa,EAAC,MAAM,YAEpB,KAAC,cAAc,CAAC,aAAa,cAAE,QAAQ,GAAgC,GAChE,CACV,CAAA;AAED,mFAAmF;AACnF,MAAM,WAAW,GAA0B,cAAc,CAAA;AACzD,MAAM,kBAAkB,GAAkC,cAAc,CAAC,OAAO,CAAA;AAChF,MAAM,gBAAgB,GAAgC,cAAc,CAAC,KAAK,CAAA;AAC1E,MAAM,iBAAiB,GAAiC,cAAc,CAAC,MAAM,CAAA;AAC7E,MAAM,cAAc,GAA8B,cAAc,CAAC,GAAG,CAAA;AACpE,MAAM,qBAAqB,GAAqC,cAAc,CAAC,UAAU,CAAA;AAMzF;;;;;;;;;;GAUG;AACH,MAAM,kBAAkB,GAEpB,eAAe,CAAC,KAAK,CAAC,UAAU,CAClC,SAAS,kBAAkB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG;IACrD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,OAAO,CACL,KAAC,cAAc,CAAC,MAAM,cACpB,KAAC,WAAW,IAAC,IAAI,EAAE,SAAS,YAC1B,KAAC,cAAc,CAAC,OAAO,IAAC,GAAG,EAAE,GAAG,KAAM,IAAI,CAAC,sBAAsB,CAAC,KAAM,KAAK,KAAM,KAAK,YACrF,QAAQ,GACc,GACb,GACQ,CACzB,CAAA;AACH,CAAC,CACF,CAAA;AAED,MAAM,qBAAqB,GAEvB,eAAe,CAAC,KAAK,CAAC,UAAU,CAClC,SAAS,qBAAqB,CAAC,KAAK,EAAE,GAAG;IACvC,OAAO,CACL,KAAC,cAAc,CAAC,UAAU,IACxB,GAAG,EAAE,GAAG,KACJ,IAAI,CAAC,0BAA0B,CAAC,KAChC,KAAK,KACL,KAAK,GACT,CACH,CAAA;AACH,CAAC,CACF,CAAA;AAiBD,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CACtD,SAAS,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG;IACxF,OAAO,CACL,KAAC,cAAc,CAAC,IAAI,IAClB,GAAG,EAAE,GAAG,KACJ,IAAI,CAAC,mBAAmB,CAAC,gBACjB,KAAK,kBACH,OAAO,EACrB,QAAQ,EAAE,QAAQ,KACd,GAAG,EACP,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAC7B,KAAK,EAAE,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EACpD,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAC3B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,KACpC,KAAK,YAER,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,GACZ,CACvB,CAAA;AACH,CAAC,CACF,CAAA;AAED,MAAM,uBAAuB,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAG9D,SAAS,uBAAuB,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG;IACrE,OAAO,CACL,MAAC,cAAc,CAAC,YAAY,IAC1B,GAAG,EAAE,GAAG,KACJ,IAAI,CAAC,4BAA4B,CAAC,EACtC,OAAO,EAAE,OAAO,KACZ,GAAG,EACP,EAAE,EAAE,QAAQ,KACR,KAAK,aAET,KAAC,SAAS,cACR,KAAC,KAAK,IAAC,IAAI,EAAE,IAAI,GAAI,GACX,EACX,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,IACJ,CAC/B,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,oBAAoB,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAG3D,SAAS,oBAAoB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG;IAChE,OAAO,CACL,MAAC,cAAc,CAAC,SAAS,IACvB,GAAG,EAAE,GAAG,KACJ,IAAI,CAAC,yBAAyB,CAAC;QACnC,4EAA4E;QAC5E,qEAAqE;QACrE,gCAAgC;QAChC,KAAK,EAAE,KAAK,KACR,GAAG,EACP,EAAE,EAAE,QAAQ,KACR,KAAK,aAET,KAAC,SAAS,cACR,KAAC,MAAM,IAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAC,cAAc,GAAG,GAC7B,EACX,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,IACP,CAC5B,CAAA;AACH,CAAC,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,cAAc,GAAG,cAAc,CAAC,UAErC,CAAA;AAED,MAAM,qBAAqB,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAG5D,SAAS,qBAAqB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG;IACjE,OAAO,CACL,MAAC,cAAc,IACb,GAAG,EAAE,GAAG,KACJ,IAAI,CAAC,0BAA0B,CAAC,gBACxB,KAAK,KACb,GAAG,EACP,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,KACzB,KAAK,aAER,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,EAChC,KAAC,YAAY,IAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAC,MAAM,EAAC,OAAO,EAAE,GAAG,GAAI,IACrC,CAClB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAGvD,SAAS,gBAAgB,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG;IAClD,OAAO,CACL,KAAC,cAAc,CAAC,KAAK,IACnB,GAAG,EAAE,GAAG,KACJ,IAAI,CAAC,oBAAoB,CAAC,gBAClB,KAAK,EACjB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,EACL,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAC7B,QAAQ,EAAC,IAAI,EACb,UAAU,EAAC,KAAK,EAChB,KAAK,EAAC,UAAU,EAChB,MAAM,EAAC,MAAM,KACT,KAAK,GACT,CACH,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,oBAAoB,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAG3D,SAAS,oBAAoB,CAAC,KAAK,EAAE,GAAG;IACxC,OAAO,CACL,KAAC,cAAc,CAAC,SAAS,IACvB,GAAG,EAAE,GAAG,KACJ,IAAI,CAAC,wBAAwB,CAAC,EAClC,MAAM,EAAE,CAAC,EACT,EAAE,EAAC,cAAc,EACjB,EAAE,EAAE,CAAC,EACL,EAAE,EAAE,CAAC,KACD,KAAK,GACT,CACH,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,4FAA4F;AAC5F,SAAS,mBAAmB,CAAC,KAAwC;IACnE,OAAO,CACL,KAAC,IAAI,OACC,IAAI,CAAC,uBAAuB,CAAC,EACjC,EAAE,EAAC,MAAM,EACT,QAAQ,EAAC,IAAI,EACb,aAAa,EAAE,CAAC,EAChB,KAAK,EAAC,UAAU,KACZ,KAAK,GACT,CACH,CAAA;AACH,CAAC;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"}
|
|
@@ -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("@
|
|
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"}
|