@vitus-labs/elements 2.0.0-alpha.9 → 2.0.0-beta.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/README.md +7 -30
- package/lib/index.d.ts +17 -215
- package/lib/index.js +124 -204
- package/lib/vitus-labs-elements.native.js +126 -780
- package/package.json +25 -13
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Provider, alignContent, extendCss, makeItResponsive, value } from "@vitus-labs/unistyle";
|
|
2
|
-
import { config,
|
|
3
|
-
import { Children,
|
|
4
|
-
import {
|
|
2
|
+
import { config, isEmpty, omit, pick, render } from "@vitus-labs/core";
|
|
3
|
+
import { Children, forwardRef, memo, useCallback, useLayoutEffect, useMemo, useRef } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { isFragment } from "react-is";
|
|
6
|
-
import { createPortal } from "react-dom";
|
|
7
6
|
|
|
8
7
|
//#region src/constants.ts
|
|
9
8
|
const PKG_NAME = "@vitus-labs/elements";
|
|
@@ -21,7 +20,7 @@ const IS_DEVELOPMENT = process.env.NODE_ENV !== "production";
|
|
|
21
20
|
* equalCols flex distribution. The "content" slot gets `flex: 1` to
|
|
22
21
|
* fill remaining space between before and after.
|
|
23
22
|
*/
|
|
24
|
-
const { styled: styled$2, css: css$2, component: component$
|
|
23
|
+
const { styled: styled$2, css: css$2, component: component$1 } = config;
|
|
25
24
|
const equalColsCSS = `
|
|
26
25
|
flex: 1;
|
|
27
26
|
`;
|
|
@@ -67,7 +66,7 @@ const styles$2 = ({ css, theme: t, rootSize }) => css`
|
|
|
67
66
|
|
|
68
67
|
${t.extraStyles && extendCss(t.extraStyles)};
|
|
69
68
|
`;
|
|
70
|
-
const StyledComponent = styled$2(component$
|
|
69
|
+
const StyledComponent = styled$2(component$1)`
|
|
71
70
|
${""};
|
|
72
71
|
|
|
73
72
|
display: flex;
|
|
@@ -86,11 +85,22 @@ const StyledComponent = styled$2(component$2)`
|
|
|
86
85
|
|
|
87
86
|
//#endregion
|
|
88
87
|
//#region src/helpers/Content/component.tsx
|
|
89
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Memoized content area used inside Element to render one of the three
|
|
90
|
+
* layout slots (before, content, after). Passes alignment, direction,
|
|
91
|
+
* gap, and equalCols styling props to the underlying styled component.
|
|
92
|
+
* Adds a `data-vl-element` attribute in development for debugging.
|
|
93
|
+
*
|
|
94
|
+
* Children are passed as raw content and rendered inside the memo boundary
|
|
95
|
+
* via core `render()` — this lets React.memo skip re-renders when the
|
|
96
|
+
* content reference is stable (common for component-type or string content).
|
|
97
|
+
*/
|
|
98
|
+
const Component$6 = ({ contentType, tag, parentDirection, direction, alignX, alignY, equalCols, gap, extendCss, children, ...props }) => {
|
|
99
|
+
const debugProps = IS_DEVELOPMENT ? { "data-vl-element": contentType } : {};
|
|
90
100
|
return /* @__PURE__ */ jsx(StyledComponent, {
|
|
91
101
|
as: tag,
|
|
92
102
|
$contentType: contentType,
|
|
93
|
-
$element: {
|
|
103
|
+
$element: useMemo(() => ({
|
|
94
104
|
contentType,
|
|
95
105
|
parentDirection,
|
|
96
106
|
direction,
|
|
@@ -99,16 +109,26 @@ const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, ali
|
|
|
99
109
|
equalCols,
|
|
100
110
|
gap,
|
|
101
111
|
extraStyles: extendCss
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
|
|
112
|
+
}), [
|
|
113
|
+
contentType,
|
|
114
|
+
parentDirection,
|
|
115
|
+
direction,
|
|
116
|
+
alignX,
|
|
117
|
+
alignY,
|
|
118
|
+
equalCols,
|
|
119
|
+
gap,
|
|
120
|
+
extendCss
|
|
121
|
+
]),
|
|
122
|
+
...debugProps,
|
|
123
|
+
...props,
|
|
124
|
+
children: render(children)
|
|
105
125
|
});
|
|
106
126
|
};
|
|
107
|
-
var component_default = memo(Component$
|
|
127
|
+
var component_default$1 = memo(Component$6);
|
|
108
128
|
|
|
109
129
|
//#endregion
|
|
110
130
|
//#region src/helpers/Content/index.ts
|
|
111
|
-
var Content_default = component_default;
|
|
131
|
+
var Content_default = component_default$1;
|
|
112
132
|
|
|
113
133
|
//#endregion
|
|
114
134
|
//#region src/helpers/Wrapper/styled.ts
|
|
@@ -119,7 +139,7 @@ var Content_default = component_default;
|
|
|
119
139
|
* split flex behavior across two DOM nodes for button/fieldset/legend
|
|
120
140
|
* elements where a single flex container is insufficient.
|
|
121
141
|
*/
|
|
122
|
-
const { styled: styled$1, css: css$1, component
|
|
142
|
+
const { styled: styled$1, css: css$1, component } = config;
|
|
123
143
|
const childFixCSS = `
|
|
124
144
|
display: flex;
|
|
125
145
|
flex: 1;
|
|
@@ -128,6 +148,7 @@ const childFixCSS = `
|
|
|
128
148
|
`;
|
|
129
149
|
const blockCSS = `
|
|
130
150
|
align-self: stretch;
|
|
151
|
+
width: 100%;
|
|
131
152
|
`;
|
|
132
153
|
const styles$1 = ({ theme: t, css }) => css`
|
|
133
154
|
${false};
|
|
@@ -139,15 +160,15 @@ const styles$1 = ({ theme: t, css }) => css`
|
|
|
139
160
|
})};
|
|
140
161
|
|
|
141
162
|
${t.block && blockCSS};
|
|
142
|
-
|
|
143
163
|
${false};
|
|
164
|
+
|
|
144
165
|
${false};
|
|
145
166
|
${false};
|
|
146
167
|
|
|
147
168
|
${t.extraStyles && extendCss(t.extraStyles)};
|
|
148
169
|
`;
|
|
149
170
|
const platformCSS = `display: flex;`;
|
|
150
|
-
var styled_default$1 = styled$1(component
|
|
171
|
+
var styled_default$1 = styled$1(component)`
|
|
151
172
|
position: relative;
|
|
152
173
|
${platformCSS};
|
|
153
174
|
|
|
@@ -171,27 +192,55 @@ var styled_default$1 = styled$1(component$1)`
|
|
|
171
192
|
* support `display: flex` consistently across browsers.
|
|
172
193
|
*/
|
|
173
194
|
const DEV_PROPS = IS_DEVELOPMENT ? { "data-vl-element": "Element" } : {};
|
|
174
|
-
const Component$
|
|
175
|
-
|
|
195
|
+
const Component$5 = forwardRef(({ children, tag, block, extendCss, direction, alignX, alignY, equalCols, isInline, ...props }, ref) => {
|
|
196
|
+
const COMMON_PROPS = {
|
|
176
197
|
...props,
|
|
177
198
|
...DEV_PROPS,
|
|
178
199
|
ref,
|
|
179
|
-
as: tag
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
200
|
+
as: tag
|
|
201
|
+
};
|
|
202
|
+
const normalElement = useMemo(() => ({
|
|
203
|
+
block,
|
|
204
|
+
direction,
|
|
205
|
+
alignX,
|
|
206
|
+
alignY,
|
|
207
|
+
equalCols,
|
|
208
|
+
extraStyles: extendCss
|
|
209
|
+
}), [
|
|
210
|
+
block,
|
|
211
|
+
direction,
|
|
212
|
+
alignX,
|
|
213
|
+
alignY,
|
|
214
|
+
equalCols,
|
|
215
|
+
extendCss
|
|
216
|
+
]);
|
|
217
|
+
useMemo(() => ({
|
|
218
|
+
parentFix: true,
|
|
219
|
+
block,
|
|
220
|
+
extraStyles: extendCss
|
|
221
|
+
}), [block, extendCss]);
|
|
222
|
+
useMemo(() => ({
|
|
223
|
+
childFix: true,
|
|
224
|
+
direction,
|
|
225
|
+
alignX,
|
|
226
|
+
alignY,
|
|
227
|
+
equalCols
|
|
228
|
+
}), [
|
|
229
|
+
direction,
|
|
230
|
+
alignX,
|
|
231
|
+
alignY,
|
|
232
|
+
equalCols
|
|
233
|
+
]);
|
|
234
|
+
return /* @__PURE__ */ jsx(styled_default$1, {
|
|
235
|
+
...COMMON_PROPS,
|
|
236
|
+
$element: normalElement,
|
|
188
237
|
children
|
|
189
238
|
});
|
|
190
239
|
});
|
|
191
240
|
|
|
192
241
|
//#endregion
|
|
193
242
|
//#region src/helpers/Wrapper/index.ts
|
|
194
|
-
var Wrapper_default = Component$
|
|
243
|
+
var Wrapper_default = Component$5;
|
|
195
244
|
|
|
196
245
|
//#endregion
|
|
197
246
|
//#region src/Element/component.tsx
|
|
@@ -207,7 +256,7 @@ const defaultDirection = "inline";
|
|
|
207
256
|
const defaultContentDirection = "rows";
|
|
208
257
|
const defaultAlignX = "left";
|
|
209
258
|
const defaultAlignY = "center";
|
|
210
|
-
const Component$
|
|
259
|
+
const Component$4 = forwardRef(({ innerRef, 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 }, ref) => {
|
|
211
260
|
const isSimpleElement = !beforeContent && !afterContent;
|
|
212
261
|
const CHILDREN = children ?? content ?? label;
|
|
213
262
|
const isInline = false;
|
|
@@ -236,8 +285,21 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
|
|
|
236
285
|
alignY,
|
|
237
286
|
direction
|
|
238
287
|
]);
|
|
288
|
+
const equalizeRef = useRef(null);
|
|
289
|
+
const externalRef = ref ?? innerRef;
|
|
290
|
+
const mergedRef = useCallback((node) => {
|
|
291
|
+
equalizeRef.current = node;
|
|
292
|
+
if (typeof externalRef === "function") externalRef(node);
|
|
293
|
+
else if (externalRef != null) externalRef.current = node;
|
|
294
|
+
}, [externalRef]);
|
|
295
|
+
useLayoutEffect(() => {}, [
|
|
296
|
+
equalBeforeAfter,
|
|
297
|
+
beforeContent,
|
|
298
|
+
afterContent,
|
|
299
|
+
direction
|
|
300
|
+
]);
|
|
239
301
|
const WRAPPER_PROPS = {
|
|
240
|
-
ref:
|
|
302
|
+
ref: mergedRef,
|
|
241
303
|
extendCss: css,
|
|
242
304
|
tag,
|
|
243
305
|
block,
|
|
@@ -246,7 +308,6 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
|
|
|
246
308
|
alignY: wrapperAlignY,
|
|
247
309
|
as: void 0
|
|
248
310
|
};
|
|
249
|
-
const contentRenderOutput = render(CHILDREN);
|
|
250
311
|
return /* @__PURE__ */ jsxs(Wrapper_default, {
|
|
251
312
|
...props,
|
|
252
313
|
...WRAPPER_PROPS,
|
|
@@ -262,9 +323,9 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
|
|
|
262
323
|
alignY: beforeContentAlignY,
|
|
263
324
|
equalCols,
|
|
264
325
|
gap,
|
|
265
|
-
children:
|
|
326
|
+
children: beforeContent
|
|
266
327
|
}),
|
|
267
|
-
isSimpleElement ?
|
|
328
|
+
isSimpleElement ? render(CHILDREN) : /* @__PURE__ */ jsx(Content_default, {
|
|
268
329
|
tag: SUB_TAG,
|
|
269
330
|
contentType: "content",
|
|
270
331
|
parentDirection: wrapperDirection,
|
|
@@ -273,7 +334,7 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
|
|
|
273
334
|
alignX: contentAlignX,
|
|
274
335
|
alignY: contentAlignY,
|
|
275
336
|
equalCols,
|
|
276
|
-
children:
|
|
337
|
+
children: CHILDREN
|
|
277
338
|
}),
|
|
278
339
|
afterContent && /* @__PURE__ */ jsx(Content_default, {
|
|
279
340
|
tag: SUB_TAG,
|
|
@@ -285,66 +346,19 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
|
|
|
285
346
|
alignY: afterContentAlignY,
|
|
286
347
|
equalCols,
|
|
287
348
|
gap,
|
|
288
|
-
children:
|
|
349
|
+
children: afterContent
|
|
289
350
|
})
|
|
290
351
|
]
|
|
291
352
|
});
|
|
292
353
|
});
|
|
293
|
-
const name$
|
|
294
|
-
Component$
|
|
295
|
-
Component$
|
|
296
|
-
Component$
|
|
297
|
-
|
|
298
|
-
//#endregion
|
|
299
|
-
//#region src/Element/withEqualSizeBeforeAfter.tsx
|
|
300
|
-
/**
|
|
301
|
-
* HOC that equalizes the dimensions of beforeContent and afterContent areas.
|
|
302
|
-
* After render, it measures both DOM nodes via useLayoutEffect and sets the
|
|
303
|
-
* larger dimension on both so they match. Uses width for inline direction
|
|
304
|
-
* and height for rows direction. This is useful for centering the main
|
|
305
|
-
* content when before/after slots have different intrinsic sizes.
|
|
306
|
-
*/
|
|
307
|
-
const types = {
|
|
308
|
-
height: "offsetHeight",
|
|
309
|
-
width: "offsetWidth"
|
|
310
|
-
};
|
|
311
|
-
const equalize = (beforeEl, afterEl, type) => {
|
|
312
|
-
const prop = types[type];
|
|
313
|
-
const beforeSize = beforeEl[prop];
|
|
314
|
-
const afterSize = afterEl[prop];
|
|
315
|
-
if (Number.isInteger(beforeSize) && Number.isInteger(afterSize)) {
|
|
316
|
-
const maxSize = `${Math.max(beforeSize, afterSize)}px`;
|
|
317
|
-
beforeEl.style[type] = maxSize;
|
|
318
|
-
afterEl.style[type] = maxSize;
|
|
319
|
-
}
|
|
320
|
-
};
|
|
321
|
-
const withEqualBeforeAfter = (WrappedComponent) => {
|
|
322
|
-
const displayName = WrappedComponent.displayName ?? WrappedComponent.name ?? "Component";
|
|
323
|
-
const Enhanced = ({ equalBeforeAfter, direction, afterContent, beforeContent, ref, ...rest }) => {
|
|
324
|
-
const internalRef = useRef(null);
|
|
325
|
-
useImperativeHandle(ref, () => internalRef.current);
|
|
326
|
-
useLayoutEffect(() => {
|
|
327
|
-
if (!equalBeforeAfter || !beforeContent || !afterContent) return;
|
|
328
|
-
if (!internalRef.current) return;
|
|
329
|
-
const el = internalRef.current;
|
|
330
|
-
const beforeEl = el.firstElementChild;
|
|
331
|
-
const afterEl = el.lastElementChild;
|
|
332
|
-
if (beforeEl && afterEl && beforeEl !== afterEl) equalize(beforeEl, afterEl, direction === "rows" ? "height" : "width");
|
|
333
|
-
});
|
|
334
|
-
return /* @__PURE__ */ jsx(WrappedComponent, {
|
|
335
|
-
...rest,
|
|
336
|
-
afterContent,
|
|
337
|
-
beforeContent,
|
|
338
|
-
ref: internalRef
|
|
339
|
-
});
|
|
340
|
-
};
|
|
341
|
-
Enhanced.displayName = `withEqualSizeBeforeAfter(${displayName})`;
|
|
342
|
-
return Enhanced;
|
|
343
|
-
};
|
|
354
|
+
const name$3 = `${PKG_NAME}/Element`;
|
|
355
|
+
Component$4.displayName = name$3;
|
|
356
|
+
Component$4.pkgName = PKG_NAME;
|
|
357
|
+
Component$4.VITUS_LABS__COMPONENT = name$3;
|
|
344
358
|
|
|
345
359
|
//#endregion
|
|
346
360
|
//#region src/Element/index.ts
|
|
347
|
-
var Element_default = Component$
|
|
361
|
+
var Element_default = Component$4;
|
|
348
362
|
|
|
349
363
|
//#endregion
|
|
350
364
|
//#region src/helpers/Iterator/component.tsx
|
|
@@ -398,7 +412,7 @@ const attachItemProps = ({ i, length }) => {
|
|
|
398
412
|
position
|
|
399
413
|
};
|
|
400
414
|
};
|
|
401
|
-
const Component$
|
|
415
|
+
const Component$3 = (props) => {
|
|
402
416
|
const { itemKey, valueName, children, component, data, wrapComponent: Wrapper, wrapProps, itemProps } = props;
|
|
403
417
|
const injectItemProps = useMemo(() => typeof itemProps === "function" ? itemProps : () => itemProps, [itemProps]);
|
|
404
418
|
const injectWrapItemProps = useMemo(() => typeof wrapProps === "function" ? wrapProps : () => wrapProps, [wrapProps]);
|
|
@@ -499,12 +513,14 @@ const Component$6 = (props) => {
|
|
|
499
513
|
};
|
|
500
514
|
return renderItems();
|
|
501
515
|
};
|
|
502
|
-
Component$
|
|
503
|
-
|
|
516
|
+
var component_default = Object.assign(memo(Component$3), {
|
|
517
|
+
isIterator: true,
|
|
518
|
+
RESERVED_PROPS
|
|
519
|
+
});
|
|
504
520
|
|
|
505
521
|
//#endregion
|
|
506
522
|
//#region src/helpers/Iterator/index.ts
|
|
507
|
-
var Iterator_default =
|
|
523
|
+
var Iterator_default = component_default;
|
|
508
524
|
|
|
509
525
|
//#endregion
|
|
510
526
|
//#region src/List/component.tsx
|
|
@@ -515,7 +531,7 @@ var Iterator_default = Component$6;
|
|
|
515
531
|
* is wrapped in an Element that receives all non-iterator props (e.g.,
|
|
516
532
|
* layout, alignment, css), allowing the list to be styled as a single block.
|
|
517
533
|
*/
|
|
518
|
-
const Component$
|
|
534
|
+
const Component$2 = forwardRef(({ rootElement = false, ...props }, ref) => {
|
|
519
535
|
const renderedList = /* @__PURE__ */ jsx(Iterator_default, { ...pick(props, Iterator_default.RESERVED_PROPS) });
|
|
520
536
|
if (!rootElement) return renderedList;
|
|
521
537
|
return /* @__PURE__ */ jsx(Element_default, {
|
|
@@ -524,682 +540,14 @@ const Component$5 = forwardRef(({ rootElement = false, ...props }, ref) => {
|
|
|
524
540
|
children: renderedList
|
|
525
541
|
});
|
|
526
542
|
});
|
|
527
|
-
const name$
|
|
528
|
-
Component$
|
|
529
|
-
Component$
|
|
530
|
-
Component$
|
|
531
|
-
|
|
532
|
-
//#endregion
|
|
533
|
-
//#region src/List/withActiveState.tsx
|
|
534
|
-
/**
|
|
535
|
-
* HOC that adds single or multi selection state management to a list component.
|
|
536
|
-
* Tracks which items are active via a scalar key (single mode) or a Map of
|
|
537
|
-
* key-to-boolean entries (multi mode). Injects `itemProps` callback that
|
|
538
|
-
* provides each item with `active`, `handleItemActive`, `toggleItemActive`,
|
|
539
|
-
* and other selection helpers. Supports `activeItemRequired` to prevent
|
|
540
|
-
* deselecting the last active item.
|
|
541
|
-
*/
|
|
542
|
-
const RESERVED_KEYS = [
|
|
543
|
-
"type",
|
|
544
|
-
"activeItems",
|
|
545
|
-
"itemProps",
|
|
546
|
-
"activeItemRequired"
|
|
547
|
-
];
|
|
548
|
-
const component = (WrappedComponent) => {
|
|
549
|
-
const displayName = WrappedComponent.displayName || WrappedComponent.name || "Component";
|
|
550
|
-
const Enhanced = (props) => {
|
|
551
|
-
const { type = "single", activeItemRequired, activeItems, itemProps = {}, ...rest } = props;
|
|
552
|
-
const initActiveItems = () => {
|
|
553
|
-
if (type === "single") {
|
|
554
|
-
if (!Array.isArray(activeItems)) return activeItems;
|
|
555
|
-
} else if (type === "multi") {
|
|
556
|
-
const activeItemsHelper = Array.isArray(activeItems) ? activeItems : [activeItems];
|
|
557
|
-
return new Map(activeItemsHelper.map((id) => [id, true]));
|
|
558
|
-
}
|
|
559
|
-
};
|
|
560
|
-
const [innerActiveItems, setActiveItems] = useState(initActiveItems());
|
|
561
|
-
const countActiveItems = (data) => {
|
|
562
|
-
let result = 0;
|
|
563
|
-
data.forEach((value) => {
|
|
564
|
-
if (value) result += 1;
|
|
565
|
-
});
|
|
566
|
-
return result;
|
|
567
|
-
};
|
|
568
|
-
const updateItemState = (key) => {
|
|
569
|
-
if (type === "single") setActiveItems((prevState) => {
|
|
570
|
-
if (activeItemRequired) return key;
|
|
571
|
-
if (prevState === key) return void 0;
|
|
572
|
-
return key;
|
|
573
|
-
});
|
|
574
|
-
else if (type === "multi") setActiveItems((prevState) => {
|
|
575
|
-
const activeItems = new Map(prevState);
|
|
576
|
-
if (activeItemRequired && activeItems.get(key) && countActiveItems(activeItems) === 1) return activeItems;
|
|
577
|
-
activeItems.set(key, !activeItems.get(key));
|
|
578
|
-
return activeItems;
|
|
579
|
-
});
|
|
580
|
-
else setActiveItems(void 0);
|
|
581
|
-
};
|
|
582
|
-
const handleItemActive = (key) => {
|
|
583
|
-
updateItemState(key);
|
|
584
|
-
};
|
|
585
|
-
const updateAllItemsState = (status) => {
|
|
586
|
-
if (!status) setActiveItems(/* @__PURE__ */ new Map());
|
|
587
|
-
};
|
|
588
|
-
const setItemActive = (key) => {
|
|
589
|
-
updateItemState(key);
|
|
590
|
-
};
|
|
591
|
-
const unsetItemActive = (key) => {
|
|
592
|
-
updateItemState(key);
|
|
593
|
-
};
|
|
594
|
-
const toggleItemActive = (key) => {
|
|
595
|
-
updateItemState(key);
|
|
596
|
-
};
|
|
597
|
-
const unsetAllItemsActive = () => {
|
|
598
|
-
updateAllItemsState(false);
|
|
599
|
-
};
|
|
600
|
-
const isItemActive = (key) => {
|
|
601
|
-
if (!innerActiveItems) return false;
|
|
602
|
-
if (type === "single") return innerActiveItems === key;
|
|
603
|
-
if (type === "multi" && innerActiveItems instanceof Map) return !!innerActiveItems.get(key);
|
|
604
|
-
return false;
|
|
605
|
-
};
|
|
606
|
-
const attachMultipleProps = { unsetAllItemsActive };
|
|
607
|
-
const attachItemProps = (props) => {
|
|
608
|
-
const { key } = props;
|
|
609
|
-
return {
|
|
610
|
-
...typeof itemProps === "object" ? itemProps : itemProps(props),
|
|
611
|
-
active: isItemActive(key),
|
|
612
|
-
handleItemActive: () => handleItemActive(key),
|
|
613
|
-
setItemActive,
|
|
614
|
-
unsetItemActive,
|
|
615
|
-
toggleItemActive,
|
|
616
|
-
...type === "multi" ? attachMultipleProps : {}
|
|
617
|
-
};
|
|
618
|
-
};
|
|
619
|
-
useEffect(() => {
|
|
620
|
-
if (type === "single" && Array.isArray(activeItems)) {
|
|
621
|
-
if (process.env.NODE_ENV !== "production") console.warn("[@vitus-labs/elements] List/withActiveState: `activeItems` was passed as an array but `type` is \"single\". In single selection mode, `activeItems` should be a single key (string | number). The array value will be ignored.");
|
|
622
|
-
}
|
|
623
|
-
}, [type, activeItems]);
|
|
624
|
-
return /* @__PURE__ */ jsx(WrappedComponent, {
|
|
625
|
-
...rest,
|
|
626
|
-
itemProps: attachItemProps
|
|
627
|
-
});
|
|
628
|
-
};
|
|
629
|
-
Enhanced.RESERVED_KEYS = RESERVED_KEYS;
|
|
630
|
-
Enhanced.displayName = `@vitus-labs/elements/List/withActiveState(${displayName})`;
|
|
631
|
-
return Enhanced;
|
|
632
|
-
};
|
|
543
|
+
const name$2 = `${PKG_NAME}/List`;
|
|
544
|
+
Component$2.displayName = name$2;
|
|
545
|
+
Component$2.pkgName = PKG_NAME;
|
|
546
|
+
Component$2.VITUS_LABS__COMPONENT = name$2;
|
|
633
547
|
|
|
634
548
|
//#endregion
|
|
635
549
|
//#region src/List/index.ts
|
|
636
|
-
var List_default = Component$
|
|
637
|
-
|
|
638
|
-
//#endregion
|
|
639
|
-
//#region src/Portal/component.ts
|
|
640
|
-
/**
|
|
641
|
-
* Portal component that creates a new DOM element on mount, appends it to
|
|
642
|
-
* the target location (defaults to document.body), and uses React's
|
|
643
|
-
* createPortal to render children into it. The DOM element is cleaned up
|
|
644
|
-
* on unmount. Accepts a custom DOMLocation for rendering into specific
|
|
645
|
-
* containers (e.g., a modal root).
|
|
646
|
-
*/
|
|
647
|
-
const Component$4 = ({ DOMLocation, tag = "div", children }) => {
|
|
648
|
-
const [element, setElement] = useState();
|
|
649
|
-
useEffect(() => {
|
|
650
|
-
if (!tag) return void 0;
|
|
651
|
-
const position = DOMLocation ?? document.body;
|
|
652
|
-
const element = document.createElement(tag);
|
|
653
|
-
setElement(element);
|
|
654
|
-
position.appendChild(element);
|
|
655
|
-
return () => {
|
|
656
|
-
position.removeChild(element);
|
|
657
|
-
};
|
|
658
|
-
}, [tag, DOMLocation]);
|
|
659
|
-
if (!tag || !element) return null;
|
|
660
|
-
return createPortal(children, element);
|
|
661
|
-
};
|
|
662
|
-
const name$3 = `${PKG_NAME}/Portal`;
|
|
663
|
-
Component$4.displayName = name$3;
|
|
664
|
-
Component$4.pkgName = PKG_NAME;
|
|
665
|
-
Component$4.VITUS_LABS__COMPONENT = name$3;
|
|
666
|
-
|
|
667
|
-
//#endregion
|
|
668
|
-
//#region src/Portal/index.ts
|
|
669
|
-
var Portal_default = Component$4;
|
|
670
|
-
|
|
671
|
-
//#endregion
|
|
672
|
-
//#region src/Overlay/context.tsx
|
|
673
|
-
/**
|
|
674
|
-
* Context for nested overlay coordination. When a child overlay opens, it
|
|
675
|
-
* sets the parent's blocked state to true, preventing the parent from
|
|
676
|
-
* closing in response to click/hover events that belong to the child.
|
|
677
|
-
*/
|
|
678
|
-
const context$1 = createContext({});
|
|
679
|
-
const { Provider: Provider$1 } = context$1;
|
|
680
|
-
const useOverlayContext = () => useContext(context$1);
|
|
681
|
-
const Component = ({ children, blocked, setBlocked, setUnblocked }) => {
|
|
682
|
-
return /* @__PURE__ */ jsx(Provider$1, {
|
|
683
|
-
value: useMemo(() => ({
|
|
684
|
-
blocked,
|
|
685
|
-
setBlocked,
|
|
686
|
-
setUnblocked
|
|
687
|
-
}), [
|
|
688
|
-
blocked,
|
|
689
|
-
setBlocked,
|
|
690
|
-
setUnblocked
|
|
691
|
-
]),
|
|
692
|
-
children
|
|
693
|
-
});
|
|
694
|
-
};
|
|
695
|
-
|
|
696
|
-
//#endregion
|
|
697
|
-
//#region src/Overlay/useOverlay.tsx
|
|
698
|
-
/**
|
|
699
|
-
* Core hook powering the Overlay component. Manages open/close state, DOM
|
|
700
|
-
* event listeners (click, hover, scroll, resize, ESC key), and dynamic
|
|
701
|
-
* positioning of overlay content relative to its trigger. Supports dropdown,
|
|
702
|
-
* tooltip, popover, and modal types with automatic edge-of-viewport flipping.
|
|
703
|
-
* Event handlers are throttled for performance, and nested overlay blocking
|
|
704
|
-
* is coordinated through the overlay context.
|
|
705
|
-
*/
|
|
706
|
-
const sel = (cond, a, b) => cond ? a : b;
|
|
707
|
-
const devWarn = (msg) => {
|
|
708
|
-
if (!IS_DEVELOPMENT) return;
|
|
709
|
-
console.warn(msg);
|
|
710
|
-
};
|
|
711
|
-
const calcDropdownVertical = (c, t, align, alignX, offsetX, offsetY) => {
|
|
712
|
-
const pos = {};
|
|
713
|
-
const topPos = t.top - offsetY - c.height;
|
|
714
|
-
const bottomPos = t.bottom + offsetY;
|
|
715
|
-
const leftPos = t.left + offsetX;
|
|
716
|
-
const rightPos = t.right - offsetX - c.width;
|
|
717
|
-
const fitsTop = topPos >= 0;
|
|
718
|
-
const fitsBottom = bottomPos + c.height <= window.innerHeight;
|
|
719
|
-
const fitsLeft = leftPos + c.width <= window.innerWidth;
|
|
720
|
-
const fitsRight = rightPos >= 0;
|
|
721
|
-
const useTop = sel(align === "top", fitsTop, !fitsBottom);
|
|
722
|
-
pos.top = sel(useTop, topPos, bottomPos);
|
|
723
|
-
const resolvedAlignY = sel(useTop, "top", "bottom");
|
|
724
|
-
let resolvedAlignX = alignX;
|
|
725
|
-
if (alignX === "left") {
|
|
726
|
-
pos.left = sel(fitsLeft, leftPos, rightPos);
|
|
727
|
-
resolvedAlignX = sel(fitsLeft, "left", "right");
|
|
728
|
-
} else if (alignX === "right") {
|
|
729
|
-
pos.left = sel(fitsRight, rightPos, leftPos);
|
|
730
|
-
resolvedAlignX = sel(fitsRight, "right", "left");
|
|
731
|
-
} else {
|
|
732
|
-
const center = t.left + (t.right - t.left) / 2 - c.width / 2;
|
|
733
|
-
const fitsCL = center >= 0;
|
|
734
|
-
const fitsCR = center + c.width <= window.innerWidth;
|
|
735
|
-
if (fitsCL && fitsCR) {
|
|
736
|
-
resolvedAlignX = "center";
|
|
737
|
-
pos.left = center;
|
|
738
|
-
} else if (fitsCL) {
|
|
739
|
-
resolvedAlignX = "left";
|
|
740
|
-
pos.left = leftPos;
|
|
741
|
-
} else if (fitsCR) {
|
|
742
|
-
resolvedAlignX = "right";
|
|
743
|
-
pos.left = rightPos;
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
return {
|
|
747
|
-
pos,
|
|
748
|
-
resolvedAlignX,
|
|
749
|
-
resolvedAlignY
|
|
750
|
-
};
|
|
751
|
-
};
|
|
752
|
-
const calcDropdownHorizontal = (c, t, align, alignY, offsetX, offsetY) => {
|
|
753
|
-
const pos = {};
|
|
754
|
-
const leftPos = t.left - offsetX - c.width;
|
|
755
|
-
const rightPos = t.right + offsetX;
|
|
756
|
-
const topPos = t.top + offsetY;
|
|
757
|
-
const bottomPos = t.bottom - offsetY - c.height;
|
|
758
|
-
const fitsLeft = leftPos >= 0;
|
|
759
|
-
const fitsRight = rightPos + c.width <= window.innerWidth;
|
|
760
|
-
const fitsTop = topPos + c.height <= window.innerHeight;
|
|
761
|
-
const fitsBottom = bottomPos >= 0;
|
|
762
|
-
const useLeft = sel(align === "left", fitsLeft, !fitsRight);
|
|
763
|
-
pos.left = sel(useLeft, leftPos, rightPos);
|
|
764
|
-
const resolvedAlignX = sel(useLeft, "left", "right");
|
|
765
|
-
let resolvedAlignY = alignY;
|
|
766
|
-
if (alignY === "top") {
|
|
767
|
-
pos.top = sel(fitsTop, topPos, bottomPos);
|
|
768
|
-
resolvedAlignY = sel(fitsTop, "top", "bottom");
|
|
769
|
-
} else if (alignY === "bottom") {
|
|
770
|
-
pos.top = sel(fitsBottom, bottomPos, topPos);
|
|
771
|
-
resolvedAlignY = sel(fitsBottom, "bottom", "top");
|
|
772
|
-
} else {
|
|
773
|
-
const center = t.top + (t.bottom - t.top) / 2 - c.height / 2;
|
|
774
|
-
const fitsCT = center >= 0;
|
|
775
|
-
const fitsCB = center + c.height <= window.innerHeight;
|
|
776
|
-
if (fitsCT && fitsCB) {
|
|
777
|
-
resolvedAlignY = "center";
|
|
778
|
-
pos.top = center;
|
|
779
|
-
} else if (fitsCT) {
|
|
780
|
-
resolvedAlignY = "top";
|
|
781
|
-
pos.top = topPos;
|
|
782
|
-
} else if (fitsCB) {
|
|
783
|
-
resolvedAlignY = "bottom";
|
|
784
|
-
pos.top = bottomPos;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
return {
|
|
788
|
-
pos,
|
|
789
|
-
resolvedAlignX,
|
|
790
|
-
resolvedAlignY
|
|
791
|
-
};
|
|
792
|
-
};
|
|
793
|
-
const calcModalPos = (c, alignX, alignY, offsetX, offsetY) => {
|
|
794
|
-
const pos = {};
|
|
795
|
-
switch (alignX) {
|
|
796
|
-
case "right":
|
|
797
|
-
pos.right = offsetX;
|
|
798
|
-
break;
|
|
799
|
-
case "left":
|
|
800
|
-
pos.left = offsetX;
|
|
801
|
-
break;
|
|
802
|
-
case "center":
|
|
803
|
-
pos.left = window.innerWidth / 2 - c.width / 2;
|
|
804
|
-
break;
|
|
805
|
-
default: pos.right = offsetX;
|
|
806
|
-
}
|
|
807
|
-
switch (alignY) {
|
|
808
|
-
case "top":
|
|
809
|
-
pos.top = offsetY;
|
|
810
|
-
break;
|
|
811
|
-
case "center":
|
|
812
|
-
pos.top = window.innerHeight / 2 - c.height / 2;
|
|
813
|
-
break;
|
|
814
|
-
case "bottom":
|
|
815
|
-
pos.bottom = offsetY;
|
|
816
|
-
break;
|
|
817
|
-
default: pos.top = offsetY;
|
|
818
|
-
}
|
|
819
|
-
return pos;
|
|
820
|
-
};
|
|
821
|
-
const adjustForAncestor = (pos, ancestor) => {
|
|
822
|
-
if (ancestor.top === 0 && ancestor.left === 0) return pos;
|
|
823
|
-
const result = { ...pos };
|
|
824
|
-
if (typeof result.top === "number") result.top -= ancestor.top;
|
|
825
|
-
if (typeof result.bottom === "number") result.bottom += ancestor.top;
|
|
826
|
-
if (typeof result.left === "number") result.left -= ancestor.left;
|
|
827
|
-
if (typeof result.right === "number") result.right += ancestor.left;
|
|
828
|
-
return result;
|
|
829
|
-
};
|
|
830
|
-
const computePosition = (type, align, alignX, alignY, offsetX, offsetY, triggerEl, contentEl, ancestorOffset) => {
|
|
831
|
-
const isDropdown = [
|
|
832
|
-
"dropdown",
|
|
833
|
-
"tooltip",
|
|
834
|
-
"popover"
|
|
835
|
-
].includes(type);
|
|
836
|
-
if (isDropdown && (!triggerEl || !contentEl)) {
|
|
837
|
-
devWarn(`[@vitus-labs/elements] Overlay (${type}): ${triggerEl ? "contentRef" : "triggerRef"} is not attached. Position cannot be calculated without both refs.`);
|
|
838
|
-
return { pos: {} };
|
|
839
|
-
}
|
|
840
|
-
if (isDropdown && triggerEl && contentEl) {
|
|
841
|
-
const c = contentEl.getBoundingClientRect();
|
|
842
|
-
const t = triggerEl.getBoundingClientRect();
|
|
843
|
-
const result = align === "top" || align === "bottom" ? calcDropdownVertical(c, t, align, alignX, offsetX, offsetY) : calcDropdownHorizontal(c, t, align, alignY, offsetX, offsetY);
|
|
844
|
-
return {
|
|
845
|
-
pos: adjustForAncestor(result.pos, ancestorOffset),
|
|
846
|
-
resolvedAlignX: result.resolvedAlignX,
|
|
847
|
-
resolvedAlignY: result.resolvedAlignY
|
|
848
|
-
};
|
|
849
|
-
}
|
|
850
|
-
if (type === "modal") {
|
|
851
|
-
if (!contentEl) {
|
|
852
|
-
devWarn("[@vitus-labs/elements] Overlay (modal): contentRef is not attached. Modal position cannot be calculated without a content element.");
|
|
853
|
-
return { pos: {} };
|
|
854
|
-
}
|
|
855
|
-
return { pos: adjustForAncestor(calcModalPos(contentEl.getBoundingClientRect(), alignX, alignY, offsetX, offsetY), ancestorOffset) };
|
|
856
|
-
}
|
|
857
|
-
return { pos: {} };
|
|
858
|
-
};
|
|
859
|
-
const processVisibilityEvent = (e, active, openOn, closeOn, isTrigger, isContent, showContent, hideContent) => {
|
|
860
|
-
if (!active && openOn === "click" && e.type === "click" && isTrigger(e)) {
|
|
861
|
-
showContent();
|
|
862
|
-
return;
|
|
863
|
-
}
|
|
864
|
-
if (!active) return;
|
|
865
|
-
if (closeOn === "hover" && e.type === "scroll") {
|
|
866
|
-
hideContent();
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
if (e.type !== "click") return;
|
|
870
|
-
if (closeOn === "click") hideContent();
|
|
871
|
-
else if (closeOn === "clickOnTrigger" && isTrigger(e)) hideContent();
|
|
872
|
-
else if (closeOn === "clickOutsideContent" && !isContent(e)) hideContent();
|
|
873
|
-
};
|
|
874
|
-
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, disabled, onOpen, onClose } = {}) => {
|
|
875
|
-
const { rootSize } = useContext(context);
|
|
876
|
-
const ctx = useOverlayContext();
|
|
877
|
-
const [isContentLoaded, setContentLoaded] = useState(false);
|
|
878
|
-
const [innerAlignX, setInnerAlignX] = useState(alignX);
|
|
879
|
-
const [innerAlignY, setInnerAlignY] = useState(alignY);
|
|
880
|
-
const [blocked, handleBlocked] = useState(false);
|
|
881
|
-
const [active, handleActive] = useState(isOpen);
|
|
882
|
-
const triggerRef = useRef(null);
|
|
883
|
-
const contentRef = useRef(null);
|
|
884
|
-
const setBlocked = useCallback(() => handleBlocked(true), []);
|
|
885
|
-
const setUnblocked = useCallback(() => handleBlocked(false), []);
|
|
886
|
-
const showContent = useCallback(() => {
|
|
887
|
-
handleActive(true);
|
|
888
|
-
}, []);
|
|
889
|
-
const hideContent = useCallback(() => {
|
|
890
|
-
handleActive(false);
|
|
891
|
-
}, []);
|
|
892
|
-
const getAncestorOffset = useCallback(() => {
|
|
893
|
-
if (position !== "absolute" || !contentRef.current) return {
|
|
894
|
-
top: 0,
|
|
895
|
-
left: 0
|
|
896
|
-
};
|
|
897
|
-
const offsetParent = contentRef.current.offsetParent;
|
|
898
|
-
if (!offsetParent || offsetParent === document.body) return {
|
|
899
|
-
top: 0,
|
|
900
|
-
left: 0
|
|
901
|
-
};
|
|
902
|
-
const rect = offsetParent.getBoundingClientRect();
|
|
903
|
-
return {
|
|
904
|
-
top: rect.top,
|
|
905
|
-
left: rect.left
|
|
906
|
-
};
|
|
907
|
-
}, [position]);
|
|
908
|
-
const calculateContentPosition = useCallback(() => {
|
|
909
|
-
if (!active || !isContentLoaded) return {};
|
|
910
|
-
const result = computePosition(type, align, alignX, alignY, offsetX, offsetY, triggerRef.current, contentRef.current, getAncestorOffset());
|
|
911
|
-
if (result.resolvedAlignX) setInnerAlignX(result.resolvedAlignX);
|
|
912
|
-
if (result.resolvedAlignY) setInnerAlignY(result.resolvedAlignY);
|
|
913
|
-
return result.pos;
|
|
914
|
-
}, [
|
|
915
|
-
isContentLoaded,
|
|
916
|
-
active,
|
|
917
|
-
align,
|
|
918
|
-
alignX,
|
|
919
|
-
alignY,
|
|
920
|
-
offsetX,
|
|
921
|
-
offsetY,
|
|
922
|
-
type,
|
|
923
|
-
getAncestorOffset
|
|
924
|
-
]);
|
|
925
|
-
const assignContentPosition = useCallback((values = {}) => {
|
|
926
|
-
if (!contentRef.current) return;
|
|
927
|
-
const el = contentRef.current;
|
|
928
|
-
const setValue = (param) => value(param, rootSize);
|
|
929
|
-
el.style.position = position;
|
|
930
|
-
el.style.top = values.top != null ? setValue(values.top) : "";
|
|
931
|
-
el.style.bottom = values.bottom != null ? setValue(values.bottom) : "";
|
|
932
|
-
el.style.left = values.left != null ? setValue(values.left) : "";
|
|
933
|
-
el.style.right = values.right != null ? setValue(values.right) : "";
|
|
934
|
-
}, [position, rootSize]);
|
|
935
|
-
const setContentPosition = useCallback(() => {
|
|
936
|
-
assignContentPosition(calculateContentPosition());
|
|
937
|
-
}, [assignContentPosition, calculateContentPosition]);
|
|
938
|
-
const isNodeOrChild = useCallback((ref) => (e) => {
|
|
939
|
-
if (e?.target && ref.current) return ref.current.contains(e.target) || e.target === ref.current;
|
|
940
|
-
return false;
|
|
941
|
-
}, []);
|
|
942
|
-
const handleVisibilityByEventType = useCallback((e) => {
|
|
943
|
-
if (blocked || disabled) return;
|
|
944
|
-
processVisibilityEvent(e, active, openOn, closeOn, isNodeOrChild(triggerRef), isNodeOrChild(contentRef), showContent, hideContent);
|
|
945
|
-
}, [
|
|
946
|
-
active,
|
|
947
|
-
blocked,
|
|
948
|
-
disabled,
|
|
949
|
-
openOn,
|
|
950
|
-
closeOn,
|
|
951
|
-
hideContent,
|
|
952
|
-
showContent,
|
|
953
|
-
isNodeOrChild
|
|
954
|
-
]);
|
|
955
|
-
const latestSetContentPosition = useRef(setContentPosition);
|
|
956
|
-
latestSetContentPosition.current = setContentPosition;
|
|
957
|
-
const latestHandleVisibility = useRef(handleVisibilityByEventType);
|
|
958
|
-
latestHandleVisibility.current = handleVisibilityByEventType;
|
|
959
|
-
const handleContentPosition = useMemo(() => throttle(() => latestSetContentPosition.current(), throttleDelay), [throttleDelay]);
|
|
960
|
-
const handleClick = handleVisibilityByEventType;
|
|
961
|
-
const handleVisibility = useMemo(() => throttle((e) => latestHandleVisibility.current(e), throttleDelay), [throttleDelay]);
|
|
962
|
-
useEffect(() => {
|
|
963
|
-
setInnerAlignX(alignX);
|
|
964
|
-
setInnerAlignY(alignY);
|
|
965
|
-
if (disabled) hideContent();
|
|
966
|
-
}, [
|
|
967
|
-
disabled,
|
|
968
|
-
alignX,
|
|
969
|
-
alignY,
|
|
970
|
-
hideContent
|
|
971
|
-
]);
|
|
972
|
-
useEffect(() => {
|
|
973
|
-
if (!active || !isContentLoaded) return void 0;
|
|
974
|
-
setContentPosition();
|
|
975
|
-
const rafId = requestAnimationFrame(() => setContentPosition());
|
|
976
|
-
return () => cancelAnimationFrame(rafId);
|
|
977
|
-
}, [
|
|
978
|
-
active,
|
|
979
|
-
isContentLoaded,
|
|
980
|
-
setContentPosition
|
|
981
|
-
]);
|
|
982
|
-
const prevActiveRef = useRef(false);
|
|
983
|
-
useEffect(() => {
|
|
984
|
-
const wasActive = prevActiveRef.current;
|
|
985
|
-
prevActiveRef.current = active;
|
|
986
|
-
if (active && !wasActive) {
|
|
987
|
-
onOpen?.();
|
|
988
|
-
ctx.setBlocked?.();
|
|
989
|
-
} else if (!active && wasActive) {
|
|
990
|
-
setContentLoaded(false);
|
|
991
|
-
onClose?.();
|
|
992
|
-
ctx.setUnblocked?.();
|
|
993
|
-
} else if (!active) setContentLoaded(false);
|
|
994
|
-
return () => {
|
|
995
|
-
if (active) {
|
|
996
|
-
onClose?.();
|
|
997
|
-
ctx.setUnblocked?.();
|
|
998
|
-
}
|
|
999
|
-
};
|
|
1000
|
-
}, [
|
|
1001
|
-
active,
|
|
1002
|
-
ctx,
|
|
1003
|
-
onClose,
|
|
1004
|
-
onOpen
|
|
1005
|
-
]);
|
|
1006
|
-
useEffect(() => {
|
|
1007
|
-
if (!closeOnEsc || !active || blocked) return void 0;
|
|
1008
|
-
const handleEscKey = (e) => {
|
|
1009
|
-
if (e.key === "Escape") hideContent();
|
|
1010
|
-
};
|
|
1011
|
-
window.addEventListener("keydown", handleEscKey);
|
|
1012
|
-
return () => {
|
|
1013
|
-
window.removeEventListener("keydown", handleEscKey);
|
|
1014
|
-
};
|
|
1015
|
-
}, [
|
|
1016
|
-
active,
|
|
1017
|
-
blocked,
|
|
1018
|
-
closeOnEsc,
|
|
1019
|
-
hideContent
|
|
1020
|
-
]);
|
|
1021
|
-
useEffect(() => {
|
|
1022
|
-
if (!active) return void 0;
|
|
1023
|
-
const shouldSetOverflow = type === "modal";
|
|
1024
|
-
const onScroll = (e) => {
|
|
1025
|
-
handleContentPosition();
|
|
1026
|
-
handleVisibility(e);
|
|
1027
|
-
};
|
|
1028
|
-
if (shouldSetOverflow) document.body.style.overflow = "hidden";
|
|
1029
|
-
window.addEventListener("resize", handleContentPosition);
|
|
1030
|
-
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1031
|
-
return () => {
|
|
1032
|
-
if (shouldSetOverflow) document.body.style.overflow = "";
|
|
1033
|
-
window.removeEventListener("resize", handleContentPosition);
|
|
1034
|
-
window.removeEventListener("scroll", onScroll);
|
|
1035
|
-
};
|
|
1036
|
-
}, [
|
|
1037
|
-
active,
|
|
1038
|
-
type,
|
|
1039
|
-
handleVisibility,
|
|
1040
|
-
handleContentPosition
|
|
1041
|
-
]);
|
|
1042
|
-
useEffect(() => {
|
|
1043
|
-
if (!active || !parentContainer) return void 0;
|
|
1044
|
-
if (closeOn !== "hover") parentContainer.style.overflow = "hidden";
|
|
1045
|
-
const onScroll = (e) => {
|
|
1046
|
-
handleContentPosition();
|
|
1047
|
-
handleVisibility(e);
|
|
1048
|
-
};
|
|
1049
|
-
parentContainer.addEventListener("scroll", onScroll, { passive: true });
|
|
1050
|
-
return () => {
|
|
1051
|
-
parentContainer.style.overflow = "";
|
|
1052
|
-
parentContainer.removeEventListener("scroll", onScroll);
|
|
1053
|
-
};
|
|
1054
|
-
}, [
|
|
1055
|
-
active,
|
|
1056
|
-
parentContainer,
|
|
1057
|
-
closeOn,
|
|
1058
|
-
handleContentPosition,
|
|
1059
|
-
handleVisibility
|
|
1060
|
-
]);
|
|
1061
|
-
useEffect(() => {
|
|
1062
|
-
if (blocked || disabled) return void 0;
|
|
1063
|
-
if (openOn === "click" || [
|
|
1064
|
-
"click",
|
|
1065
|
-
"clickOnTrigger",
|
|
1066
|
-
"clickOutsideContent"
|
|
1067
|
-
].includes(closeOn)) window.addEventListener("click", handleClick);
|
|
1068
|
-
return () => {
|
|
1069
|
-
window.removeEventListener("click", handleClick);
|
|
1070
|
-
};
|
|
1071
|
-
}, [
|
|
1072
|
-
openOn,
|
|
1073
|
-
closeOn,
|
|
1074
|
-
blocked,
|
|
1075
|
-
disabled,
|
|
1076
|
-
handleClick
|
|
1077
|
-
]);
|
|
1078
|
-
const hoverTimeoutRef = useRef(null);
|
|
1079
|
-
useEffect(() => {
|
|
1080
|
-
if (blocked || disabled || !(openOn === "hover" || closeOn === "hover")) return void 0;
|
|
1081
|
-
const trigger = triggerRef.current;
|
|
1082
|
-
const content = contentRef.current;
|
|
1083
|
-
const clearHoverTimeout = () => {
|
|
1084
|
-
if (hoverTimeoutRef.current != null) {
|
|
1085
|
-
clearTimeout(hoverTimeoutRef.current);
|
|
1086
|
-
hoverTimeoutRef.current = null;
|
|
1087
|
-
}
|
|
1088
|
-
};
|
|
1089
|
-
const scheduleHide = () => {
|
|
1090
|
-
clearHoverTimeout();
|
|
1091
|
-
hoverTimeoutRef.current = setTimeout(hideContent, 100);
|
|
1092
|
-
};
|
|
1093
|
-
const onTriggerEnter = () => {
|
|
1094
|
-
clearHoverTimeout();
|
|
1095
|
-
if (openOn === "hover" && !active) showContent();
|
|
1096
|
-
};
|
|
1097
|
-
const onTriggerLeave = () => {
|
|
1098
|
-
if (closeOn === "hover" && active) scheduleHide();
|
|
1099
|
-
};
|
|
1100
|
-
const onContentEnter = () => {
|
|
1101
|
-
clearHoverTimeout();
|
|
1102
|
-
};
|
|
1103
|
-
const onContentLeave = () => {
|
|
1104
|
-
if (closeOn === "hover" && active) scheduleHide();
|
|
1105
|
-
};
|
|
1106
|
-
if (trigger) {
|
|
1107
|
-
trigger.addEventListener("mouseenter", onTriggerEnter);
|
|
1108
|
-
trigger.addEventListener("mouseleave", onTriggerLeave);
|
|
1109
|
-
}
|
|
1110
|
-
if (content) {
|
|
1111
|
-
content.addEventListener("mouseenter", onContentEnter);
|
|
1112
|
-
content.addEventListener("mouseleave", onContentLeave);
|
|
1113
|
-
}
|
|
1114
|
-
return () => {
|
|
1115
|
-
clearHoverTimeout();
|
|
1116
|
-
if (trigger) {
|
|
1117
|
-
trigger.removeEventListener("mouseenter", onTriggerEnter);
|
|
1118
|
-
trigger.removeEventListener("mouseleave", onTriggerLeave);
|
|
1119
|
-
}
|
|
1120
|
-
if (content) {
|
|
1121
|
-
content.removeEventListener("mouseenter", onContentEnter);
|
|
1122
|
-
content.removeEventListener("mouseleave", onContentLeave);
|
|
1123
|
-
}
|
|
1124
|
-
};
|
|
1125
|
-
}, [
|
|
1126
|
-
active,
|
|
1127
|
-
isContentLoaded,
|
|
1128
|
-
blocked,
|
|
1129
|
-
disabled,
|
|
1130
|
-
openOn,
|
|
1131
|
-
closeOn,
|
|
1132
|
-
showContent,
|
|
1133
|
-
hideContent
|
|
1134
|
-
]);
|
|
1135
|
-
return {
|
|
1136
|
-
triggerRef,
|
|
1137
|
-
contentRef: useCallback((node) => {
|
|
1138
|
-
if (node) {
|
|
1139
|
-
contentRef.current = node;
|
|
1140
|
-
setContentLoaded(true);
|
|
1141
|
-
}
|
|
1142
|
-
}, []),
|
|
1143
|
-
active,
|
|
1144
|
-
align,
|
|
1145
|
-
alignX: innerAlignX,
|
|
1146
|
-
alignY: innerAlignY,
|
|
1147
|
-
showContent,
|
|
1148
|
-
hideContent,
|
|
1149
|
-
blocked,
|
|
1150
|
-
setBlocked,
|
|
1151
|
-
setUnblocked,
|
|
1152
|
-
Provider: Component
|
|
1153
|
-
};
|
|
1154
|
-
};
|
|
1155
|
-
|
|
1156
|
-
//#endregion
|
|
1157
|
-
//#region src/Overlay/component.tsx
|
|
1158
|
-
/**
|
|
1159
|
-
* Overlay component that renders a trigger element and conditionally shows
|
|
1160
|
-
* content via a Portal. The trigger receives a ref and optional show/hide
|
|
1161
|
-
* callbacks; the content is positioned and managed by the useOverlay hook.
|
|
1162
|
-
* A context Provider wraps the content to support nested overlays (e.g.,
|
|
1163
|
-
* a dropdown inside another dropdown) via blocked-state propagation.
|
|
1164
|
-
*/
|
|
1165
|
-
const IS_BROWSER = typeof window !== "undefined";
|
|
1166
|
-
const Component$3 = ({ children, trigger, DOMLocation, triggerRefName = "ref", contentRefName = "ref", ...props }) => {
|
|
1167
|
-
const { active, triggerRef, contentRef, showContent, hideContent, align, alignX, alignY, Provider, ...ctx } = useOverlay(props);
|
|
1168
|
-
const { openOn, closeOn } = props;
|
|
1169
|
-
const passHandlers = useMemo(() => openOn === "manual" || closeOn === "manual" || closeOn === "clickOutsideContent", [openOn, closeOn]);
|
|
1170
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [render(trigger, {
|
|
1171
|
-
[triggerRefName]: triggerRef,
|
|
1172
|
-
active,
|
|
1173
|
-
...passHandlers ? {
|
|
1174
|
-
showContent,
|
|
1175
|
-
hideContent
|
|
1176
|
-
} : {}
|
|
1177
|
-
}), IS_BROWSER && active && /* @__PURE__ */ jsx(Portal_default, {
|
|
1178
|
-
DOMLocation,
|
|
1179
|
-
children: /* @__PURE__ */ jsx(Provider, {
|
|
1180
|
-
...ctx,
|
|
1181
|
-
children: render(children, {
|
|
1182
|
-
[contentRefName]: contentRef,
|
|
1183
|
-
active,
|
|
1184
|
-
align,
|
|
1185
|
-
alignX,
|
|
1186
|
-
alignY,
|
|
1187
|
-
...passHandlers ? {
|
|
1188
|
-
showContent,
|
|
1189
|
-
hideContent
|
|
1190
|
-
} : {}
|
|
1191
|
-
})
|
|
1192
|
-
})
|
|
1193
|
-
})] });
|
|
1194
|
-
};
|
|
1195
|
-
const name$2 = `${PKG_NAME}/Overlay`;
|
|
1196
|
-
Component$3.displayName = name$2;
|
|
1197
|
-
Component$3.pkgName = PKG_NAME;
|
|
1198
|
-
Component$3.VITUS_LABS__COMPONENT = name$2;
|
|
1199
|
-
|
|
1200
|
-
//#endregion
|
|
1201
|
-
//#region src/Overlay/index.ts
|
|
1202
|
-
var Overlay_default = Component$3;
|
|
550
|
+
var List_default = Component$2;
|
|
1203
551
|
|
|
1204
552
|
//#endregion
|
|
1205
553
|
//#region src/Text/styled.ts
|
|
@@ -1214,9 +562,7 @@ const styles = ({ css, theme: t }) => css`
|
|
|
1214
562
|
${t.extraStyles && extendCss(t.extraStyles)};
|
|
1215
563
|
`;
|
|
1216
564
|
var styled_default = styled(textComponent)`
|
|
1217
|
-
|
|
1218
|
-
font-weight: inherit;
|
|
1219
|
-
line-height: 1;
|
|
565
|
+
${false};
|
|
1220
566
|
|
|
1221
567
|
${makeItResponsive({
|
|
1222
568
|
key: "$text",
|
|
@@ -1228,7 +574,7 @@ var styled_default = styled(textComponent)`
|
|
|
1228
574
|
|
|
1229
575
|
//#endregion
|
|
1230
576
|
//#region src/Text/component.tsx
|
|
1231
|
-
const Component$
|
|
577
|
+
const Component$1 = forwardRef(({ paragraph, label, children, tag, css, ...props }, ref) => {
|
|
1232
578
|
const renderContent = (as = void 0) => /* @__PURE__ */ jsx(styled_default, {
|
|
1233
579
|
ref,
|
|
1234
580
|
as,
|
|
@@ -1240,14 +586,14 @@ const Component$2 = forwardRef(({ paragraph, label, children, tag, css, ...props
|
|
|
1240
586
|
return renderContent(finalTag);
|
|
1241
587
|
});
|
|
1242
588
|
const name$1 = `${PKG_NAME}/Text`;
|
|
1243
|
-
Component$
|
|
1244
|
-
Component$
|
|
1245
|
-
Component$
|
|
1246
|
-
Component$
|
|
589
|
+
Component$1.displayName = name$1;
|
|
590
|
+
Component$1.pkgName = PKG_NAME;
|
|
591
|
+
Component$1.VITUS_LABS__COMPONENT = name$1;
|
|
592
|
+
Component$1.isText = true;
|
|
1247
593
|
|
|
1248
594
|
//#endregion
|
|
1249
595
|
//#region src/Text/index.ts
|
|
1250
|
-
var Text_default = Component$
|
|
596
|
+
var Text_default = Component$1;
|
|
1251
597
|
|
|
1252
598
|
//#endregion
|
|
1253
599
|
//#region src/Util/component.tsx
|
|
@@ -1256,7 +602,7 @@ var Text_default = Component$2;
|
|
|
1256
602
|
* children without adding any DOM nodes of its own. Uses the core `render`
|
|
1257
603
|
* helper to clone children with the merged props.
|
|
1258
604
|
*/
|
|
1259
|
-
const Component
|
|
605
|
+
const Component = ({ children, className, style }) => {
|
|
1260
606
|
const mergedClasses = useMemo(() => Array.isArray(className) ? className.join(" ") : className, [className]);
|
|
1261
607
|
const finalProps = {};
|
|
1262
608
|
if (style) finalProps.style = style;
|
|
@@ -1264,14 +610,14 @@ const Component$1 = ({ children, className, style }) => {
|
|
|
1264
610
|
return render(children, finalProps);
|
|
1265
611
|
};
|
|
1266
612
|
const name = `${PKG_NAME}/Util`;
|
|
1267
|
-
Component
|
|
1268
|
-
Component
|
|
1269
|
-
Component
|
|
613
|
+
Component.displayName = name;
|
|
614
|
+
Component.pkgName = PKG_NAME;
|
|
615
|
+
Component.VITUS_LABS__COMPONENT = name;
|
|
1270
616
|
|
|
1271
617
|
//#endregion
|
|
1272
618
|
//#region src/Util/index.ts
|
|
1273
|
-
var Util_default = Component
|
|
619
|
+
var Util_default = Component;
|
|
1274
620
|
|
|
1275
621
|
//#endregion
|
|
1276
|
-
export { Element_default as Element, List_default as List,
|
|
622
|
+
export { Element_default as Element, List_default as List, Provider, Text_default as Text, Util_default as Util };
|
|
1277
623
|
//# sourceMappingURL=vitus-labs-elements.native.js.map
|