@astryxdesign/core 0.4.1-canary.9e8a72a → 0.4.1-canary.e07f38f
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/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +9 -7
- package/dist/Chat/ChatMessage.d.ts +7 -0
- package/dist/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/Chat/ChatMessageBubble.d.ts +13 -1
- package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
- package/dist/Chat/ChatMessageBubble.js +19 -1
- package/dist/HoverCard/HoverCard.d.ts +1 -1
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +5 -13
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +6 -5
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +7 -2
- package/dist/Layer/layerHost.d.ts +24 -0
- package/dist/Layer/layerHost.d.ts.map +1 -0
- package/dist/Layer/layerHost.js +79 -0
- package/dist/Layer/useLayer.d.ts +14 -6
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +155 -29
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +54 -13
- package/dist/astryx.css +3 -7
- package/dist/astryx.umd.js +46 -46
- package/dist/astryx.umd.js.map +4 -4
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +16 -2
- package/package.json +2 -2
- package/src/Button/Button.tsx +5 -3
- package/src/ButtonGroup/ButtonGroup.test.tsx +7 -4
- package/src/Chat/Chat.doc.mjs +4 -1
- package/src/Chat/ChatMessage.doc.mjs +3 -3
- package/src/Chat/ChatMessage.tsx +7 -0
- package/src/Chat/ChatMessageBubble.doc.mjs +7 -0
- package/src/Chat/ChatMessageBubble.test.tsx +95 -6
- package/src/Chat/ChatMessageBubble.tsx +25 -0
- package/src/HoverCard/HoverCard.doc.mjs +3 -3
- package/src/HoverCard/HoverCard.test.tsx +283 -55
- package/src/HoverCard/HoverCard.tsx +5 -13
- package/src/HoverCard/useHoverCard.tsx +8 -11
- package/src/InputGroup/groupStyles.ts +7 -8
- package/src/Layer/layerHost.test.ts +99 -0
- package/src/Layer/layerHost.ts +141 -0
- package/src/Layer/useLayer.doc.mjs +14 -4
- package/src/Layer/useLayer.test.tsx +318 -7
- package/src/Layer/useLayer.tsx +229 -35
- package/src/Slider/Slider.test.tsx +69 -33
- package/src/Slider/Slider.tsx +56 -13
- package/src/Text/Text.doc.mjs +1 -1
- package/src/Timestamp/Timestamp.test.tsx +40 -22
- package/src/Toolbar/Toolbar.test.tsx +14 -14
- package/src/hooks/index.ts +5 -1
- package/src/hooks/useFocusTrap.test.tsx +16 -0
- package/src/hooks/useFocusTrap.ts +20 -2
- package/src/theme/themingTargets.test.ts +152 -26
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAE,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAuB3C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAIrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAuG9C,QAAA,MAAM,UAAU;;;;;;;;;;EAUd,CAAC;AAkFH;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,UAAU,CAAC;AAEjD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC,oDAAoD;IACpD,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAChD,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACrD;;OAEG;IACH,WAAW,CAAC,EAAE,CACZ,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KACnC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"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"}
|
package/dist/Button/Button.js
CHANGED
|
@@ -253,8 +253,10 @@ const loadingStyles = {
|
|
|
253
253
|
*
|
|
254
254
|
* Layers always carry the native `popover` attribute (useLayer.tsx), and a
|
|
255
255
|
* popover is never an in-flow member — it is `display: none` until shown, then
|
|
256
|
-
* promoted to the top layer.
|
|
257
|
-
*
|
|
256
|
+
* promoted to the top layer. Context layers also retain an inert `<template>`
|
|
257
|
+
* marker so they can re-resolve their JSX position. Neither element is a group
|
|
258
|
+
* member, so "last member" is: no following element sibling besides those two
|
|
259
|
+
* pieces of layer infrastructure.
|
|
258
260
|
*
|
|
259
261
|
* Reading it the other way round — marking the *buttons* and testing for a
|
|
260
262
|
* marked sibling — is the trap: it silently reclassifies anything it doesn't
|
|
@@ -270,13 +272,13 @@ const loadingStyles = {
|
|
|
270
272
|
* The leading edge still uses `:first-child` — a member's button always precedes
|
|
271
273
|
* its own layer, so the first button is genuinely `:first-child`.
|
|
272
274
|
*/
|
|
273
|
-
const IS_LAST_ITEM = ':not(:has(~ *:not([popover])))';
|
|
275
|
+
const IS_LAST_ITEM = ':not(:has(~ *:not([popover]):not(template)))';
|
|
274
276
|
const groupStyles = {
|
|
275
277
|
horizontal: {
|
|
276
278
|
krdFHd: "x15mokao x8eehn2",
|
|
277
279
|
kVL7Gh: "xbiv7yw x1xrp5p4",
|
|
278
|
-
kfmiAY: "x1ga7v0g
|
|
279
|
-
kT0f0o: "x16uus16
|
|
280
|
+
kfmiAY: "x1ga7v0g x1tzxhge",
|
|
281
|
+
kT0f0o: "x16uus16 x1rmb4wm",
|
|
280
282
|
k2ei4v: "xgbv0en x1pjv70x",
|
|
281
283
|
kVhnKS: "x1t7ytsu xyf0ibl",
|
|
282
284
|
kGJrpR: "x1j92z86",
|
|
@@ -285,8 +287,8 @@ const groupStyles = {
|
|
|
285
287
|
vertical: {
|
|
286
288
|
krdFHd: "x15mokao x8eehn2",
|
|
287
289
|
kfmiAY: "x1ga7v0g x2qxyot",
|
|
288
|
-
kVL7Gh: "xbiv7yw
|
|
289
|
-
kT0f0o: "x16uus16
|
|
290
|
+
kVL7Gh: "xbiv7yw xturttb",
|
|
291
|
+
kT0f0o: "x16uus16 x1rmb4wm",
|
|
290
292
|
kEafiO: "x11xkdxz x1g31smg",
|
|
291
293
|
kPef9Z: "x13fuv20 x1d9v4yf",
|
|
292
294
|
kLZC3w: "x1pc3f07",
|
|
@@ -20,6 +20,13 @@ import type { BaseProps } from '../BaseProps';
|
|
|
20
20
|
export interface ChatMessageProps extends BaseProps<HTMLElement> {
|
|
21
21
|
ref?: React.Ref<HTMLElement>;
|
|
22
22
|
sender: ChatMessageSender;
|
|
23
|
+
/**
|
|
24
|
+
* Message body — bubbles, tool calls, images, or any free-form content.
|
|
25
|
+
* Custom (non-bubble) children render flush with the message edge; wrap
|
|
26
|
+
* them in a ghost bubble (`<ChatMessageBubble variant="ghost">`) to align
|
|
27
|
+
* them with the bubble's text column, and add `width="100%"` when they
|
|
28
|
+
* should span the full message column.
|
|
29
|
+
*/
|
|
23
30
|
children: ReactNode;
|
|
24
31
|
avatar?: ReactNode;
|
|
25
32
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAQrD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAoFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA2FlB;yBAxGe,WAAW"}
|
|
1
|
+
{"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAQrD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAoFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA2FlB;yBAxGe,WAAW"}
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
* - If you use bubbles on one side (e.g. assistant), use them consistently
|
|
12
12
|
* for all messages on that side. Use `ghost` variant for content that
|
|
13
13
|
* needs alignment without a visual boundary.
|
|
14
|
+
* - For custom content (cards, attachments, citations) that should span
|
|
15
|
+
* the full message column instead of the default width cap, combine
|
|
16
|
+
* `ghost` with `width="100%"` (#2574).
|
|
14
17
|
* - Put `name` on the first bubble in a message, `metadata` on the last.
|
|
15
18
|
* - For unbubbled messages, use ChatMessage's `name` and `metadata`
|
|
16
19
|
* props instead.
|
|
@@ -21,6 +24,7 @@
|
|
|
21
24
|
* - /packages/cli/assets/templates/blocks/components/ChatMessageBubble/ (block examples)
|
|
22
25
|
*/
|
|
23
26
|
import type { ReactNode } from 'react';
|
|
27
|
+
import type { SizeValue } from '../utils/types';
|
|
24
28
|
import type { BaseProps } from '../BaseProps';
|
|
25
29
|
export type ChatMessageBubbleVariant = 'filled' | 'ghost';
|
|
26
30
|
export interface ChatMessageBubbleProps extends BaseProps<HTMLDivElement> {
|
|
@@ -60,6 +64,14 @@ export interface ChatMessageBubbleProps extends BaseProps<HTMLDivElement> {
|
|
|
60
64
|
* Leave unset for standalone bubbles (full radius).
|
|
61
65
|
*/
|
|
62
66
|
group?: 'first' | 'middle' | 'last';
|
|
67
|
+
/**
|
|
68
|
+
* Width of the bubble.
|
|
69
|
+
* Numbers are treated as pixels, strings are used as-is (e.g. "100%").
|
|
70
|
+
* When set, replaces the default `max(80%, 280px)` width cap; leave unset
|
|
71
|
+
* to keep the cap. Combine with `variant="ghost"` to let custom content
|
|
72
|
+
* (an artifact card, attachments) span the full message column.
|
|
73
|
+
*/
|
|
74
|
+
width?: SizeValue;
|
|
63
75
|
}
|
|
64
76
|
/**
|
|
65
77
|
* Styled content container — the chat "bubble."
|
|
@@ -78,7 +90,7 @@ export interface ChatMessageBubbleProps extends BaseProps<HTMLDivElement> {
|
|
|
78
90
|
* </ChatMessage>
|
|
79
91
|
* ```
|
|
80
92
|
*/
|
|
81
|
-
export declare function ChatMessageBubble({ children, variant, name, metadata, group, xstyle, className, style: styleProp, 'data-testid': testId, ref, ...rest }: ChatMessageBubbleProps): import("react").JSX.Element;
|
|
93
|
+
export declare function ChatMessageBubble({ children, variant, name, metadata, group, width, xstyle, className, style: styleProp, 'data-testid': testId, ref, ...rest }: ChatMessageBubbleProps): import("react").JSX.Element;
|
|
82
94
|
export declare namespace ChatMessageBubble {
|
|
83
95
|
var displayName: string;
|
|
84
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessageBubble.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessageBubble.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"ChatMessageBubble.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessageBubble.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAWrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,sBAAuB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACvE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAEpC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAwHD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,OAAkB,EAClB,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,sBAAsB,+BA0FxB;yBAvGe,iBAAiB"}
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
* - If you use bubbles on one side (e.g. assistant), use them consistently
|
|
16
16
|
* for all messages on that side. Use `ghost` variant for content that
|
|
17
17
|
* needs alignment without a visual boundary.
|
|
18
|
+
* - For custom content (cards, attachments, citations) that should span
|
|
19
|
+
* the full message column instead of the default width cap, combine
|
|
20
|
+
* `ghost` with `width="100%"` (#2574).
|
|
18
21
|
* - Put `name` on the first bubble in a message, `metadata` on the last.
|
|
19
22
|
* - For unbubbled messages, use ChatMessage's `name` and `metadata`
|
|
20
23
|
* props instead.
|
|
@@ -144,6 +147,20 @@ const styles = {
|
|
|
144
147
|
}
|
|
145
148
|
};
|
|
146
149
|
|
|
150
|
+
// Dynamic styles for sizing props
|
|
151
|
+
const _temp = {
|
|
152
|
+
ks0D6T: "x1x1rfll",
|
|
153
|
+
"$$css": true
|
|
154
|
+
};
|
|
155
|
+
const dynamicStyles = {
|
|
156
|
+
sizing: width => [_temp, {
|
|
157
|
+
kzqmXN: width != null ? "x5lhr3w" : width,
|
|
158
|
+
$$css: true
|
|
159
|
+
}, {
|
|
160
|
+
"--x-width": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(width)
|
|
161
|
+
}]
|
|
162
|
+
};
|
|
163
|
+
|
|
147
164
|
// =============================================================================
|
|
148
165
|
// Component
|
|
149
166
|
// =============================================================================
|
|
@@ -171,6 +188,7 @@ export function ChatMessageBubble({
|
|
|
171
188
|
name,
|
|
172
189
|
metadata,
|
|
173
190
|
group,
|
|
191
|
+
width,
|
|
174
192
|
xstyle,
|
|
175
193
|
className,
|
|
176
194
|
style: styleProp,
|
|
@@ -199,7 +217,7 @@ export function ChatMessageBubble({
|
|
|
199
217
|
sender,
|
|
200
218
|
variant,
|
|
201
219
|
density
|
|
202
|
-
}), stylex.props(styles.content, density === 'compact' && styles.radiusCompact, senderStyle, paddingStyle, variant === 'ghost' && styles.paddingBlockNone, groupStyle, xstyle), className, styleProp),
|
|
220
|
+
}), stylex.props(styles.content, density === 'compact' && styles.radiusCompact, senderStyle, paddingStyle, variant === 'ghost' && styles.paddingBlockNone, groupStyle, width != null && dynamicStyles.sizing(width), xstyle), className, styleProp),
|
|
203
221
|
children: children
|
|
204
222
|
}), metadata && /*#__PURE__*/_jsx("div", {
|
|
205
223
|
...stylex.props(metadataPaddingStyle, styles.metadataReducedGap, isUser && styles.alignEnd),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @file HoverCard.tsx
|
|
3
3
|
* @input Uses React, useHoverCard hook
|
|
4
4
|
* @output Exports HoverCard component for hover/focus triggered layers
|
|
5
|
-
* @position Layer component;
|
|
5
|
+
* @position Layer component; inline-safe trigger wrapper, floating layer hosted by useLayer
|
|
6
6
|
*
|
|
7
7
|
* SYNC: When modified, update these files to stay in sync:
|
|
8
8
|
* - /packages/core/src/HoverCard/HoverCard.test.tsx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCard.d.ts","sourceRoot":"","sources":["../../src/HoverCard/HoverCard.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAG7E,OAAO,EAAe,KAAK,qBAAqB,EAAC,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,YAAY,EAAC,qBAAqB,EAAC,MAAM,gBAAgB,CAAC;AAiB1D,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,SAAS,EACT,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,SAAS,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IAErC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAEtC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAiBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,OAAO,EACP,SAAmB,EACnB,SAAoB,EACpB,KAAW,EACX,SAAe,EACf,YAAqB,EACrB,SAAgB,EAChB,KAAK,EACL,YAAY,EACZ,kBAA2B,EAC3B,MAAM,EACN,aAAa,EACb,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,cAAc,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"HoverCard.d.ts","sourceRoot":"","sources":["../../src/HoverCard/HoverCard.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAG7E,OAAO,EAAe,KAAK,qBAAqB,EAAC,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,YAAY,EAAC,qBAAqB,EAAC,MAAM,gBAAgB,CAAC;AAiB1D,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,SAAS,EACT,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,SAAS,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IAErC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAEtC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAiBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,OAAO,EACP,SAAmB,EACnB,SAAoB,EACpB,KAAW,EACX,SAAe,EACf,YAAqB,EACrB,SAAgB,EAChB,KAAK,EACL,YAAY,EACZ,kBAA2B,EAC3B,MAAM,EACN,aAAa,EACb,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,cAAc,GAAG,YAAY,CAyG/B;yBA1He,SAAS"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @file HoverCard.tsx
|
|
7
7
|
* @input Uses React, useHoverCard hook
|
|
8
8
|
* @output Exports HoverCard component for hover/focus triggered layers
|
|
9
|
-
* @position Layer component;
|
|
9
|
+
* @position Layer component; inline-safe trigger wrapper, floating layer hosted by useLayer
|
|
10
10
|
*
|
|
11
11
|
* SYNC: When modified, update these files to stay in sync:
|
|
12
12
|
* - /packages/core/src/HoverCard/HoverCard.test.tsx
|
|
@@ -127,18 +127,10 @@ export function HoverCard({
|
|
|
127
127
|
};
|
|
128
128
|
}, [textOnly, hoverCard.ref, hoverCard.describedBy]);
|
|
129
129
|
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
// anchor positioning resolves the trigger reference regardless of where the
|
|
135
|
-
// element sits in the DOM, so no portal is needed to "escape" layout.
|
|
136
|
-
//
|
|
137
|
-
// The layer renders as inline-safe phrasing markup (a `<span>`, see
|
|
138
|
-
// useHoverCard), which stays put inside a `<p>` instead of being reparented
|
|
139
|
-
// by the HTML parser. That keeps the server markup and the first client
|
|
140
|
-
// render identical, so there is no hydration mismatch — and it preserves the
|
|
141
|
-
// inline-safety guarantee (no block elements injected into a paragraph).
|
|
130
|
+
// While closed, useLayer leaves only an inert <template> marker at this JSX
|
|
131
|
+
// position. When the card needs to open, it uses that marker to keep the
|
|
132
|
+
// final layer inline when the parent is safe or portal it outside a <p>,
|
|
133
|
+
// link, or other ancestor that cannot contain it safely.
|
|
142
134
|
const renderedHoverCard = hoverCard.renderHoverCard(content, {
|
|
143
135
|
xstyle,
|
|
144
136
|
className,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHoverCard.d.ts","sourceRoot":"","sources":["../../src/HoverCard/useHoverCard.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"useHoverCard.d.ts","sourceRoot":"","sources":["../../src/HoverCard/useHoverCard.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AA4B3B;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IAErC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,GAAG,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAE9B;;;OAGG;IACH,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEtC;;;;OAIG;IACH,cAAc,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEzC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,eAAe,EAAE,CACf,QAAQ,EAAE,SAAS,EACnB,KAAK,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,KAC5C,SAAS,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE,MAAM,IAAI,CAAC;IAEjB;;OAEG;IACH,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAyBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAkT5E"}
|
|
@@ -88,6 +88,7 @@ export function useHoverCard(options = {}) {
|
|
|
88
88
|
} = options;
|
|
89
89
|
const layer = useLayer({
|
|
90
90
|
mode: 'context',
|
|
91
|
+
lazyMount: true,
|
|
91
92
|
onShow,
|
|
92
93
|
onHide
|
|
93
94
|
});
|
|
@@ -254,15 +255,15 @@ export function useHoverCard(options = {}) {
|
|
|
254
255
|
// Consumer surface style props land on the layer container — the
|
|
255
256
|
// themed surface (bg/radius/shadow) where the theme class lives — so
|
|
256
257
|
// customizing the card targets the same element as the theme. The inner
|
|
257
|
-
//
|
|
258
|
+
// div keeps `styles.content` for padding.
|
|
258
259
|
xstyle: [popoverXstyle, layerAnimations[renderPlacement], props?.xstyle],
|
|
259
260
|
className: props?.className ? `${themeClassName} ${props.className}` : themeClassName,
|
|
260
261
|
style: props?.style,
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
as: '
|
|
262
|
+
// useLayer mounts only after it has verified or corrected the parent,
|
|
263
|
+
// so rich HoverCard content can use block-safe markup.
|
|
264
|
+
as: 'div'
|
|
264
265
|
};
|
|
265
|
-
return layer.render(/*#__PURE__*/_jsx("
|
|
266
|
+
return layer.render(/*#__PURE__*/_jsx("div", {
|
|
266
267
|
...{
|
|
267
268
|
className: "x1lliihq x1vlblms xvmdzux x126nfab x1t818jl"
|
|
268
269
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupStyles.d.ts","sourceRoot":"","sources":["../../src/InputGroup/groupStyles.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"groupStyles.d.ts","sourceRoot":"","sources":["../../src/InputGroup/groupStyles.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAQ3C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;EA6BtB,CAAC"}
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
import * as stylex from '@stylexjs/stylex';
|
|
11
11
|
import "../theme/tokens.stylex.js";
|
|
12
12
|
import { radiusVars, borderVars } from "../theme/tokens.stylex.js";
|
|
13
|
+
|
|
14
|
+
// A grouped control may be followed by context-layer infrastructure rather
|
|
15
|
+
// than another control. Neither the inert marker nor the popover is a visual
|
|
16
|
+
// group member, so skip both when finding the trailing edge.
|
|
17
|
+
const IS_LAST_ITEM = ':not(:has(~ *:not([popover]):not(template)))';
|
|
13
18
|
export const groupStyles = {
|
|
14
19
|
inGroup: {
|
|
15
20
|
kUk6DE: "x98rzlu",
|
|
@@ -18,8 +23,8 @@ export const groupStyles = {
|
|
|
18
23
|
keTefX: "xd10s4z x1pwwqoy",
|
|
19
24
|
krdFHd: "x15mokao x8eehn2",
|
|
20
25
|
kVL7Gh: "xbiv7yw x1xrp5p4",
|
|
21
|
-
kfmiAY: "x1ga7v0g
|
|
22
|
-
kT0f0o: "x16uus16
|
|
26
|
+
kfmiAY: "x1ga7v0g x1tzxhge",
|
|
27
|
+
kT0f0o: "x16uus16 x1rmb4wm",
|
|
23
28
|
kXnDq0: "x1rm9qnc",
|
|
24
29
|
$$css: true
|
|
25
30
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return the corrective portal target for a layer's intended inline parent.
|
|
3
|
+
*
|
|
4
|
+
* A null result means the inline parent and all of its ancestors are safe, so
|
|
5
|
+
* the layer should stay at its JSX position. Otherwise the result is the
|
|
6
|
+
* nearest element outside every unsafe ancestor around that position.
|
|
7
|
+
*
|
|
8
|
+
* Walking up from the actual render position (rather than the trigger, or
|
|
9
|
+
* portaling to `document.body`) keeps the two things a layer inherits there:
|
|
10
|
+
*
|
|
11
|
+
* - **Theme.** Theme scopes live on DOM ancestors. Staying as close as
|
|
12
|
+
* possible to the intended render position preserves their component rules
|
|
13
|
+
* and custom properties; `document.body` may sit outside a nested scope.
|
|
14
|
+
* - **Tab order.** Sequential focus follows DOM order, so a host near the
|
|
15
|
+
* trigger keeps the layer's focusables next to it. (`show()` also passes
|
|
16
|
+
* the trigger as the popover's invoker `source`, which pins focus order to
|
|
17
|
+
* the invoker in browsers that support it.)
|
|
18
|
+
*
|
|
19
|
+
* The outermost unsafe ancestor matters. A safe div may itself sit inside an
|
|
20
|
+
* anchor; stopping at that div would still put the layer's buttons inside the
|
|
21
|
+
* link. Walking the whole chain ensures the target is outside both.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveLayerPortalTarget(inlineParent: HTMLElement | null): HTMLElement | null;
|
|
24
|
+
//# sourceMappingURL=layerHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layerHost.d.ts","sourceRoot":"","sources":["../../src/Layer/layerHost.ts"],"names":[],"mappings":"AAqGA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,WAAW,GAAG,IAAI,GAC/B,WAAW,GAAG,IAAI,CAepB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file layerHost.ts
|
|
5
|
+
* @input Uses the layer's intended inline parent element
|
|
6
|
+
* @output Exports resolveLayerPortalTarget, the corrective portal target
|
|
7
|
+
* @position Layer utility; used by useLayer to place the popover in the DOM
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When modified, update:
|
|
10
|
+
* - /packages/core/src/Layer/layerHost.test.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Ancestors a layer must not be hosted inside.
|
|
15
|
+
*
|
|
16
|
+
* Two overlapping reasons, both verified in Chrome:
|
|
17
|
+
*
|
|
18
|
+
* 1. The HTML parser owns server markup. `<p>` and the heading-ish elements
|
|
19
|
+
* take phrasing content only, so a block element inside one makes the
|
|
20
|
+
* parser close the paragraph and reparent the rest — the layer's content
|
|
21
|
+
* ends up in the page instead of the popover. A nested `<a>` triggers the
|
|
22
|
+
* same tearing through the adoption agency algorithm.
|
|
23
|
+
* 2. Interactive ancestors capture the layer's own interactions. A card
|
|
24
|
+
* hosted inside an `<a>` or `<button>` puts its links and buttons inside
|
|
25
|
+
* that control: clicking one navigates the wrapping link, and every
|
|
26
|
+
* focusable in the card joins the control's own tab stop.
|
|
27
|
+
*
|
|
28
|
+
* Inline formatting elements are on the list for a third, milder reason: a
|
|
29
|
+
* layer hosted in one inherits its typography (font-size, text-align), so a
|
|
30
|
+
* card in a 13px centered paragraph renders 13px and centered.
|
|
31
|
+
*/
|
|
32
|
+
const UNSAFE_HOSTS = new Set([
|
|
33
|
+
// Phrasing-content-only containers
|
|
34
|
+
'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dt', 'pre', 'legend', 'data', 'dfn', 'meter', 'output', 'progress', 'option', 'optgroup',
|
|
35
|
+
// Structural containers whose direct children are restricted. An inert
|
|
36
|
+
// <template> marker is valid script-supporting content in these positions,
|
|
37
|
+
// but the eventual div/span layer is not.
|
|
38
|
+
'table', 'thead', 'tbody', 'tfoot', 'tr', 'colgroup', 'ul', 'ol', 'menu', 'dl', 'select', 'datalist', 'picture', 'hgroup', 'ruby', 'rt', 'rp',
|
|
39
|
+
// Interactive containers
|
|
40
|
+
'a', 'button', 'label', 'summary',
|
|
41
|
+
// Inline formatting context
|
|
42
|
+
'span', 'em', 'strong', 'b', 'i', 'u', 's', 'small', 'mark', 'code', 'kbd', 'samp', 'var', 'sub', 'sup', 'abbr', 'cite', 'q', 'time', 'bdi', 'bdo', 'ins', 'del']);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Return the corrective portal target for a layer's intended inline parent.
|
|
46
|
+
*
|
|
47
|
+
* A null result means the inline parent and all of its ancestors are safe, so
|
|
48
|
+
* the layer should stay at its JSX position. Otherwise the result is the
|
|
49
|
+
* nearest element outside every unsafe ancestor around that position.
|
|
50
|
+
*
|
|
51
|
+
* Walking up from the actual render position (rather than the trigger, or
|
|
52
|
+
* portaling to `document.body`) keeps the two things a layer inherits there:
|
|
53
|
+
*
|
|
54
|
+
* - **Theme.** Theme scopes live on DOM ancestors. Staying as close as
|
|
55
|
+
* possible to the intended render position preserves their component rules
|
|
56
|
+
* and custom properties; `document.body` may sit outside a nested scope.
|
|
57
|
+
* - **Tab order.** Sequential focus follows DOM order, so a host near the
|
|
58
|
+
* trigger keeps the layer's focusables next to it. (`show()` also passes
|
|
59
|
+
* the trigger as the popover's invoker `source`, which pins focus order to
|
|
60
|
+
* the invoker in browsers that support it.)
|
|
61
|
+
*
|
|
62
|
+
* The outermost unsafe ancestor matters. A safe div may itself sit inside an
|
|
63
|
+
* anchor; stopping at that div would still put the layer's buttons inside the
|
|
64
|
+
* link. Walking the whole chain ensures the target is outside both.
|
|
65
|
+
*/
|
|
66
|
+
export function resolveLayerPortalTarget(inlineParent) {
|
|
67
|
+
if (!inlineParent) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
let outermostUnsafe = null;
|
|
71
|
+
let node = inlineParent;
|
|
72
|
+
while (node) {
|
|
73
|
+
if (UNSAFE_HOSTS.has(node.tagName.toLowerCase())) {
|
|
74
|
+
outermostUnsafe = node;
|
|
75
|
+
}
|
|
76
|
+
node = node.parentElement;
|
|
77
|
+
}
|
|
78
|
+
return outermostUnsafe?.parentElement ?? null;
|
|
79
|
+
}
|
package/dist/Layer/useLayer.d.ts
CHANGED
|
@@ -94,12 +94,11 @@ export interface ContextRenderProps {
|
|
|
94
94
|
/**
|
|
95
95
|
* HTML tag to render the popover container as.
|
|
96
96
|
*
|
|
97
|
-
* Defaults to `'div'`.
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* the same on either tag.
|
|
97
|
+
* Defaults to `'div'`. Context layers render an inert `<template>` marker at
|
|
98
|
+
* the JSX position. The marker's parent is checked before the requested
|
|
99
|
+
* container mounts there or portals outside ancestors that cannot safely
|
|
100
|
+
* contain it. The marker remains available to detect a new parent if the
|
|
101
|
+
* render call moves. With `lazyMount`, the first check waits until `show()`.
|
|
103
102
|
*
|
|
104
103
|
* @default 'div'
|
|
105
104
|
*/
|
|
@@ -162,6 +161,15 @@ interface BaseLayerOptions {
|
|
|
162
161
|
*/
|
|
163
162
|
export interface ContextLayerOptions extends BaseLayerOptions {
|
|
164
163
|
mode: 'context';
|
|
164
|
+
/**
|
|
165
|
+
* Defer mounting the final layer and resolving its inline/portal position
|
|
166
|
+
* until `show()` is requested. Hiding unmounts it while the inert marker
|
|
167
|
+
* remains at the JSX position. Use this when rich content must never enter
|
|
168
|
+
* an unsafe ancestor, even briefly, and does not need to exist while closed.
|
|
169
|
+
*
|
|
170
|
+
* @default false
|
|
171
|
+
*/
|
|
172
|
+
lazyMount?: boolean;
|
|
165
173
|
}
|
|
166
174
|
/**
|
|
167
175
|
* Options for fixed mode (manual positioning)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"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"}
|