@vitus-labs/elements 2.0.0-alpha.2 → 2.0.0-alpha.20

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 CHANGED
@@ -1,8 +1,7 @@
1
1
  import { Provider } from "@vitus-labs/unistyle";
2
2
  import { BreakpointKeys, HTMLTags, HTMLTextTags, config, render } from "@vitus-labs/core";
3
3
  import * as react from "react";
4
- import { ComponentType, FC, ForwardRefExoticComponent, ForwardedRef, PropsWithoutRef, ReactNode, Ref, RefAttributes } from "react";
5
- import * as react_jsx_runtime0 from "react/jsx-runtime";
4
+ import { ComponentType, FC, ForwardRefExoticComponent, ForwardedRef, PropsWithoutRef, ReactNode, RefAttributes } from "react";
6
5
 
7
6
  //#region src/types.d.ts
8
7
  type ExtractNullableKeys<T> = { [P in keyof T as T[P] extends null | undefined ? never : P]: T[P] };
@@ -10,7 +9,6 @@ type Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;
10
9
  type SpreadTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & R>;
11
10
  type Spread<A extends readonly [...any]> = A extends [infer L, ...infer R] ? SpreadTwo<L, Spread<R>> : unknown;
12
11
  type MergeTypes<A extends readonly [...any]> = ExtractNullableKeys<Spread<A>>;
13
- type SimpleHoc<P extends Record<string, unknown> = {}> = (WrappedComponent: ComponentType<P>) => ComponentType<P>;
14
12
  type InnerRef = ForwardedRef<any>;
15
13
  type CssCallback = (css: typeof config.css) => ReturnType<typeof css>;
16
14
  type Css = CssCallback | ReturnType<typeof config.css> | string;
@@ -109,6 +107,14 @@ type Props = Partial<{
109
107
  * (have the same width or height)
110
108
  */
111
109
  equalCols: ResponsiveBoolType;
110
+ /**
111
+ * When true, measures the `beforeContent` and `afterContent` slot wrappers
112
+ * after render and sets both to the larger dimension so they match.
113
+ * Uses width for inline direction and height for rows direction.
114
+ * Useful for centering the main content when before/after slots have
115
+ * different intrinsic sizes.
116
+ */
117
+ equalBeforeAfter: boolean;
112
118
  /**
113
119
  * Defines a `gap` spacing between inner wrappers between `beforeContent` and `children`
114
120
  * and `children` and `afterContent`
@@ -270,195 +276,18 @@ type Props = Partial<{
270
276
  */
271
277
  css: ExtendCss;
272
278
  /**
273
- * An additional prop for extending styling of the **content** wrapper element
274
- *
275
- * #### [A] Template literals
276
- *
277
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
278
- *
279
- * ```jsx
280
- * export default () => (
281
- * <Element
282
- * label="This is an element"
283
- * css={`
284
- * text-color: red;
285
- * `}
286
- * />
287
- * )
288
- * ```
289
- *
290
- * #### [B] String
291
- *
292
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
293
- *
294
- * ```jsx
295
- * export default () => (
296
- * <Element
297
- * label="This is an element"
298
- * css="text-color: red;"
299
- * />
300
- * )
301
- * ```
302
- *
303
- * #### [C] Css Function
304
- *
305
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
306
- *
307
- * ```jsx
308
- * import { css } from 'styled-components'
309
- *
310
- * export default () => (
311
- * <Element
312
- * label="This is an element"
313
- * css={css`
314
- * text-color: red;
315
- * `}
316
- * />
317
- * )
318
- * ```
319
- *
320
- * #### [D] Css Callback
321
- *
322
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
323
- *
324
- * ```jsx
325
- * export default () => (
326
- * <Element
327
- * label="This is an element"
328
- * css={css => css`
329
- * text-color: red;
330
- * `}
331
- * />
332
- * )
333
- * ```
279
+ * An additional prop for extending styling of the **content** wrapper element.
280
+ * Accepts the same formats as `css` — template literal, string, css function, or callback.
334
281
  */
335
282
  contentCss: ExtendCss;
336
283
  /**
337
- * An additional prop for extending styling of the **beforeContent** wrapper element
338
- *
339
- * #### [A] Template literals
340
- *
341
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
342
- *
343
- * ```jsx
344
- * export default () => (
345
- * <Element
346
- * label="This is an element"
347
- * css={`
348
- * text-color: red;
349
- * `}
350
- * />
351
- * )
352
- * ```
353
- *
354
- * #### [B] String
355
- *
356
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
357
- *
358
- * ```jsx
359
- * export default () => (
360
- * <Element
361
- * label="This is an element"
362
- * css="text-color: red;"
363
- * />
364
- * )
365
- * ```
366
- *
367
- * #### [C] Css Function
368
- *
369
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
370
- *
371
- * ```jsx
372
- * import { css } from 'styled-components'
373
- *
374
- * export default () => (
375
- * <Element
376
- * label="This is an element"
377
- * css={css`
378
- * text-color: red;
379
- * `}
380
- * />
381
- * )
382
- * ```
383
- *
384
- * #### [D] Css Callback
385
- *
386
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
387
- *
388
- * ```jsx
389
- * export default () => (
390
- * <Element
391
- * label="This is an element"
392
- * css={css => css`
393
- * text-color: red;
394
- * `}
395
- * />
396
- * )
397
- * ```
284
+ * An additional prop for extending styling of the **beforeContent** wrapper element.
285
+ * Accepts the same formats as `css` — template literal, string, css function, or callback.
398
286
  */
399
287
  beforeContentCss: ExtendCss;
400
288
  /**
401
- * An additional prop for extending styling of the **afterContent** wrapper element
402
- *
403
- * #### [A] Template literals
404
- *
405
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
406
- *
407
- * ```jsx
408
- * export default () => (
409
- * <Element
410
- * label="This is an element"
411
- * css={`
412
- * text-color: red;
413
- * `}
414
- * />
415
- * )
416
- * ```
417
- *
418
- * #### [B] String
419
- *
420
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
421
- *
422
- * ```jsx
423
- * export default () => (
424
- * <Element
425
- * label="This is an element"
426
- * css="text-color: red;"
427
- * />
428
- * )
429
- * ```
430
- *
431
- * #### [C] Css Function
432
- *
433
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
434
- *
435
- * ```jsx
436
- * import { css } from 'styled-components'
437
- *
438
- * export default () => (
439
- * <Element
440
- * label="This is an element"
441
- * css={css`
442
- * text-color: red;
443
- * `}
444
- * />
445
- * )
446
- * ```
447
- *
448
- * #### [D] Css Callback
449
- *
450
- * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
451
- *
452
- * ```jsx
453
- * export default () => (
454
- * <Element
455
- * label="This is an element"
456
- * css={css => css`
457
- * text-color: red;
458
- * `}
459
- * />
460
- * )
461
- * ```
289
+ * An additional prop for extending styling of the **afterContent** wrapper element.
290
+ * Accepts the same formats as `css` — template literal, string, css function, or callback.
462
291
  */
463
292
  afterContentCss: ExtendCss;
464
293
  }>;
