@bonprix-ds/react-dialog 1.1.4 → 1.2.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/dist/index.js CHANGED
@@ -1,2 +1 @@
1
- import e from "./src/Dialog.js";
2
- export { e as default };
1
+ export { default } from "./src/Dialog.js";
@@ -1,10 +1,9 @@
1
1
  import e, { ButtonSection as t, Content as n, PrimaryButton as r, SecondaryButton as i, Title as a } from "./DialogRoot.js";
2
2
  import "react";
3
3
  import { jsx as o } from "react/jsx-runtime";
4
- //#region src/Dialog.tsx
4
+ // src/Dialog.tsx
5
5
  var s = (t) => /* @__PURE__ */ o(e, { ...t });
6
6
  s.displayName = "Dialog", s.Title = a, s.Content = n, s.ButtonSection = t, s.PrimaryButton = r, s.SecondaryButton = i;
7
- //#endregion
8
7
  export { s as default };
9
8
 
10
9
  //# sourceMappingURL=Dialog.js.map
@@ -3,7 +3,11 @@ import "./Dialog.css";
3
3
  interface BaseProps {
4
4
  /** Here, all of the subcomponents should be placed. */
5
5
  children: ReactNode;
6
- /** Callback function that is called when the dialog is supposed to be closed. Should be used in conjunction with `open` property. */
6
+ /**
7
+ * Callback function that is called when the dialog is supposed to be closed. Should be used in conjunction with `open` property.
8
+ *
9
+ * Once the dialog has closed, focus returns to the element that had it before the dialog opened.
10
+ */
7
11
  onClose: () => void;
8
12
  /** The z-index of the dialog. */
9
13
  zIndex?: number;
@@ -11,6 +15,8 @@ interface BaseProps {
11
15
  image?: ReactNode;
12
16
  /** Additional CSS classes for the wrapper element around `image`, not the image itself. Useful to specify height and tweak layout. */
13
17
  imageWrapperClassName?: string;
18
+ /** The accessible name of the close button. */
19
+ closeButtonLabel?: string;
14
20
  }
15
21
  type OpenProps = BaseProps & {
16
22
  /** Controls the visibility of the dialog. Should be used in conjunction with `onClose`. */
@@ -46,7 +52,7 @@ type DialogButtonProps<C extends ElementType> = {
46
52
  component?: C;
47
53
  } & Omit<ComponentProps<C>, "component">;
48
54
  declare const DialogRoot: {
49
- ({ open, isOpen, onClose, zIndex, children, image, imageWrapperClassName }: Props): React.JSX.Element;
55
+ ({ open, isOpen, onClose, zIndex, children, image, imageWrapperClassName, closeButtonLabel, }: Props): React.JSX.Element;
50
56
  displayName: string;
51
57
  };
52
58
  export declare const Title: {
@@ -1,18 +1,18 @@
1
1
  "use client";
2
- import "react";
3
- import * as e from "@radix-ui/react-dialog";
4
- import { twMerge as t } from "tailwind-merge";
5
- import { tv as n } from "tailwind-variants";
6
- import { backdrop as r, fadeAnimation as i } from "@bonprix-ds/internal-components";
7
- import a from "@bonprix-ds/react-button";
8
- import o from "@bonprix-ds/react-icon-button";
9
- import { CloserIcon as s } from "@bonprix-ds/react-icon/icons";
10
- import { ZIndexContext as c, useInnerOpen as l, usePrefersReducedMotion as u } from "@bonprix-ds/utils";
11
- import { warnDeprecated as d } from "@bonprix-ds/utils/deprecation";
2
+ import { useRef as e } from "react";
3
+ import * as t from "@radix-ui/react-dialog";
4
+ import { twMerge as n } from "tailwind-merge";
5
+ import { tv as r } from "tailwind-variants";
6
+ import { backdrop as i, fadeAnimation as a } from "@bonprix-ds/internal-components";
7
+ import o from "@bonprix-ds/react-button";
8
+ import s from "@bonprix-ds/react-icon-button";
9
+ import { CloserIcon as c } from "@bonprix-ds/react-icon/icons";
10
+ import { ZIndexContext as l, useFocusReturn as u, useInnerOpen as d, usePrefersReducedMotion as f } from "@bonprix-ds/utils";
11
+ import { warnDeprecated as p } from "@bonprix-ds/utils/deprecation";
12
12
  import "#styles";
13
- import { jsx as f, jsxs as p } from "react/jsx-runtime";
14
- //#region src/DialogRoot.tsx
15
- var m = n({
13
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
14
+ // src/DialogRoot.tsx
15
+ var g = r({
16
16
  slots: {
17
17
  modal: [
18
18
  "preflight fixed start-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
@@ -32,94 +32,100 @@ var m = n({
32
32
  },
33
33
  variants: {
34
34
  image: { true: { modal: "grid-cols-1 grid-rows-2 l:grid-cols-2 l:grid-rows-1" } },
35
- prefersReducedMotion: { false: { modal: [i()] } }
35
+ prefersReducedMotion: { false: { modal: [a()] } }
36
36
  }
37
- }), h = ({ open: n, isOpen: i, onClose: a, zIndex: h = 2, children: g, image: _, imageWrapperClassName: v = "" }) => {
38
- i !== void 0 && d("is-open-prop");
39
- let { wrapper: y } = m(), { innerOpen: b } = l(n ?? i ?? !1), { modal: x, imageBox: S, contentBox: C, closeButtonWrapper: w } = m({
40
- prefersReducedMotion: u(),
41
- image: !!_
37
+ }), _ = ({ open: r, isOpen: a, onClose: o, zIndex: _ = 2, children: v, image: y, imageWrapperClassName: b = "", closeButtonLabel: x = "Schließen" }) => {
38
+ a !== void 0 && p("is-open-prop");
39
+ let { wrapper: S } = g(), { innerOpen: C } = d(r ?? a ?? !1), w = e(null), { returnFocus: T } = u(C, w), { modal: E, imageBox: D, contentBox: O, closeButtonWrapper: k } = g({
40
+ prefersReducedMotion: f(),
41
+ image: !!y
42
42
  });
43
- return /* @__PURE__ */ f(e.Root, {
44
- open: b,
45
- children: /* @__PURE__ */ p(e.Portal, { children: [/* @__PURE__ */ f(e.Overlay, {
46
- className: r(),
47
- onClick: a,
48
- style: { zIndex: h - 1 }
49
- }), /* @__PURE__ */ f(e.Content, {
50
- className: x(),
51
- style: { zIndex: h },
43
+ return /* @__PURE__ */ m(t.Root, {
44
+ open: C,
45
+ children: /* @__PURE__ */ h(t.Portal, { children: [/* @__PURE__ */ m(t.Overlay, {
46
+ className: i(),
47
+ onClick: o,
48
+ style: { zIndex: _ - 1 }
49
+ }), /* @__PURE__ */ m(t.Content, {
50
+ ref: w,
51
+ className: E(),
52
+ style: { zIndex: _ },
52
53
  "data-bpds": "dialog",
53
54
  "aria-modal": "true",
54
- onEscapeKeyDown: a,
55
- children: /* @__PURE__ */ p(c.Provider, {
56
- value: h,
57
- children: [_ && /* @__PURE__ */ f("div", {
58
- className: t(S(), v),
59
- style: { zIndex: h },
60
- children: _
61
- }), /* @__PURE__ */ p("div", {
62
- className: C(),
63
- style: { zIndex: h },
55
+ onOpenAutoFocus: (e) => {
56
+ e.preventDefault(), e.target.focus();
57
+ },
58
+ onCloseAutoFocus: (e) => {
59
+ e.preventDefault(), T();
60
+ },
61
+ onEscapeKeyDown: o,
62
+ children: /* @__PURE__ */ h(l.Provider, {
63
+ value: _,
64
+ children: [y && /* @__PURE__ */ m("div", {
65
+ className: n(D(), b),
66
+ style: { zIndex: _ },
67
+ children: y
68
+ }), /* @__PURE__ */ h("div", {
69
+ className: O(),
70
+ style: { zIndex: _ },
64
71
  children: [
65
- /* @__PURE__ */ f(e.Close, {
72
+ /* @__PURE__ */ m(t.Close, {
66
73
  asChild: !0,
67
- children: /* @__PURE__ */ f("div", {
68
- className: w(),
69
- children: /* @__PURE__ */ f(o, {
74
+ children: /* @__PURE__ */ m("div", {
75
+ className: k(),
76
+ children: /* @__PURE__ */ m(s, {
70
77
  variant: "tertiary",
71
- icon: /* @__PURE__ */ f(s, {}),
78
+ icon: /* @__PURE__ */ m(c, {}),
72
79
  size: "small",
73
- label: "Schließen",
74
- onClick: a
80
+ label: x,
81
+ onClick: o
75
82
  })
76
83
  })
77
84
  }),
78
- /* @__PURE__ */ f(e.Description, { className: "sr-only" }),
79
- /* @__PURE__ */ f("div", {
80
- className: y(),
81
- children: g
85
+ /* @__PURE__ */ m(t.Description, { className: "sr-only" }),
86
+ /* @__PURE__ */ m("div", {
87
+ className: S(),
88
+ children: v
82
89
  })
83
90
  ]
84
91
  })]
85
92
  })
86
93
  })] })
87
94
  });
88
- }, g = ({ children: t }) => {
89
- let { title: n } = m();
90
- return /* @__PURE__ */ f(e.Title, {
95
+ }, v = ({ children: e }) => {
96
+ let { title: n } = g();
97
+ return /* @__PURE__ */ m(t.Title, {
91
98
  className: n(),
92
- children: t
99
+ children: e
93
100
  });
94
- }, _ = ({ children: e }) => {
95
- let { scrollArea: t, contentWrapper: n } = m();
96
- return /* @__PURE__ */ f("div", {
101
+ }, y = ({ children: e }) => {
102
+ let { scrollArea: t, contentWrapper: n } = g();
103
+ return /* @__PURE__ */ m("div", {
97
104
  className: t(),
98
- children: /* @__PURE__ */ f("div", {
105
+ children: /* @__PURE__ */ m("div", {
99
106
  className: n(),
100
107
  children: e
101
108
  })
102
109
  });
103
- }, v = ({ children: e }) => {
104
- let { buttonSection: t } = m();
105
- return /* @__PURE__ */ f("div", {
110
+ }, b = ({ children: e }) => {
111
+ let { buttonSection: t } = g();
112
+ return /* @__PURE__ */ m("div", {
106
113
  className: t(),
107
114
  children: e
108
115
  });
109
- }, y = ({ children: e, component: t = "button", ...n }) => /* @__PURE__ */ f(a, {
116
+ }, x = ({ children: e, component: t = "button", ...n }) => /* @__PURE__ */ m(o, {
110
117
  component: t,
111
118
  ...n,
112
119
  size: "large",
113
120
  children: e
114
- }), b = ({ children: e, component: t = "button", ...n }) => /* @__PURE__ */ f(a, {
121
+ }), S = ({ children: e, component: t = "button", ...n }) => /* @__PURE__ */ m(o, {
115
122
  component: t,
116
123
  ...n,
117
124
  variant: "secondary",
118
125
  size: "large",
119
126
  children: e
120
127
  });
121
- h.displayName = "Dialog", g.displayName = "Dialog.Title", _.displayName = "Dialog.Content", v.displayName = "Dialog.ButtonSection", y.displayName = "Dialog.PrimaryButton", b.displayName = "Dialog.SecondaryButton";
122
- //#endregion
123
- export { v as ButtonSection, _ as Content, y as PrimaryButton, b as SecondaryButton, g as Title, h as default };
128
+ _.displayName = "Dialog", v.displayName = "Dialog.Title", y.displayName = "Dialog.Content", b.displayName = "Dialog.ButtonSection", x.displayName = "Dialog.PrimaryButton", S.displayName = "Dialog.SecondaryButton";
129
+ export { b as ButtonSection, y as Content, x as PrimaryButton, S as SecondaryButton, v as Title, _ as default };
124
130
 
125
131
  //# sourceMappingURL=DialogRoot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DialogRoot.js","names":["Component","DialogPrimitive","Button","IconButton","generateClasses","tv","fadeAnimation","DialogRoot","isOpen","warnDeprecated","useInnerOpen","open","usePrefersReducedMotion","image","innerOpen","backdrop","onClose","zIndex","modal","ZIndexContext","twMerge","imageBox","imageWrapperClassName","contentBox","closeButtonWrapper","CloserIcon","wrapper","Title","title","Content","scrollArea","contentWrapper","ButtonSection","buttonSection","PrimaryButton","props","SecondaryButton"],"sources":["../../src/DialogRoot.tsx"],"sourcesContent":["\"use client\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport React, { ComponentProps, ElementType, ReactNode } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { tv } from \"tailwind-variants\";\n\nimport { backdrop, fadeAnimation } from \"@bonprix-ds/internal-components\";\nimport Button from \"@bonprix-ds/react-button\";\nimport IconButton from \"@bonprix-ds/react-icon-button\";\nimport { CloserIcon } from \"@bonprix-ds/react-icon/icons\";\nimport { usePrefersReducedMotion, ZIndexContext } from \"@bonprix-ds/utils\";\nimport { useInnerOpen } from \"@bonprix-ds/utils\";\nimport { warnDeprecated } from \"@bonprix-ds/utils/deprecation\";\n\nimport \"./Dialog.css\";\n\nconst generateClasses = tv({\n slots: {\n modal: [\n \"preflight fixed start-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2\", // Fixed position and centering\n \"h-fit min-h-[12.375rem] w-[37.5rem] max-w-[calc(100vw-2.5rem)] l:w-[67.5rem]\", // Size considering spacing to screen edges\n \"max-h-[calc(100dvh-var(--app-safe-area-inset-bottom,2.5rem)*2)]\",\n \"box-border grid grid-rows-1 justify-items-center\",\n \"outline-none\", // A click inside focuses the dialog, and a key press after it would draw the browser's focus ring around it\n ],\n imageBox: \"flex h-full w-full\",\n contentBox: \"relative box-border flex w-full max-w-[37.5rem] flex-col bg-clr-bg-modal py-7\",\n title: \"typography-bonprix-h4 px-7 text-clr-primary\",\n closeButtonWrapper: \"absolute end-1 top-1\",\n wrapper: \"flex h-full flex-col gap-5\",\n scrollArea: \"scroll-area relative h-full px-7\",\n contentWrapper: \"flex flex-col overflow-hidden\",\n buttonSection: \"flex flex-col gap-3 px-7\",\n },\n variants: {\n image: {\n true: {\n modal: \"grid-cols-1 grid-rows-2 l:grid-cols-2 l:grid-rows-1\",\n },\n },\n prefersReducedMotion: {\n false: {\n modal: [fadeAnimation()],\n },\n },\n },\n});\n\ninterface BaseProps {\n /** Here, all of the subcomponents should be placed. */\n children: ReactNode;\n /** Callback function that is called when the dialog is supposed to be closed. Should be used in conjunction with `open` property. */\n onClose: () => void;\n /** The z-index of the dialog. */\n zIndex?: number;\n /** Optional image slot that gets rendered left to (desktop) or above (mobile) the `children`. */\n image?: ReactNode;\n /** Additional CSS classes for the wrapper element around `image`, not the image itself. Useful to specify height and tweak layout. */\n imageWrapperClassName?: string;\n}\n\ntype OpenProps = BaseProps & {\n /** Controls the visibility of the dialog. Should be used in conjunction with `onClose`. */\n open: boolean;\n /** @deprecated [is-open-prop] Use `open` instead. */\n isOpen?: never;\n};\n\ntype DeprecatedOpenProps = BaseProps & {\n open?: never;\n /**\n * Controls the visibility of the dialog. Should be used in conjunction with `onClose`.\n * @deprecated [is-open-prop] Use `open` instead.\n */\n isOpen: boolean;\n};\n\nexport type Props = DeprecatedOpenProps | OpenProps;\n\nexport interface DialogTitleProps {\n /** The title to display in the dialog. */\n children: string;\n}\n\nexport interface DialogContentProps {\n /** The content to display in the dialog. */\n children: ReactNode;\n}\n\nexport interface DialogButtonSectionProps {\n /** Primary and secondary buttons should be placed inside this section. */\n children: ReactNode;\n}\n\ntype DialogButtonProps<C extends ElementType> = {\n /** The button text to render. */\n children: string;\n /** The semantic component to render the Button. Preferrably `\"button\"`. Native props will be passed to this component. */\n component?: C;\n} & Omit<ComponentProps<C>, \"component\">;\n\nconst DialogRoot = ({ open, isOpen, onClose, zIndex = 2, children, image, imageWrapperClassName = \"\" }: Props) => {\n if (isOpen !== undefined) warnDeprecated(\"is-open-prop\");\n const { wrapper } = generateClasses();\n const { innerOpen } = useInnerOpen(open ?? isOpen ?? false);\n\n const prefersReducedMotion = usePrefersReducedMotion();\n\n const { modal, imageBox, contentBox, closeButtonWrapper } = generateClasses({ prefersReducedMotion, image: !!image });\n const closeLabel = \"Schließen\";\n\n return (\n <DialogPrimitive.Root open={innerOpen}>\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay className={backdrop()} onClick={onClose} style={{ zIndex: zIndex - 1 }} />\n <DialogPrimitive.Content className={modal()} style={{ zIndex }} data-bpds=\"dialog\" aria-modal=\"true\" onEscapeKeyDown={onClose}>\n <ZIndexContext.Provider value={zIndex}>\n {image && (\n <div className={twMerge(imageBox(), imageWrapperClassName)} style={{ zIndex }}>\n {image}\n </div>\n )}\n <div className={contentBox()} style={{ zIndex }}>\n <DialogPrimitive.Close asChild>\n <div className={closeButtonWrapper()}>\n <IconButton variant=\"tertiary\" icon={<CloserIcon />} size=\"small\" label={closeLabel} onClick={onClose} />\n </div>\n </DialogPrimitive.Close>\n <DialogPrimitive.Description className=\"sr-only\"></DialogPrimitive.Description>\n <div className={wrapper()}>{children}</div>\n </div>\n </ZIndexContext.Provider>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n};\n\nexport const Title = ({ children }: DialogTitleProps) => {\n const { title } = generateClasses();\n\n return <DialogPrimitive.Title className={title()}>{children}</DialogPrimitive.Title>;\n};\n\nexport const Content = ({ children }: DialogContentProps) => {\n const { scrollArea, contentWrapper } = generateClasses();\n\n return (\n <div className={scrollArea()}>\n <div className={contentWrapper()}>{children}</div>\n </div>\n );\n};\n\nexport const ButtonSection = ({ children }: DialogButtonSectionProps) => {\n const { buttonSection } = generateClasses();\n\n return <div className={buttonSection()}>{children}</div>;\n};\n\nexport const PrimaryButton = <C extends ElementType>({ children, component = \"button\" as C, ...props }: DialogButtonProps<C>) => {\n const Component: ElementType = component;\n return (\n <Button component={Component} {...props} size=\"large\">\n {children}\n </Button>\n );\n};\n\nexport const SecondaryButton = <C extends ElementType>({ children, component = \"button\" as C, ...props }: DialogButtonProps<C>) => {\n const Component: ElementType = component;\n return (\n <Button component={Component} {...props} variant=\"secondary\" size=\"large\">\n {children}\n </Button>\n );\n};\n\nDialogRoot.displayName = \"Dialog\";\nTitle.displayName = \"Dialog.Title\";\nContent.displayName = \"Dialog.Content\";\nButtonSection.displayName = \"Dialog.ButtonSection\";\nPrimaryButton.displayName = \"Dialog.PrimaryButton\";\nSecondaryButton.displayName = \"Dialog.SecondaryButton\";\n\nexport default DialogRoot;\n"],"mappings":"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"}
1
+ {"version":3,"file":"DialogRoot.js","names":["Component","DialogPrimitive","Button","IconButton","generateClasses","tv","fadeAnimation","DialogRoot","isOpen","warnDeprecated","useInnerOpen","open","contentRef","useRef","useFocusReturn","innerOpen","usePrefersReducedMotion","image","backdrop","onClose","zIndex","modal","event","returnFocus","ZIndexContext","twMerge","imageBox","imageWrapperClassName","contentBox","closeButtonWrapper","CloserIcon","closeButtonLabel","wrapper","Title","title","Content","scrollArea","contentWrapper","ButtonSection","buttonSection","PrimaryButton","props","SecondaryButton"],"sources":["../../src/DialogRoot.tsx"],"sourcesContent":["\"use client\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport React, { ComponentProps, ElementType, ReactNode, useRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { tv } from \"tailwind-variants\";\n\nimport { backdrop, fadeAnimation } from \"@bonprix-ds/internal-components\";\nimport Button from \"@bonprix-ds/react-button\";\nimport IconButton from \"@bonprix-ds/react-icon-button\";\nimport { CloserIcon } from \"@bonprix-ds/react-icon/icons\";\nimport { useFocusReturn, useInnerOpen, usePrefersReducedMotion, ZIndexContext } from \"@bonprix-ds/utils\";\nimport { warnDeprecated } from \"@bonprix-ds/utils/deprecation\";\n\nimport \"./Dialog.css\";\n\nconst generateClasses = tv({\n slots: {\n modal: [\n \"preflight fixed start-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2\", // Fixed position and centering\n \"h-fit min-h-[12.375rem] w-[37.5rem] max-w-[calc(100vw-2.5rem)] l:w-[67.5rem]\", // Size considering spacing to screen edges\n \"max-h-[calc(100dvh-var(--app-safe-area-inset-bottom,2.5rem)*2)]\",\n \"box-border grid grid-rows-1 justify-items-center\",\n \"outline-none\", // A click inside focuses the dialog, and a key press after it would draw the browser's focus ring around it\n ],\n imageBox: \"flex h-full w-full\",\n contentBox: \"relative box-border flex w-full max-w-[37.5rem] flex-col bg-clr-bg-modal py-7\",\n title: \"typography-bonprix-h4 px-7 text-clr-primary\",\n closeButtonWrapper: \"absolute end-1 top-1\",\n wrapper: \"flex h-full flex-col gap-5\",\n scrollArea: \"scroll-area relative h-full px-7\",\n contentWrapper: \"flex flex-col overflow-hidden\",\n buttonSection: \"flex flex-col gap-3 px-7\",\n },\n variants: {\n image: {\n true: {\n modal: \"grid-cols-1 grid-rows-2 l:grid-cols-2 l:grid-rows-1\",\n },\n },\n prefersReducedMotion: {\n false: {\n modal: [fadeAnimation()],\n },\n },\n },\n});\n\ninterface BaseProps {\n /** Here, all of the subcomponents should be placed. */\n children: ReactNode;\n /**\n * Callback function that is called when the dialog is supposed to be closed. Should be used in conjunction with `open` property.\n *\n * Once the dialog has closed, focus returns to the element that had it before the dialog opened.\n */\n onClose: () => void;\n /** The z-index of the dialog. */\n zIndex?: number;\n /** Optional image slot that gets rendered left to (desktop) or above (mobile) the `children`. */\n image?: ReactNode;\n /** Additional CSS classes for the wrapper element around `image`, not the image itself. Useful to specify height and tweak layout. */\n imageWrapperClassName?: string;\n /** The accessible name of the close button. */\n closeButtonLabel?: string;\n}\n\ntype OpenProps = BaseProps & {\n /** Controls the visibility of the dialog. Should be used in conjunction with `onClose`. */\n open: boolean;\n /** @deprecated [is-open-prop] Use `open` instead. */\n isOpen?: never;\n};\n\ntype DeprecatedOpenProps = BaseProps & {\n open?: never;\n /**\n * Controls the visibility of the dialog. Should be used in conjunction with `onClose`.\n * @deprecated [is-open-prop] Use `open` instead.\n */\n isOpen: boolean;\n};\n\nexport type Props = DeprecatedOpenProps | OpenProps;\n\nexport interface DialogTitleProps {\n /** The title to display in the dialog. */\n children: string;\n}\n\nexport interface DialogContentProps {\n /** The content to display in the dialog. */\n children: ReactNode;\n}\n\nexport interface DialogButtonSectionProps {\n /** Primary and secondary buttons should be placed inside this section. */\n children: ReactNode;\n}\n\ntype DialogButtonProps<C extends ElementType> = {\n /** The button text to render. */\n children: string;\n /** The semantic component to render the Button. Preferrably `\"button\"`. Native props will be passed to this component. */\n component?: C;\n} & Omit<ComponentProps<C>, \"component\">;\n\nconst DialogRoot = ({\n open,\n isOpen,\n onClose,\n zIndex = 2,\n children,\n image,\n imageWrapperClassName = \"\",\n closeButtonLabel = \"Schließen\",\n}: Props) => {\n if (isOpen !== undefined) warnDeprecated(\"is-open-prop\");\n const { wrapper } = generateClasses();\n const { innerOpen } = useInnerOpen(open ?? isOpen ?? false);\n const contentRef = useRef<HTMLDivElement>(null);\n const { returnFocus } = useFocusReturn(innerOpen, contentRef);\n\n const prefersReducedMotion = usePrefersReducedMotion();\n\n const { modal, imageBox, contentBox, closeButtonWrapper } = generateClasses({ prefersReducedMotion, image: !!image });\n\n const focusDialog = (event: Event) => {\n event.preventDefault();\n (event.target as HTMLElement).focus();\n };\n\n const returnFocusOnceClosed = (event: Event) => {\n event.preventDefault();\n returnFocus();\n };\n\n return (\n <DialogPrimitive.Root open={innerOpen}>\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay className={backdrop()} onClick={onClose} style={{ zIndex: zIndex - 1 }} />\n <DialogPrimitive.Content\n ref={contentRef}\n className={modal()}\n style={{ zIndex }}\n data-bpds=\"dialog\"\n aria-modal=\"true\"\n onOpenAutoFocus={focusDialog}\n onCloseAutoFocus={returnFocusOnceClosed}\n onEscapeKeyDown={onClose}\n >\n <ZIndexContext.Provider value={zIndex}>\n {image && (\n <div className={twMerge(imageBox(), imageWrapperClassName)} style={{ zIndex }}>\n {image}\n </div>\n )}\n <div className={contentBox()} style={{ zIndex }}>\n <DialogPrimitive.Close asChild>\n <div className={closeButtonWrapper()}>\n <IconButton variant=\"tertiary\" icon={<CloserIcon />} size=\"small\" label={closeButtonLabel} onClick={onClose} />\n </div>\n </DialogPrimitive.Close>\n <DialogPrimitive.Description className=\"sr-only\"></DialogPrimitive.Description>\n <div className={wrapper()}>{children}</div>\n </div>\n </ZIndexContext.Provider>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n};\n\nexport const Title = ({ children }: DialogTitleProps) => {\n const { title } = generateClasses();\n\n return <DialogPrimitive.Title className={title()}>{children}</DialogPrimitive.Title>;\n};\n\nexport const Content = ({ children }: DialogContentProps) => {\n const { scrollArea, contentWrapper } = generateClasses();\n\n return (\n <div className={scrollArea()}>\n <div className={contentWrapper()}>{children}</div>\n </div>\n );\n};\n\nexport const ButtonSection = ({ children }: DialogButtonSectionProps) => {\n const { buttonSection } = generateClasses();\n\n return <div className={buttonSection()}>{children}</div>;\n};\n\nexport const PrimaryButton = <C extends ElementType>({ children, component = \"button\" as C, ...props }: DialogButtonProps<C>) => {\n const Component: ElementType = component;\n return (\n <Button component={Component} {...props} size=\"large\">\n {children}\n </Button>\n );\n};\n\nexport const SecondaryButton = <C extends ElementType>({ children, component = \"button\" as C, ...props }: DialogButtonProps<C>) => {\n const Component: ElementType = component;\n return (\n <Button component={Component} {...props} variant=\"secondary\" size=\"large\">\n {children}\n </Button>\n );\n};\n\nDialogRoot.displayName = \"Dialog\";\nTitle.displayName = \"Dialog.Title\";\nContent.displayName = \"Dialog.Content\";\nButtonSection.displayName = \"Dialog.ButtonSection\";\nPrimaryButton.displayName = \"Dialog.PrimaryButton\";\nSecondaryButton.displayName = \"Dialog.SecondaryButton\";\n\nexport default DialogRoot;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bonprix-ds/react-dialog",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "Dialog component, implemented in React, for the Bonprix Design System.",
5
5
  "keywords": [],
6
6
  "license": "UNLICENSED",
@@ -41,21 +41,21 @@
41
41
  "provenance": true
42
42
  },
43
43
  "dependencies": {
44
- "@radix-ui/react-dialog": "1.1.23",
45
- "tailwind-merge": "2.5.4",
46
- "@bonprix-ds/internal-components": "0.2.5",
47
- "@bonprix-ds/react-button": "1.1.5",
48
- "@bonprix-ds/react-icon": "1.3.2",
49
- "@bonprix-ds/react-icon-button": "1.2.5",
50
- "@bonprix-ds/utils": "0.5.0"
44
+ "@bonprix-ds/internal-components": "0.2.6",
45
+ "@bonprix-ds/react-button": "1.1.6",
46
+ "@bonprix-ds/react-icon": "1.3.3",
47
+ "@bonprix-ds/react-icon-button": "1.2.6",
48
+ "@bonprix-ds/utils": "0.6.0",
49
+ "@radix-ui/react-dialog": "1.3.1",
50
+ "tailwind-merge": "2.5.4"
51
51
  },
52
52
  "devDependencies": {
53
+ "@bonprix-ds/vite-config": "0.0.0",
53
54
  "@testing-library/dom": "10.4.2",
54
55
  "@testing-library/react": "16.3.3",
55
56
  "@types/react": "19.3.0",
56
- "vite": "8.3.3",
57
- "vitest": "5.0.5",
58
- "@bonprix-ds/vite-config": "0.0.0"
57
+ "vite": "8.3.5",
58
+ "vitest": "5.0.5"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "react": "^19",