@radix-solid-js/hover-card 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,297 @@
1
+ 'use strict';
2
+
3
+ var solidJs = require('solid-js');
4
+ var primitive = require('@radix-solid-js/primitive');
5
+ var composeRefs = require('@radix-solid-js/compose-refs');
6
+ var context = require('@radix-solid-js/context');
7
+ var dismissableLayer = require('@radix-solid-js/dismissable-layer');
8
+ var popper = require('@radix-solid-js/popper');
9
+ var portal = require('@radix-solid-js/portal');
10
+ var presence = require('@radix-solid-js/presence');
11
+ var primitiveComponent = require('@radix-solid-js/primitive-component');
12
+ var useControllableState = require('@radix-solid-js/use-controllable-state');
13
+
14
+ // src/hover-card.tsx
15
+ var originalBodyUserSelect;
16
+ var HOVERCARD_NAME = "HoverCard";
17
+ var [createHoverCardContext, createHoverCardScope] = context.createContextScope(
18
+ HOVERCARD_NAME,
19
+ [popper.createPopperScope]
20
+ );
21
+ var usePopperScope = popper.createPopperScope();
22
+ var [HoverCardProvider, useHoverCardContext] = createHoverCardContext(HOVERCARD_NAME);
23
+ function HoverCard(inProps) {
24
+ const [local] = solidJs.splitProps(inProps, [
25
+ "__scopeHoverCard",
26
+ "children",
27
+ "open",
28
+ "defaultOpen",
29
+ "onOpenChange",
30
+ "openDelay",
31
+ "closeDelay"
32
+ ]);
33
+ const popperScope = usePopperScope(local.__scopeHoverCard);
34
+ let openTimerRef = 0;
35
+ let closeTimerRef = 0;
36
+ const hasSelectionRef = { current: false };
37
+ const isPointerDownOnContentRef = { current: false };
38
+ const openDelay = () => local.openDelay ?? 700;
39
+ const closeDelay = () => local.closeDelay ?? 300;
40
+ const [open, setOpen] = useControllableState.createControllableSignal({
41
+ prop: () => local.open,
42
+ defaultProp: local.defaultOpen ?? false,
43
+ onChange: (value) => {
44
+ local.onOpenChange?.(value);
45
+ }
46
+ });
47
+ const handleOpen = () => {
48
+ clearTimeout(closeTimerRef);
49
+ openTimerRef = window.setTimeout(() => setOpen(true), openDelay());
50
+ };
51
+ const handleClose = () => {
52
+ clearTimeout(openTimerRef);
53
+ if (!hasSelectionRef.current && !isPointerDownOnContentRef.current) {
54
+ closeTimerRef = window.setTimeout(() => setOpen(false), closeDelay());
55
+ }
56
+ };
57
+ const handleDismiss = () => setOpen(false);
58
+ solidJs.onCleanup(() => {
59
+ clearTimeout(openTimerRef);
60
+ clearTimeout(closeTimerRef);
61
+ });
62
+ return /* @__PURE__ */ React.createElement(
63
+ HoverCardProvider,
64
+ {
65
+ scope: local.__scopeHoverCard,
66
+ open: open(),
67
+ onOpenChange: setOpen,
68
+ onOpen: handleOpen,
69
+ onClose: handleClose,
70
+ onDismiss: handleDismiss,
71
+ hasSelectionRef,
72
+ isPointerDownOnContentRef
73
+ },
74
+ /* @__PURE__ */ React.createElement(popper.Popper, { ...popperScope }, local.children)
75
+ );
76
+ }
77
+ HoverCard.displayName = HOVERCARD_NAME;
78
+ var TRIGGER_NAME = "HoverCardTrigger";
79
+ function HoverCardTrigger(inProps) {
80
+ const [local, rest] = solidJs.splitProps(inProps, ["__scopeHoverCard", "ref"]);
81
+ const context = useHoverCardContext(TRIGGER_NAME, local.__scopeHoverCard);
82
+ const popperScope = usePopperScope(local.__scopeHoverCard);
83
+ return /* @__PURE__ */ React.createElement(popper.PopperAnchor, { asChild: true, ...popperScope }, /* @__PURE__ */ React.createElement(
84
+ primitiveComponent.Primitive.a,
85
+ {
86
+ "data-state": context.open ? "open" : "closed",
87
+ ...rest,
88
+ ref: local.ref,
89
+ onPointerEnter: primitive.composeEventHandlers(rest.onPointerEnter, excludeTouch(context.onOpen)),
90
+ onPointerLeave: primitive.composeEventHandlers(rest.onPointerLeave, excludeTouch(context.onClose)),
91
+ onFocus: primitive.composeEventHandlers(rest.onFocus, context.onOpen),
92
+ onBlur: primitive.composeEventHandlers(rest.onBlur, context.onClose),
93
+ onTouchStart: primitive.composeEventHandlers(
94
+ rest.onTouchStart,
95
+ (event) => event.preventDefault()
96
+ )
97
+ }
98
+ ));
99
+ }
100
+ HoverCardTrigger.displayName = TRIGGER_NAME;
101
+ var PORTAL_NAME = "HoverCardPortal";
102
+ var [PortalProvider, usePortalContext] = createHoverCardContext(
103
+ PORTAL_NAME,
104
+ { forceMount: void 0 }
105
+ );
106
+ function HoverCardPortal(inProps) {
107
+ const [local] = solidJs.splitProps(inProps, [
108
+ "__scopeHoverCard",
109
+ "children",
110
+ "container",
111
+ "forceMount"
112
+ ]);
113
+ return /* @__PURE__ */ React.createElement(PortalProvider, { scope: local.__scopeHoverCard, forceMount: local.forceMount }, /* @__PURE__ */ React.createElement(portal.Portal, { container: local.container }, local.children));
114
+ }
115
+ HoverCardPortal.displayName = PORTAL_NAME;
116
+ var CONTENT_NAME = "HoverCardContent";
117
+ function HoverCardContent(inProps) {
118
+ const [local, rest] = solidJs.splitProps(inProps, [
119
+ "__scopeHoverCard",
120
+ "forceMount",
121
+ "ref"
122
+ ]);
123
+ const portalContext = usePortalContext(CONTENT_NAME, local.__scopeHoverCard);
124
+ const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);
125
+ const forceMount = () => local.forceMount ?? portalContext.forceMount;
126
+ return /* @__PURE__ */ React.createElement(presence.Presence, { present: forceMount() || context.open }, /* @__PURE__ */ React.createElement(
127
+ HoverCardContentImpl,
128
+ {
129
+ "data-state": context.open ? "open" : "closed",
130
+ ...rest,
131
+ __scopeHoverCard: local.__scopeHoverCard,
132
+ onPointerEnter: primitive.composeEventHandlers(
133
+ rest.onPointerEnter,
134
+ excludeTouch(context.onOpen)
135
+ ),
136
+ onPointerLeave: primitive.composeEventHandlers(
137
+ rest.onPointerLeave,
138
+ excludeTouch(context.onClose)
139
+ ),
140
+ ref: local.ref
141
+ }
142
+ ));
143
+ }
144
+ HoverCardContent.displayName = CONTENT_NAME;
145
+ function HoverCardContentImpl(inProps) {
146
+ const [local, rest] = solidJs.splitProps(inProps, [
147
+ "__scopeHoverCard",
148
+ "__scopePopper",
149
+ "ref",
150
+ "side",
151
+ "sideOffset",
152
+ "align",
153
+ "alignOffset",
154
+ "avoidCollisions",
155
+ "collisionBoundary",
156
+ "collisionPadding",
157
+ "arrowPadding",
158
+ "sticky",
159
+ "hideWhenDetached",
160
+ "onEscapeKeyDown",
161
+ "onPointerDownOutside",
162
+ "onFocusOutside",
163
+ "onInteractOutside",
164
+ "style",
165
+ "children"
166
+ ]);
167
+ const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);
168
+ const popperScope = usePopperScope(local.__scopeHoverCard);
169
+ let contentRef;
170
+ const [containSelection, setContainSelection] = solidJs.createSignal(false);
171
+ solidJs.createEffect(() => {
172
+ if (containSelection()) {
173
+ const body = document.body;
174
+ originalBodyUserSelect = body.style.userSelect || body.style.webkitUserSelect;
175
+ body.style.userSelect = "none";
176
+ body.style.webkitUserSelect = "none";
177
+ solidJs.onCleanup(() => {
178
+ body.style.userSelect = originalBodyUserSelect;
179
+ body.style.webkitUserSelect = originalBodyUserSelect;
180
+ });
181
+ }
182
+ });
183
+ solidJs.createEffect(() => {
184
+ if (contentRef) {
185
+ const handlePointerUp = () => {
186
+ setContainSelection(false);
187
+ context.isPointerDownOnContentRef.current = false;
188
+ setTimeout(() => {
189
+ const hasSelection = document.getSelection()?.toString() !== "";
190
+ if (hasSelection) context.hasSelectionRef.current = true;
191
+ });
192
+ };
193
+ document.addEventListener("pointerup", handlePointerUp);
194
+ solidJs.onCleanup(() => {
195
+ document.removeEventListener("pointerup", handlePointerUp);
196
+ context.hasSelectionRef.current = false;
197
+ context.isPointerDownOnContentRef.current = false;
198
+ });
199
+ }
200
+ });
201
+ solidJs.createEffect(() => {
202
+ if (contentRef) {
203
+ const tabbables = getTabbableNodes(contentRef);
204
+ tabbables.forEach((tabbable) => tabbable.setAttribute("tabindex", "-1"));
205
+ }
206
+ });
207
+ return /* @__PURE__ */ React.createElement(
208
+ dismissableLayer.DismissableLayer,
209
+ {
210
+ asChild: true,
211
+ disableOutsidePointerEvents: false,
212
+ onInteractOutside: local.onInteractOutside,
213
+ onEscapeKeyDown: local.onEscapeKeyDown,
214
+ onPointerDownOutside: local.onPointerDownOutside,
215
+ onFocusOutside: primitive.composeEventHandlers(local.onFocusOutside, (event) => {
216
+ event.preventDefault();
217
+ }),
218
+ onDismiss: context.onDismiss
219
+ },
220
+ /* @__PURE__ */ React.createElement(
221
+ popper.PopperContent,
222
+ {
223
+ ...popperScope,
224
+ ...rest,
225
+ ref: composeRefs.mergeRefs(local.ref, (el) => contentRef = el),
226
+ side: local.side,
227
+ sideOffset: local.sideOffset,
228
+ align: local.align,
229
+ alignOffset: local.alignOffset,
230
+ avoidCollisions: local.avoidCollisions,
231
+ collisionBoundary: local.collisionBoundary,
232
+ collisionPadding: local.collisionPadding,
233
+ arrowPadding: local.arrowPadding,
234
+ sticky: local.sticky,
235
+ hideWhenDetached: local.hideWhenDetached,
236
+ onPointerDown: primitive.composeEventHandlers(rest.onPointerDown, (event) => {
237
+ if (event.currentTarget.contains(event.target)) {
238
+ setContainSelection(true);
239
+ }
240
+ context.hasSelectionRef.current = false;
241
+ context.isPointerDownOnContentRef.current = true;
242
+ }),
243
+ style: {
244
+ ...typeof local.style === "object" ? local.style : {},
245
+ "user-select": containSelection() ? "text" : void 0,
246
+ "-webkit-user-select": containSelection() ? "text" : void 0,
247
+ // re-namespace exposed content custom properties
248
+ "--radix-hover-card-content-transform-origin": "var(--radix-popper-transform-origin)",
249
+ "--radix-hover-card-content-available-width": "var(--radix-popper-available-width)",
250
+ "--radix-hover-card-content-available-height": "var(--radix-popper-available-height)",
251
+ "--radix-hover-card-trigger-width": "var(--radix-popper-anchor-width)",
252
+ "--radix-hover-card-trigger-height": "var(--radix-popper-anchor-height)"
253
+ }
254
+ },
255
+ local.children
256
+ )
257
+ );
258
+ }
259
+ var ARROW_NAME = "HoverCardArrow";
260
+ function HoverCardArrow(inProps) {
261
+ const [local, rest] = solidJs.splitProps(inProps, ["__scopeHoverCard"]);
262
+ const popperScope = usePopperScope(local.__scopeHoverCard);
263
+ return /* @__PURE__ */ React.createElement(popper.PopperArrow, { ...popperScope, ...rest });
264
+ }
265
+ HoverCardArrow.displayName = ARROW_NAME;
266
+ function excludeTouch(eventHandler) {
267
+ return (event) => event.pointerType === "touch" ? void 0 : eventHandler();
268
+ }
269
+ function getTabbableNodes(container) {
270
+ const nodes = [];
271
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
272
+ acceptNode: (node) => {
273
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
274
+ }
275
+ });
276
+ while (walker.nextNode()) nodes.push(walker.currentNode);
277
+ return nodes;
278
+ }
279
+ var Root = HoverCard;
280
+ var Trigger = HoverCardTrigger;
281
+ var HoverCardPortalExport = HoverCardPortal;
282
+ var Content = HoverCardContent;
283
+ var Arrow = HoverCardArrow;
284
+
285
+ exports.Arrow = Arrow;
286
+ exports.Content = Content;
287
+ exports.HoverCard = HoverCard;
288
+ exports.HoverCardArrow = HoverCardArrow;
289
+ exports.HoverCardContent = HoverCardContent;
290
+ exports.HoverCardPortal = HoverCardPortal;
291
+ exports.HoverCardTrigger = HoverCardTrigger;
292
+ exports.Portal = HoverCardPortalExport;
293
+ exports.Root = Root;
294
+ exports.Trigger = Trigger;
295
+ exports.createHoverCardScope = createHoverCardScope;
296
+ //# sourceMappingURL=index.cjs.map
297
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hover-card.tsx"],"names":["createContextScope","createPopperScope","splitProps","createControllableSignal","onCleanup","Popper","PopperAnchor","Primitive","composeEventHandlers","Portal","Presence","createSignal","createEffect","DismissableLayer","PopperContent","mergeRefs","PopperArrow"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n type JSX,\n createSignal,\n createEffect,\n onCleanup,\n splitProps,\n} from 'solid-js';\nimport { composeEventHandlers } from '@radix-solid-js/primitive';\nimport { mergeRefs } from '@radix-solid-js/compose-refs';\nimport { createContextScope, type Scope } from '@radix-solid-js/context';\nimport { DismissableLayer } from '@radix-solid-js/dismissable-layer';\nimport {\n createPopperScope,\n Popper,\n PopperAnchor,\n PopperContent,\n PopperArrow,\n} from '@radix-solid-js/popper';\nimport { Portal } from '@radix-solid-js/portal';\nimport { Presence } from '@radix-solid-js/presence';\nimport { Primitive } from '@radix-solid-js/primitive-component';\nimport { createControllableSignal } from '@radix-solid-js/use-controllable-state';\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCard\n * -----------------------------------------------------------------------------------------------*/\n\nlet originalBodyUserSelect: string;\n\nconst HOVERCARD_NAME = 'HoverCard';\n\ntype ScopedProps<P> = P & { __scopeHoverCard?: Scope };\nconst [createHoverCardContext, createHoverCardScope] = createContextScope(\n HOVERCARD_NAME,\n [createPopperScope]\n);\nconst usePopperScope = createPopperScope();\n\ntype HoverCardContextValue = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onOpen: () => void;\n onClose: () => void;\n onDismiss: () => void;\n hasSelectionRef: { current: boolean };\n isPointerDownOnContentRef: { current: boolean };\n};\n\nconst [HoverCardProvider, useHoverCardContext] =\n createHoverCardContext<HoverCardContextValue>(HOVERCARD_NAME);\n\ninterface HoverCardProps {\n children?: JSX.Element;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n openDelay?: number;\n closeDelay?: number;\n}\n\nfunction HoverCard(inProps: ScopedProps<HoverCardProps>) {\n const [local] = splitProps(inProps, [\n '__scopeHoverCard',\n 'children',\n 'open',\n 'defaultOpen',\n 'onOpenChange',\n 'openDelay',\n 'closeDelay',\n ]);\n\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n let openTimerRef = 0;\n let closeTimerRef = 0;\n const hasSelectionRef = { current: false };\n const isPointerDownOnContentRef = { current: false };\n\n const openDelay = () => local.openDelay ?? 700;\n const closeDelay = () => local.closeDelay ?? 300;\n\n const [open, setOpen] = createControllableSignal({\n prop: () => local.open,\n defaultProp: local.defaultOpen ?? false,\n onChange: (value) => {\n local.onOpenChange?.(value);\n },\n });\n\n const handleOpen = () => {\n clearTimeout(closeTimerRef);\n openTimerRef = window.setTimeout(() => setOpen(true), openDelay());\n };\n\n const handleClose = () => {\n clearTimeout(openTimerRef);\n if (!hasSelectionRef.current && !isPointerDownOnContentRef.current) {\n closeTimerRef = window.setTimeout(() => setOpen(false), closeDelay());\n }\n };\n\n const handleDismiss = () => setOpen(false);\n\n // cleanup any queued state updates on unmount\n onCleanup(() => {\n clearTimeout(openTimerRef);\n clearTimeout(closeTimerRef);\n });\n\n return (\n <HoverCardProvider\n scope={local.__scopeHoverCard}\n open={open()}\n onOpenChange={setOpen}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n hasSelectionRef={hasSelectionRef}\n isPointerDownOnContentRef={isPointerDownOnContentRef}\n >\n <Popper {...popperScope}>{local.children}</Popper>\n </HoverCardProvider>\n );\n}\n\nHoverCard.displayName = HOVERCARD_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardTrigger\n * -----------------------------------------------------------------------------------------------*/\n\nconst TRIGGER_NAME = 'HoverCardTrigger';\n\ninterface HoverCardTriggerProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {\n ref?: (el: HTMLElement) => void;\n}\n\nfunction HoverCardTrigger(inProps: ScopedProps<HoverCardTriggerProps>) {\n const [local, rest] = splitProps(inProps, ['__scopeHoverCard', 'ref']);\n const context = useHoverCardContext(TRIGGER_NAME, local.__scopeHoverCard);\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n return (\n <PopperAnchor asChild {...popperScope}>\n <Primitive.a\n data-state={context.open ? 'open' : 'closed'}\n {...rest}\n ref={local.ref}\n onPointerEnter={composeEventHandlers(rest.onPointerEnter as any, excludeTouch(context.onOpen))}\n onPointerLeave={composeEventHandlers(rest.onPointerLeave as any, excludeTouch(context.onClose))}\n onFocus={composeEventHandlers(rest.onFocus as any, context.onOpen)}\n onBlur={composeEventHandlers(rest.onBlur as any, context.onClose)}\n // prevent focus event on touch devices\n onTouchStart={composeEventHandlers(rest.onTouchStart as any, (event: TouchEvent) =>\n event.preventDefault()\n )}\n />\n </PopperAnchor>\n );\n}\n\nHoverCardTrigger.displayName = TRIGGER_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'HoverCardPortal';\n\ntype PortalContextValue = { forceMount?: true };\nconst [PortalProvider, usePortalContext] = createHoverCardContext<PortalContextValue>(\n PORTAL_NAME,\n { forceMount: undefined }\n);\n\ninterface HoverCardPortalProps {\n children?: JSX.Element;\n /**\n * Specify a container element to portal the content into.\n */\n container?: Element | DocumentFragment | null;\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with animation libraries.\n */\n forceMount?: true;\n}\n\nfunction HoverCardPortal(inProps: ScopedProps<HoverCardPortalProps>) {\n const [local] = splitProps(inProps, [\n '__scopeHoverCard',\n 'children',\n 'container',\n 'forceMount',\n ]);\n\n // Portal is always mounted — visibility is controlled by Presence in HoverCardContent.\n // This avoids the dual-Presence problem where the outer Presence would unmount\n // the portal before the inner exit animation completes.\n return (\n <PortalProvider scope={local.__scopeHoverCard} forceMount={local.forceMount}>\n <Portal container={local.container}>\n {local.children}\n </Portal>\n </PortalProvider>\n );\n}\n\nHoverCardPortal.displayName = PORTAL_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'HoverCardContent';\n\ninterface HoverCardContentProps extends HoverCardContentImplProps {\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with animation libraries.\n */\n forceMount?: true;\n}\n\nfunction HoverCardContent(inProps: ScopedProps<HoverCardContentProps>) {\n const [local, rest] = splitProps(inProps, [\n '__scopeHoverCard',\n 'forceMount',\n 'ref',\n ]);\n\n const portalContext = usePortalContext(CONTENT_NAME, local.__scopeHoverCard);\n const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);\n const forceMount = () => local.forceMount ?? portalContext.forceMount;\n\n return (\n <Presence present={forceMount() || context.open}>\n <HoverCardContentImpl\n data-state={context.open ? 'open' : 'closed'}\n {...rest}\n __scopeHoverCard={local.__scopeHoverCard}\n onPointerEnter={composeEventHandlers(\n rest.onPointerEnter as any,\n excludeTouch(context.onOpen)\n )}\n onPointerLeave={composeEventHandlers(\n rest.onPointerLeave as any,\n excludeTouch(context.onClose)\n )}\n ref={local.ref}\n />\n </Presence>\n );\n}\n\nHoverCardContent.displayName = CONTENT_NAME;\n\n/* ---------------------------------------------------------------------------------------------- */\n\ninterface HoverCardContentImplProps extends JSX.HTMLAttributes<HTMLDivElement> {\n side?: 'top' | 'right' | 'bottom' | 'left';\n sideOffset?: number;\n align?: 'start' | 'center' | 'end';\n alignOffset?: number;\n avoidCollisions?: boolean;\n collisionBoundary?: Element | Element[] | null;\n collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;\n arrowPadding?: number;\n sticky?: 'partial' | 'always';\n hideWhenDetached?: boolean;\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n onPointerDownOutside?: (event: any) => void;\n onFocusOutside?: (event: any) => void;\n onInteractOutside?: (event: any) => void;\n ref?: (el: HTMLElement) => void;\n}\n\nfunction HoverCardContentImpl(inProps: ScopedProps<HoverCardContentImplProps & Record<string, any>>) {\n const [local, rest] = splitProps(inProps, [\n '__scopeHoverCard',\n '__scopePopper',\n 'ref',\n 'side',\n 'sideOffset',\n 'align',\n 'alignOffset',\n 'avoidCollisions',\n 'collisionBoundary',\n 'collisionPadding',\n 'arrowPadding',\n 'sticky',\n 'hideWhenDetached',\n 'onEscapeKeyDown',\n 'onPointerDownOutside',\n 'onFocusOutside',\n 'onInteractOutside',\n 'style',\n 'children',\n ]);\n\n const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n let contentRef: HTMLDivElement | undefined;\n const [containSelection, setContainSelection] = createSignal(false);\n\n // Manage body user-select when containing selection\n createEffect(() => {\n if (containSelection()) {\n const body = document.body;\n // Safari requires prefix\n originalBodyUserSelect = body.style.userSelect || body.style.webkitUserSelect;\n body.style.userSelect = 'none';\n body.style.webkitUserSelect = 'none';\n\n onCleanup(() => {\n body.style.userSelect = originalBodyUserSelect;\n body.style.webkitUserSelect = originalBodyUserSelect;\n });\n }\n });\n\n // Listen for pointerup to stop selection containment\n createEffect(() => {\n if (contentRef) {\n const handlePointerUp = () => {\n setContainSelection(false);\n context.isPointerDownOnContentRef.current = false;\n\n // Delay a frame to ensure we always access the latest selection\n setTimeout(() => {\n const hasSelection = document.getSelection()?.toString() !== '';\n if (hasSelection) context.hasSelectionRef.current = true;\n });\n };\n\n document.addEventListener('pointerup', handlePointerUp);\n\n onCleanup(() => {\n document.removeEventListener('pointerup', handlePointerUp);\n context.hasSelectionRef.current = false;\n context.isPointerDownOnContentRef.current = false;\n });\n }\n });\n\n // Make tabbable nodes non-tabbable\n createEffect(() => {\n if (contentRef) {\n const tabbables = getTabbableNodes(contentRef);\n tabbables.forEach((tabbable) => tabbable.setAttribute('tabindex', '-1'));\n }\n });\n\n return (\n <DismissableLayer\n asChild\n disableOutsidePointerEvents={false}\n onInteractOutside={local.onInteractOutside}\n onEscapeKeyDown={local.onEscapeKeyDown}\n onPointerDownOutside={local.onPointerDownOutside}\n onFocusOutside={composeEventHandlers(local.onFocusOutside, (event: any) => {\n event.preventDefault();\n })}\n onDismiss={context.onDismiss}\n >\n <PopperContent\n {...popperScope}\n {...rest}\n ref={mergeRefs(local.ref, (el: HTMLElement) => (contentRef = el as HTMLDivElement))}\n side={local.side}\n sideOffset={local.sideOffset}\n align={local.align}\n alignOffset={local.alignOffset}\n avoidCollisions={local.avoidCollisions}\n collisionBoundary={local.collisionBoundary}\n collisionPadding={local.collisionPadding}\n arrowPadding={local.arrowPadding}\n sticky={local.sticky}\n hideWhenDetached={local.hideWhenDetached}\n onPointerDown={composeEventHandlers(rest.onPointerDown as any, (event: PointerEvent) => {\n // Contain selection to current layer\n if ((event.currentTarget as HTMLElement).contains(event.target as HTMLElement)) {\n setContainSelection(true);\n }\n context.hasSelectionRef.current = false;\n context.isPointerDownOnContentRef.current = true;\n })}\n style={{\n ...(typeof local.style === 'object' ? local.style : {}),\n 'user-select': containSelection() ? 'text' : undefined,\n '-webkit-user-select': containSelection() ? 'text' : undefined,\n // re-namespace exposed content custom properties\n '--radix-hover-card-content-transform-origin': 'var(--radix-popper-transform-origin)',\n '--radix-hover-card-content-available-width': 'var(--radix-popper-available-width)',\n '--radix-hover-card-content-available-height': 'var(--radix-popper-available-height)',\n '--radix-hover-card-trigger-width': 'var(--radix-popper-anchor-width)',\n '--radix-hover-card-trigger-height': 'var(--radix-popper-anchor-height)',\n } as JSX.CSSProperties}\n >\n {local.children}\n </PopperContent>\n </DismissableLayer>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardArrow\n * -----------------------------------------------------------------------------------------------*/\n\nconst ARROW_NAME = 'HoverCardArrow';\n\ninterface HoverCardArrowProps extends JSX.SvgSVGAttributes<SVGSVGElement> {\n ref?: (el: SVGSVGElement) => void;\n}\n\nfunction HoverCardArrow(inProps: ScopedProps<HoverCardArrowProps>) {\n const [local, rest] = splitProps(inProps, ['__scopeHoverCard']);\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n return <PopperArrow {...popperScope} {...rest} />;\n}\n\nHoverCardArrow.displayName = ARROW_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction excludeTouch(eventHandler: () => void) {\n return (event: PointerEvent) =>\n event.pointerType === 'touch' ? undefined : eventHandler();\n}\n\n/**\n * Returns a list of nodes that can be in the tab sequence.\n * @see: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker\n */\nfunction getTabbableNodes(container: HTMLElement) {\n const nodes: HTMLElement[] = [];\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node: any) => {\n // `.tabIndex` is not the same as the `tabindex` attribute. It works on the\n // runtime's understanding of tabbability, so this automatically accounts\n // for any kind of element that could be tabbed to.\n return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;\n },\n });\n while (walker.nextNode()) nodes.push(walker.currentNode as HTMLElement);\n return nodes;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Exports\n * -----------------------------------------------------------------------------------------------*/\n\nconst Root = HoverCard;\nconst Trigger = HoverCardTrigger;\nconst HoverCardPortalExport = HoverCardPortal;\nconst Content = HoverCardContent;\nconst Arrow = HoverCardArrow;\n\nexport {\n createHoverCardScope,\n //\n HoverCard,\n HoverCardTrigger,\n HoverCardPortal,\n HoverCardContent,\n HoverCardArrow,\n //\n Root,\n Trigger,\n HoverCardPortalExport as Portal,\n Content,\n Arrow,\n};\nexport type {\n HoverCardProps,\n HoverCardTriggerProps,\n HoverCardPortalProps,\n HoverCardContentProps,\n HoverCardArrowProps,\n};\n"]}
@@ -0,0 +1,85 @@
1
+ import * as _radix_solid_js_context from '@radix-solid-js/context';
2
+ import { Scope } from '@radix-solid-js/context';
3
+ import { JSX } from 'solid-js';
4
+
5
+ type ScopedProps<P> = P & {
6
+ __scopeHoverCard?: Scope;
7
+ };
8
+ declare const createHoverCardScope: _radix_solid_js_context.CreateScope;
9
+ interface HoverCardProps {
10
+ children?: JSX.Element;
11
+ open?: boolean;
12
+ defaultOpen?: boolean;
13
+ onOpenChange?: (open: boolean) => void;
14
+ openDelay?: number;
15
+ closeDelay?: number;
16
+ }
17
+ declare function HoverCard(inProps: ScopedProps<HoverCardProps>): JSX.Element;
18
+ declare namespace HoverCard {
19
+ var displayName: string;
20
+ }
21
+ interface HoverCardTriggerProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {
22
+ ref?: (el: HTMLElement) => void;
23
+ }
24
+ declare function HoverCardTrigger(inProps: ScopedProps<HoverCardTriggerProps>): JSX.Element;
25
+ declare namespace HoverCardTrigger {
26
+ var displayName: string;
27
+ }
28
+ interface HoverCardPortalProps {
29
+ children?: JSX.Element;
30
+ /**
31
+ * Specify a container element to portal the content into.
32
+ */
33
+ container?: Element | DocumentFragment | null;
34
+ /**
35
+ * Used to force mounting when more control is needed. Useful when
36
+ * controlling animation with animation libraries.
37
+ */
38
+ forceMount?: true;
39
+ }
40
+ declare function HoverCardPortal(inProps: ScopedProps<HoverCardPortalProps>): JSX.Element;
41
+ declare namespace HoverCardPortal {
42
+ var displayName: string;
43
+ }
44
+ interface HoverCardContentProps extends HoverCardContentImplProps {
45
+ /**
46
+ * Used to force mounting when more control is needed. Useful when
47
+ * controlling animation with animation libraries.
48
+ */
49
+ forceMount?: true;
50
+ }
51
+ declare function HoverCardContent(inProps: ScopedProps<HoverCardContentProps>): JSX.Element;
52
+ declare namespace HoverCardContent {
53
+ var displayName: string;
54
+ }
55
+ interface HoverCardContentImplProps extends JSX.HTMLAttributes<HTMLDivElement> {
56
+ side?: 'top' | 'right' | 'bottom' | 'left';
57
+ sideOffset?: number;
58
+ align?: 'start' | 'center' | 'end';
59
+ alignOffset?: number;
60
+ avoidCollisions?: boolean;
61
+ collisionBoundary?: Element | Element[] | null;
62
+ collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;
63
+ arrowPadding?: number;
64
+ sticky?: 'partial' | 'always';
65
+ hideWhenDetached?: boolean;
66
+ onEscapeKeyDown?: (event: KeyboardEvent) => void;
67
+ onPointerDownOutside?: (event: any) => void;
68
+ onFocusOutside?: (event: any) => void;
69
+ onInteractOutside?: (event: any) => void;
70
+ ref?: (el: HTMLElement) => void;
71
+ }
72
+ interface HoverCardArrowProps extends JSX.SvgSVGAttributes<SVGSVGElement> {
73
+ ref?: (el: SVGSVGElement) => void;
74
+ }
75
+ declare function HoverCardArrow(inProps: ScopedProps<HoverCardArrowProps>): JSX.Element;
76
+ declare namespace HoverCardArrow {
77
+ var displayName: string;
78
+ }
79
+ declare const Root: typeof HoverCard;
80
+ declare const Trigger: typeof HoverCardTrigger;
81
+ declare const HoverCardPortalExport: typeof HoverCardPortal;
82
+ declare const Content: typeof HoverCardContent;
83
+ declare const Arrow: typeof HoverCardArrow;
84
+
85
+ export { Arrow, Content, HoverCard, HoverCardArrow, type HoverCardArrowProps, HoverCardContent, type HoverCardContentProps, HoverCardPortal, type HoverCardPortalProps, type HoverCardProps, HoverCardTrigger, type HoverCardTriggerProps, HoverCardPortalExport as Portal, Root, Trigger, createHoverCardScope };
@@ -0,0 +1,85 @@
1
+ import * as _radix_solid_js_context from '@radix-solid-js/context';
2
+ import { Scope } from '@radix-solid-js/context';
3
+ import { JSX } from 'solid-js';
4
+
5
+ type ScopedProps<P> = P & {
6
+ __scopeHoverCard?: Scope;
7
+ };
8
+ declare const createHoverCardScope: _radix_solid_js_context.CreateScope;
9
+ interface HoverCardProps {
10
+ children?: JSX.Element;
11
+ open?: boolean;
12
+ defaultOpen?: boolean;
13
+ onOpenChange?: (open: boolean) => void;
14
+ openDelay?: number;
15
+ closeDelay?: number;
16
+ }
17
+ declare function HoverCard(inProps: ScopedProps<HoverCardProps>): JSX.Element;
18
+ declare namespace HoverCard {
19
+ var displayName: string;
20
+ }
21
+ interface HoverCardTriggerProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {
22
+ ref?: (el: HTMLElement) => void;
23
+ }
24
+ declare function HoverCardTrigger(inProps: ScopedProps<HoverCardTriggerProps>): JSX.Element;
25
+ declare namespace HoverCardTrigger {
26
+ var displayName: string;
27
+ }
28
+ interface HoverCardPortalProps {
29
+ children?: JSX.Element;
30
+ /**
31
+ * Specify a container element to portal the content into.
32
+ */
33
+ container?: Element | DocumentFragment | null;
34
+ /**
35
+ * Used to force mounting when more control is needed. Useful when
36
+ * controlling animation with animation libraries.
37
+ */
38
+ forceMount?: true;
39
+ }
40
+ declare function HoverCardPortal(inProps: ScopedProps<HoverCardPortalProps>): JSX.Element;
41
+ declare namespace HoverCardPortal {
42
+ var displayName: string;
43
+ }
44
+ interface HoverCardContentProps extends HoverCardContentImplProps {
45
+ /**
46
+ * Used to force mounting when more control is needed. Useful when
47
+ * controlling animation with animation libraries.
48
+ */
49
+ forceMount?: true;
50
+ }
51
+ declare function HoverCardContent(inProps: ScopedProps<HoverCardContentProps>): JSX.Element;
52
+ declare namespace HoverCardContent {
53
+ var displayName: string;
54
+ }
55
+ interface HoverCardContentImplProps extends JSX.HTMLAttributes<HTMLDivElement> {
56
+ side?: 'top' | 'right' | 'bottom' | 'left';
57
+ sideOffset?: number;
58
+ align?: 'start' | 'center' | 'end';
59
+ alignOffset?: number;
60
+ avoidCollisions?: boolean;
61
+ collisionBoundary?: Element | Element[] | null;
62
+ collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;
63
+ arrowPadding?: number;
64
+ sticky?: 'partial' | 'always';
65
+ hideWhenDetached?: boolean;
66
+ onEscapeKeyDown?: (event: KeyboardEvent) => void;
67
+ onPointerDownOutside?: (event: any) => void;
68
+ onFocusOutside?: (event: any) => void;
69
+ onInteractOutside?: (event: any) => void;
70
+ ref?: (el: HTMLElement) => void;
71
+ }
72
+ interface HoverCardArrowProps extends JSX.SvgSVGAttributes<SVGSVGElement> {
73
+ ref?: (el: SVGSVGElement) => void;
74
+ }
75
+ declare function HoverCardArrow(inProps: ScopedProps<HoverCardArrowProps>): JSX.Element;
76
+ declare namespace HoverCardArrow {
77
+ var displayName: string;
78
+ }
79
+ declare const Root: typeof HoverCard;
80
+ declare const Trigger: typeof HoverCardTrigger;
81
+ declare const HoverCardPortalExport: typeof HoverCardPortal;
82
+ declare const Content: typeof HoverCardContent;
83
+ declare const Arrow: typeof HoverCardArrow;
84
+
85
+ export { Arrow, Content, HoverCard, HoverCardArrow, type HoverCardArrowProps, HoverCardContent, type HoverCardContentProps, HoverCardPortal, type HoverCardPortalProps, type HoverCardProps, HoverCardTrigger, type HoverCardTriggerProps, HoverCardPortalExport as Portal, Root, Trigger, createHoverCardScope };
package/dist/index.js ADDED
@@ -0,0 +1,285 @@
1
+ import { splitProps, onCleanup, createSignal, createEffect } from 'solid-js';
2
+ import { composeEventHandlers } from '@radix-solid-js/primitive';
3
+ import { mergeRefs } from '@radix-solid-js/compose-refs';
4
+ import { createContextScope } from '@radix-solid-js/context';
5
+ import { DismissableLayer } from '@radix-solid-js/dismissable-layer';
6
+ import { createPopperScope, Popper, PopperAnchor, PopperContent, PopperArrow } from '@radix-solid-js/popper';
7
+ import { Portal } from '@radix-solid-js/portal';
8
+ import { Presence } from '@radix-solid-js/presence';
9
+ import { Primitive } from '@radix-solid-js/primitive-component';
10
+ import { createControllableSignal } from '@radix-solid-js/use-controllable-state';
11
+
12
+ // src/hover-card.tsx
13
+ var originalBodyUserSelect;
14
+ var HOVERCARD_NAME = "HoverCard";
15
+ var [createHoverCardContext, createHoverCardScope] = createContextScope(
16
+ HOVERCARD_NAME,
17
+ [createPopperScope]
18
+ );
19
+ var usePopperScope = createPopperScope();
20
+ var [HoverCardProvider, useHoverCardContext] = createHoverCardContext(HOVERCARD_NAME);
21
+ function HoverCard(inProps) {
22
+ const [local] = splitProps(inProps, [
23
+ "__scopeHoverCard",
24
+ "children",
25
+ "open",
26
+ "defaultOpen",
27
+ "onOpenChange",
28
+ "openDelay",
29
+ "closeDelay"
30
+ ]);
31
+ const popperScope = usePopperScope(local.__scopeHoverCard);
32
+ let openTimerRef = 0;
33
+ let closeTimerRef = 0;
34
+ const hasSelectionRef = { current: false };
35
+ const isPointerDownOnContentRef = { current: false };
36
+ const openDelay = () => local.openDelay ?? 700;
37
+ const closeDelay = () => local.closeDelay ?? 300;
38
+ const [open, setOpen] = createControllableSignal({
39
+ prop: () => local.open,
40
+ defaultProp: local.defaultOpen ?? false,
41
+ onChange: (value) => {
42
+ local.onOpenChange?.(value);
43
+ }
44
+ });
45
+ const handleOpen = () => {
46
+ clearTimeout(closeTimerRef);
47
+ openTimerRef = window.setTimeout(() => setOpen(true), openDelay());
48
+ };
49
+ const handleClose = () => {
50
+ clearTimeout(openTimerRef);
51
+ if (!hasSelectionRef.current && !isPointerDownOnContentRef.current) {
52
+ closeTimerRef = window.setTimeout(() => setOpen(false), closeDelay());
53
+ }
54
+ };
55
+ const handleDismiss = () => setOpen(false);
56
+ onCleanup(() => {
57
+ clearTimeout(openTimerRef);
58
+ clearTimeout(closeTimerRef);
59
+ });
60
+ return /* @__PURE__ */ React.createElement(
61
+ HoverCardProvider,
62
+ {
63
+ scope: local.__scopeHoverCard,
64
+ open: open(),
65
+ onOpenChange: setOpen,
66
+ onOpen: handleOpen,
67
+ onClose: handleClose,
68
+ onDismiss: handleDismiss,
69
+ hasSelectionRef,
70
+ isPointerDownOnContentRef
71
+ },
72
+ /* @__PURE__ */ React.createElement(Popper, { ...popperScope }, local.children)
73
+ );
74
+ }
75
+ HoverCard.displayName = HOVERCARD_NAME;
76
+ var TRIGGER_NAME = "HoverCardTrigger";
77
+ function HoverCardTrigger(inProps) {
78
+ const [local, rest] = splitProps(inProps, ["__scopeHoverCard", "ref"]);
79
+ const context = useHoverCardContext(TRIGGER_NAME, local.__scopeHoverCard);
80
+ const popperScope = usePopperScope(local.__scopeHoverCard);
81
+ return /* @__PURE__ */ React.createElement(PopperAnchor, { asChild: true, ...popperScope }, /* @__PURE__ */ React.createElement(
82
+ Primitive.a,
83
+ {
84
+ "data-state": context.open ? "open" : "closed",
85
+ ...rest,
86
+ ref: local.ref,
87
+ onPointerEnter: composeEventHandlers(rest.onPointerEnter, excludeTouch(context.onOpen)),
88
+ onPointerLeave: composeEventHandlers(rest.onPointerLeave, excludeTouch(context.onClose)),
89
+ onFocus: composeEventHandlers(rest.onFocus, context.onOpen),
90
+ onBlur: composeEventHandlers(rest.onBlur, context.onClose),
91
+ onTouchStart: composeEventHandlers(
92
+ rest.onTouchStart,
93
+ (event) => event.preventDefault()
94
+ )
95
+ }
96
+ ));
97
+ }
98
+ HoverCardTrigger.displayName = TRIGGER_NAME;
99
+ var PORTAL_NAME = "HoverCardPortal";
100
+ var [PortalProvider, usePortalContext] = createHoverCardContext(
101
+ PORTAL_NAME,
102
+ { forceMount: void 0 }
103
+ );
104
+ function HoverCardPortal(inProps) {
105
+ const [local] = splitProps(inProps, [
106
+ "__scopeHoverCard",
107
+ "children",
108
+ "container",
109
+ "forceMount"
110
+ ]);
111
+ return /* @__PURE__ */ React.createElement(PortalProvider, { scope: local.__scopeHoverCard, forceMount: local.forceMount }, /* @__PURE__ */ React.createElement(Portal, { container: local.container }, local.children));
112
+ }
113
+ HoverCardPortal.displayName = PORTAL_NAME;
114
+ var CONTENT_NAME = "HoverCardContent";
115
+ function HoverCardContent(inProps) {
116
+ const [local, rest] = splitProps(inProps, [
117
+ "__scopeHoverCard",
118
+ "forceMount",
119
+ "ref"
120
+ ]);
121
+ const portalContext = usePortalContext(CONTENT_NAME, local.__scopeHoverCard);
122
+ const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);
123
+ const forceMount = () => local.forceMount ?? portalContext.forceMount;
124
+ return /* @__PURE__ */ React.createElement(Presence, { present: forceMount() || context.open }, /* @__PURE__ */ React.createElement(
125
+ HoverCardContentImpl,
126
+ {
127
+ "data-state": context.open ? "open" : "closed",
128
+ ...rest,
129
+ __scopeHoverCard: local.__scopeHoverCard,
130
+ onPointerEnter: composeEventHandlers(
131
+ rest.onPointerEnter,
132
+ excludeTouch(context.onOpen)
133
+ ),
134
+ onPointerLeave: composeEventHandlers(
135
+ rest.onPointerLeave,
136
+ excludeTouch(context.onClose)
137
+ ),
138
+ ref: local.ref
139
+ }
140
+ ));
141
+ }
142
+ HoverCardContent.displayName = CONTENT_NAME;
143
+ function HoverCardContentImpl(inProps) {
144
+ const [local, rest] = splitProps(inProps, [
145
+ "__scopeHoverCard",
146
+ "__scopePopper",
147
+ "ref",
148
+ "side",
149
+ "sideOffset",
150
+ "align",
151
+ "alignOffset",
152
+ "avoidCollisions",
153
+ "collisionBoundary",
154
+ "collisionPadding",
155
+ "arrowPadding",
156
+ "sticky",
157
+ "hideWhenDetached",
158
+ "onEscapeKeyDown",
159
+ "onPointerDownOutside",
160
+ "onFocusOutside",
161
+ "onInteractOutside",
162
+ "style",
163
+ "children"
164
+ ]);
165
+ const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);
166
+ const popperScope = usePopperScope(local.__scopeHoverCard);
167
+ let contentRef;
168
+ const [containSelection, setContainSelection] = createSignal(false);
169
+ createEffect(() => {
170
+ if (containSelection()) {
171
+ const body = document.body;
172
+ originalBodyUserSelect = body.style.userSelect || body.style.webkitUserSelect;
173
+ body.style.userSelect = "none";
174
+ body.style.webkitUserSelect = "none";
175
+ onCleanup(() => {
176
+ body.style.userSelect = originalBodyUserSelect;
177
+ body.style.webkitUserSelect = originalBodyUserSelect;
178
+ });
179
+ }
180
+ });
181
+ createEffect(() => {
182
+ if (contentRef) {
183
+ const handlePointerUp = () => {
184
+ setContainSelection(false);
185
+ context.isPointerDownOnContentRef.current = false;
186
+ setTimeout(() => {
187
+ const hasSelection = document.getSelection()?.toString() !== "";
188
+ if (hasSelection) context.hasSelectionRef.current = true;
189
+ });
190
+ };
191
+ document.addEventListener("pointerup", handlePointerUp);
192
+ onCleanup(() => {
193
+ document.removeEventListener("pointerup", handlePointerUp);
194
+ context.hasSelectionRef.current = false;
195
+ context.isPointerDownOnContentRef.current = false;
196
+ });
197
+ }
198
+ });
199
+ createEffect(() => {
200
+ if (contentRef) {
201
+ const tabbables = getTabbableNodes(contentRef);
202
+ tabbables.forEach((tabbable) => tabbable.setAttribute("tabindex", "-1"));
203
+ }
204
+ });
205
+ return /* @__PURE__ */ React.createElement(
206
+ DismissableLayer,
207
+ {
208
+ asChild: true,
209
+ disableOutsidePointerEvents: false,
210
+ onInteractOutside: local.onInteractOutside,
211
+ onEscapeKeyDown: local.onEscapeKeyDown,
212
+ onPointerDownOutside: local.onPointerDownOutside,
213
+ onFocusOutside: composeEventHandlers(local.onFocusOutside, (event) => {
214
+ event.preventDefault();
215
+ }),
216
+ onDismiss: context.onDismiss
217
+ },
218
+ /* @__PURE__ */ React.createElement(
219
+ PopperContent,
220
+ {
221
+ ...popperScope,
222
+ ...rest,
223
+ ref: mergeRefs(local.ref, (el) => contentRef = el),
224
+ side: local.side,
225
+ sideOffset: local.sideOffset,
226
+ align: local.align,
227
+ alignOffset: local.alignOffset,
228
+ avoidCollisions: local.avoidCollisions,
229
+ collisionBoundary: local.collisionBoundary,
230
+ collisionPadding: local.collisionPadding,
231
+ arrowPadding: local.arrowPadding,
232
+ sticky: local.sticky,
233
+ hideWhenDetached: local.hideWhenDetached,
234
+ onPointerDown: composeEventHandlers(rest.onPointerDown, (event) => {
235
+ if (event.currentTarget.contains(event.target)) {
236
+ setContainSelection(true);
237
+ }
238
+ context.hasSelectionRef.current = false;
239
+ context.isPointerDownOnContentRef.current = true;
240
+ }),
241
+ style: {
242
+ ...typeof local.style === "object" ? local.style : {},
243
+ "user-select": containSelection() ? "text" : void 0,
244
+ "-webkit-user-select": containSelection() ? "text" : void 0,
245
+ // re-namespace exposed content custom properties
246
+ "--radix-hover-card-content-transform-origin": "var(--radix-popper-transform-origin)",
247
+ "--radix-hover-card-content-available-width": "var(--radix-popper-available-width)",
248
+ "--radix-hover-card-content-available-height": "var(--radix-popper-available-height)",
249
+ "--radix-hover-card-trigger-width": "var(--radix-popper-anchor-width)",
250
+ "--radix-hover-card-trigger-height": "var(--radix-popper-anchor-height)"
251
+ }
252
+ },
253
+ local.children
254
+ )
255
+ );
256
+ }
257
+ var ARROW_NAME = "HoverCardArrow";
258
+ function HoverCardArrow(inProps) {
259
+ const [local, rest] = splitProps(inProps, ["__scopeHoverCard"]);
260
+ const popperScope = usePopperScope(local.__scopeHoverCard);
261
+ return /* @__PURE__ */ React.createElement(PopperArrow, { ...popperScope, ...rest });
262
+ }
263
+ HoverCardArrow.displayName = ARROW_NAME;
264
+ function excludeTouch(eventHandler) {
265
+ return (event) => event.pointerType === "touch" ? void 0 : eventHandler();
266
+ }
267
+ function getTabbableNodes(container) {
268
+ const nodes = [];
269
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
270
+ acceptNode: (node) => {
271
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
272
+ }
273
+ });
274
+ while (walker.nextNode()) nodes.push(walker.currentNode);
275
+ return nodes;
276
+ }
277
+ var Root = HoverCard;
278
+ var Trigger = HoverCardTrigger;
279
+ var HoverCardPortalExport = HoverCardPortal;
280
+ var Content = HoverCardContent;
281
+ var Arrow = HoverCardArrow;
282
+
283
+ export { Arrow, Content, HoverCard, HoverCardArrow, HoverCardContent, HoverCardPortal, HoverCardTrigger, HoverCardPortalExport as Portal, Root, Trigger, createHoverCardScope };
284
+ //# sourceMappingURL=index.js.map
285
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hover-card.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import {\n type JSX,\n createSignal,\n createEffect,\n onCleanup,\n splitProps,\n} from 'solid-js';\nimport { composeEventHandlers } from '@radix-solid-js/primitive';\nimport { mergeRefs } from '@radix-solid-js/compose-refs';\nimport { createContextScope, type Scope } from '@radix-solid-js/context';\nimport { DismissableLayer } from '@radix-solid-js/dismissable-layer';\nimport {\n createPopperScope,\n Popper,\n PopperAnchor,\n PopperContent,\n PopperArrow,\n} from '@radix-solid-js/popper';\nimport { Portal } from '@radix-solid-js/portal';\nimport { Presence } from '@radix-solid-js/presence';\nimport { Primitive } from '@radix-solid-js/primitive-component';\nimport { createControllableSignal } from '@radix-solid-js/use-controllable-state';\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCard\n * -----------------------------------------------------------------------------------------------*/\n\nlet originalBodyUserSelect: string;\n\nconst HOVERCARD_NAME = 'HoverCard';\n\ntype ScopedProps<P> = P & { __scopeHoverCard?: Scope };\nconst [createHoverCardContext, createHoverCardScope] = createContextScope(\n HOVERCARD_NAME,\n [createPopperScope]\n);\nconst usePopperScope = createPopperScope();\n\ntype HoverCardContextValue = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onOpen: () => void;\n onClose: () => void;\n onDismiss: () => void;\n hasSelectionRef: { current: boolean };\n isPointerDownOnContentRef: { current: boolean };\n};\n\nconst [HoverCardProvider, useHoverCardContext] =\n createHoverCardContext<HoverCardContextValue>(HOVERCARD_NAME);\n\ninterface HoverCardProps {\n children?: JSX.Element;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n openDelay?: number;\n closeDelay?: number;\n}\n\nfunction HoverCard(inProps: ScopedProps<HoverCardProps>) {\n const [local] = splitProps(inProps, [\n '__scopeHoverCard',\n 'children',\n 'open',\n 'defaultOpen',\n 'onOpenChange',\n 'openDelay',\n 'closeDelay',\n ]);\n\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n let openTimerRef = 0;\n let closeTimerRef = 0;\n const hasSelectionRef = { current: false };\n const isPointerDownOnContentRef = { current: false };\n\n const openDelay = () => local.openDelay ?? 700;\n const closeDelay = () => local.closeDelay ?? 300;\n\n const [open, setOpen] = createControllableSignal({\n prop: () => local.open,\n defaultProp: local.defaultOpen ?? false,\n onChange: (value) => {\n local.onOpenChange?.(value);\n },\n });\n\n const handleOpen = () => {\n clearTimeout(closeTimerRef);\n openTimerRef = window.setTimeout(() => setOpen(true), openDelay());\n };\n\n const handleClose = () => {\n clearTimeout(openTimerRef);\n if (!hasSelectionRef.current && !isPointerDownOnContentRef.current) {\n closeTimerRef = window.setTimeout(() => setOpen(false), closeDelay());\n }\n };\n\n const handleDismiss = () => setOpen(false);\n\n // cleanup any queued state updates on unmount\n onCleanup(() => {\n clearTimeout(openTimerRef);\n clearTimeout(closeTimerRef);\n });\n\n return (\n <HoverCardProvider\n scope={local.__scopeHoverCard}\n open={open()}\n onOpenChange={setOpen}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n hasSelectionRef={hasSelectionRef}\n isPointerDownOnContentRef={isPointerDownOnContentRef}\n >\n <Popper {...popperScope}>{local.children}</Popper>\n </HoverCardProvider>\n );\n}\n\nHoverCard.displayName = HOVERCARD_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardTrigger\n * -----------------------------------------------------------------------------------------------*/\n\nconst TRIGGER_NAME = 'HoverCardTrigger';\n\ninterface HoverCardTriggerProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {\n ref?: (el: HTMLElement) => void;\n}\n\nfunction HoverCardTrigger(inProps: ScopedProps<HoverCardTriggerProps>) {\n const [local, rest] = splitProps(inProps, ['__scopeHoverCard', 'ref']);\n const context = useHoverCardContext(TRIGGER_NAME, local.__scopeHoverCard);\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n return (\n <PopperAnchor asChild {...popperScope}>\n <Primitive.a\n data-state={context.open ? 'open' : 'closed'}\n {...rest}\n ref={local.ref}\n onPointerEnter={composeEventHandlers(rest.onPointerEnter as any, excludeTouch(context.onOpen))}\n onPointerLeave={composeEventHandlers(rest.onPointerLeave as any, excludeTouch(context.onClose))}\n onFocus={composeEventHandlers(rest.onFocus as any, context.onOpen)}\n onBlur={composeEventHandlers(rest.onBlur as any, context.onClose)}\n // prevent focus event on touch devices\n onTouchStart={composeEventHandlers(rest.onTouchStart as any, (event: TouchEvent) =>\n event.preventDefault()\n )}\n />\n </PopperAnchor>\n );\n}\n\nHoverCardTrigger.displayName = TRIGGER_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'HoverCardPortal';\n\ntype PortalContextValue = { forceMount?: true };\nconst [PortalProvider, usePortalContext] = createHoverCardContext<PortalContextValue>(\n PORTAL_NAME,\n { forceMount: undefined }\n);\n\ninterface HoverCardPortalProps {\n children?: JSX.Element;\n /**\n * Specify a container element to portal the content into.\n */\n container?: Element | DocumentFragment | null;\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with animation libraries.\n */\n forceMount?: true;\n}\n\nfunction HoverCardPortal(inProps: ScopedProps<HoverCardPortalProps>) {\n const [local] = splitProps(inProps, [\n '__scopeHoverCard',\n 'children',\n 'container',\n 'forceMount',\n ]);\n\n // Portal is always mounted — visibility is controlled by Presence in HoverCardContent.\n // This avoids the dual-Presence problem where the outer Presence would unmount\n // the portal before the inner exit animation completes.\n return (\n <PortalProvider scope={local.__scopeHoverCard} forceMount={local.forceMount}>\n <Portal container={local.container}>\n {local.children}\n </Portal>\n </PortalProvider>\n );\n}\n\nHoverCardPortal.displayName = PORTAL_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'HoverCardContent';\n\ninterface HoverCardContentProps extends HoverCardContentImplProps {\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with animation libraries.\n */\n forceMount?: true;\n}\n\nfunction HoverCardContent(inProps: ScopedProps<HoverCardContentProps>) {\n const [local, rest] = splitProps(inProps, [\n '__scopeHoverCard',\n 'forceMount',\n 'ref',\n ]);\n\n const portalContext = usePortalContext(CONTENT_NAME, local.__scopeHoverCard);\n const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);\n const forceMount = () => local.forceMount ?? portalContext.forceMount;\n\n return (\n <Presence present={forceMount() || context.open}>\n <HoverCardContentImpl\n data-state={context.open ? 'open' : 'closed'}\n {...rest}\n __scopeHoverCard={local.__scopeHoverCard}\n onPointerEnter={composeEventHandlers(\n rest.onPointerEnter as any,\n excludeTouch(context.onOpen)\n )}\n onPointerLeave={composeEventHandlers(\n rest.onPointerLeave as any,\n excludeTouch(context.onClose)\n )}\n ref={local.ref}\n />\n </Presence>\n );\n}\n\nHoverCardContent.displayName = CONTENT_NAME;\n\n/* ---------------------------------------------------------------------------------------------- */\n\ninterface HoverCardContentImplProps extends JSX.HTMLAttributes<HTMLDivElement> {\n side?: 'top' | 'right' | 'bottom' | 'left';\n sideOffset?: number;\n align?: 'start' | 'center' | 'end';\n alignOffset?: number;\n avoidCollisions?: boolean;\n collisionBoundary?: Element | Element[] | null;\n collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;\n arrowPadding?: number;\n sticky?: 'partial' | 'always';\n hideWhenDetached?: boolean;\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n onPointerDownOutside?: (event: any) => void;\n onFocusOutside?: (event: any) => void;\n onInteractOutside?: (event: any) => void;\n ref?: (el: HTMLElement) => void;\n}\n\nfunction HoverCardContentImpl(inProps: ScopedProps<HoverCardContentImplProps & Record<string, any>>) {\n const [local, rest] = splitProps(inProps, [\n '__scopeHoverCard',\n '__scopePopper',\n 'ref',\n 'side',\n 'sideOffset',\n 'align',\n 'alignOffset',\n 'avoidCollisions',\n 'collisionBoundary',\n 'collisionPadding',\n 'arrowPadding',\n 'sticky',\n 'hideWhenDetached',\n 'onEscapeKeyDown',\n 'onPointerDownOutside',\n 'onFocusOutside',\n 'onInteractOutside',\n 'style',\n 'children',\n ]);\n\n const context = useHoverCardContext(CONTENT_NAME, local.__scopeHoverCard);\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n let contentRef: HTMLDivElement | undefined;\n const [containSelection, setContainSelection] = createSignal(false);\n\n // Manage body user-select when containing selection\n createEffect(() => {\n if (containSelection()) {\n const body = document.body;\n // Safari requires prefix\n originalBodyUserSelect = body.style.userSelect || body.style.webkitUserSelect;\n body.style.userSelect = 'none';\n body.style.webkitUserSelect = 'none';\n\n onCleanup(() => {\n body.style.userSelect = originalBodyUserSelect;\n body.style.webkitUserSelect = originalBodyUserSelect;\n });\n }\n });\n\n // Listen for pointerup to stop selection containment\n createEffect(() => {\n if (contentRef) {\n const handlePointerUp = () => {\n setContainSelection(false);\n context.isPointerDownOnContentRef.current = false;\n\n // Delay a frame to ensure we always access the latest selection\n setTimeout(() => {\n const hasSelection = document.getSelection()?.toString() !== '';\n if (hasSelection) context.hasSelectionRef.current = true;\n });\n };\n\n document.addEventListener('pointerup', handlePointerUp);\n\n onCleanup(() => {\n document.removeEventListener('pointerup', handlePointerUp);\n context.hasSelectionRef.current = false;\n context.isPointerDownOnContentRef.current = false;\n });\n }\n });\n\n // Make tabbable nodes non-tabbable\n createEffect(() => {\n if (contentRef) {\n const tabbables = getTabbableNodes(contentRef);\n tabbables.forEach((tabbable) => tabbable.setAttribute('tabindex', '-1'));\n }\n });\n\n return (\n <DismissableLayer\n asChild\n disableOutsidePointerEvents={false}\n onInteractOutside={local.onInteractOutside}\n onEscapeKeyDown={local.onEscapeKeyDown}\n onPointerDownOutside={local.onPointerDownOutside}\n onFocusOutside={composeEventHandlers(local.onFocusOutside, (event: any) => {\n event.preventDefault();\n })}\n onDismiss={context.onDismiss}\n >\n <PopperContent\n {...popperScope}\n {...rest}\n ref={mergeRefs(local.ref, (el: HTMLElement) => (contentRef = el as HTMLDivElement))}\n side={local.side}\n sideOffset={local.sideOffset}\n align={local.align}\n alignOffset={local.alignOffset}\n avoidCollisions={local.avoidCollisions}\n collisionBoundary={local.collisionBoundary}\n collisionPadding={local.collisionPadding}\n arrowPadding={local.arrowPadding}\n sticky={local.sticky}\n hideWhenDetached={local.hideWhenDetached}\n onPointerDown={composeEventHandlers(rest.onPointerDown as any, (event: PointerEvent) => {\n // Contain selection to current layer\n if ((event.currentTarget as HTMLElement).contains(event.target as HTMLElement)) {\n setContainSelection(true);\n }\n context.hasSelectionRef.current = false;\n context.isPointerDownOnContentRef.current = true;\n })}\n style={{\n ...(typeof local.style === 'object' ? local.style : {}),\n 'user-select': containSelection() ? 'text' : undefined,\n '-webkit-user-select': containSelection() ? 'text' : undefined,\n // re-namespace exposed content custom properties\n '--radix-hover-card-content-transform-origin': 'var(--radix-popper-transform-origin)',\n '--radix-hover-card-content-available-width': 'var(--radix-popper-available-width)',\n '--radix-hover-card-content-available-height': 'var(--radix-popper-available-height)',\n '--radix-hover-card-trigger-width': 'var(--radix-popper-anchor-width)',\n '--radix-hover-card-trigger-height': 'var(--radix-popper-anchor-height)',\n } as JSX.CSSProperties}\n >\n {local.children}\n </PopperContent>\n </DismissableLayer>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * HoverCardArrow\n * -----------------------------------------------------------------------------------------------*/\n\nconst ARROW_NAME = 'HoverCardArrow';\n\ninterface HoverCardArrowProps extends JSX.SvgSVGAttributes<SVGSVGElement> {\n ref?: (el: SVGSVGElement) => void;\n}\n\nfunction HoverCardArrow(inProps: ScopedProps<HoverCardArrowProps>) {\n const [local, rest] = splitProps(inProps, ['__scopeHoverCard']);\n const popperScope = usePopperScope(local.__scopeHoverCard);\n\n return <PopperArrow {...popperScope} {...rest} />;\n}\n\nHoverCardArrow.displayName = ARROW_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction excludeTouch(eventHandler: () => void) {\n return (event: PointerEvent) =>\n event.pointerType === 'touch' ? undefined : eventHandler();\n}\n\n/**\n * Returns a list of nodes that can be in the tab sequence.\n * @see: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker\n */\nfunction getTabbableNodes(container: HTMLElement) {\n const nodes: HTMLElement[] = [];\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node: any) => {\n // `.tabIndex` is not the same as the `tabindex` attribute. It works on the\n // runtime's understanding of tabbability, so this automatically accounts\n // for any kind of element that could be tabbed to.\n return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;\n },\n });\n while (walker.nextNode()) nodes.push(walker.currentNode as HTMLElement);\n return nodes;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Exports\n * -----------------------------------------------------------------------------------------------*/\n\nconst Root = HoverCard;\nconst Trigger = HoverCardTrigger;\nconst HoverCardPortalExport = HoverCardPortal;\nconst Content = HoverCardContent;\nconst Arrow = HoverCardArrow;\n\nexport {\n createHoverCardScope,\n //\n HoverCard,\n HoverCardTrigger,\n HoverCardPortal,\n HoverCardContent,\n HoverCardArrow,\n //\n Root,\n Trigger,\n HoverCardPortalExport as Portal,\n Content,\n Arrow,\n};\nexport type {\n HoverCardProps,\n HoverCardTriggerProps,\n HoverCardPortalProps,\n HoverCardContentProps,\n HoverCardArrowProps,\n};\n"]}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@radix-solid-js/hover-card",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "sideEffects": false,
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "clean": "rm -rf dist",
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "vitest run"
30
+ },
31
+ "dependencies": {
32
+ "@radix-solid-js/primitive": "workspace:*",
33
+ "@radix-solid-js/compose-refs": "workspace:*",
34
+ "@radix-solid-js/context": "workspace:*",
35
+ "@radix-solid-js/dismissable-layer": "workspace:*",
36
+ "@radix-solid-js/popper": "workspace:*",
37
+ "@radix-solid-js/portal": "workspace:*",
38
+ "@radix-solid-js/presence": "workspace:*",
39
+ "@radix-solid-js/primitive-component": "workspace:*",
40
+ "@radix-solid-js/use-controllable-state": "workspace:*"
41
+ },
42
+ "peerDependencies": {
43
+ "solid-js": "^1.8.0"
44
+ },
45
+ "devDependencies": {
46
+ "@repo/tsconfig": "workspace:*",
47
+ "tsup": "^8.3.6",
48
+ "typescript": "^5.7.3",
49
+ "solid-js": "^1.9.3",
50
+ "vitest": "^2.1.8"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "https://github.com/ljho01/shadcn-solid-js.git",
58
+ "directory": "packages/solid/hover-card"
59
+ }
60
+ }