@@ -467,23 +296,6 @@ type VLElement<P extends Record<string, unknown> = {}> = ForwardRefExoticCompone
467
296
  //#region src/Element/component.d.ts
468
297
  declare const Component: VLElement;
469
298
  //#endregion
470
- //#region src/Element/withEqualSizeBeforeAfter.d.ts
471
- type Props$8 = Props & Partial<{
472
- equalBeforeAfter: boolean;
473
- ref: Ref<HTMLElement>;
474
- }>;
475
- declare const withEqualBeforeAfter: (WrappedComponent: any) => {
476
- ({
477
- equalBeforeAfter,
478
- direction,
479
- afterContent,
480
- beforeContent,
481
- ref,
482
- ...rest
483
- }: Props$8): react_jsx_runtime0.JSX.Element;
484
- displayName: string;
485
- };
486
- //#endregion
487
299
  //#region src/helpers/Iterator/types.d.ts
488
300
  type MaybeNull = undefined | null;
489
301
  type TObj = Record<string, unknown>;
@@ -563,16 +375,6 @@ type ListProps = {
563
375
  type Props$2 = MergeTypes<[Props$1, ListProps]>;
564
376
  declare const Component$1: VLElement<Props$2>;
565
377
  //#endregion
566
- //#region src/List/withActiveState.d.ts
567
- type Key = string | number;
568
- interface Props$7 {
569
- type?: 'single' | 'multi';
570
- activeItemRequired?: boolean;
571
- activeItems?: Key | (string | number)[];
572
- itemProps?: Record<string, unknown> | ((props: Record<string, unknown>) => Record<string, unknown>);
573
- }
574
- declare const component: SimpleHoc<Props$7>;
575
- //#endregion
576
378
  //#region src/Overlay/context.d.ts
577
379
  interface Context {
578
380
  blocked: boolean;
@@ -820,5 +622,5 @@ interface Props$6 {
820
622
  }
821
623
  declare const Component$6: VLComponent<Props$6>;
822
624
  //#endregion
823
- export { type AlignX, type AlignY, type Content, type ContentBoolean, type Direction, Component as Element, type Props as ElementProps, type ElementType, type ExtendCss, type ExtendedProps, type InnerRef, type Props$1 as IteratorProps, Component$1 as List, type Props$2 as ListProps, type ObjectValue, Component$2 as Overlay, type Props$3 as OverlayProps, Component$3 as OverlayProvider, Component$4 as Portal, type Props$4 as PortalProps, type PropsCallback, Provider, type Responsive, type ResponsiveBoolType, Component$5 as Text, type Props$5 as TextProps, type UseOverlayProps, Component$6 as Util, type Props$6 as UtilProps, type VLStatic, useOverlay, component as withActiveState, withEqualBeforeAfter as withEqualSizeBeforeAfter };
625
+ export { type AlignX, type AlignY, type Content, type ContentBoolean, type Direction, Component as Element, type Props as ElementProps, type ElementType, type ExtendCss, type ExtendedProps, type InnerRef, type Props$1 as IteratorProps, Component$1 as List, type Props$2 as ListProps, type ObjectValue, Component$2 as Overlay, type Props$3 as OverlayProps, Component$3 as OverlayProvider, Component$4 as Portal, type Props$4 as PortalProps, type PropsCallback, Provider, type Responsive, type ResponsiveBoolType, Component$5 as Text, type Props$5 as TextProps, type UseOverlayProps, Component$6 as Util, type Props$6 as UtilProps, type VLStatic, useOverlay };
824
626
  //# sourceMappingURL=index2.d.ts.map
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Provider, alignContent, extendCss, makeItResponsive, value } from "@vitus-labs/unistyle";
2
2
  import { config, context, isEmpty, omit, pick, render, throttle } from "@vitus-labs/core";
3
- import { Children, createContext, forwardRef, memo, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import { Children, createContext, forwardRef, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { isFragment } from "react-is";
6
6
  import { createPortal } from "react-dom";
@@ -21,7 +21,7 @@ const IS_DEVELOPMENT = process.env.NODE_ENV !== "production";
21
21
  * equalCols flex distribution. The "content" slot gets `flex: 1` to
22
22
  * fill remaining space between before and after.
23
23
  */
24
- const { styled: styled$2, css: css$2, component: component$2 } = config;
24
+ const { styled: styled$2, css: css$2, component: component$1 } = config;
25
25
  const equalColsCSS = `
26
26
  flex: 1;
27
27
  `;
@@ -67,7 +67,7 @@ const styles$2 = ({ css, theme: t, rootSize }) => css`
67
67
 
68
68
  ${t.extraStyles && extendCss(t.extraStyles)};
69
69
  `;
70
- const StyledComponent = styled$2(component$2)`
70
+ const StyledComponent = styled$2(component$1)`
71
71
  ${`box-sizing: border-box;`};
72
72
 
73
73
  display: flex;
@@ -86,11 +86,22 @@ const StyledComponent = styled$2(component$2)`
86
86
 
87
87
  //#endregion
88
88
  //#region src/helpers/Content/component.tsx
89
- const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, alignY, equalCols, gap, extendCss, ...props }) => {
89
+ /**
90
+ * Memoized content area used inside Element to render one of the three
91
+ * layout slots (before, content, after). Passes alignment, direction,
92
+ * gap, and equalCols styling props to the underlying styled component.
93
+ * Adds a `data-vl-element` attribute in development for debugging.
94
+ *
95
+ * Children are passed as raw content and rendered inside the memo boundary
96
+ * via core `render()` — this lets React.memo skip re-renders when the
97
+ * content reference is stable (common for component-type or string content).
98
+ */
99
+ const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, alignY, equalCols, gap, extendCss, children, ...props }) => {
100
+ const debugProps = IS_DEVELOPMENT ? { "data-vl-element": contentType } : {};
90
101
  return /* @__PURE__ */ jsx(StyledComponent, {
91
102
  as: tag,
92
103
  $contentType: contentType,
93
- $element: {
104
+ $element: useMemo(() => ({
94
105
  contentType,
95
106
  parentDirection,
96
107
  direction,
@@ -99,16 +110,26 @@ const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, ali
99
110
  equalCols,
100
111
  gap,
101
112
  extraStyles: extendCss
102
- },
103
- ...IS_DEVELOPMENT ? { "data-vl-element": contentType } : {},
104
- ...props
113
+ }), [
114
+ contentType,
115
+ parentDirection,
116
+ direction,
117
+ alignX,
118
+ alignY,
119
+ equalCols,
120
+ gap,
121
+ extendCss
122
+ ]),
123
+ ...debugProps,
124
+ ...props,
125
+ children: render(children)
105
126
  });
106
127
  };
107
- var component_default = memo(Component$9);
128
+ var component_default$1 = memo(Component$9);
108
129
 
109
130
  //#endregion
110
131
  //#region src/helpers/Content/index.ts
111
- var Content_default = component_default;
132
+ var Content_default = component_default$1;
112
133
 
113
134
  //#endregion
114
135
  //#region src/helpers/Wrapper/styled.ts
@@ -119,7 +140,7 @@ var Content_default = component_default;
119
140
  * split flex behavior across two DOM nodes for button/fieldset/legend
120
141
  * elements where a single flex container is insufficient.
121
142
  */
122
- const { styled: styled$1, css: css$1, component: component$1 } = config;
143
+ const { styled: styled$1, css: css$1, component } = config;
123
144
  const childFixCSS = `
124
145
  display: flex;
125
146
  flex: 1;
@@ -157,7 +178,7 @@ const styles$1 = ({ theme: t, css }) => css`
157
178
  ${t.extraStyles && extendCss(t.extraStyles)};
158
179
  `;
159
180
  const platformCSS = `box-sizing: border-box;`;
160
- var styled_default$1 = styled$1(component$1)`
181
+ var styled_default$1 = styled$1(component)`
161
182
  position: relative;
162
183
  ${platformCSS};
163
184
 
@@ -208,36 +229,52 @@ const Component$8 = forwardRef(({ children, tag, block, extendCss, direction, al
208
229
  ref,
209
230
  as: tag
210
231
  };
211
- if (!(!props.dangerouslySetInnerHTML && isWebFixNeeded(tag)) || false) return /* @__PURE__ */ jsx(styled_default$1, {
232
+ const needsFix = !props.dangerouslySetInnerHTML && isWebFixNeeded(tag);
233
+ const normalElement = useMemo(() => ({
234
+ block,
235
+ direction,
236
+ alignX,
237
+ alignY,
238
+ equalCols,
239
+ extraStyles: extendCss
240
+ }), [
241
+ block,
242
+ direction,
243
+ alignX,
244
+ alignY,
245
+ equalCols,
246
+ extendCss
247
+ ]);
248
+ const parentFixElement = useMemo(() => ({
249
+ parentFix: true,
250
+ block,
251
+ extraStyles: extendCss
252
+ }), [block, extendCss]);
253
+ const childFixElement = useMemo(() => ({
254
+ childFix: true,
255
+ direction,
256
+ alignX,
257
+ alignY,
258
+ equalCols
259
+ }), [
260
+ direction,
261
+ alignX,
262
+ alignY,
263
+ equalCols
264
+ ]);
265
+ if (!needsFix || false) return /* @__PURE__ */ jsx(styled_default$1, {
212
266
  ...COMMON_PROPS,
213
- $element: {
214
- block,
215
- direction,
216
- alignX,
217
- alignY,
218
- equalCols,
219
- extraStyles: extendCss
220
- },
267
+ $element: normalElement,
221
268
  children
222
269
  });
223
270
  const asTag = isInline ? "span" : "div";
224
271
  return /* @__PURE__ */ jsx(styled_default$1, {
225
272
  ...COMMON_PROPS,
226
- $element: {
227
- parentFix: true,
228
- block,
229
- extraStyles: extendCss
230
- },
273
+ $element: parentFixElement,
231
274
  children: /* @__PURE__ */ jsx(styled_default$1, {
232
275
  as: asTag,
233
276
  $childFix: true,
234
- $element: {
235
- childFix: true,
236
- direction,
237
- alignX,
238
- alignY,
239
- equalCols
240
- },
277
+ $element: childFixElement,
241
278
  children
242
279
  })
243
280
  });
@@ -332,11 +369,26 @@ const getShouldBeEmpty = (tag) => {
332
369
  * like void elements (input, img) and inline elements (span, a) by
333
370
  * skipping children or switching sub-tags accordingly.
334
371
  */
372
+ const equalize = (el, direction) => {
373
+ const beforeEl = el.firstElementChild;
374
+ const afterEl = el.lastElementChild;
375
+ if (beforeEl && afterEl && beforeEl !== afterEl) {
376
+ const type = direction === "rows" ? "height" : "width";
377
+ const prop = type === "height" ? "offsetHeight" : "offsetWidth";
378
+ const beforeSize = beforeEl[prop];
379
+ const afterSize = afterEl[prop];
380
+ if (Number.isInteger(beforeSize) && Number.isInteger(afterSize)) {
381
+ const maxSize = `${Math.max(beforeSize, afterSize)}px`;
382
+ beforeEl.style[type] = maxSize;
383
+ afterEl.style[type] = maxSize;
384
+ }
385
+ }
386
+ };
335
387
  const defaultDirection = "inline";
336
388
  const defaultContentDirection = "rows";
337
389
  const defaultAlignX = "left";
338
390
  const defaultAlignY = "center";
339
- const Component$7 = forwardRef(({ innerRef, tag, label, content, children, beforeContent, afterContent, 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) => {
391
+ const Component$7 = 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) => {
340
392
  const shouldBeEmpty = !!props.dangerouslySetInnerHTML || getShouldBeEmpty(tag);
341
393
  const isSimpleElement = !beforeContent && !afterContent;
342
394
  const CHILDREN = children ?? content ?? label;
@@ -366,8 +418,24 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
366
418
  alignY,
367
419
  direction
368
420
  ]);
421
+ const equalizeRef = useRef(null);
422
+ const externalRef = ref ?? innerRef;
423
+ const mergedRef = useCallback((node) => {
424
+ equalizeRef.current = node;
425
+ if (typeof externalRef === "function") externalRef(node);
426
+ else if (externalRef != null) externalRef.current = node;
427
+ }, [externalRef]);
428
+ useLayoutEffect(() => {
429
+ if (!equalBeforeAfter || !beforeContent || !afterContent) return;
430
+ if (equalizeRef.current) equalize(equalizeRef.current, direction);
431
+ }, [
432
+ equalBeforeAfter,
433
+ beforeContent,
434
+ afterContent,
435
+ direction
436
+ ]);
369
437
  const WRAPPER_PROPS = {
370
- ref: ref ?? innerRef,
438
+ ref: mergedRef,
371
439
  extendCss: css,
372
440
  tag,
373
441
  block,
@@ -380,7 +448,6 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
380
448
  ...props,
381
449
  ...WRAPPER_PROPS
382
450
  });
383
- const contentRenderOutput = render(CHILDREN);
384
451
  return /* @__PURE__ */ jsxs(Wrapper_default, {
385
452
  ...props,
386
453
  ...WRAPPER_PROPS,
@@ -396,9 +463,9 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
396
463
  alignY: beforeContentAlignY,
397
464
  equalCols,
398
465
  gap,
399
- children: render(beforeContent)
466
+ children: beforeContent
400
467
  }),
401
- isSimpleElement ? contentRenderOutput : /* @__PURE__ */ jsx(Content_default, {
468
+ isSimpleElement ? render(CHILDREN) : /* @__PURE__ */ jsx(Content_default, {
402
469
  tag: SUB_TAG,
403
470
  contentType: "content",
404
471
  parentDirection: wrapperDirection,
@@ -407,7 +474,7 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
407
474
  alignX: contentAlignX,
408
475
  alignY: contentAlignY,
409
476
  equalCols,
410
- children: contentRenderOutput
477
+ children: CHILDREN
411
478
  }),
412
479
  afterContent && /* @__PURE__ */ jsx(Content_default, {
413
480
  tag: SUB_TAG,
@@ -419,7 +486,7 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
419
486
  alignY: afterContentAlignY,
420
487
  equalCols,
421
488
  gap,
422
- children: render(afterContent)
489
+ children: afterContent
423
490
  })
424
491
  ]
425
492
  });
@@ -429,53 +496,6 @@ Component$7.displayName = name$5;
429
496
  Component$7.pkgName = PKG_NAME;
430
497
  Component$7.VITUS_LABS__COMPONENT = name$5;
431
498
 
432
- //#endregion
433
- //#region src/Element/withEqualSizeBeforeAfter.tsx
434
- /**
435
- * HOC that equalizes the dimensions of beforeContent and afterContent areas.
436
- * After render, it measures both DOM nodes via useLayoutEffect and sets the
437
- * larger dimension on both so they match. Uses width for inline direction
438
- * and height for rows direction. This is useful for centering the main
439
- * content when before/after slots have different intrinsic sizes.
440
- */
441
- const types = {
442
- height: "offsetHeight",
443
- width: "offsetWidth"
444
- };
445
- const equalize = (beforeEl, afterEl, type) => {
446
- const prop = types[type];
447
- const beforeSize = beforeEl[prop];
448
- const afterSize = afterEl[prop];
449
- if (Number.isInteger(beforeSize) && Number.isInteger(afterSize)) {
450
- const maxSize = `${Math.max(beforeSize, afterSize)}px`;
451
- beforeEl.style[type] = maxSize;
452
- afterEl.style[type] = maxSize;
453
- }
454
- };
455
- const withEqualBeforeAfter = (WrappedComponent) => {
456
- const displayName = WrappedComponent.displayName ?? WrappedComponent.name ?? "Component";
457
- const Enhanced = ({ equalBeforeAfter, direction, afterContent, beforeContent, ref, ...rest }) => {
458
- const internalRef = useRef(null);
459
- useImperativeHandle(ref, () => internalRef.current);
460
- useLayoutEffect(() => {
461
- if (!equalBeforeAfter || !beforeContent || !afterContent) return;
462
- if (!internalRef.current) return;
463
- const el = internalRef.current;
464
- const beforeEl = el.firstElementChild;
465
- const afterEl = el.lastElementChild;
466
- if (beforeEl && afterEl && beforeEl !== afterEl) equalize(beforeEl, afterEl, direction === "rows" ? "height" : "width");
467
- });
468
- return /* @__PURE__ */ jsx(WrappedComponent, {
469
- ...rest,
470
- afterContent,
471
- beforeContent,
472
- ref: internalRef
473
- });
474
- };
475
- Enhanced.displayName = `withEqualSizeBeforeAfter(${displayName})`;
476
- return Enhanced;
477
- };
478
-
479
499
  //#endregion
480
500
  //#region src/Element/index.ts
481
501
  var Element_default = Component$7;
@@ -633,12 +653,14 @@ const Component$6 = (props) => {
633
653
  };
634
654
  return renderItems();
635
655
  };
636
- Component$6.isIterator = true;
637
- Component$6.RESERVED_PROPS = RESERVED_PROPS;
656
+ var component_default = Object.assign(memo(Component$6), {
657
+ isIterator: true,
658
+ RESERVED_PROPS
659
+ });
638
660
 
639
661
  //#endregion
640
662
  //#region src/helpers/Iterator/index.ts
641
- var Iterator_default = Component$6;
663
+ var Iterator_default = component_default;
642
664
 
643
665
  //#endregion
644
666
  //#region src/List/component.tsx
@@ -663,108 +685,6 @@ Component$5.displayName = name$4;
663
685
  Component$5.pkgName = PKG_NAME;
664
686
  Component$5.VITUS_LABS__COMPONENT = name$4;
665
687
 
666
- //#endregion
667
- //#region src/List/withActiveState.tsx
668
- /**
669
- * HOC that adds single or multi selection state management to a list component.
670
- * Tracks which items are active via a scalar key (single mode) or a Map of
671
- * key-to-boolean entries (multi mode). Injects `itemProps` callback that
672
- * provides each item with `active`, `handleItemActive`, `toggleItemActive`,
673
- * and other selection helpers. Supports `activeItemRequired` to prevent
674
- * deselecting the last active item.
675
- */
676
- const RESERVED_KEYS = [
677
- "type",
678
- "activeItems",
679
- "itemProps",
680
- "activeItemRequired"
681
- ];
682
- const component = (WrappedComponent) => {
683
- const displayName = WrappedComponent.displayName || WrappedComponent.name || "Component";
684
- const Enhanced = (props) => {
685
- const { type = "single", activeItemRequired, activeItems, itemProps = {}, ...rest } = props;
686
- const initActiveItems = () => {
687
- if (type === "single") {
688
- if (!Array.isArray(activeItems)) return activeItems;
689
- } else if (type === "multi") {
690
- const activeItemsHelper = Array.isArray(activeItems) ? activeItems : [activeItems];
691
- return new Map(activeItemsHelper.map((id) => [id, true]));
692
- }
693
- };
694
- const [innerActiveItems, setActiveItems] = useState(initActiveItems());
695
- const countActiveItems = (data) => {
696
- let result = 0;
697
- data.forEach((value) => {
698
- if (value) result += 1;
699
- });
700
- return result;
701
- };
702
- const updateItemState = (key) => {
703
- if (type === "single") setActiveItems((prevState) => {
704
- if (activeItemRequired) return key;
705
- if (prevState === key) return void 0;
706
- return key;
707
- });
708
- else if (type === "multi") setActiveItems((prevState) => {
709
- const activeItems = new Map(prevState);
710
- if (activeItemRequired && activeItems.get(key) && countActiveItems(activeItems) === 1) return activeItems;
711
- activeItems.set(key, !activeItems.get(key));
712
- return activeItems;
713
- });
714
- else setActiveItems(void 0);
715
- };
716
- const handleItemActive = (key) => {
717
- updateItemState(key);
718
- };
719
- const updateAllItemsState = (status) => {
720
- if (!status) setActiveItems(/* @__PURE__ */ new Map());
721
- };
722
- const setItemActive = (key) => {
723
- updateItemState(key);
724
- };
725
- const unsetItemActive = (key) => {
726
- updateItemState(key);
727
- };
728
- const toggleItemActive = (key) => {
729
- updateItemState(key);
730
- };
731
- const unsetAllItemsActive = () => {
732
- updateAllItemsState(false);
733
- };
734
- const isItemActive = (key) => {
735
- if (!innerActiveItems) return false;
736
- if (type === "single") return innerActiveItems === key;
737
- if (type === "multi" && innerActiveItems instanceof Map) return !!innerActiveItems.get(key);
738
- return false;
739
- };
740
- const attachMultipleProps = { unsetAllItemsActive };
741
- const attachItemProps = (props) => {
742
- const { key } = props;
743
- return {
744
- ...typeof itemProps === "object" ? itemProps : itemProps(props),
745
- active: isItemActive(key),
746
- handleItemActive: () => handleItemActive(key),
747
- setItemActive,
748
- unsetItemActive,
749
- toggleItemActive,
750
- ...type === "multi" ? attachMultipleProps : {}
751
- };
752
- };
753
- useEffect(() => {
754
- if (type === "single" && Array.isArray(activeItems)) {
755
- 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.");
756
- }
757
- }, [type, activeItems]);
758
- return /* @__PURE__ */ jsx(WrappedComponent, {
759
- ...rest,
760
- itemProps: attachItemProps
761
- });
762
- };
763
- Enhanced.RESERVED_KEYS = RESERVED_KEYS;
764
- Enhanced.displayName = `@vitus-labs/elements/List/withActiveState(${displayName})`;
765
- return Enhanced;
766
- };
767
-
768
688
  //#endregion
769
689
  //#region src/List/index.ts
770
690
  var List_default = Component$5;
@@ -1409,5 +1329,5 @@ Component$1.VITUS_LABS__COMPONENT = name;
1409
1329
  var Util_default = Component$1;
1410
1330
 
1411
1331
  //#endregion
1412
- export { Element_default as Element, List_default as List, Overlay_default as Overlay, Component as OverlayProvider, Portal_default as Portal, Provider, Text_default as Text, Util_default as Util, useOverlay, component as withActiveState, withEqualBeforeAfter as withEqualSizeBeforeAfter };
1332
+ export { Element_default as Element, List_default as List, Overlay_default as Overlay, Component as OverlayProvider, Portal_default as Portal, Provider, Text_default as Text, Util_default as Util, useOverlay };
1413
1333
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  import { Provider, alignContent, extendCss, makeItResponsive, value } from "@vitus-labs/unistyle";
2
2
  import { config, context, isEmpty, omit, pick, render, throttle } from "@vitus-labs/core";
3
- import { Children, createContext, forwardRef, memo, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import { Children, createContext, forwardRef, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { isFragment } from "react-is";
6
6
  import { createPortal } from "react-dom";
@@ -21,7 +21,7 @@ const IS_DEVELOPMENT = process.env.NODE_ENV !== "production";
21
21
  * equalCols flex distribution. The "content" slot gets `flex: 1` to
22
22
  * fill remaining space between before and after.
23
23
  */
24
- const { styled: styled$2, css: css$2, component: component$2 } = config;
24
+ const { styled: styled$2, css: css$2, component: component$1 } = config;
25
25
  const equalColsCSS = `
26
26
  flex: 1;
27
27
  `;
@@ -67,7 +67,7 @@ const styles$2 = ({ css, theme: t, rootSize }) => css`
67
67
 
68
68
  ${t.extraStyles && extendCss(t.extraStyles)};
69
69
  `;
70
- const StyledComponent = styled$2(component$2)`
70
+ const StyledComponent = styled$2(component$1)`
71
71
  ${""};
72
72
 
73
73
  display: flex;
@@ -86,11 +86,22 @@ const StyledComponent = styled$2(component$2)`
86
86
 
87
87
  //#endregion
88
88
  //#region src/helpers/Content/component.tsx
89
- const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, alignY, equalCols, gap, extendCss, ...props }) => {
89
+ /**
90
+ * Memoized content area used inside Element to render one of the three
91
+ * layout slots (before, content, after). Passes alignment, direction,
92
+ * gap, and equalCols styling props to the underlying styled component.
93
+ * Adds a `data-vl-element` attribute in development for debugging.
94
+ *
95
+ * Children are passed as raw content and rendered inside the memo boundary
96
+ * via core `render()` — this lets React.memo skip re-renders when the
97
+ * content reference is stable (common for component-type or string content).
98
+ */
99
+ const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, alignY, equalCols, gap, extendCss, children, ...props }) => {
100
+ const debugProps = IS_DEVELOPMENT ? { "data-vl-element": contentType } : {};
90
101
  return /* @__PURE__ */ jsx(StyledComponent, {
91
102
  as: tag,
92
103
  $contentType: contentType,
93
- $element: {
104
+ $element: useMemo(() => ({
94
105
  contentType,
95
106
  parentDirection,
96
107
  direction,
@@ -99,16 +110,26 @@ const Component$9 = ({ contentType, tag, parentDirection, direction, alignX, ali
99
110
  equalCols,
100
111
  gap,
101
112
  extraStyles: extendCss
102
- },
103
- ...IS_DEVELOPMENT ? { "data-vl-element": contentType } : {},
104
- ...props
113
+ }), [
114
+ contentType,
115
+ parentDirection,
116
+ direction,
117
+ alignX,
118
+ alignY,
119
+ equalCols,
120
+ gap,
121
+ extendCss
122
+ ]),
123
+ ...debugProps,
124
+ ...props,
125
+ children: render(children)
105
126
  });
106
127
  };
107
- var component_default = memo(Component$9);
128
+ var component_default$1 = memo(Component$9);
108
129
 
109
130
  //#endregion
110
131
  //#region src/helpers/Content/index.ts
111
- var Content_default = component_default;
132
+ var Content_default = component_default$1;
112
133
 
113
134
  //#endregion
114
135
  //#region src/helpers/Wrapper/styled.ts
@@ -119,7 +140,7 @@ var Content_default = component_default;
119
140
  * split flex behavior across two DOM nodes for button/fieldset/legend
120
141
  * elements where a single flex container is insufficient.
121
142
  */
122
- const { styled: styled$1, css: css$1, component: component$1 } = config;
143
+ const { styled: styled$1, css: css$1, component } = config;
123
144
  const childFixCSS = `
124
145
  display: flex;
125
146
  flex: 1;
@@ -147,7 +168,7 @@ const styles$1 = ({ theme: t, css }) => css`
147
168
  ${t.extraStyles && extendCss(t.extraStyles)};
148
169
  `;
149
170
  const platformCSS = `display: flex;`;
150
- var styled_default$1 = styled$1(component$1)`
171
+ var styled_default$1 = styled$1(component)`
151
172
  position: relative;
152
173
  ${platformCSS};
153
174
 
@@ -172,19 +193,47 @@ var styled_default$1 = styled$1(component$1)`
172
193
  */
173
194
  const DEV_PROPS = IS_DEVELOPMENT ? { "data-vl-element": "Element" } : {};
174
195
  const Component$8 = forwardRef(({ children, tag, block, extendCss, direction, alignX, alignY, equalCols, isInline, ...props }, ref) => {
175
- return /* @__PURE__ */ jsx(styled_default$1, {
196
+ const COMMON_PROPS = {
176
197
  ...props,
177
198
  ...DEV_PROPS,
178
199
  ref,
179
- as: tag,
180
- $element: {
181
- block,
182
- direction,
183
- alignX,
184
- alignY,
185
- equalCols,
186
- extraStyles: extendCss
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
  });
@@ -203,11 +252,26 @@ var Wrapper_default = Component$8;
203
252
  * like void elements (input, img) and inline elements (span, a) by
204
253
  * skipping children or switching sub-tags accordingly.
205
254
  */
255
+ const equalize = (el, direction) => {
256
+ const beforeEl = el.firstElementChild;
257
+ const afterEl = el.lastElementChild;
258
+ if (beforeEl && afterEl && beforeEl !== afterEl) {
259
+ const type = direction === "rows" ? "height" : "width";
260
+ const prop = type === "height" ? "offsetHeight" : "offsetWidth";
261
+ const beforeSize = beforeEl[prop];
262
+ const afterSize = afterEl[prop];
263
+ if (Number.isInteger(beforeSize) && Number.isInteger(afterSize)) {
264
+ const maxSize = `${Math.max(beforeSize, afterSize)}px`;
265
+ beforeEl.style[type] = maxSize;
266
+ afterEl.style[type] = maxSize;
267
+ }
268
+ }
269
+ };
206
270
  const defaultDirection = "inline";
207
271
  const defaultContentDirection = "rows";
208
272
  const defaultAlignX = "left";
209
273
  const defaultAlignY = "center";
210
- const Component$7 = forwardRef(({ innerRef, tag, label, content, children, beforeContent, afterContent, 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) => {
274
+ const Component$7 = 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
275
  const isSimpleElement = !beforeContent && !afterContent;
212
276
  const CHILDREN = children ?? content ?? label;
213
277
  const isInline = false;
@@ -236,8 +300,24 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
236
300
  alignY,
237
301
  direction
238
302
  ]);
303
+ const equalizeRef = useRef(null);
304
+ const externalRef = ref ?? innerRef;
305
+ const mergedRef = useCallback((node) => {
306
+ equalizeRef.current = node;
307
+ if (typeof externalRef === "function") externalRef(node);
308
+ else if (externalRef != null) externalRef.current = node;
309
+ }, [externalRef]);
310
+ useLayoutEffect(() => {
311
+ if (!equalBeforeAfter || !beforeContent || !afterContent) return;
312
+ if (equalizeRef.current) equalize(equalizeRef.current, direction);
313
+ }, [
314
+ equalBeforeAfter,
315
+ beforeContent,
316
+ afterContent,
317
+ direction
318
+ ]);
239
319
  const WRAPPER_PROPS = {
240
- ref: ref ?? innerRef,
320
+ ref: mergedRef,
241
321
  extendCss: css,
242
322
  tag,
243
323
  block,
@@ -246,7 +326,6 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
246
326
  alignY: wrapperAlignY,
247
327
  as: void 0
248
328
  };
249
- const contentRenderOutput = render(CHILDREN);
250
329
  return /* @__PURE__ */ jsxs(Wrapper_default, {
251
330
  ...props,
252
331
  ...WRAPPER_PROPS,
@@ -262,9 +341,9 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
262
341
  alignY: beforeContentAlignY,
263
342
  equalCols,
264
343
  gap,
265
- children: render(beforeContent)
344
+ children: beforeContent
266
345
  }),
267
- isSimpleElement ? contentRenderOutput : /* @__PURE__ */ jsx(Content_default, {
346
+ isSimpleElement ? render(CHILDREN) : /* @__PURE__ */ jsx(Content_default, {
268
347
  tag: SUB_TAG,
269
348
  contentType: "content",
270
349
  parentDirection: wrapperDirection,
@@ -273,7 +352,7 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
273
352
  alignX: contentAlignX,
274
353
  alignY: contentAlignY,
275
354
  equalCols,
276
- children: contentRenderOutput
355
+ children: CHILDREN
277
356
  }),
278
357
  afterContent && /* @__PURE__ */ jsx(Content_default, {
279
358
  tag: SUB_TAG,
@@ -285,7 +364,7 @@ const Component$7 = forwardRef(({ innerRef, tag, label, content, children, befor
285
364
  alignY: afterContentAlignY,
286
365
  equalCols,
287
366
  gap,
288
- children: render(afterContent)
367
+ children: afterContent
289
368
  })
290
369
  ]
291
370
  });
@@ -295,53 +374,6 @@ Component$7.displayName = name$5;
295
374
  Component$7.pkgName = PKG_NAME;
296
375
  Component$7.VITUS_LABS__COMPONENT = name$5;
297
376
 
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
- };
344
-
345
377
  //#endregion
346
378
  //#region src/Element/index.ts
347
379
  var Element_default = Component$7;
@@ -499,12 +531,14 @@ const Component$6 = (props) => {
499
531
  };
500
532
  return renderItems();
501
533
  };
502
- Component$6.isIterator = true;
503
- Component$6.RESERVED_PROPS = RESERVED_PROPS;
534
+ var component_default = Object.assign(memo(Component$6), {
535
+ isIterator: true,
536
+ RESERVED_PROPS
537
+ });
504
538
 
505
539
  //#endregion
506
540
  //#region src/helpers/Iterator/index.ts
507
- var Iterator_default = Component$6;
541
+ var Iterator_default = component_default;
508
542
 
509
543
  //#endregion
510
544
  //#region src/List/component.tsx
@@ -529,108 +563,6 @@ Component$5.displayName = name$4;
529
563
  Component$5.pkgName = PKG_NAME;
530
564
  Component$5.VITUS_LABS__COMPONENT = name$4;
531
565
 
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
- };
633
-
634
566
  //#endregion
635
567
  //#region src/List/index.ts
636
568
  var List_default = Component$5;
@@ -1273,5 +1205,5 @@ Component$1.VITUS_LABS__COMPONENT = name;
1273
1205
  var Util_default = Component$1;
1274
1206
 
1275
1207
  //#endregion
1276
- export { Element_default as Element, List_default as List, Overlay_default as Overlay, Component as OverlayProvider, Portal_default as Portal, Provider, Text_default as Text, Util_default as Util, useOverlay, component as withActiveState, withEqualBeforeAfter as withEqualSizeBeforeAfter };
1208
+ export { Element_default as Element, List_default as List, Overlay_default as Overlay, Component as OverlayProvider, Portal_default as Portal, Provider, Text_default as Text, Util_default as Util, useOverlay };
1277
1209
  //# sourceMappingURL=vitus-labs-elements.native.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitus-labs/elements",
3
- "version": "2.0.0-alpha.2+8004069",
3
+ "version": "2.0.0-alpha.20",
4
4
  "license": "MIT",
5
5
  "author": "Vit Bokisch <vit@bokisch.cz>",
6
6
  "maintainers": [
@@ -61,15 +61,15 @@
61
61
  "react-dom": ">= 19"
62
62
  },
63
63
  "devDependencies": {
64
- "@vitus-labs/core": "2.0.0-alpha.2+8004069",
65
- "@vitus-labs/rocketstyle": "2.0.0-alpha.2+8004069",
64
+ "@vitus-labs/core": "2.0.0-alpha.20",
65
+ "@vitus-labs/rocketstyle": "2.0.0-alpha.20",
66
66
  "@vitus-labs/tools-rolldown": "^1.6.0",
67
67
  "@vitus-labs/tools-storybook": "^1.6.0",
68
68
  "@vitus-labs/tools-typescript": "^1.6.0",
69
- "@vitus-labs/unistyle": "2.0.0-alpha.2+8004069"
69
+ "@vitus-labs/unistyle": "2.0.0-alpha.20"
70
70
  },
71
71
  "dependencies": {
72
72
  "react-is": "^19.2.3"
73
73
  },
74
- "gitHead": "80040697d7306c958055474e2581d1fcdab0deb9"
74
+ "gitHead": "4159928108bd65c6d0756ecf21430908c8b6804d"
75
75
  }