@navikt/ds-react 7.29.0 → 7.30.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.
Files changed (110) hide show
  1. package/cjs/date/datepicker/parts/DatePicker.WeekNumber.js +1 -1
  2. package/cjs/date/datepicker/parts/DatePicker.WeekNumber.js.map +1 -1
  3. package/cjs/form/checkbox/Checkbox.js +1 -1
  4. package/cjs/form/checkbox/Checkbox.js.map +1 -1
  5. package/cjs/form/form-summary/FormSummary.d.ts +11 -17
  6. package/cjs/form/form-summary/FormSummary.js +5 -1
  7. package/cjs/form/form-summary/FormSummary.js.map +1 -1
  8. package/cjs/form/form-summary/FormSummaryEditLink.js +6 -1
  9. package/cjs/form/form-summary/FormSummaryEditLink.js.map +1 -1
  10. package/cjs/form/form-summary/FormSummaryFooter.d.ts +12 -0
  11. package/cjs/form/form-summary/FormSummaryFooter.js +56 -0
  12. package/cjs/form/form-summary/FormSummaryFooter.js.map +1 -0
  13. package/cjs/form/form-summary/FormSummaryHeader.d.ts +1 -1
  14. package/cjs/form/form-summary/FormSummaryHeader.js +3 -1
  15. package/cjs/form/form-summary/FormSummaryHeader.js.map +1 -1
  16. package/cjs/form/form-summary/index.d.ts +1 -0
  17. package/cjs/form/form-summary/index.js +3 -1
  18. package/cjs/form/form-summary/index.js.map +1 -1
  19. package/cjs/list/List.Item.js +1 -1
  20. package/cjs/list/List.Item.js.map +1 -1
  21. package/cjs/overlays/floating-menu/parts/FocusScope.d.ts +1 -1
  22. package/cjs/overlays/floating-menu/parts/FocusScope.js +2 -3
  23. package/cjs/overlays/floating-menu/parts/FocusScope.js.map +1 -1
  24. package/cjs/slot/Slot.d.ts +1 -1
  25. package/cjs/slot/Slot.js +8 -38
  26. package/cjs/slot/Slot.js.map +1 -1
  27. package/cjs/timeline/period/index.d.ts +1 -1
  28. package/cjs/timeline/period/index.js.map +1 -1
  29. package/cjs/timeline/utils/timeline.d.ts +7 -6
  30. package/cjs/timeline/utils/timeline.js +39 -62
  31. package/cjs/timeline/utils/timeline.js.map +1 -1
  32. package/cjs/timeline/utils/types.external.d.ts +2 -3
  33. package/cjs/timeline/utils/types.internal.d.ts +1 -1
  34. package/cjs/util/composition-warning/CompositionWarning.d.ts +37 -0
  35. package/cjs/util/composition-warning/CompositionWarning.js +71 -0
  36. package/cjs/util/composition-warning/CompositionWarning.js.map +1 -0
  37. package/cjs/util/composition-warning/index.d.ts +1 -0
  38. package/cjs/util/composition-warning/index.js +38 -0
  39. package/cjs/util/composition-warning/index.js.map +1 -0
  40. package/cjs/util/getChildRef.d.ts +1 -0
  41. package/cjs/util/getChildRef.js +8 -0
  42. package/cjs/util/getChildRef.js.map +1 -0
  43. package/cjs/util/renderStoriesForChromatic.d.ts +2 -10
  44. package/cjs/util/renderStoriesForChromatic.js +2 -2
  45. package/cjs/util/renderStoriesForChromatic.js.map +1 -1
  46. package/esm/date/datepicker/parts/DatePicker.WeekNumber.js +1 -1
  47. package/esm/date/datepicker/parts/DatePicker.WeekNumber.js.map +1 -1
  48. package/esm/form/checkbox/Checkbox.js +1 -1
  49. package/esm/form/checkbox/Checkbox.js.map +1 -1
  50. package/esm/form/form-summary/FormSummary.d.ts +11 -17
  51. package/esm/form/form-summary/FormSummary.js +5 -1
  52. package/esm/form/form-summary/FormSummary.js.map +1 -1
  53. package/esm/form/form-summary/FormSummaryEditLink.js +6 -1
  54. package/esm/form/form-summary/FormSummaryEditLink.js.map +1 -1
  55. package/esm/form/form-summary/FormSummaryFooter.d.ts +12 -0
  56. package/esm/form/form-summary/FormSummaryFooter.js +20 -0
  57. package/esm/form/form-summary/FormSummaryFooter.js.map +1 -0
  58. package/esm/form/form-summary/FormSummaryHeader.d.ts +1 -1
  59. package/esm/form/form-summary/FormSummaryHeader.js +3 -1
  60. package/esm/form/form-summary/FormSummaryHeader.js.map +1 -1
  61. package/esm/form/form-summary/index.d.ts +1 -0
  62. package/esm/form/form-summary/index.js +1 -0
  63. package/esm/form/form-summary/index.js.map +1 -1
  64. package/esm/list/List.Item.js +1 -1
  65. package/esm/list/List.Item.js.map +1 -1
  66. package/esm/overlays/floating-menu/parts/FocusScope.d.ts +1 -1
  67. package/esm/overlays/floating-menu/parts/FocusScope.js +1 -2
  68. package/esm/overlays/floating-menu/parts/FocusScope.js.map +1 -1
  69. package/esm/slot/Slot.d.ts +1 -1
  70. package/esm/slot/Slot.js +1 -1
  71. package/esm/slot/Slot.js.map +1 -1
  72. package/esm/timeline/period/index.d.ts +1 -1
  73. package/esm/timeline/period/index.js.map +1 -1
  74. package/esm/timeline/utils/timeline.d.ts +7 -6
  75. package/esm/timeline/utils/timeline.js +39 -62
  76. package/esm/timeline/utils/timeline.js.map +1 -1
  77. package/esm/timeline/utils/types.external.d.ts +2 -3
  78. package/esm/timeline/utils/types.internal.d.ts +1 -1
  79. package/esm/util/composition-warning/CompositionWarning.d.ts +37 -0
  80. package/esm/util/composition-warning/CompositionWarning.js +34 -0
  81. package/esm/util/composition-warning/CompositionWarning.js.map +1 -0
  82. package/esm/util/composition-warning/index.d.ts +1 -0
  83. package/esm/util/composition-warning/index.js +2 -0
  84. package/esm/util/composition-warning/index.js.map +1 -0
  85. package/esm/util/getChildRef.d.ts +1 -0
  86. package/esm/util/getChildRef.js +4 -0
  87. package/esm/util/getChildRef.js.map +1 -0
  88. package/esm/util/renderStoriesForChromatic.d.ts +2 -10
  89. package/esm/util/renderStoriesForChromatic.js +2 -2
  90. package/esm/util/renderStoriesForChromatic.js.map +1 -1
  91. package/package.json +3 -3
  92. package/src/date/datepicker/parts/DatePicker.WeekNumber.tsx +3 -1
  93. package/src/form/checkbox/Checkbox.tsx +0 -2
  94. package/src/form/combobox/__tests__/combobox.test.tsx +2 -1
  95. package/src/form/form-summary/FormSummary.tsx +12 -17
  96. package/src/form/form-summary/FormSummaryEditLink.tsx +16 -7
  97. package/src/form/form-summary/FormSummaryFooter.tsx +33 -0
  98. package/src/form/form-summary/FormSummaryHeader.tsx +12 -9
  99. package/src/form/form-summary/index.ts +4 -0
  100. package/src/list/List.Item.tsx +0 -2
  101. package/src/overlays/floating-menu/parts/FocusScope.tsx +1 -2
  102. package/src/slot/Slot.tsx +1 -1
  103. package/src/timeline/period/index.tsx +3 -1
  104. package/src/timeline/utils/timeline.ts +56 -67
  105. package/src/timeline/utils/types.external.ts +4 -3
  106. package/src/timeline/utils/types.internal.ts +3 -1
  107. package/src/util/composition-warning/CompositionWarning.tsx +67 -0
  108. package/src/util/composition-warning/index.ts +1 -0
  109. package/src/util/getChildRef.ts +6 -0
  110. package/src/util/renderStoriesForChromatic.tsx +12 -9
