@vitus-labs/elements 2.6.2 → 2.7.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/lib/index.d.ts +8 -9
- package/lib/index.js +234 -171
- package/lib/vitus-labs-elements.native.js +42 -58
- package/package.json +13 -12
package/lib/index.d.ts
CHANGED
|
@@ -9,8 +9,7 @@ type SpreadTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & R>;
|
|
|
9
9
|
type Spread<A extends readonly [...any]> = A extends [infer L, ...infer R] ? SpreadTwo<L, Spread<R>> : unknown;
|
|
10
10
|
type MergeTypes<A extends readonly [...any]> = ExtractNullableKeys<Spread<A>>;
|
|
11
11
|
type InnerRef = ForwardedRef<any>;
|
|
12
|
-
type
|
|
13
|
-
type Css = CssCallback | ReturnType<typeof config.css> | string;
|
|
12
|
+
type Css = ((css: typeof config.css) => ReturnType<typeof css>) | ReturnType<typeof config.css> | string;
|
|
14
13
|
type Content = Parameters<typeof render>['0'];
|
|
15
14
|
type ContentAlignX = 'left' | 'center' | 'right' | 'spaceBetween' | 'spaceAround' | 'block';
|
|
16
15
|
type ContentAlignY = 'top' | 'center' | 'bottom' | 'spaceBetween' | 'spaceAround' | 'block';
|
|
@@ -296,7 +295,7 @@ type VLElement<P extends Record<string, unknown> = {}> = ((props: Props & P & {
|
|
|
296
295
|
}) => ReactElement | null) & VLStatic;
|
|
297
296
|
//#endregion
|
|
298
297
|
//#region src/Element/component.d.ts
|
|
299
|
-
declare const
|
|
298
|
+
declare const MemoComponent: VLElement;
|
|
300
299
|
//#endregion
|
|
301
300
|
//#region src/helpers/Iterator/types.d.ts
|
|
302
301
|
type MaybeNull = undefined | null;
|
|
@@ -447,7 +446,7 @@ interface Context {
|
|
|
447
446
|
setBlocked: () => void;
|
|
448
447
|
setUnblocked: () => void;
|
|
449
448
|
}
|
|
450
|
-
declare const Component$
|
|
449
|
+
declare const Component$1: FC<Context & {
|
|
451
450
|
children: ReactNode;
|
|
452
451
|
}>;
|
|
453
452
|
//#endregion
|
|
@@ -634,7 +633,7 @@ type Props$3 = {
|
|
|
634
633
|
*/
|
|
635
634
|
contentRefName?: string;
|
|
636
635
|
} & UseOverlayProps;
|
|
637
|
-
declare const Component
|
|
636
|
+
declare const Component: VLComponent<Props$3>;
|
|
638
637
|
//#endregion
|
|
639
638
|
//#region src/Portal/component.d.ts
|
|
640
639
|
interface Props$4 {
|
|
@@ -652,7 +651,7 @@ interface Props$4 {
|
|
|
652
651
|
*/
|
|
653
652
|
tag?: string;
|
|
654
653
|
}
|
|
655
|
-
declare const Component$
|
|
654
|
+
declare const Component$2: VLComponent<Props$4>;
|
|
656
655
|
//#endregion
|
|
657
656
|
//#region src/Text/component.d.ts
|
|
658
657
|
type Props$5 = Partial<{
|
|
@@ -677,7 +676,7 @@ type Props$5 = Partial<{
|
|
|
677
676
|
*/
|
|
678
677
|
css: ExtendCss;
|
|
679
678
|
}>;
|
|
680
|
-
declare const Component$
|
|
679
|
+
declare const Component$3: VLComponent<Props$5> & {
|
|
681
680
|
isText?: true;
|
|
682
681
|
};
|
|
683
682
|
//#endregion
|
|
@@ -696,7 +695,7 @@ interface Props$6 {
|
|
|
696
695
|
*/
|
|
697
696
|
style?: Record<string, unknown>;
|
|
698
697
|
}
|
|
699
|
-
declare const Component$
|
|
698
|
+
declare const Component$4: VLComponent<Props$6>;
|
|
700
699
|
//#endregion
|
|
701
|
-
export { type AlignX, type AlignY, type Content, type ContentBoolean, type Direction,
|
|
700
|
+
export { type AlignX, type AlignY, type Content, type ContentBoolean, type Direction, MemoComponent as Element, type Props as ElementProps, type ElementType, type ExtendCss, type ExtendedProps, type InnerRef, type Props$1 as IteratorProps, _default as List, type Props$2 as ListProps, type ObjectValue, Component as Overlay, type Props$3 as OverlayProps, Component$1 as OverlayProvider, Component$2 as Portal, type Props$4 as PortalProps, type PropsCallback, Provider, type Responsive, type ResponsiveBoolType, Component$3 as Text, type Props$5 as TextProps, type UseOverlayProps, Component$4 as Util, type Props$6 as UtilProps, type VLStatic, useOverlay };
|
|
702
701
|
//# sourceMappingURL=index2.d.ts.map
|
package/lib/index.js
CHANGED
|
@@ -22,10 +22,7 @@ const IS_DEVELOPMENT = process.env.NODE_ENV !== "production";
|
|
|
22
22
|
* fill remaining space between before and after.
|
|
23
23
|
*/
|
|
24
24
|
const { styled: styled$2, css: css$2, component: component$1 } = config;
|
|
25
|
-
const
|
|
26
|
-
flex: 1;
|
|
27
|
-
`;
|
|
28
|
-
const typeContentCSS = `
|
|
25
|
+
const FLEX_1 = `
|
|
29
26
|
flex: 1;
|
|
30
27
|
`;
|
|
31
28
|
const gapDimensions = {
|
|
@@ -57,7 +54,7 @@ const styles$2 = ({ css, theme: t, rootSize }) => css`
|
|
|
57
54
|
alignY: t.alignY
|
|
58
55
|
})};
|
|
59
56
|
|
|
60
|
-
${t.equalCols &&
|
|
57
|
+
${t.equalCols && FLEX_1};
|
|
61
58
|
|
|
62
59
|
${t.gap && t.contentType && calculateGap({
|
|
63
60
|
direction: t.parentDirection,
|
|
@@ -74,7 +71,7 @@ const StyledComponent = styled$2(component$1)`
|
|
|
74
71
|
align-self: stretch;
|
|
75
72
|
flex-wrap: wrap;
|
|
76
73
|
|
|
77
|
-
${({ $contentType }) => $contentType === "content" &&
|
|
74
|
+
${({ $contentType }) => $contentType === "content" && FLEX_1};
|
|
78
75
|
|
|
79
76
|
${makeItResponsive({
|
|
80
77
|
key: "$element",
|
|
@@ -125,11 +122,11 @@ const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, ali
|
|
|
125
122
|
children: render(children)
|
|
126
123
|
});
|
|
127
124
|
};
|
|
128
|
-
var component_default = memo(Component$9);
|
|
125
|
+
var component_default$1 = memo(Component$9);
|
|
129
126
|
|
|
130
127
|
//#endregion
|
|
131
128
|
//#region src/helpers/Content/index.ts
|
|
132
|
-
var Content_default = component_default;
|
|
129
|
+
var Content_default = component_default$1;
|
|
133
130
|
|
|
134
131
|
//#endregion
|
|
135
132
|
//#region src/helpers/Wrapper/styled.ts
|
|
@@ -216,23 +213,34 @@ const isWebFixNeeded = (tag) => {
|
|
|
216
213
|
* (parent + child Styled) because these HTML elements do not natively
|
|
217
214
|
* support `display: flex` consistently across browsers.
|
|
218
215
|
*/
|
|
219
|
-
const DEV_PROPS = IS_DEVELOPMENT ? { "data-vl-element": "Element" } :
|
|
216
|
+
const DEV_PROPS = IS_DEVELOPMENT ? { "data-vl-element": "Element" } : null;
|
|
220
217
|
const Component$8 = ({ children, ref, tag, block, extendCss, direction, alignX, alignY, equalCols, isInline, ...props }) => {
|
|
221
|
-
const COMMON_PROPS = {
|
|
222
|
-
...props,
|
|
223
|
-
...DEV_PROPS,
|
|
224
|
-
ref,
|
|
225
|
-
as: tag
|
|
226
|
-
};
|
|
227
218
|
const needsFix = !props.dangerouslySetInnerHTML && isWebFixNeeded(tag);
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
219
|
+
const $element = useMemo(() => {
|
|
220
|
+
if (!needsFix) return {
|
|
221
|
+
block,
|
|
222
|
+
direction,
|
|
223
|
+
alignX,
|
|
224
|
+
alignY,
|
|
225
|
+
equalCols,
|
|
226
|
+
extraStyles: extendCss
|
|
227
|
+
};
|
|
228
|
+
return {
|
|
229
|
+
parent: {
|
|
230
|
+
parentFix: true,
|
|
231
|
+
block,
|
|
232
|
+
extraStyles: extendCss
|
|
233
|
+
},
|
|
234
|
+
child: {
|
|
235
|
+
childFix: true,
|
|
236
|
+
direction,
|
|
237
|
+
alignX,
|
|
238
|
+
alignY,
|
|
239
|
+
equalCols
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}, [
|
|
243
|
+
needsFix,
|
|
236
244
|
block,
|
|
237
245
|
direction,
|
|
238
246
|
alignX,
|
|
@@ -240,44 +248,35 @@ const Component$8 = ({ children, ref, tag, block, extendCss, direction, alignX,
|
|
|
240
248
|
equalCols,
|
|
241
249
|
extendCss
|
|
242
250
|
]);
|
|
243
|
-
const parentFixElement = useMemo(() => ({
|
|
244
|
-
parentFix: true,
|
|
245
|
-
block,
|
|
246
|
-
extraStyles: extendCss
|
|
247
|
-
}), [block, extendCss]);
|
|
248
|
-
const childFixElement = useMemo(() => ({
|
|
249
|
-
childFix: true,
|
|
250
|
-
direction,
|
|
251
|
-
alignX,
|
|
252
|
-
alignY,
|
|
253
|
-
equalCols
|
|
254
|
-
}), [
|
|
255
|
-
direction,
|
|
256
|
-
alignX,
|
|
257
|
-
alignY,
|
|
258
|
-
equalCols
|
|
259
|
-
]);
|
|
260
251
|
if (!needsFix || false) return /* @__PURE__ */ jsx(styled_default$1, {
|
|
261
|
-
...
|
|
262
|
-
|
|
252
|
+
...props,
|
|
253
|
+
...DEV_PROPS,
|
|
254
|
+
ref,
|
|
255
|
+
as: tag,
|
|
256
|
+
$element,
|
|
263
257
|
children
|
|
264
258
|
});
|
|
265
259
|
const asTag = isInline ? "span" : "div";
|
|
260
|
+
const fix = $element;
|
|
266
261
|
return /* @__PURE__ */ jsx(styled_default$1, {
|
|
267
|
-
...
|
|
268
|
-
|
|
262
|
+
...props,
|
|
263
|
+
...DEV_PROPS,
|
|
264
|
+
ref,
|
|
265
|
+
as: tag,
|
|
266
|
+
$element: fix.parent,
|
|
269
267
|
children: /* @__PURE__ */ jsx(styled_default$1, {
|
|
270
268
|
as: asTag,
|
|
271
269
|
$childFix: true,
|
|
272
|
-
$element:
|
|
270
|
+
$element: fix.child,
|
|
273
271
|
children
|
|
274
272
|
})
|
|
275
273
|
});
|
|
276
274
|
};
|
|
275
|
+
var component_default = memo(Component$8);
|
|
277
276
|
|
|
278
277
|
//#endregion
|
|
279
278
|
//#region src/helpers/Wrapper/index.ts
|
|
280
|
-
var Wrapper_default =
|
|
279
|
+
var Wrapper_default = component_default;
|
|
281
280
|
|
|
282
281
|
//#endregion
|
|
283
282
|
//#region src/Element/constants.ts
|
|
@@ -333,7 +332,6 @@ const EMPTY_ELEMENTS = {
|
|
|
333
332
|
hr: true,
|
|
334
333
|
img: true,
|
|
335
334
|
input: true,
|
|
336
|
-
keygen: true,
|
|
337
335
|
link: true,
|
|
338
336
|
textarea: true,
|
|
339
337
|
source: true,
|
|
@@ -367,22 +365,22 @@ const getShouldBeEmpty = (tag) => {
|
|
|
367
365
|
const equalize = (el, direction) => {
|
|
368
366
|
const beforeEl = el.firstElementChild;
|
|
369
367
|
const afterEl = el.lastElementChild;
|
|
370
|
-
if (beforeEl
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}
|
|
368
|
+
if (!beforeEl || !afterEl || beforeEl === afterEl) return;
|
|
369
|
+
const type = direction === "rows" ? "height" : "width";
|
|
370
|
+
const prop = type === "height" ? "offsetHeight" : "offsetWidth";
|
|
371
|
+
const beforeSize = beforeEl[prop];
|
|
372
|
+
const afterSize = afterEl[prop];
|
|
373
|
+
if (!Number.isInteger(beforeSize) || !Number.isInteger(afterSize)) return;
|
|
374
|
+
if (beforeSize === afterSize && beforeSize > 0) return;
|
|
375
|
+
const maxSize = `${Math.max(beforeSize, afterSize)}px`;
|
|
376
|
+
beforeEl.style[type] = maxSize;
|
|
377
|
+
afterEl.style[type] = maxSize;
|
|
381
378
|
};
|
|
382
379
|
const defaultDirection = "inline";
|
|
383
380
|
const defaultContentDirection = "rows";
|
|
384
381
|
const defaultAlignX = "left";
|
|
385
382
|
const defaultAlignY = "center";
|
|
383
|
+
const AS_RESET = { as: void 0 };
|
|
386
384
|
const Component$7 = ({ innerRef, ref, tag, label, content, children, beforeContent, afterContent, equalBeforeAfter, block, equalCols, gap, direction, alignX = defaultAlignX, alignY = defaultAlignY, css, contentCss, beforeContentCss, afterContentCss, contentDirection = defaultContentDirection, contentAlignX = defaultAlignX, contentAlignY = defaultAlignY, beforeContentDirection = defaultDirection, beforeContentAlignX = defaultAlignX, beforeContentAlignY = defaultAlignY, afterContentDirection = defaultDirection, afterContentAlignX = defaultAlignX, afterContentAlignY = defaultAlignY, ...props }) => {
|
|
387
385
|
const shouldBeEmpty = !!props.dangerouslySetInnerHTML || getShouldBeEmpty(tag);
|
|
388
386
|
const isSimpleElement = !beforeContent && !afterContent;
|
|
@@ -415,11 +413,14 @@ const Component$7 = ({ innerRef, ref, tag, label, content, children, beforeConte
|
|
|
415
413
|
]);
|
|
416
414
|
const equalizeRef = useRef(null);
|
|
417
415
|
const externalRef = ref ?? innerRef;
|
|
416
|
+
const latestExternalRef = useRef(externalRef);
|
|
417
|
+
latestExternalRef.current = externalRef;
|
|
418
418
|
const mergedRef = useCallback((node) => {
|
|
419
419
|
equalizeRef.current = node;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
420
|
+
const r = latestExternalRef.current;
|
|
421
|
+
if (typeof r === "function") r(node);
|
|
422
|
+
else if (r != null) r.current = node;
|
|
423
|
+
}, []);
|
|
423
424
|
useLayoutEffect(() => {
|
|
424
425
|
if (!equalBeforeAfter || !beforeContent || !afterContent) return;
|
|
425
426
|
const node = equalizeRef.current;
|
|
@@ -435,7 +436,8 @@ const Component$7 = ({ innerRef, ref, tag, label, content, children, beforeConte
|
|
|
435
436
|
afterContent,
|
|
436
437
|
direction
|
|
437
438
|
]);
|
|
438
|
-
|
|
439
|
+
if (shouldBeEmpty) return /* @__PURE__ */ jsx(Wrapper_default, {
|
|
440
|
+
...props,
|
|
439
441
|
ref: mergedRef,
|
|
440
442
|
extendCss: css,
|
|
441
443
|
tag,
|
|
@@ -443,16 +445,19 @@ const Component$7 = ({ innerRef, ref, tag, label, content, children, beforeConte
|
|
|
443
445
|
direction: wrapperDirection,
|
|
444
446
|
alignX: wrapperAlignX,
|
|
445
447
|
alignY: wrapperAlignY,
|
|
446
|
-
|
|
447
|
-
};
|
|
448
|
-
if (shouldBeEmpty) return /* @__PURE__ */ jsx(Wrapper_default, {
|
|
449
|
-
...props,
|
|
450
|
-
...WRAPPER_PROPS
|
|
448
|
+
...AS_RESET
|
|
451
449
|
});
|
|
452
450
|
return /* @__PURE__ */ jsxs(Wrapper_default, {
|
|
453
451
|
...props,
|
|
454
|
-
|
|
452
|
+
ref: mergedRef,
|
|
453
|
+
extendCss: css,
|
|
454
|
+
tag,
|
|
455
|
+
block,
|
|
456
|
+
direction: wrapperDirection,
|
|
457
|
+
alignX: wrapperAlignX,
|
|
458
|
+
alignY: wrapperAlignY,
|
|
455
459
|
isInline,
|
|
460
|
+
...AS_RESET,
|
|
456
461
|
children: [
|
|
457
462
|
beforeContent && /* @__PURE__ */ jsx(Content_default, {
|
|
458
463
|
tag: SUB_TAG,
|
|
@@ -493,13 +498,14 @@ const Component$7 = ({ innerRef, ref, tag, label, content, children, beforeConte
|
|
|
493
498
|
});
|
|
494
499
|
};
|
|
495
500
|
const name$5 = `${PKG_NAME}/Element`;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
501
|
+
const MemoComponent = memo(Component$7);
|
|
502
|
+
MemoComponent.displayName = name$5;
|
|
503
|
+
MemoComponent.pkgName = PKG_NAME;
|
|
504
|
+
MemoComponent.VITUS_LABS__COMPONENT = name$5;
|
|
499
505
|
|
|
500
506
|
//#endregion
|
|
501
507
|
//#region src/Element/index.ts
|
|
502
|
-
var Element_default =
|
|
508
|
+
var Element_default = MemoComponent;
|
|
503
509
|
|
|
504
510
|
//#endregion
|
|
505
511
|
//#region src/helpers/Iterator/component.tsx
|
|
@@ -662,12 +668,13 @@ var Iterator_default = Iterator;
|
|
|
662
668
|
* is wrapped in an Element that receives all non-iterator props (e.g.,
|
|
663
669
|
* layout, alignment, css), allowing the list to be styled as a single block.
|
|
664
670
|
*/
|
|
671
|
+
const RESERVED_PROPS_SET = new Set(Iterator_default.RESERVED_PROPS);
|
|
665
672
|
const Component$5 = ({ rootElement = false, ref, ...props }) => {
|
|
666
673
|
const renderedList = /* @__PURE__ */ jsx(Iterator_default, { ...pick(props, Iterator_default.RESERVED_PROPS) });
|
|
667
674
|
if (!rootElement) return renderedList;
|
|
668
675
|
return /* @__PURE__ */ jsx(Element_default, {
|
|
669
676
|
ref,
|
|
670
|
-
...omit(props,
|
|
677
|
+
...omit(props, RESERVED_PROPS_SET),
|
|
671
678
|
children: renderedList
|
|
672
679
|
});
|
|
673
680
|
};
|
|
@@ -746,6 +753,11 @@ const Component = ({ children, blocked, setBlocked, setUnblocked }) => {
|
|
|
746
753
|
* the final viewport-relative position and the alignment that was actually used
|
|
747
754
|
* (which may differ from the requested alignment when an edge would be clipped).
|
|
748
755
|
*/
|
|
756
|
+
const DROPDOWN_TYPES = new Set([
|
|
757
|
+
"dropdown",
|
|
758
|
+
"tooltip",
|
|
759
|
+
"popover"
|
|
760
|
+
]);
|
|
749
761
|
const sel = (cond, a, b) => cond ? a : b;
|
|
750
762
|
const devWarn = (msg) => {
|
|
751
763
|
if (!IS_DEVELOPMENT) return;
|
|
@@ -871,11 +883,7 @@ const adjustForAncestor = (pos, ancestor) => {
|
|
|
871
883
|
return result;
|
|
872
884
|
};
|
|
873
885
|
const computePosition = (type, align, alignX, alignY, offsetX, offsetY, triggerEl, contentEl, ancestorOffset) => {
|
|
874
|
-
const isDropdown =
|
|
875
|
-
"dropdown",
|
|
876
|
-
"tooltip",
|
|
877
|
-
"popover"
|
|
878
|
-
].includes(type);
|
|
886
|
+
const isDropdown = DROPDOWN_TYPES.has(type);
|
|
879
887
|
if (isDropdown && (!triggerEl || !contentEl)) {
|
|
880
888
|
devWarn(`[@vitus-labs/elements] Overlay (${type}): ${triggerEl ? "contentRef" : "triggerRef"} is not attached. Position cannot be calculated without both refs.`);
|
|
881
889
|
return { pos: {} };
|
|
@@ -934,6 +942,80 @@ const useEscapeKey = (enabled, active, blocked, hide) => {
|
|
|
934
942
|
]);
|
|
935
943
|
};
|
|
936
944
|
|
|
945
|
+
//#endregion
|
|
946
|
+
//#region src/Overlay/useFocusTrap.ts
|
|
947
|
+
const FOCUSABLE = [
|
|
948
|
+
"a[href]",
|
|
949
|
+
"button:not([disabled])",
|
|
950
|
+
"input:not([disabled])",
|
|
951
|
+
"select:not([disabled])",
|
|
952
|
+
"textarea:not([disabled])",
|
|
953
|
+
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
954
|
+
"video[controls]",
|
|
955
|
+
"audio[controls]",
|
|
956
|
+
"summary",
|
|
957
|
+
"[tabindex]:not([tabindex=\"-1\"])"
|
|
958
|
+
].join(",");
|
|
959
|
+
const isTabbable = (el) => el.getAttribute("aria-disabled") !== "true";
|
|
960
|
+
const useFocusTrap = (ref, enabled = true, options) => {
|
|
961
|
+
const autoFocus = options?.autoFocus !== false;
|
|
962
|
+
useEffect(() => {
|
|
963
|
+
if (!enabled) return void 0;
|
|
964
|
+
const container = ref.current;
|
|
965
|
+
if (!container) return void 0;
|
|
966
|
+
let focusable = [];
|
|
967
|
+
const refresh = () => {
|
|
968
|
+
const all = container.querySelectorAll(FOCUSABLE);
|
|
969
|
+
const result = [];
|
|
970
|
+
for (let i = 0; i < all.length; i++) {
|
|
971
|
+
const el = all[i];
|
|
972
|
+
if (el && isTabbable(el)) result.push(el);
|
|
973
|
+
}
|
|
974
|
+
focusable = result;
|
|
975
|
+
};
|
|
976
|
+
refresh();
|
|
977
|
+
const observer = new MutationObserver(refresh);
|
|
978
|
+
observer.observe(container, {
|
|
979
|
+
childList: true,
|
|
980
|
+
subtree: true
|
|
981
|
+
});
|
|
982
|
+
const prevFocus = document.activeElement;
|
|
983
|
+
if (autoFocus) if (focusable.length > 0) focusable[0].focus();
|
|
984
|
+
else {
|
|
985
|
+
if (container.tabIndex < 0) container.tabIndex = -1;
|
|
986
|
+
container.focus();
|
|
987
|
+
}
|
|
988
|
+
const handler = (e) => {
|
|
989
|
+
if (e.key !== "Tab" || focusable.length === 0) return;
|
|
990
|
+
const first = focusable[0];
|
|
991
|
+
const last = focusable[focusable.length - 1];
|
|
992
|
+
const active = document.activeElement;
|
|
993
|
+
if (active && !container.contains(active)) {
|
|
994
|
+
e.preventDefault();
|
|
995
|
+
first.focus();
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
if (e.shiftKey && active === first) {
|
|
999
|
+
e.preventDefault();
|
|
1000
|
+
last.focus();
|
|
1001
|
+
} else if (!e.shiftKey && active === last) {
|
|
1002
|
+
e.preventDefault();
|
|
1003
|
+
first.focus();
|
|
1004
|
+
}
|
|
1005
|
+
};
|
|
1006
|
+
document.addEventListener("keydown", handler);
|
|
1007
|
+
return () => {
|
|
1008
|
+
observer.disconnect();
|
|
1009
|
+
document.removeEventListener("keydown", handler);
|
|
1010
|
+
if (autoFocus && prevFocus && typeof prevFocus.focus === "function") prevFocus.focus();
|
|
1011
|
+
};
|
|
1012
|
+
}, [
|
|
1013
|
+
ref,
|
|
1014
|
+
enabled,
|
|
1015
|
+
autoFocus
|
|
1016
|
+
]);
|
|
1017
|
+
};
|
|
1018
|
+
|
|
937
1019
|
//#endregion
|
|
938
1020
|
//#region src/Overlay/useHoverListeners.ts
|
|
939
1021
|
/**
|
|
@@ -1002,50 +1084,49 @@ const useHoverListeners = ({ triggerRef, contentRef, isContentLoaded, active, bl
|
|
|
1002
1084
|
]);
|
|
1003
1085
|
};
|
|
1004
1086
|
|
|
1087
|
+
//#endregion
|
|
1088
|
+
//#region src/Overlay/useScrollLock.ts
|
|
1089
|
+
let lockCount = 0;
|
|
1090
|
+
let originalOverflow;
|
|
1091
|
+
const useScrollLock = (enabled) => {
|
|
1092
|
+
useEffect(() => {
|
|
1093
|
+
if (!enabled) return void 0;
|
|
1094
|
+
if (lockCount === 0) originalOverflow = document.body.style.overflow;
|
|
1095
|
+
lockCount++;
|
|
1096
|
+
document.body.style.overflow = "hidden";
|
|
1097
|
+
return () => {
|
|
1098
|
+
lockCount--;
|
|
1099
|
+
if (lockCount === 0) {
|
|
1100
|
+
document.body.style.overflow = originalOverflow ?? "";
|
|
1101
|
+
originalOverflow = void 0;
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
}, [enabled]);
|
|
1105
|
+
};
|
|
1106
|
+
|
|
1005
1107
|
//#endregion
|
|
1006
1108
|
//#region src/Overlay/useScrollReposition.ts
|
|
1007
|
-
|
|
1008
|
-
/**
|
|
1009
|
-
* Window-level scroll/resize listeners that reposition active overlays and
|
|
1010
|
-
* re-evaluate close-on-scroll behavior. Also manages the body overflow lock
|
|
1011
|
-
* for modal overlays (refcounted across nested modals).
|
|
1012
|
-
*/
|
|
1013
|
-
const useWindowReposition = (active, type, handleContentPosition, handleVisibility) => {
|
|
1109
|
+
const useWindowReposition = (active, handleContentPosition, handleVisibility) => {
|
|
1014
1110
|
useEffect(() => {
|
|
1015
1111
|
if (!active) return void 0;
|
|
1016
|
-
const shouldSetOverflow = type === "modal";
|
|
1017
1112
|
const onScroll = (e) => {
|
|
1018
1113
|
handleContentPosition();
|
|
1019
1114
|
handleVisibility(e);
|
|
1020
1115
|
};
|
|
1021
|
-
if (shouldSetOverflow) {
|
|
1022
|
-
modalOverflowCount++;
|
|
1023
|
-
if (modalOverflowCount === 1) document.body.style.overflow = "hidden";
|
|
1024
|
-
}
|
|
1025
1116
|
window.addEventListener("resize", handleContentPosition);
|
|
1026
1117
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1027
1118
|
return () => {
|
|
1028
1119
|
handleContentPosition.cancel();
|
|
1029
1120
|
handleVisibility.cancel();
|
|
1030
|
-
if (shouldSetOverflow) {
|
|
1031
|
-
modalOverflowCount--;
|
|
1032
|
-
if (modalOverflowCount === 0) document.body.style.overflow = "";
|
|
1033
|
-
}
|
|
1034
1121
|
window.removeEventListener("resize", handleContentPosition);
|
|
1035
1122
|
window.removeEventListener("scroll", onScroll);
|
|
1036
1123
|
};
|
|
1037
1124
|
}, [
|
|
1038
1125
|
active,
|
|
1039
|
-
type,
|
|
1040
1126
|
handleContentPosition,
|
|
1041
1127
|
handleVisibility
|
|
1042
1128
|
]);
|
|
1043
1129
|
};
|
|
1044
|
-
/**
|
|
1045
|
-
* Same as `useWindowReposition` but for a custom scrollable ancestor.
|
|
1046
|
-
* Locks the parent's overflow while the overlay is active (unless hover-driven,
|
|
1047
|
-
* which expects the parent to keep scrolling).
|
|
1048
|
-
*/
|
|
1049
1130
|
const useParentContainerReposition = (active, parentContainer, closeOn, handleContentPosition, handleVisibility) => {
|
|
1050
1131
|
useEffect(() => {
|
|
1051
1132
|
if (!active || !parentContainer) return void 0;
|
|
@@ -1067,8 +1148,8 @@ const useParentContainerReposition = (active, parentContainer, closeOn, handleCo
|
|
|
1067
1148
|
handleVisibility
|
|
1068
1149
|
]);
|
|
1069
1150
|
};
|
|
1070
|
-
const useScrollReposition = ({ active,
|
|
1071
|
-
useWindowReposition(active,
|
|
1151
|
+
const useScrollReposition = ({ active, parentContainer, closeOn, handleContentPosition, handleVisibility }) => {
|
|
1152
|
+
useWindowReposition(active, handleContentPosition, handleVisibility);
|
|
1072
1153
|
useParentContainerReposition(active, parentContainer, closeOn, handleContentPosition, handleVisibility);
|
|
1073
1154
|
};
|
|
1074
1155
|
|
|
@@ -1089,6 +1170,7 @@ const CLICK_CLOSE_KINDS = new Set([
|
|
|
1089
1170
|
"clickOnTrigger",
|
|
1090
1171
|
"clickOutsideContent"
|
|
1091
1172
|
]);
|
|
1173
|
+
const isNodeOrChildOf = (node, target) => !!(node && target && (node.contains(target) || target === node));
|
|
1092
1174
|
const useOverlay = ({ isOpen = false, openOn = "click", closeOn = "click", type = "dropdown", position = "fixed", align = "bottom", alignX = "left", alignY = "bottom", offsetX = 0, offsetY = 0, throttleDelay = 200, parentContainer, closeOnEsc = true, hoverDelay = 100, disabled, onOpen, onClose } = {}) => {
|
|
1093
1175
|
const { rootSize } = useContext(context);
|
|
1094
1176
|
const ctx = useOverlayContext();
|
|
@@ -1100,7 +1182,6 @@ const useOverlay = ({ isOpen = false, openOn = "click", closeOn = "click", type
|
|
|
1100
1182
|
const [active, setActive] = useState(isOpen);
|
|
1101
1183
|
const triggerRef = useRef(null);
|
|
1102
1184
|
const contentRef = useRef(null);
|
|
1103
|
-
const prevFocusRef = useRef(null);
|
|
1104
1185
|
const setBlocked = useCallback(() => setBlockedCount((c) => c + 1), []);
|
|
1105
1186
|
const setUnblocked = useCallback(() => setBlockedCount((c) => Math.max(0, c - 1)), []);
|
|
1106
1187
|
const showContent = useCallback(() => setActive(true), []);
|
|
@@ -1151,13 +1232,11 @@ const useOverlay = ({ isOpen = false, openOn = "click", closeOn = "click", type
|
|
|
1151
1232
|
const setContentPosition = useCallback(() => {
|
|
1152
1233
|
assignContentPosition(calculateContentPosition());
|
|
1153
1234
|
}, [assignContentPosition, calculateContentPosition]);
|
|
1154
|
-
const
|
|
1155
|
-
|
|
1156
|
-
return false;
|
|
1157
|
-
}, []);
|
|
1235
|
+
const isTriggerOrChild = useCallback((e) => isNodeOrChildOf(triggerRef.current, e?.target), []);
|
|
1236
|
+
const isContentOrChild = useCallback((e) => isNodeOrChildOf(contentRef.current, e?.target), []);
|
|
1158
1237
|
const handleVisibilityByEventType = useCallback((e) => {
|
|
1159
1238
|
if (blocked || disabled) return;
|
|
1160
|
-
processVisibilityEvent(e, active, openOn, closeOn,
|
|
1239
|
+
processVisibilityEvent(e, active, openOn, closeOn, isTriggerOrChild, isContentOrChild, showContent, hideContent);
|
|
1161
1240
|
}, [
|
|
1162
1241
|
active,
|
|
1163
1242
|
blocked,
|
|
@@ -1166,7 +1245,8 @@ const useOverlay = ({ isOpen = false, openOn = "click", closeOn = "click", type
|
|
|
1166
1245
|
closeOn,
|
|
1167
1246
|
hideContent,
|
|
1168
1247
|
showContent,
|
|
1169
|
-
|
|
1248
|
+
isTriggerOrChild,
|
|
1249
|
+
isContentOrChild
|
|
1170
1250
|
]);
|
|
1171
1251
|
const latestSetContentPosition = useRef(setContentPosition);
|
|
1172
1252
|
latestSetContentPosition.current = setContentPosition;
|
|
@@ -1195,50 +1275,35 @@ const useOverlay = ({ isOpen = false, openOn = "click", closeOn = "click", type
|
|
|
1195
1275
|
isContentLoaded,
|
|
1196
1276
|
setContentPosition
|
|
1197
1277
|
]);
|
|
1278
|
+
const latestOnOpen = useRef(onOpen);
|
|
1279
|
+
latestOnOpen.current = onOpen;
|
|
1280
|
+
const latestOnClose = useRef(onClose);
|
|
1281
|
+
latestOnClose.current = onClose;
|
|
1198
1282
|
const prevActiveRef = useRef(false);
|
|
1199
1283
|
useEffect(() => {
|
|
1200
1284
|
const wasActive = prevActiveRef.current;
|
|
1201
1285
|
prevActiveRef.current = active;
|
|
1202
1286
|
if (active && !wasActive) {
|
|
1203
|
-
|
|
1287
|
+
latestOnOpen.current?.();
|
|
1204
1288
|
ctx.setBlocked?.();
|
|
1205
1289
|
} else if (!active && wasActive) {
|
|
1206
1290
|
setContentLoaded(false);
|
|
1207
|
-
|
|
1291
|
+
latestOnClose.current?.();
|
|
1208
1292
|
ctx.setUnblocked?.();
|
|
1209
1293
|
} else if (!active) setContentLoaded(false);
|
|
1210
1294
|
return () => {
|
|
1211
1295
|
if (active) {
|
|
1212
|
-
|
|
1296
|
+
latestOnClose.current?.();
|
|
1213
1297
|
ctx.setUnblocked?.();
|
|
1214
1298
|
}
|
|
1215
1299
|
};
|
|
1216
|
-
}, [
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
onOpen
|
|
1221
|
-
]);
|
|
1222
|
-
useEffect(() => {
|
|
1223
|
-
if (type !== "modal") return;
|
|
1224
|
-
if (active && isContentLoaded && contentRef.current) {
|
|
1225
|
-
prevFocusRef.current = document.activeElement;
|
|
1226
|
-
if (contentRef.current.tabIndex < 0) contentRef.current.tabIndex = -1;
|
|
1227
|
-
contentRef.current.focus();
|
|
1228
|
-
}
|
|
1229
|
-
if (!active && prevFocusRef.current) {
|
|
1230
|
-
prevFocusRef.current.focus();
|
|
1231
|
-
prevFocusRef.current = null;
|
|
1232
|
-
}
|
|
1233
|
-
}, [
|
|
1234
|
-
active,
|
|
1235
|
-
isContentLoaded,
|
|
1236
|
-
type
|
|
1237
|
-
]);
|
|
1300
|
+
}, [active, ctx]);
|
|
1301
|
+
const modalActive = type === "modal" && active && isContentLoaded;
|
|
1302
|
+
useFocusTrap(contentRef, modalActive);
|
|
1303
|
+
useScrollLock(modalActive);
|
|
1238
1304
|
useEscapeKey(closeOnEsc, active, blocked, hideContent);
|
|
1239
1305
|
useScrollReposition({
|
|
1240
1306
|
active,
|
|
1241
|
-
type,
|
|
1242
1307
|
parentContainer,
|
|
1243
1308
|
closeOn,
|
|
1244
1309
|
handleContentPosition,
|
|
@@ -1246,8 +1311,8 @@ const useOverlay = ({ isOpen = false, openOn = "click", closeOn = "click", type
|
|
|
1246
1311
|
});
|
|
1247
1312
|
useEffect(() => {
|
|
1248
1313
|
if (blocked || disabled) return void 0;
|
|
1249
|
-
if (openOn === "click" || CLICK_CLOSE_KINDS.has(closeOn))
|
|
1250
|
-
return () =>
|
|
1314
|
+
if (openOn === "click" || CLICK_CLOSE_KINDS.has(closeOn)) document.addEventListener("click", handleClick);
|
|
1315
|
+
return () => document.removeEventListener("click", handleClick);
|
|
1251
1316
|
}, [
|
|
1252
1317
|
openOn,
|
|
1253
1318
|
closeOn,
|
|
@@ -1301,44 +1366,42 @@ const Component$3 = ({ children, trigger, DOMLocation, triggerRefName = "ref", c
|
|
|
1301
1366
|
const { active, triggerRef, contentRef, showContent, hideContent, align, alignX, alignY, Provider, ...ctx } = useOverlay(props);
|
|
1302
1367
|
const { openOn, closeOn, type } = props;
|
|
1303
1368
|
const contentId = useId();
|
|
1304
|
-
const passHandlers =
|
|
1305
|
-
const ariaHasPopup =
|
|
1306
|
-
|
|
1307
|
-
case "modal": return "dialog";
|
|
1308
|
-
case "tooltip": return "true";
|
|
1309
|
-
default: return "menu";
|
|
1310
|
-
}
|
|
1311
|
-
}, [type]);
|
|
1312
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [render(trigger, {
|
|
1369
|
+
const passHandlers = openOn === "manual" || closeOn === "manual" || closeOn === "clickOutsideContent";
|
|
1370
|
+
const ariaHasPopup = type === "modal" ? "dialog" : type === "tooltip" ? "true" : "menu";
|
|
1371
|
+
const triggerProps = {
|
|
1313
1372
|
[triggerRefName]: triggerRef,
|
|
1314
1373
|
active,
|
|
1315
1374
|
"aria-expanded": active,
|
|
1316
1375
|
"aria-haspopup": ariaHasPopup,
|
|
1317
|
-
"aria-controls": active ? contentId : void 0
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1376
|
+
"aria-controls": active ? contentId : void 0
|
|
1377
|
+
};
|
|
1378
|
+
if (passHandlers) {
|
|
1379
|
+
triggerProps.showContent = showContent;
|
|
1380
|
+
triggerProps.hideContent = hideContent;
|
|
1381
|
+
}
|
|
1382
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [render(trigger, triggerProps), IS_BROWSER && active && (() => {
|
|
1383
|
+
const contentProps = {
|
|
1384
|
+
[contentRefName]: contentRef,
|
|
1385
|
+
id: contentId,
|
|
1386
|
+
role: type === "modal" ? "dialog" : void 0,
|
|
1387
|
+
"aria-modal": type === "modal" ? true : void 0,
|
|
1388
|
+
active,
|
|
1389
|
+
align,
|
|
1390
|
+
alignX,
|
|
1391
|
+
alignY
|
|
1392
|
+
};
|
|
1393
|
+
if (passHandlers) {
|
|
1394
|
+
contentProps.showContent = showContent;
|
|
1395
|
+
contentProps.hideContent = hideContent;
|
|
1396
|
+
}
|
|
1397
|
+
return /* @__PURE__ */ jsx(Portal_default, {
|
|
1398
|
+
DOMLocation,
|
|
1399
|
+
children: /* @__PURE__ */ jsx(Provider, {
|
|
1400
|
+
...ctx,
|
|
1401
|
+
children: render(children, contentProps)
|
|
1339
1402
|
})
|
|
1340
|
-
})
|
|
1341
|
-
})] });
|
|
1403
|
+
});
|
|
1404
|
+
})()] });
|
|
1342
1405
|
};
|
|
1343
1406
|
const name$2 = `${PKG_NAME}/Overlay`;
|
|
1344
1407
|
Component$3.displayName = name$2;
|
|
@@ -1405,7 +1468,7 @@ var Text_default = Component$2;
|
|
|
1405
1468
|
* helper to clone children with the merged props.
|
|
1406
1469
|
*/
|
|
1407
1470
|
const Component$1 = ({ children, className, style }) => {
|
|
1408
|
-
const mergedClasses =
|
|
1471
|
+
const mergedClasses = Array.isArray(className) ? className.join(" ") : className;
|
|
1409
1472
|
const finalProps = {};
|
|
1410
1473
|
if (style) finalProps.style = style;
|
|
1411
1474
|
if (mergedClasses) finalProps.className = mergedClasses;
|
|
@@ -21,10 +21,7 @@ const IS_DEVELOPMENT = process.env.NODE_ENV !== "production";
|
|
|
21
21
|
* fill remaining space between before and after.
|
|
22
22
|
*/
|
|
23
23
|
const { styled: styled$2, css: css$2, component: component$1 } = config;
|
|
24
|
-
const
|
|
25
|
-
flex: 1;
|
|
26
|
-
`;
|
|
27
|
-
const typeContentCSS = `
|
|
24
|
+
const FLEX_1 = `
|
|
28
25
|
flex: 1;
|
|
29
26
|
`;
|
|
30
27
|
const gapDimensions = {
|
|
@@ -56,7 +53,7 @@ const styles$2 = ({ css, theme: t, rootSize }) => css`
|
|
|
56
53
|
alignY: t.alignY
|
|
57
54
|
})};
|
|
58
55
|
|
|
59
|
-
${t.equalCols &&
|
|
56
|
+
${t.equalCols && FLEX_1};
|
|
60
57
|
|
|
61
58
|
${t.gap && t.contentType && calculateGap({
|
|
62
59
|
direction: t.parentDirection,
|
|
@@ -73,7 +70,7 @@ const StyledComponent = styled$2(component$1)`
|
|
|
73
70
|
align-self: stretch;
|
|
74
71
|
flex-wrap: wrap;
|
|
75
72
|
|
|
76
|
-
${({ $contentType }) => $contentType === "content" &&
|
|
73
|
+
${({ $contentType }) => $contentType === "content" && FLEX_1};
|
|
77
74
|
|
|
78
75
|
${makeItResponsive({
|
|
79
76
|
key: "$element",
|
|
@@ -124,11 +121,11 @@ const Component$6 = ({ contentType, tag, parentDirection, direction, alignX, ali
|
|
|
124
121
|
children: render(children)
|
|
125
122
|
});
|
|
126
123
|
};
|
|
127
|
-
var component_default = memo(Component$6);
|
|
124
|
+
var component_default$1 = memo(Component$6);
|
|
128
125
|
|
|
129
126
|
//#endregion
|
|
130
127
|
//#region src/helpers/Content/index.ts
|
|
131
|
-
var Content_default = component_default;
|
|
128
|
+
var Content_default = component_default$1;
|
|
132
129
|
|
|
133
130
|
//#endregion
|
|
134
131
|
//#region src/helpers/Wrapper/styled.ts
|
|
@@ -190,22 +187,19 @@ var styled_default$1 = styled$1(component)`
|
|
|
190
187
|
* (parent + child Styled) because these HTML elements do not natively
|
|
191
188
|
* support `display: flex` consistently across browsers.
|
|
192
189
|
*/
|
|
193
|
-
const DEV_PROPS = IS_DEVELOPMENT ? { "data-vl-element": "Element" } :
|
|
190
|
+
const DEV_PROPS = IS_DEVELOPMENT ? { "data-vl-element": "Element" } : null;
|
|
194
191
|
const Component$5 = ({ children, ref, tag, block, extendCss, direction, alignX, alignY, equalCols, isInline, ...props }) => {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
equalCols,
|
|
207
|
-
extraStyles: extendCss
|
|
208
|
-
}), [
|
|
192
|
+
const $element = useMemo(() => {
|
|
193
|
+
return {
|
|
194
|
+
block,
|
|
195
|
+
direction,
|
|
196
|
+
alignX,
|
|
197
|
+
alignY,
|
|
198
|
+
equalCols,
|
|
199
|
+
extraStyles: extendCss
|
|
200
|
+
};
|
|
201
|
+
}, [
|
|
202
|
+
false,
|
|
209
203
|
block,
|
|
210
204
|
direction,
|
|
211
205
|
alignX,
|
|
@@ -213,33 +207,20 @@ const Component$5 = ({ children, ref, tag, block, extendCss, direction, alignX,
|
|
|
213
207
|
equalCols,
|
|
214
208
|
extendCss
|
|
215
209
|
]);
|
|
216
|
-
useMemo(() => ({
|
|
217
|
-
parentFix: true,
|
|
218
|
-
block,
|
|
219
|
-
extraStyles: extendCss
|
|
220
|
-
}), [block, extendCss]);
|
|
221
|
-
useMemo(() => ({
|
|
222
|
-
childFix: true,
|
|
223
|
-
direction,
|
|
224
|
-
alignX,
|
|
225
|
-
alignY,
|
|
226
|
-
equalCols
|
|
227
|
-
}), [
|
|
228
|
-
direction,
|
|
229
|
-
alignX,
|
|
230
|
-
alignY,
|
|
231
|
-
equalCols
|
|
232
|
-
]);
|
|
233
210
|
return /* @__PURE__ */ jsx(styled_default$1, {
|
|
234
|
-
...
|
|
235
|
-
|
|
211
|
+
...props,
|
|
212
|
+
...DEV_PROPS,
|
|
213
|
+
ref,
|
|
214
|
+
as: tag,
|
|
215
|
+
$element,
|
|
236
216
|
children
|
|
237
217
|
});
|
|
238
218
|
};
|
|
219
|
+
var component_default = memo(Component$5);
|
|
239
220
|
|
|
240
221
|
//#endregion
|
|
241
222
|
//#region src/helpers/Wrapper/index.ts
|
|
242
|
-
var Wrapper_default =
|
|
223
|
+
var Wrapper_default = component_default;
|
|
243
224
|
|
|
244
225
|
//#endregion
|
|
245
226
|
//#region src/Element/component.tsx
|
|
@@ -255,6 +236,7 @@ const defaultDirection = "inline";
|
|
|
255
236
|
const defaultContentDirection = "rows";
|
|
256
237
|
const defaultAlignX = "left";
|
|
257
238
|
const defaultAlignY = "center";
|
|
239
|
+
const AS_RESET = { as: void 0 };
|
|
258
240
|
const Component$4 = ({ innerRef, ref, tag, label, content, children, beforeContent, afterContent, equalBeforeAfter, block, equalCols, gap, direction, alignX = defaultAlignX, alignY = defaultAlignY, css, contentCss, beforeContentCss, afterContentCss, contentDirection = defaultContentDirection, contentAlignX = defaultAlignX, contentAlignY = defaultAlignY, beforeContentDirection = defaultDirection, beforeContentAlignX = defaultAlignX, beforeContentAlignY = defaultAlignY, afterContentDirection = defaultDirection, afterContentAlignX = defaultAlignX, afterContentAlignY = defaultAlignY, ...props }) => {
|
|
259
241
|
const isSimpleElement = !beforeContent && !afterContent;
|
|
260
242
|
const CHILDREN = children ?? content ?? label;
|
|
@@ -286,18 +268,22 @@ const Component$4 = ({ innerRef, ref, tag, label, content, children, beforeConte
|
|
|
286
268
|
]);
|
|
287
269
|
const equalizeRef = useRef(null);
|
|
288
270
|
const externalRef = ref ?? innerRef;
|
|
271
|
+
const latestExternalRef = useRef(externalRef);
|
|
272
|
+
latestExternalRef.current = externalRef;
|
|
289
273
|
const mergedRef = useCallback((node) => {
|
|
290
274
|
equalizeRef.current = node;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
275
|
+
const r = latestExternalRef.current;
|
|
276
|
+
if (typeof r === "function") r(node);
|
|
277
|
+
else if (r != null) r.current = node;
|
|
278
|
+
}, []);
|
|
294
279
|
useLayoutEffect(() => {}, [
|
|
295
280
|
equalBeforeAfter,
|
|
296
281
|
beforeContent,
|
|
297
282
|
afterContent,
|
|
298
283
|
direction
|
|
299
284
|
]);
|
|
300
|
-
|
|
285
|
+
return /* @__PURE__ */ jsxs(Wrapper_default, {
|
|
286
|
+
...props,
|
|
301
287
|
ref: mergedRef,
|
|
302
288
|
extendCss: css,
|
|
303
289
|
tag,
|
|
@@ -305,12 +291,8 @@ const Component$4 = ({ innerRef, ref, tag, label, content, children, beforeConte
|
|
|
305
291
|
direction: wrapperDirection,
|
|
306
292
|
alignX: wrapperAlignX,
|
|
307
293
|
alignY: wrapperAlignY,
|
|
308
|
-
as: void 0
|
|
309
|
-
};
|
|
310
|
-
return /* @__PURE__ */ jsxs(Wrapper_default, {
|
|
311
|
-
...props,
|
|
312
|
-
...WRAPPER_PROPS,
|
|
313
294
|
isInline,
|
|
295
|
+
...AS_RESET,
|
|
314
296
|
children: [
|
|
315
297
|
beforeContent && /* @__PURE__ */ jsx(Content_default, {
|
|
316
298
|
tag: SUB_TAG,
|
|
@@ -351,13 +333,14 @@ const Component$4 = ({ innerRef, ref, tag, label, content, children, beforeConte
|
|
|
351
333
|
});
|
|
352
334
|
};
|
|
353
335
|
const name$3 = `${PKG_NAME}/Element`;
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
336
|
+
const MemoComponent = memo(Component$4);
|
|
337
|
+
MemoComponent.displayName = name$3;
|
|
338
|
+
MemoComponent.pkgName = PKG_NAME;
|
|
339
|
+
MemoComponent.VITUS_LABS__COMPONENT = name$3;
|
|
357
340
|
|
|
358
341
|
//#endregion
|
|
359
342
|
//#region src/Element/index.ts
|
|
360
|
-
var Element_default =
|
|
343
|
+
var Element_default = MemoComponent;
|
|
361
344
|
|
|
362
345
|
//#endregion
|
|
363
346
|
//#region src/helpers/Iterator/component.tsx
|
|
@@ -520,12 +503,13 @@ var Iterator_default = Iterator;
|
|
|
520
503
|
* is wrapped in an Element that receives all non-iterator props (e.g.,
|
|
521
504
|
* layout, alignment, css), allowing the list to be styled as a single block.
|
|
522
505
|
*/
|
|
506
|
+
const RESERVED_PROPS_SET = new Set(Iterator_default.RESERVED_PROPS);
|
|
523
507
|
const Component$2 = ({ rootElement = false, ref, ...props }) => {
|
|
524
508
|
const renderedList = /* @__PURE__ */ jsx(Iterator_default, { ...pick(props, Iterator_default.RESERVED_PROPS) });
|
|
525
509
|
if (!rootElement) return renderedList;
|
|
526
510
|
return /* @__PURE__ */ jsx(Element_default, {
|
|
527
511
|
ref,
|
|
528
|
-
...omit(props,
|
|
512
|
+
...omit(props, RESERVED_PROPS_SET),
|
|
529
513
|
children: renderedList
|
|
530
514
|
});
|
|
531
515
|
};
|
|
@@ -590,7 +574,7 @@ var Text_default = Component$1;
|
|
|
590
574
|
* helper to clone children with the merged props.
|
|
591
575
|
*/
|
|
592
576
|
const Component = ({ children, className, style }) => {
|
|
593
|
-
const mergedClasses =
|
|
577
|
+
const mergedClasses = Array.isArray(className) ? className.join(" ") : className;
|
|
594
578
|
const finalProps = {};
|
|
595
579
|
if (style) finalProps.style = style;
|
|
596
580
|
if (mergedClasses) finalProps.className = mergedClasses;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitus-labs/elements",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Vit Bokisch <vit@bokisch.cz>",
|
|
6
6
|
"maintainers": [
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"prepublish": "bun run build",
|
|
50
50
|
"build": "bun run vl_rolldown_build",
|
|
51
51
|
"build:watch": "bun run vl_rolldown_build-watch",
|
|
52
|
+
"bench": "bun benchmarks/render-bench.tsx",
|
|
52
53
|
"lint": "biome check src/",
|
|
53
54
|
"test": "vitest run",
|
|
54
55
|
"test:coverage": "vitest run --coverage",
|
|
@@ -57,27 +58,27 @@
|
|
|
57
58
|
"typecheck": "tsc --noEmit"
|
|
58
59
|
},
|
|
59
60
|
"peerDependencies": {
|
|
60
|
-
"@vitus-labs/core": "^2.
|
|
61
|
-
"@vitus-labs/unistyle": "^2.
|
|
61
|
+
"@vitus-labs/core": "^2.7.0",
|
|
62
|
+
"@vitus-labs/unistyle": "^2.7.0",
|
|
62
63
|
"react": ">= 19",
|
|
63
|
-
"react-dom": ">= 19"
|
|
64
|
-
"react-native": ">= 0.76"
|
|
64
|
+
"react-dom": ">= 19"
|
|
65
65
|
},
|
|
66
66
|
"peerDependenciesMeta": {
|
|
67
67
|
"react-dom": {
|
|
68
68
|
"optional": true
|
|
69
|
-
},
|
|
70
|
-
"react-native": {
|
|
71
|
-
"optional": true
|
|
72
69
|
}
|
|
73
70
|
},
|
|
74
71
|
"devDependencies": {
|
|
72
|
+
"@vitus-labs/connector-styler": "workspace:*",
|
|
75
73
|
"@vitus-labs/core": "workspace:*",
|
|
76
74
|
"@vitus-labs/rocketstyle": "workspace:*",
|
|
77
|
-
"@vitus-labs/
|
|
78
|
-
"@vitus-labs/tools-
|
|
79
|
-
"@vitus-labs/tools-
|
|
80
|
-
"@vitus-labs/
|
|
75
|
+
"@vitus-labs/styler": "workspace:*",
|
|
76
|
+
"@vitus-labs/tools-rolldown": "2.5.0",
|
|
77
|
+
"@vitus-labs/tools-storybook": "2.5.0",
|
|
78
|
+
"@vitus-labs/tools-typescript": "2.5.0",
|
|
79
|
+
"@vitus-labs/unistyle": "workspace:*",
|
|
80
|
+
"jsdom": "^29.1.1",
|
|
81
|
+
"tinybench": "^6.0.1"
|
|
81
82
|
},
|
|
82
83
|
"dependencies": {
|
|
83
84
|
"react-is": "^19.2.4"
|