@@ -1,6 +1,8 @@
1
1
  import React, { forwardRef } from "react";
2
+ import { PencilIcon } from "@navikt/aksel-icons";
2
3
  import { Link } from "../../link";
3
4
  import { useRenameCSS } from "../../theme/Theme";
5
+ import { CompositionWarning } from "../../util/composition-warning";
4
6
  import { useI18n } from "../../util/i18n/i18n.hooks";
5
7
  import { OverridableComponent } from "../../util/types";
6
8
 
@@ -24,17 +26,24 @@ export const FormSummaryEditLink: OverridableComponent<
24
26
  HTMLAnchorElement
25
27
  > = forwardRef(({ children, className, as = "a", ...rest }, ref) => {
26
28
  const { cn } = useRenameCSS();
29
+
27
30
  const translate = useI18n("FormSummary");
28
31
 
29
32
  return (
30
- <Link
31
- ref={ref}
32
- as={as}
33
- {...rest}
34
- className={cn("navds-form-summary__edit", className)}
33
+ <CompositionWarning.Forbidden
34
+ name="FormSummary.Header"
35
+ message="<FormSummary.EditLink> should not be placed in <FormSummary.Header> anymore. See https://aksel.nav.no/komponenter/core/formsummary"
35
36
  >
36
- {children || translate("editAnswer")}
37
- </Link>
37
+ <Link
38
+ ref={ref}
39
+ as={as}
40
+ {...rest}
41
+ className={cn("navds-form-summary__edit", className)}
42
+ >
43
+ <PencilIcon aria-hidden fontSize="1.5rem" />
44
+ {children || translate("editAnswer")}
45
+ </Link>
46
+ </CompositionWarning.Forbidden>
38
47
  );
39
48
  });
40
49
 
@@ -0,0 +1,33 @@
1
+ import React, { forwardRef } from "react";
2
+ import { useRenameCSS } from "../../theme/Theme";
3
+
4
+ /**
5
+ * Footer slot for actions in `FormSummary`.
6
+ */
7
+ export interface FormSummaryFooterProps
8
+ extends React.HTMLAttributes<HTMLDivElement> {
9
+ /**
10
+ * Should include `<FormSummary.EditLink>`.
11
+ */
12
+ children: React.ReactNode;
13
+ }
14
+
15
+ export const FormSummaryFooter = forwardRef<
16
+ HTMLDivElement,
17
+ FormSummaryFooterProps
18
+ >(({ children, className, ...rest }, ref) => {
19
+ const { cn } = useRenameCSS();
20
+
21
+ return (
22
+ <div
23
+ ref={ref}
24
+ data-color="info"
25
+ {...rest}
26
+ className={cn("navds-form-summary__footer", className)}
27
+ >
28
+ {children}
29
+ </div>
30
+ );
31
+ });
32
+
33
+ export default FormSummaryFooter;
@@ -1,10 +1,11 @@
1
1
  import React, { forwardRef } from "react";
2
2
  import { useRenameCSS } from "../../theme/Theme";
3
+ import { CompositionWarning } from "../../util/composition-warning";
3
4
 
4
5
  export interface FormSummaryHeaderProps
5
6
  extends React.HTMLAttributes<HTMLDivElement> {
6
7
  /**
7
- * Must include `<FormSummary.Heading>` and optionally `<FormSummary.EditLink>`.
8
+ * Must include `<FormSummary.Heading>`.
8
9
  */
9
10
  children: React.ReactNode;
10
11
  }
@@ -12,17 +13,19 @@ export interface FormSummaryHeaderProps
12
13
  export const FormSummaryHeader = forwardRef<
13
14
  HTMLDivElement,
14
15
  FormSummaryHeaderProps
15
- >(({ children, className, ...rest }, ref) => {
16
+ >(({ children, className, ...rest }: FormSummaryHeaderProps, ref) => {
16
17
  const { cn } = useRenameCSS();
17
18
 
18
19
  return (
19
- <header
20
- ref={ref}
21
- {...rest}
22
- className={cn("navds-form-summary__header", className)}
23
- >
24
- {children}
25
- </header>
20
+ <CompositionWarning.Root name="FormSummary.Header">
21
+ <div
22
+ ref={ref}
23
+ {...rest}
24
+ className={cn("navds-form-summary__header", className)}
25
+ >
26
+ {children}
27
+ </div>
28
+ </CompositionWarning.Root>
26
29
  );
27
30
  });
28
31
 
@@ -12,6 +12,10 @@ export {
12
12
  default as FormSummaryEditLink,
13
13
  type FormSummaryEditProps,
14
14
  } from "./FormSummaryEditLink";
15
+ export {
16
+ default as FormSummaryFooter,
17
+ type FormSummaryFooterProps,
18
+ } from "./FormSummaryFooter";
15
19
  export {
16
20
  default as FormSummaryHeader,
17
21
  type FormSummaryHeaderProps,
@@ -31,8 +31,6 @@ export const ListItem = forwardRef<HTMLLIElement, ListItemProps>(
31
31
  icon
32
32
  ) : (
33
33
  <svg
34
- width="0.375rem"
35
- height="0.375rem"
36
34
  viewBox="0 0 6 6"
37
35
  fill="none"
38
36
  xmlns="http://www.w3.org/2000/svg"
@@ -1,5 +1,4 @@
1
- import * as React from "react";
2
- import { forwardRef, useEffect, useState } from "react";
1
+ import React, { forwardRef, useEffect, useState } from "react";
3
2
  import { Slot } from "../../../slot/Slot";
4
3
  import { useCallbackRef, useMergeRefs } from "../../../util/hooks";
5
4
 
package/src/slot/Slot.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import * as React from "react";
1
+ import React from "react";
2
2
  import { mergeRefs } from "../util/hooks/useMergeRefs";
3
3
  import { mergeProps } from "./merge-props";
4
4
 
@@ -32,7 +32,9 @@ export interface TimelinePeriodProps
32
32
  /**
33
33
  * Callback when selecting a period.
34
34
  */
35
- onSelectPeriod?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
35
+ onSelectPeriod?: (
36
+ event: React.MouseEvent<Element> | React.KeyboardEvent<Element>,
37
+ ) => void;
36
38
  /**
37
39
  * Content displayed in Popover on click.
38
40
  */
@@ -1,82 +1,71 @@
1
1
  import React, { ReactNode } from "react";
2
+ import type { TimelinePeriod, TimelineRow, TimelineRowProps } from "..";
2
3
  import { omit } from "../../util";
4
+ import { getChildRef } from "../../util/getChildRef";
3
5
  import { Period } from "./types.external";
4
6
 
5
- type ParsedChild = {
6
- label?: string;
7
+ type TimelineRowPropsWithRef = React.ComponentProps<typeof TimelineRow>;
8
+ type TimelinePeriodPropsWithRef = React.ComponentProps<typeof TimelinePeriod>;
9
+
10
+ type ParsedRow = {
11
+ label: string;
7
12
  icon?: React.ReactNode;
8
- headingTag: string;
13
+ headingTag?: string;
9
14
  periods: Omit<Period, "id" | "endInclusive">[];
10
- restProps: any;
11
- ref: any;
15
+ restProps: Omit<TimelineRowProps, "label" | "icon" | "headingTag">;
16
+ ref?: React.Ref<HTMLOListElement>;
12
17
  };
13
18
 
14
19
  export const parseRows = (rowChildren: ReactNode[]) => {
15
- const parsedChildren: ParsedChild[] = [];
16
- rowChildren?.forEach((r: React.ReactNode) => {
17
- const periods: ParsedChild["periods"] = [];
18
- if (React.isValidElement(r) && r?.props?.children) {
19
- if (Array.isArray(r.props.children)) {
20
- for (let i = 0; i < r.props.children.length; i++) {
21
- const p = r.props.children[i];
20
+ const parsedChildren: ParsedRow[] = [];
21
+
22
+ rowChildren?.forEach((row: React.ReactNode) => {
23
+ const periods: ParsedRow["periods"] = [];
24
+
25
+ if (
26
+ !React.isValidElement<TimelineRowPropsWithRef>(row) ||
27
+ !row.props.children
28
+ ) {
29
+ return;
30
+ }
22
31
 
23
- periods.push({
24
- start: p?.props?.start,
25
- end: p?.props?.end,
26
- status: p?.props?.status || "neutral",
27
- onSelectPeriod: p.props?.onSelectPeriod,
28
- label: r.props.label,
29
- icon: p.props.icon,
30
- children: p.props.children,
31
- isActive: p.props.isActive,
32
- statusLabel: p.props.statusLabel,
33
- restProps: omit(p.props, [
34
- "start",
35
- "end",
36
- "status",
37
- "onSelectPeriod",
38
- "label",
39
- "icon",
40
- "children",
41
- "isActive",
42
- "statusLabel",
43
- ]),
44
- ref: p?.ref,
45
- });
46
- }
47
- } else {
48
- periods.push({
49
- start: r.props.children.props.start,
50
- end: r.props.children.props.end,
51
- status: r.props.children.props?.status || "neutral",
52
- onSelectPeriod: r.props.children.props?.onSelectPeriod,
53
- label: r.props.label,
54
- icon: r.props.children.props?.icon,
55
- children: r.props.children.props?.children,
56
- statusLabel: r.props.children.props?.statusLabel,
57
- restProps: omit(r.props.children.props, [
58
- "start",
59
- "end",
60
- "status",
61
- "onSelectPeriod",
62
- "label",
63
- "icon",
64
- "children",
65
- "isActive",
66
- "statusLabel",
67
- ]),
68
- ref: r.props?.children?.ref,
69
- });
32
+ React.Children.toArray(row.props.children).forEach((period) => {
33
+ if (!React.isValidElement<TimelinePeriodPropsWithRef>(period)) {
34
+ return;
70
35
  }
71
- parsedChildren.push({
72
- label: r.props.label,
73
- icon: r.props.icon,
74
- headingTag: r.props.headingTag,
75
- periods,
76
- restProps: omit(r.props, ["label", "icon", "headingTag"]),
77
- ref: (r as any)?.ref,
36
+
37
+ periods.push({
38
+ start: period.props.start,
39
+ end: period.props.end,
40
+ status: period.props.status || "neutral",
41
+ onSelectPeriod: period.props.onSelectPeriod,
42
+ icon: period.props.icon,
43
+ children: period.props.children,
44
+ isActive: period.props.isActive,
45
+ statusLabel: period.props.statusLabel,
46
+ restProps: omit(period.props, [
47
+ "start",
48
+ "end",
49
+ "status",
50
+ "onSelectPeriod",
51
+ "icon",
52
+ "children",
53
+ "isActive",
54
+ "statusLabel",
55
+ "placement",
56
+ ]),
57
+ ref: getChildRef(period),
78
58
  });
79
- }
59
+ });
60
+
61
+ parsedChildren.push({
62
+ label: row.props.label,
63
+ icon: row.props.icon,
64
+ headingTag: row.props.headingTag,
65
+ periods,
66
+ restProps: omit(row.props, ["label", "icon", "headingTag"]),
67
+ ref: getChildRef(row),
68
+ });
80
69
  });
81
70
 
82
71
  return parsedChildren;
@@ -16,18 +16,19 @@ export interface Positioned {
16
16
 
17
17
  export interface Period {
18
18
  id: string;
19
- label?: string;
20
19
  start: Date;
21
20
  endInclusive: Date;
22
21
  status?: PeriodStatus;
23
- onSelectPeriod?: () => void;
22
+ onSelectPeriod?: (
23
+ e: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>,
24
+ ) => void;
24
25
  icon?: React.ReactNode;
25
26
  children?: React.ReactNode;
26
27
  end: Date;
27
28
  isActive?: boolean;
28
29
  statusLabel?: string;
29
30
  restProps?: any;
30
- ref?: Element;
31
+ ref?: React.Ref<HTMLDivElement | HTMLButtonElement>;
31
32
  }
32
33
 
33
34
  export interface PositionedPeriod extends Period, Positioned {
@@ -21,7 +21,9 @@ export interface Period {
21
21
  start: Date;
22
22
  endInclusive: Date;
23
23
  status?: PeriodStatus;
24
- onSelectPeriod?: () => void;
24
+ onSelectPeriod?: (
25
+ e: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>,
26
+ ) => void;
25
27
  icon?: React.ReactNode;
26
28
  children?: React.ReactNode;
27
29
  isActive?: boolean;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Give warnings based on component composition (which slot/parent a child is rendered in).
3
+ *
4
+ * Used when child components need to know which slot/parent they are rendered in
5
+ * (e.g. `FormSummary.Header` vs `FormSummary.Footer`) and should warn or error in development
6
+ * if placed in a discouraged or forbidden slot.
7
+ *
8
+ * Usage:
9
+ * - Wrap slot components with <CompositionWarning.Root name="FormSummary.Header">...</CompositionWarning.Root>
10
+ * - In child: `<CompositionWarning.Forbidden name="FormSummary.Header" />` to forbid slot.
11
+ *
12
+ * This is guidance only: warnings are logged to the console in development, never enforced at runtime.
13
+ */
14
+ import React, { useEffect, useRef } from "react";
15
+ import { Slot } from "../../slot/Slot";
16
+ import { createContext } from "../create-context";
17
+
18
+ type CompositionName = string;
19
+
20
+ const isDev = process.env.NODE_ENV !== "production";
21
+
22
+ type CompositionWarningContextType = {
23
+ /**
24
+ * Name of the slot component we want to check.
25
+ */
26
+ name: CompositionName;
27
+ };
28
+
29
+ const [CompositionWarning, useCompositionWarning] =
30
+ createContext<CompositionWarningContextType>({
31
+ errorMessage:
32
+ "useCompositionWarning() must be used within <CompositionWarning />",
33
+ });
34
+
35
+ type CompositionWarningForbiddenProps = {
36
+ children?: React.ReactElement;
37
+ /**
38
+ * Name of the parent slot component where the child is not allowed.
39
+ */
40
+ name: CompositionName;
41
+ /**
42
+ * Warning message to display if the child is found.
43
+ */
44
+ message: string;
45
+ };
46
+
47
+ function CompositionWarningForbidden({
48
+ children,
49
+ name,
50
+ message,
51
+ }: CompositionWarningForbiddenProps) {
52
+ const compositionName = useCompositionWarning(false)?.name;
53
+
54
+ const elementRef = useRef<HTMLElement>(null);
55
+
56
+ useEffect(() => {
57
+ if (!isDev || !compositionName || name !== compositionName) {
58
+ return;
59
+ }
60
+
61
+ console.warn(`[Aksel] ${message}\nElement: `, elementRef.current);
62
+ }, [compositionName, name, message]);
63
+
64
+ return <Slot ref={elementRef}>{children}</Slot>;
65
+ }
66
+
67
+ export { CompositionWarningForbidden as Forbidden, CompositionWarning as Root };
@@ -0,0 +1 @@
1
+ export * as CompositionWarning from "./CompositionWarning";
@@ -0,0 +1,6 @@
1
+ export const getChildRef = <T>(
2
+ children: React.ReactElement<React.RefAttributes<T>>,
3
+ ): React.Ref<T> | undefined =>
4
+ Object.prototype.propertyIsEnumerable.call(children.props, "ref")
5
+ ? (children.props as any).ref // React 19 (children.ref still works, but gives a warning)
6
+ : (children as any).ref; // React <19
@@ -1,4 +1,4 @@
1
- import { Args } from "@storybook/react";
1
+ import { Args, StoryObj } from "@storybook/react";
2
2
  import React from "react";
3
3
  import { Renderer, StoryContext } from "storybook/internal/types";
4
4
 
@@ -8,15 +8,18 @@ export function renderStoriesForChromatic(
8
8
  | { render?: (...args: any[]) => React.ReactNode }
9
9
  | React.FunctionComponent<void>
10
10
  >,
11
- ) {
11
+ ): StoryObj {
12
12
  return {
13
- render: (...args: [Args, StoryContext<Renderer, Args>]) =>
14
- Object.entries(stories).map(([storyName, story]) => (
15
- <div key={storyName}>
16
- <h2 className="storyheading">{storyName}</h2>
17
- {typeof story === "function" ? story() : story.render?.(...args)}
18
- </div>
19
- )),
13
+ render: (...args: [Args, StoryContext<Renderer, Args>]) => (
14
+ <>
15
+ {Object.entries(stories).map(([storyName, story]) => (
16
+ <div key={storyName}>
17
+ <h2 className="storyheading">{storyName}</h2>
18
+ {typeof story === "function" ? story() : story.render?.(...args)}
19
+ </div>
20
+ ))}
21
+ </>
22
+ ),
20
23
  parameters: {
21
24
  chromatic: { disable: false },
22
25
  },