@jobber/components 9.10.4 → 9.12.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.
@@ -5,7 +5,13 @@ import type { IconProps } from "../Icon";
5
5
  type AvatarSize = "base" | "large" | "small";
6
6
  interface AvatarFoundationProps {
7
7
  /**
8
- * A url for the image that will be displayed
8
+ * A URL for the image that will be displayed
9
+ */
10
+ readonly src?: string;
11
+ /**
12
+ * A URL for the image that will be displayed
13
+ *
14
+ * @deprecated Use `src` instead.
9
15
  */
10
16
  readonly imageUrl?: string;
11
17
  /**
@@ -50,13 +56,16 @@ interface AvatarFoundationProps {
50
56
  } & InitialsUnsafeStyleProps;
51
57
  }
52
58
  interface AvatarWithImageProps extends AvatarFoundationProps {
59
+ readonly src: string;
60
+ }
61
+ interface AvatarWithLegacyImageProps extends AvatarFoundationProps {
53
62
  readonly imageUrl: string;
54
63
  }
55
64
  interface AvatarWithInitialsProps extends AvatarFoundationProps {
56
65
  readonly initials: string;
57
66
  }
58
- export type AvatarProps = XOR<AvatarWithImageProps, AvatarWithInitialsProps>;
59
- export declare function Avatar({ imageUrl, name, initials, size, color, testID, UNSAFE_className, UNSAFE_style, }: AvatarProps): React.JSX.Element;
67
+ export type AvatarProps = XOR<AvatarWithImageProps | AvatarWithLegacyImageProps, AvatarWithInitialsProps>;
68
+ export declare function Avatar({ src, imageUrl, name, initials, size, color, testID, UNSAFE_className, UNSAFE_style, }: AvatarProps): React.JSX.Element;
60
69
  interface InitialsUnsafeClassNameProps {
61
70
  initials?: string;
62
71
  fallbackIcon?: IconProps["UNSAFE_className"];
@@ -42,15 +42,16 @@ function deconstructCssCustomProperty(color) {
42
42
  }
43
43
 
44
44
  const MAX_VISIBLE_INITIALS = 3;
45
- function Avatar({ imageUrl, name, initials, size = "base", color, testID, UNSAFE_className = {}, UNSAFE_style = {}, }) {
45
+ function Avatar({ src, imageUrl, name, initials, size = "base", color, testID, UNSAFE_className = {}, UNSAFE_style = {}, }) {
46
+ const imageSource = src !== null && src !== void 0 ? src : imageUrl;
46
47
  const style = Object.assign({ backgroundColor: color, borderColor: color }, UNSAFE_style.container);
47
- if (imageUrl) {
48
- style.backgroundImage = `url(${imageUrl})`;
48
+ if (imageSource) {
49
+ style.backgroundImage = `url(${imageSource})`;
49
50
  }
50
51
  const shouldBeDark = color == undefined || isDark(color);
51
52
  const hasCustomColor = color != undefined;
52
53
  const className = classnames(styles.avatar, size !== "base" && styles[size], {
53
- [styles.hasBorder]: imageUrl && color,
54
+ [styles.hasBorder]: imageSource && color,
54
55
  [styles.isDark]: shouldBeDark,
55
56
  [styles.hasCustomColor]: hasCustomColor,
56
57
  });
@@ -60,7 +61,7 @@ function Avatar({ imageUrl, name, initials, size = "base", color, testID, UNSAFE
60
61
  : "text"
61
62
  : "textReverse";
62
63
  const containerClassNames = classnames(className, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container);
63
- return (React.createElement("div", { className: containerClassNames, style: style, role: imageUrl && "img", "aria-label": name, "data-testid": testID }, !imageUrl && (React.createElement(Initials, { initials: initials, iconColor: iconColor, iconSize: size, UNSAFE_className: {
64
+ return (React.createElement("div", { className: containerClassNames, style: style, role: imageSource && "img", "aria-label": name, "data-testid": testID }, !imageSource && (React.createElement(Initials, { initials: initials, iconColor: iconColor, iconSize: size, UNSAFE_className: {
64
65
  initials: UNSAFE_className.initials,
65
66
  fallbackIcon: UNSAFE_className.fallbackIcon,
66
67
  }, UNSAFE_style: {
package/dist/Avatar-es.js CHANGED
@@ -40,15 +40,16 @@ function deconstructCssCustomProperty(color) {
40
40
  }
41
41
 
42
42
  const MAX_VISIBLE_INITIALS = 3;
43
- function Avatar({ imageUrl, name, initials, size = "base", color, testID, UNSAFE_className = {}, UNSAFE_style = {}, }) {
43
+ function Avatar({ src, imageUrl, name, initials, size = "base", color, testID, UNSAFE_className = {}, UNSAFE_style = {}, }) {
44
+ const imageSource = src !== null && src !== void 0 ? src : imageUrl;
44
45
  const style = Object.assign({ backgroundColor: color, borderColor: color }, UNSAFE_style.container);
45
- if (imageUrl) {
46
- style.backgroundImage = `url(${imageUrl})`;
46
+ if (imageSource) {
47
+ style.backgroundImage = `url(${imageSource})`;
47
48
  }
48
49
  const shouldBeDark = color == undefined || isDark(color);
49
50
  const hasCustomColor = color != undefined;
50
51
  const className = classnames(styles.avatar, size !== "base" && styles[size], {
51
- [styles.hasBorder]: imageUrl && color,
52
+ [styles.hasBorder]: imageSource && color,
52
53
  [styles.isDark]: shouldBeDark,
53
54
  [styles.hasCustomColor]: hasCustomColor,
54
55
  });
@@ -58,7 +59,7 @@ function Avatar({ imageUrl, name, initials, size = "base", color, testID, UNSAFE
58
59
  : "text"
59
60
  : "textReverse";
60
61
  const containerClassNames = classnames(className, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container);
61
- return (React__default.createElement("div", { className: containerClassNames, style: style, role: imageUrl && "img", "aria-label": name, "data-testid": testID }, !imageUrl && (React__default.createElement(Initials, { initials: initials, iconColor: iconColor, iconSize: size, UNSAFE_className: {
62
+ return (React__default.createElement("div", { className: containerClassNames, style: style, role: imageSource && "img", "aria-label": name, "data-testid": testID }, !imageSource && (React__default.createElement(Initials, { initials: initials, iconColor: iconColor, iconSize: size, UNSAFE_className: {
62
63
  initials: UNSAFE_className.initials,
63
64
  fallbackIcon: UNSAFE_className.fallbackIcon,
64
65
  }, UNSAFE_style: {
@@ -106,11 +106,13 @@ export type DialogCloseRender = ReactElement | ((props: DialogCloseRenderProps)
106
106
  export interface DialogCloseProps extends DialogBaseProps, Omit<BaseDialog.Close.Props, BaseUIPropsToExclude> {
107
107
  /**
108
108
  * Optional content for the dismiss control. An Atlantis `<Button>` is adapted
109
- * automatically; any other valid element is used as-is. The default ButtonDismiss is used if no children or render is provided.
109
+ * automatically; any other valid element is used as-is. Defaults to a subtle
110
+ * tertiary `Button` with a `cross` icon when neither `children` nor `render`
111
+ * is provided.
110
112
  */
111
113
  readonly children?: ReactNode;
112
114
  /**
113
- * Renders a custom dismiss element in place of the default `ButtonDismiss`
115
+ * Renders a custom dismiss element in place of the default close button.
114
116
  * Pass an element or a function that receives the
115
117
  * BaseUI close props (so the element stays wired to close the dialog).
116
118
  */
@@ -15,8 +15,8 @@ export declare function resolveComposableTriggerRender({ children, render, }: {
15
15
  /**
16
16
  * Resolves the dismiss element for `Dialog.Close`, mirroring
17
17
  * `resolveComposableTriggerRender` so a custom render works in both shells.
18
- * Falls back to the subtle "cross" `ButtonDismiss` when neither `render` nor
19
- * `children` are supplied. An Atlantis `<Button>`/`<ButtonDismiss>` passed via
18
+ * Falls back to a subtle tertiary `Button` with a `cross` icon when neither
19
+ * `render` nor `children` are supplied. An Atlantis `<Button>` passed via
20
20
  * `render` or `children` is adapted; any other valid element is used as-is.
21
21
  */
22
22
  export declare function resolveComposableCloseRender({ children, render, }: {
@@ -24,17 +24,19 @@ const inputAvatarMessages = useAtlantisI18n.defineMessages({
24
24
  });
25
25
 
26
26
  function InputAvatar(_a) {
27
+ var _b;
27
28
  var { getUploadParams, onUploadComplete, onChange } = _a, avatarProps = tslib_es6.__rest(_a, ["getUploadParams", "onUploadComplete", "onChange"]);
28
29
  const [progress, setProgress] = React.useState(1);
29
30
  const { t } = useAtlantisI18n.useAtlantisI18n(inputAvatarMessages);
31
+ const imageSource = (_b = avatarProps.src) !== null && _b !== void 0 ? _b : avatarProps.imageUrl;
30
32
  return (React.createElement("div", { className: styles.inputAvatar },
31
33
  React.createElement("div", { className: styles.preview },
32
34
  React.createElement(Avatar.Avatar, Object.assign({ size: "large" }, avatarProps)),
33
35
  progress < 1 && (React.createElement(Overlay, null,
34
36
  React.createElement(Centered, null,
35
37
  React.createElement(ProgressBar.ProgressBar, { size: "small", currentStep: progress * 100, totalSteps: 100 }))))),
36
- React.createElement(InputFile.InputFile, { variation: "button", buttonLabel: avatarProps.imageUrl ? t("changeImage") : undefined, size: "small", allowedTypes: "images", getUploadParams: getUploadParams, onUploadStart: handleChange, onUploadProgress: handleUpload, onUploadComplete: handleUploadComplete }),
37
- avatarProps.imageUrl != undefined && progress === 1 && (React.createElement(Button.Button, { label: t("remove"), size: "small", type: "secondary", variation: "destructive", onClick: clearAvatar }))));
38
+ React.createElement(InputFile.InputFile, { variation: "button", buttonLabel: imageSource ? t("changeImage") : undefined, size: "small", allowedTypes: "images", getUploadParams: getUploadParams, onUploadStart: handleChange, onUploadProgress: handleUpload, onUploadComplete: handleUploadComplete }),
39
+ imageSource != undefined && progress === 1 && (React.createElement(Button.Button, { label: t("remove"), size: "small", type: "secondary", variation: "destructive", onClick: clearAvatar }))));
38
40
  function handleChange(newFile) {
39
41
  onChange && onChange(newFile);
40
42
  handleUpload(newFile);
@@ -22,17 +22,19 @@ const inputAvatarMessages = defineMessages({
22
22
  });
23
23
 
24
24
  function InputAvatar(_a) {
25
+ var _b;
25
26
  var { getUploadParams, onUploadComplete, onChange } = _a, avatarProps = __rest(_a, ["getUploadParams", "onUploadComplete", "onChange"]);
26
27
  const [progress, setProgress] = useState(1);
27
28
  const { t } = useAtlantisI18n(inputAvatarMessages);
29
+ const imageSource = (_b = avatarProps.src) !== null && _b !== void 0 ? _b : avatarProps.imageUrl;
28
30
  return (React__default.createElement("div", { className: styles.inputAvatar },
29
31
  React__default.createElement("div", { className: styles.preview },
30
32
  React__default.createElement(Avatar, Object.assign({ size: "large" }, avatarProps)),
31
33
  progress < 1 && (React__default.createElement(Overlay, null,
32
34
  React__default.createElement(Centered, null,
33
35
  React__default.createElement(ProgressBar, { size: "small", currentStep: progress * 100, totalSteps: 100 }))))),
34
- React__default.createElement(InputFile, { variation: "button", buttonLabel: avatarProps.imageUrl ? t("changeImage") : undefined, size: "small", allowedTypes: "images", getUploadParams: getUploadParams, onUploadStart: handleChange, onUploadProgress: handleUpload, onUploadComplete: handleUploadComplete }),
35
- avatarProps.imageUrl != undefined && progress === 1 && (React__default.createElement(Button, { label: t("remove"), size: "small", type: "secondary", variation: "destructive", onClick: clearAvatar }))));
36
+ React__default.createElement(InputFile, { variation: "button", buttonLabel: imageSource ? t("changeImage") : undefined, size: "small", allowedTypes: "images", getUploadParams: getUploadParams, onUploadStart: handleChange, onUploadProgress: handleUpload, onUploadComplete: handleUploadComplete }),
37
+ imageSource != undefined && progress === 1 && (React__default.createElement(Button, { label: t("remove"), size: "small", type: "secondary", variation: "destructive", onClick: clearAvatar }))));
36
38
  function handleChange(newFile) {
37
39
  onChange && onChange(newFile);
38
40
  handleUpload(newFile);
@@ -1,3 +1,6 @@
1
1
  import React from "react";
2
2
  import type { ModalLegacyProps } from "./Modal.types";
3
+ /**
4
+ * @deprecated Use the `Dialog` component instead.
5
+ */
3
6
  export declare function ModalLegacy({ open, title, size, dismissible, children, primaryAction, secondaryAction, tertiaryAction, onRequestClose, ariaLabel, }: ModalLegacyProps): React.JSX.Element;
@@ -1,11 +1,25 @@
1
1
  import type { PropsWithChildren } from "react";
2
2
  import React from "react";
3
3
  import type { HeaderProps, ModalActionsProps, ModalContentProps as ModalContainerProps } from "./Modal.types";
4
+ /**
5
+ * @deprecated Use `Dialog.Header` with `Dialog.Title` and `Dialog.Close` instead.
6
+ */
4
7
  export declare function ModalHeader({ title, children }: HeaderProps): React.JSX.Element;
8
+ /**
9
+ * @deprecated Use `Dialog.Actions` inside a `Dialog.Footer` instead.
10
+ */
5
11
  export declare function ModalActions({ primary, secondary, tertiary, }: ModalActionsProps): React.JSX.Element;
12
+ /**
13
+ * @deprecated Use `Dialog.Trigger` instead.
14
+ */
6
15
  export declare function ModalActivator({ children }: PropsWithChildren): React.JSX.Element;
7
16
  /**
8
17
  * Background overlay for the modal. Used in the ModalContent.
18
+ *
19
+ * @deprecated Use the `Dialog` component instead, which renders its own overlay.
9
20
  */
10
21
  export declare function ModalOverlay({ children }: PropsWithChildren): React.JSX.Element;
22
+ /**
23
+ * @deprecated Use `Dialog.Content` with `Dialog.Body` instead.
24
+ */
11
25
  export declare function ModalContent({ children }: ModalContainerProps): React.JSX.Element;
@@ -112,6 +112,9 @@ type HeaderWithChildren = PropsWithChildren<{
112
112
  readonly variant?: "inline" | "sticky";
113
113
  }>;
114
114
  export type HeaderProps = XOR<HeaderPropsWithoutChildren, HeaderWithChildren>;
115
+ /**
116
+ * @deprecated Use the `Dialog` component instead.
117
+ */
115
118
  export interface ModalLegacyProps {
116
119
  /**
117
120
  * @default false
@@ -13,5 +13,11 @@ export interface ModalProviderProps {
13
13
  readonly modalLabelledBy?: string;
14
14
  readonly ariaLabel?: string;
15
15
  }
16
+ /**
17
+ * @deprecated Use `Dialog` as the composable root instead.
18
+ */
16
19
  export declare function ModalProvider({ children, open, size, onRequestClose, activatorRef: refProp, dismissible, modalLabelledBy, ariaLabel, }: ModalProviderProps): React.JSX.Element;
20
+ /**
21
+ * @deprecated Use `Dialog.Close` or `Dialog.createHandle` instead.
22
+ */
17
23
  export declare function useModalContext(): ModalContextType;
@@ -44,6 +44,10 @@ const modalMessages = useAtlantisI18n.defineMessages({
44
44
  },
45
45
  });
46
46
 
47
+ /* eslint-disable import/no-deprecated -- Implements the deprecated prop-driven Modal; the imports below are Modal's own internals. Dialog is the replacement. */
48
+ /**
49
+ * @deprecated Use the `Dialog` component instead.
50
+ */
47
51
  function ModalLegacy({ open = false, title, size, dismissible = true, children, primaryAction, secondaryAction, tertiaryAction, onRequestClose, ariaLabel, }) {
48
52
  const modalClassName = classnames(styles$1.modal, size && sizes[size]);
49
53
  const containerClassName = classnames(styles$1.container, size === "fullScreen" && styles$1.containerFullScreen);
@@ -155,6 +159,9 @@ const ModalContext = React.createContext({
155
159
  dismissible: true,
156
160
  getFloatingProps: identity.identity,
157
161
  });
162
+ /**
163
+ * @deprecated Use `Dialog` as the composable root instead.
164
+ */
158
165
  function ModalProvider({ children, open = false, size, onRequestClose = noop.noop, activatorRef: refProp, dismissible = true, modalLabelledBy = MODAL_HEADER_ID, ariaLabel, }) {
159
166
  const startedInsideRef = React.useRef(true);
160
167
  const { floatingRefs, floatingContext, nodeId, activatorRef, parentId, getFloatingProps, } = useModal({
@@ -182,12 +189,18 @@ function ModalProvider({ children, open = false, size, onRequestClose = noop.noo
182
189
  }
183
190
  return React.createElement(floatingUi_react.FloatingTree, null, content);
184
191
  }
192
+ /**
193
+ * @deprecated Use `Dialog.Close` or `Dialog.createHandle` instead.
194
+ */
185
195
  function useModalContext() {
186
196
  return React.useContext(ModalContext);
187
197
  }
188
198
 
189
199
  var styles = {"overlay":"cRhQeXmZobs-","overlayBackground":"PO6ZUDxQoFE-","modal":"OiqCKNmbHZ0-","modalWithStickyRegions":"_6dGKr5VVf9Y-","stickyHeaderRegion":"uo6BCADQuLU-","stickyActionsRegion":"Vq0y9ggAxtI-","modalBody":"zM9SWwAd5Dg-","header":"GDWGHwmjgAc-","closeButton":"KJlGo4z-E6Q-","actionBar":"ZGrhWCAymCw-","leftAction":"hOiEWds2Vq8-","rightAction":"K31NzxPZP9s-","spinning":"SKeimJFlB-g-"};
190
200
 
201
+ /**
202
+ * @deprecated Use the `Dialog` component instead, which owns its own styling.
203
+ */
191
204
  function useModalStyles(size) {
192
205
  return {
193
206
  modal: classnames(styles.modal, size && sizes[size]),
@@ -201,6 +214,9 @@ function useModalStyles(size) {
201
214
  };
202
215
  }
203
216
 
217
+ /**
218
+ * @deprecated Use `Dialog.Header` with `Dialog.Title` and `Dialog.Close` instead.
219
+ */
204
220
  function ModalHeader({ title, children }) {
205
221
  const { header, dismissButton } = useModalStyles();
206
222
  const { dismissible, onRequestClose, modalLabelledBy } = useModalContext();
@@ -213,6 +229,9 @@ function ModalHeader({ title, children }) {
213
229
  dismissible && (React.createElement("div", { className: dismissButton },
214
230
  React.createElement(ButtonDismiss.ButtonDismiss, { onClick: onRequestClose, ariaLabel: t("closeModal") })))));
215
231
  }
232
+ /**
233
+ * @deprecated Use `Dialog.Actions` inside a `Dialog.Footer` instead.
234
+ */
216
235
  function ModalActions({ primary, secondary, tertiary, }) {
217
236
  const { actionBar, rightAction, leftAction } = useModalStyles();
218
237
  const shouldShow = primary != undefined || secondary != undefined || tertiary != undefined;
@@ -223,12 +242,17 @@ function ModalActions({ primary, secondary, tertiary, }) {
223
242
  tertiary && (React.createElement("div", { className: leftAction },
224
243
  React.createElement(Button.Button, Object.assign({ type: "secondary", variation: "destructive" }, tertiary))))))));
225
244
  }
245
+ /**
246
+ * @deprecated Use `Dialog.Trigger` instead.
247
+ */
226
248
  function ModalActivator({ children }) {
227
249
  const { activatorRef } = useModalContext();
228
250
  return (React.createElement("span", { ref: activatorRef, style: { display: "contents" } }, children));
229
251
  }
230
252
  /**
231
253
  * Background overlay for the modal. Used in the ModalContent.
254
+ *
255
+ * @deprecated Use the `Dialog` component instead, which renders its own overlay.
232
256
  */
233
257
  function ModalOverlay({ children }) {
234
258
  const { overlay, overlayBackground } = useModalStyles();
@@ -241,6 +265,9 @@ function ModalOverlay({ children }) {
241
265
  } }),
242
266
  children));
243
267
  }
268
+ /**
269
+ * @deprecated Use `Dialog.Content` with `Dialog.Body` instead.
270
+ */
244
271
  function ModalContent({ children }) {
245
272
  const { open, floatingContext, activatorRef, floatingRefs, size, floatingNodeId, modalLabelledBy, ariaLabel, getFloatingProps, startedInsideRef, } = useModalContext();
246
273
  const { modal } = useModalStyles(size);
@@ -287,13 +314,33 @@ function extractSticky(children, componentType, match) {
287
314
  return { sticky, rest };
288
315
  }
289
316
 
317
+ /* eslint-disable import/no-deprecated -- Assembles the deprecated Modal namespace from its own parts. Dialog is the replacement. */
318
+ /**
319
+ * @deprecated Use the `Dialog` component instead.
320
+ * @see https://atlantis.getjobber.com/components/Dialog/implement#component-view-migrating-to-dialog
321
+ */
290
322
  function Modal(props) {
291
323
  return React.createElement(ModalLegacy, Object.assign({}, props));
292
324
  }
325
+ /**
326
+ * @deprecated Use `Dialog.Header` with `Dialog.Title` and `Dialog.Close` instead.
327
+ */
293
328
  Modal.Header = ModalHeader;
329
+ /**
330
+ * @deprecated Use `Dialog.Actions` inside a `Dialog.Footer` instead.
331
+ */
294
332
  Modal.Actions = ModalActions;
333
+ /**
334
+ * @deprecated Use `Dialog.Trigger` instead.
335
+ */
295
336
  Modal.Activator = ModalActivator;
337
+ /**
338
+ * @deprecated Use `Dialog` as the composable root instead.
339
+ */
296
340
  Modal.Provider = ModalProvider;
341
+ /**
342
+ * @deprecated Use `Dialog.Content` with `Dialog.Body` instead.
343
+ */
297
344
  Modal.Content = ModalContent;
298
345
 
299
346
  exports.Modal = Modal;
@@ -3,8 +3,12 @@ import { ModalProvider } from "./ModalContext.rebuilt";
3
3
  import { ModalActions, ModalActivator, ModalContent, ModalHeader } from "./Modal.rebuilt";
4
4
  import type { ModalLegacyProps } from "./Modal.types";
5
5
  export type { ModalLegacyProps as ModalProps } from "./Modal.types";
6
- declare function Modal(props: ModalLegacyProps): React.JSX.Element;
7
- declare namespace Modal {
6
+ /**
7
+ * @deprecated Use the `Dialog` component instead.
8
+ * @see https://atlantis.getjobber.com/components/Dialog/implement#component-view-migrating-to-dialog
9
+ */
10
+ export declare function Modal(props: ModalLegacyProps): React.JSX.Element;
11
+ export declare namespace Modal {
8
12
  var Header: typeof ModalHeader;
9
13
  var Actions: typeof ModalActions;
10
14
  var Activator: typeof ModalActivator;
@@ -13,4 +17,3 @@ declare namespace Modal {
13
17
  }
14
18
  export { useModalContext } from "./ModalContext.rebuilt";
15
19
  export { useModalStyles } from "./useModalStyles";
16
- export { Modal };
@@ -42,6 +42,10 @@ const modalMessages = defineMessages({
42
42
  },
43
43
  });
44
44
 
45
+ /* eslint-disable import/no-deprecated -- Implements the deprecated prop-driven Modal; the imports below are Modal's own internals. Dialog is the replacement. */
46
+ /**
47
+ * @deprecated Use the `Dialog` component instead.
48
+ */
45
49
  function ModalLegacy({ open = false, title, size, dismissible = true, children, primaryAction, secondaryAction, tertiaryAction, onRequestClose, ariaLabel, }) {
46
50
  const modalClassName = classnames(styles$1.modal, size && sizes[size]);
47
51
  const containerClassName = classnames(styles$1.container, size === "fullScreen" && styles$1.containerFullScreen);
@@ -153,6 +157,9 @@ const ModalContext = createContext({
153
157
  dismissible: true,
154
158
  getFloatingProps: identity,
155
159
  });
160
+ /**
161
+ * @deprecated Use `Dialog` as the composable root instead.
162
+ */
156
163
  function ModalProvider({ children, open = false, size, onRequestClose = noop, activatorRef: refProp, dismissible = true, modalLabelledBy = MODAL_HEADER_ID, ariaLabel, }) {
157
164
  const startedInsideRef = useRef(true);
158
165
  const { floatingRefs, floatingContext, nodeId, activatorRef, parentId, getFloatingProps, } = useModal({
@@ -180,12 +187,18 @@ function ModalProvider({ children, open = false, size, onRequestClose = noop, ac
180
187
  }
181
188
  return React__default.createElement(FloatingTree, null, content);
182
189
  }
190
+ /**
191
+ * @deprecated Use `Dialog.Close` or `Dialog.createHandle` instead.
192
+ */
183
193
  function useModalContext() {
184
194
  return useContext(ModalContext);
185
195
  }
186
196
 
187
197
  var styles = {"overlay":"cRhQeXmZobs-","overlayBackground":"PO6ZUDxQoFE-","modal":"OiqCKNmbHZ0-","modalWithStickyRegions":"_6dGKr5VVf9Y-","stickyHeaderRegion":"uo6BCADQuLU-","stickyActionsRegion":"Vq0y9ggAxtI-","modalBody":"zM9SWwAd5Dg-","header":"GDWGHwmjgAc-","closeButton":"KJlGo4z-E6Q-","actionBar":"ZGrhWCAymCw-","leftAction":"hOiEWds2Vq8-","rightAction":"K31NzxPZP9s-","spinning":"SKeimJFlB-g-"};
188
198
 
199
+ /**
200
+ * @deprecated Use the `Dialog` component instead, which owns its own styling.
201
+ */
189
202
  function useModalStyles(size) {
190
203
  return {
191
204
  modal: classnames(styles.modal, size && sizes[size]),
@@ -199,6 +212,9 @@ function useModalStyles(size) {
199
212
  };
200
213
  }
201
214
 
215
+ /**
216
+ * @deprecated Use `Dialog.Header` with `Dialog.Title` and `Dialog.Close` instead.
217
+ */
202
218
  function ModalHeader({ title, children }) {
203
219
  const { header, dismissButton } = useModalStyles();
204
220
  const { dismissible, onRequestClose, modalLabelledBy } = useModalContext();
@@ -211,6 +227,9 @@ function ModalHeader({ title, children }) {
211
227
  dismissible && (React__default.createElement("div", { className: dismissButton },
212
228
  React__default.createElement(ButtonDismiss, { onClick: onRequestClose, ariaLabel: t("closeModal") })))));
213
229
  }
230
+ /**
231
+ * @deprecated Use `Dialog.Actions` inside a `Dialog.Footer` instead.
232
+ */
214
233
  function ModalActions({ primary, secondary, tertiary, }) {
215
234
  const { actionBar, rightAction, leftAction } = useModalStyles();
216
235
  const shouldShow = primary != undefined || secondary != undefined || tertiary != undefined;
@@ -221,12 +240,17 @@ function ModalActions({ primary, secondary, tertiary, }) {
221
240
  tertiary && (React__default.createElement("div", { className: leftAction },
222
241
  React__default.createElement(Button, Object.assign({ type: "secondary", variation: "destructive" }, tertiary))))))));
223
242
  }
243
+ /**
244
+ * @deprecated Use `Dialog.Trigger` instead.
245
+ */
224
246
  function ModalActivator({ children }) {
225
247
  const { activatorRef } = useModalContext();
226
248
  return (React__default.createElement("span", { ref: activatorRef, style: { display: "contents" } }, children));
227
249
  }
228
250
  /**
229
251
  * Background overlay for the modal. Used in the ModalContent.
252
+ *
253
+ * @deprecated Use the `Dialog` component instead, which renders its own overlay.
230
254
  */
231
255
  function ModalOverlay({ children }) {
232
256
  const { overlay, overlayBackground } = useModalStyles();
@@ -239,6 +263,9 @@ function ModalOverlay({ children }) {
239
263
  } }),
240
264
  children));
241
265
  }
266
+ /**
267
+ * @deprecated Use `Dialog.Content` with `Dialog.Body` instead.
268
+ */
242
269
  function ModalContent({ children }) {
243
270
  const { open, floatingContext, activatorRef, floatingRefs, size, floatingNodeId, modalLabelledBy, ariaLabel, getFloatingProps, startedInsideRef, } = useModalContext();
244
271
  const { modal } = useModalStyles(size);
@@ -285,13 +312,33 @@ function extractSticky(children, componentType, match) {
285
312
  return { sticky, rest };
286
313
  }
287
314
 
315
+ /* eslint-disable import/no-deprecated -- Assembles the deprecated Modal namespace from its own parts. Dialog is the replacement. */
316
+ /**
317
+ * @deprecated Use the `Dialog` component instead.
318
+ * @see https://atlantis.getjobber.com/components/Dialog/implement#component-view-migrating-to-dialog
319
+ */
288
320
  function Modal(props) {
289
321
  return React__default.createElement(ModalLegacy, Object.assign({}, props));
290
322
  }
323
+ /**
324
+ * @deprecated Use `Dialog.Header` with `Dialog.Title` and `Dialog.Close` instead.
325
+ */
291
326
  Modal.Header = ModalHeader;
327
+ /**
328
+ * @deprecated Use `Dialog.Actions` inside a `Dialog.Footer` instead.
329
+ */
292
330
  Modal.Actions = ModalActions;
331
+ /**
332
+ * @deprecated Use `Dialog.Trigger` instead.
333
+ */
293
334
  Modal.Activator = ModalActivator;
335
+ /**
336
+ * @deprecated Use `Dialog` as the composable root instead.
337
+ */
294
338
  Modal.Provider = ModalProvider;
339
+ /**
340
+ * @deprecated Use `Dialog.Content` with `Dialog.Body` instead.
341
+ */
295
342
  Modal.Content = ModalContent;
296
343
 
297
344
  export { Modal, useModalContext, useModalStyles };
@@ -1,4 +1,7 @@
1
1
  import sizes from "./ModalSizes.module.css";
2
+ /**
3
+ * @deprecated Use the `Dialog` component instead, which owns its own styling.
4
+ */
2
5
  export declare function useModalStyles(size?: keyof typeof sizes): {
3
6
  modal: string;
4
7
  overlay: string;
@@ -53,8 +53,8 @@ function resolveComposableTriggerRender({ children, render, }) {
53
53
  /**
54
54
  * Resolves the dismiss element for `Dialog.Close`, mirroring
55
55
  * `resolveComposableTriggerRender` so a custom render works in both shells.
56
- * Falls back to the subtle "cross" `ButtonDismiss` when neither `render` nor
57
- * `children` are supplied. An Atlantis `<Button>`/`<ButtonDismiss>` passed via
56
+ * Falls back to a subtle tertiary `Button` with a `cross` icon when neither
57
+ * `render` nor `children` are supplied. An Atlantis `<Button>` passed via
58
58
  * `render` or `children` is adapted; any other valid element is used as-is.
59
59
  */
60
60
  function resolveComposableCloseRender({ children, render, }) {
@@ -51,8 +51,8 @@ function resolveComposableTriggerRender({ children, render, }) {
51
51
  /**
52
52
  * Resolves the dismiss element for `Dialog.Close`, mirroring
53
53
  * `resolveComposableTriggerRender` so a custom render works in both shells.
54
- * Falls back to the subtle "cross" `ButtonDismiss` when neither `render` nor
55
- * `children` are supplied. An Atlantis `<Button>`/`<ButtonDismiss>` passed via
54
+ * Falls back to a subtle tertiary `Button` with a `cross` icon when neither
55
+ * `render` nor `children` are supplied. An Atlantis `<Button>` passed via
56
56
  * `render` or `children` is adapted; any other valid element is used as-is.
57
57
  */
58
58
  function resolveComposableCloseRender({ children, render, }) {
@@ -52,7 +52,7 @@ useful for applying styles via CSS Modules.
52
52
  // For Avatar with image
53
53
  <Avatar
54
54
  name="Custom Container Class Name"
55
- imageUrl="https://api.adorable.io/avatars/150/jobbler"
55
+ src="https://api.adorable.io/avatars/150/jobbler"
56
56
  UNSAFE_className={{ container: styles.customContainerClassName }}
57
57
  />
58
58
 
@@ -100,7 +100,7 @@ Use `UNSAFE_style` to apply inline custom styles to the Avatar component.
100
100
  // For Avatar with image
101
101
  <Avatar
102
102
  name="Custom Container Style"
103
- imageUrl="https://api.adorable.io/avatars/150/jobbler"
103
+ src="https://api.adorable.io/avatars/150/jobbler"
104
104
  UNSAFE_style={{
105
105
  container: {
106
106
  borderColor: "var(--color-green)",
@@ -139,10 +139,11 @@ Use `UNSAFE_style` to apply inline custom styles to the Avatar component.
139
139
  | Prop | Type | Required | Default | Description |
140
140
  |------|------|----------|---------|-------------|
141
141
  | `color` | `string` | No | — | The background and border color that represents the user. This should be represented as a value that can be read by CSS |
142
- | `imageUrl` | `string` | No | — | A url for the image that will be displayed |
142
+ | `imageUrl` | `string` | No | — | A URL for the image that will be displayed @deprecated Use `src` instead. |
143
143
  | `initials` | `string` | No | — | The initials that will be displayed if no image is set.\ |
144
144
  | `name` | `string` | No | — | A users name to be used for assistive technology |
145
145
  | `size` | `AvatarSize` | No | `base` | Change the size of the avatar @property "large" - Make avatar to be the focal point @property "small" - For higher-de... |
146
+ | `src` | `string` | No | — | A URL for the image that will be displayed |
146
147
  | `testID` | `string` | No | — | A reference to the element in the rendered output |
147
148
  | `UNSAFE_className` | `{ container?: string; } & InitialsUnsafeClassNameProps` | No | `{}` | **Use at your own risk:** Custom class names for specific elements. This should only be used as a **last resort**. Us... |
148
149
  | `UNSAFE_style` | `{ container?: CSSProperties; } & InitialsUnsafeStyleProps` | No | `{}` | **Use at your own risk:** Custom style for specific elements. This should only be used as a **last resort**. Using th... |
@@ -388,7 +388,7 @@ A key distinction between subtle buttons and the other variations is that the
388
388
  primary/secondary/tertiary scale is styled differently, but the conceptual
389
389
  hierarchy is the same. Notably, the tertiary subtle button has a transparent
390
390
  background, allowing it to be *extra* subtle when placed overtop
391
- `surface--background` elements such as a Modal header.
391
+ `surface--background` elements such as a Dialog header.
392
392
 
393
393
  ```tsx
394
394
  import React from "react";
@@ -1,7 +1,7 @@
1
1
  # Button Dismiss
2
2
 
3
3
  This private component is used as a dismissal button for public components, such
4
- as Modal and Popover.
4
+ as Popover and Drawer.
5
5
 
6
6
  ## Design & usage guidelines
7
7
 
@@ -22,7 +22,7 @@ export function ChipWithAvatarExample(
22
22
  <Chip.Prefix>
23
23
  <Avatar
24
24
  size="small"
25
- imageUrl="https://images.unsplash.com/photo-1669475535925-a011d7c31d45?q=80&w=1886&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
25
+ src="https://images.unsplash.com/photo-1669475535925-a011d7c31d45?q=80&w=1886&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
26
26
  />
27
27
  </Chip.Prefix>
28
28
  <Chip.Suffix>
@@ -156,7 +156,7 @@ application.
156
156
  #### Overlay
157
157
 
158
158
  Use to mask an area of the interface to promote focus to a foreground action,
159
- such as a [Modal](../Modal/Modal.md)'s appearance. Overlay includes built-in
159
+ such as a [Dialog](../Dialog/Dialog.md)'s appearance. Overlay includes built-in
160
160
  opacity values.
161
161
 
162
162
  #### Overlay--Dimmed
@@ -102,7 +102,7 @@ language should be direct and honest about the impact without being alarming.
102
102
  * To present non-blocking, contextual, text-only content, use a
103
103
  [Tooltip](../Tooltip/Tooltip.md)
104
104
  * To simply present information for users to view, edit, or for a temporary
105
- change of context, use a regular [Modal](../Modal/Modal.md)
105
+ change of context, use a regular [Dialog](../Dialog/Dialog.md)
106
106
 
107
107
 
108
108
  ## Props
@@ -295,12 +295,12 @@ control, omit `open`/`onRequestClose` and let the dialog manage itself.
295
295
 
296
296
  `Dialog.Trigger` and `Dialog.Close` accept Atlantis-style content and can render
297
297
  a default control, composed Atlantis `Button` content, or a custom element via
298
- `render`. An Atlantis `<Button>`/`<ButtonDismiss>` is adapted automatically; any
299
- other valid element is used as-is. When `render` is a function, it receives the
300
- Base UI props so the element stays wired to open/close the dialog.
298
+ `render`. An Atlantis `<Button>` is adapted automatically; any other valid
299
+ element is used as-is. When `render` is a function, it receives the Base UI
300
+ props so the element stays wired to open/close the dialog.
301
301
 
302
302
  ```tsx
303
- {/* default primary Button trigger / default ButtonDismiss close */}
303
+ {/* default primary Button trigger / default close Button */}
304
304
  <Dialog.Trigger>Open</Dialog.Trigger>
305
305
  <Dialog.Close />
306
306
 
@@ -951,7 +951,7 @@ verify the result rather than expecting an exact match.
951
951
  | `children` | `ReactNode` | No | — | Optional content for the dismiss control. An Atlantis `<Button>` is adapted automatically; any other valid element is... |
952
952
  | `className` | `string` | No | — | Class name applied to the part's root element. |
953
953
  | `nativeButton` | `boolean` | No | `true` | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if ... |
954
- | `render` | `DialogCloseRender` | No | — | Renders a custom dismiss element in place of the default `ButtonDismiss` Pass an element or a function that receives ... |
954
+ | `render` | `DialogCloseRender` | No | — | Renders a custom dismiss element in place of the default close button. Pass an element or a function that receives th... |
955
955
  | `style` | `CSSProperties` | No | — | Inline styles applied to the part's root element. |
956
956
 
957
957
  #### Dialog.Content
@@ -9,7 +9,7 @@ Use [SideDrawer](../SideDrawer/SideDrawer.md) if you need to overlay the page's
9
9
  content and block user interaction with the page, while still maintaining
10
10
  visibilty of the page's primary contents.
11
11
 
12
- Use [Modal](../Modal/Modal.md) if you need to overlay the page's content and
12
+ Use [Dialog](../Dialog/Dialog.md) if you need to overlay the page's content and
13
13
  block user interaction with the page, and do not need the user to have visibilty
14
14
  of the page's primary contents.
15
15
 
@@ -18,9 +18,10 @@ avatar. You can read more about `getUploadParams` in the
18
18
  |------|------|----------|---------|-------------|
19
19
  | `getUploadParams` | `(file: File) => UploadParams | Promise<UploadParams>` | Yes | — | A callback that receives a file object and returns a `UploadParams` needed to upload the file. More info is availabl... |
20
20
  | `color` | `string` | No | — | The background and border color that represents the user. This should be represented as a value that can be read by CSS |
21
- | `imageUrl` | `string` | No | — | A url for the image that will be displayed |
21
+ | `imageUrl` | `string` | No | — | A URL for the image that will be displayed @deprecated Use `src` instead. |
22
22
  | `initials` | `string` | No | — | The initials that will be displayed if no image is set.\ |
23
23
  | `name` | `string` | No | — | A users name to be used for assistive technology |
24
24
  | `onChange` | `(file?: FileUpload) => void` | No | — | Triggered when an image is changed. |
25
25
  | `onUploadComplete` | `(file?: FileUpload) => void` | No | — | Triggered when an image upload has completed. |
26
+ | `src` | `string` | No | — | A URL for the image that will be displayed |
26
27
  | `testID` | `string` | No | — | A reference to the element in the rendered output |
@@ -1,5 +1,10 @@
1
1
  # Modal
2
2
 
3
+ > **WARNING:** This component is deprecated. Use [Dialog](../Dialog/Dialog.md) instead for new
4
+ > work — see [migrating to
5
+ > Dialog](/components/Dialog/implement#component-view-migrating-to-dialog).
6
+ > `Modal` continues to work unchanged for existing call sites.
7
+
3
8
  Modals are overlays that allow users to view, edit, or show informations that
4
9
  doesn't require a page to be built. It also prevent users from interacting with
5
10
  the rest of the application until a specific action is taken.
@@ -10,7 +10,7 @@ Use [Drawer](../Drawer/Drawer.md) if you need to allow users to view
10
10
  supplementary content while still allowing users to interact with the main
11
11
  contents of the page.
12
12
 
13
- Use [Modal](../Modal/Modal.md) if you need to overlay the page's content and
13
+ Use [Dialog](../Dialog/Dialog.md) if you need to overlay the page's content and
14
14
  block user interaction with the page, and do not need the user to have visibilty
15
15
  of the page's primary contents.
16
16
 
@@ -48,7 +48,7 @@ form elements.
48
48
  ### Large
49
49
 
50
50
  Use `large` spacing for higher-level "parent" containers.
51
- [Modal](../Modal/Modal.md) uses `large` spacing in its header and around the
51
+ [Dialog](../Dialog/Dialog.md) uses `large` spacing in its header and around the
52
52
  edges to give itself a bit more prominence as a standalone view, in a similar
53
53
  manner to [Page](../Page/Page.md).
54
54
 
@@ -43,6 +43,35 @@ More complex full-page scaffolding can be found on the [Scaffolding](../scaffold
43
43
  </Stack>
44
44
  ```
45
45
 
46
+ ```tsx
47
+ <Stack>
48
+ <Heading level={2}>Stack Dialog Layouts</Heading>
49
+ <Text>Stacks are a great way to layout content in a dialog format. They are responsive and easy to read.</Text>
50
+ <Dialog>
51
+ <Dialog.Trigger>
52
+ <Button label="Open Dialog" />
53
+ </Dialog.Trigger>
54
+ <Dialog.Content>
55
+ <Dialog.Header>
56
+ <Dialog.Title>Dialog Layout</Dialog.Title>
57
+ <Dialog.Close />
58
+ </Dialog.Header>
59
+ <Dialog.Body>
60
+ <Stack>
61
+ <Text>A dialog with a header, body text, and footer</Text>
62
+ <Text>And they're all stacked vertically with equal spacing</Text>
63
+ </Stack>
64
+ </Dialog.Body>
65
+ <Dialog.Footer>
66
+ <Dialog.Actions
67
+ primary={<Dialog.Close render={<Button label="Close the Dialog" />} />}
68
+ />
69
+ </Dialog.Footer>
70
+ </Dialog.Content>
71
+ </Dialog>
72
+ </Stack>
73
+ ```
74
+
46
75
  ```tsx
47
76
  <Stack>
48
77
  <Heading level={1}>Cluster</Heading>
@@ -26,7 +26,7 @@ Most settings can be managed with the
26
26
  [FeatureSwitch](../FeatureSwitch/FeatureSwitch.md) component, which allows:
27
27
 
28
28
  * turning functionality on and off
29
- * editing aspects of the feature via a [Modal](../Modal/Modal.md)
29
+ * editing aspects of the feature via a [Dialog](../Dialog/Dialog.md)
30
30
  * if the page supports it, live updates to the setting
31
31
 
32
32
  ### Grouping settings
@@ -37,7 +37,7 @@ Use a [Card](../Card/Card.md) to group related settings together.
37
37
 
38
38
  The [FeatureSwitch](../FeatureSwitch/FeatureSwitch.md) component is a good starting
39
39
  point for most settings. If the setting is more complex, you can trigger a
40
- [Modal](../Modal/Modal.md) to edit the setting.
40
+ [Dialog](../Dialog/Dialog.md) to edit the setting.
41
41
 
42
42
  For cases where you don't need the full functionality of the `FeatureSwitch`,
43
43
  you can either opt out of props like `onSwitch` or `onEdit`, or compose a layout
@@ -49,7 +49,7 @@ of the pieces you do need.
49
49
 
50
50
  * [FeatureSwitch](../FeatureSwitch/FeatureSwitch.md)
51
51
  * [Card](../Card/Card.md)
52
- * [Modal](../Modal/Modal.md)
52
+ * [Dialog](../Dialog/Dialog.md)
53
53
  * [Switch](../Switch/Switch.md)
54
54
 
55
55
  ## Principles
@@ -5,22 +5,13 @@ before generating any Atlantis code.
5
5
 
6
6
  ***
7
7
 
8
- ## Always use version= for migrated components
9
-
10
- The following components have a v2 implementation. **Always pass
11
- `version={2}`**. Never generate v1 usage for these components — v1 is
12
- deprecated.
13
-
14
- | Component | Import | v2 prop |
15
- | --------- | -------------------------------------------------- | ------------------------------------------------- |
16
- | Modal | `import { Modal } from "@jobber/components/Modal"` | `version={2}` — uses `Modal.Provider` composition |
17
-
18
8
  ## Deprecated components — do not use
19
9
 
20
- | Deprecated | Replacement | Notes |
21
- | --------------------- | ------------------------------------------------------ | ---------------------------------------- |
22
- | `MultiSelect` | `Autocomplete` with `multiple` prop, or `FilterPicker` | Fully deprecated, no longer supported. |
23
- | `Chips` (dismissible) | `Autocomplete` with `multiple` prop | Dismissible Chips variant is deprecated. |
10
+ | Deprecated | Replacement | Notes |
11
+ | --------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
12
+ | `Modal` | `Dialog` | Includes `Modal.Provider` and the `Modal.*` subcomponents. See [migrating to Dialog](/components/Dialog/implement#component-view-migrating-to-dialog). |
13
+ | `MultiSelect` | `Autocomplete` with `multiple` prop, or `FilterPicker` | Fully deprecated, no longer supported. |
14
+ | `Chips` (dismissible) | `Autocomplete` with `multiple` prop | Dismissible Chips variant is deprecated. |
24
15
 
25
16
  ### Deprecated props on still-supported components
26
17
 
@@ -74,7 +65,7 @@ parent reads its compound children to wire up state, accessibility, and styling.
74
65
 
75
66
  | Component | Subcomponents | Usage |
76
67
  | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
77
- | `Modal` v2 | `Modal.Provider`, `Modal.Activator`, `Modal.Content`, `Modal.Header`, `Modal.Actions` | Wrap with `Modal.Provider`. `Modal.Header` and `Modal.Actions` must be **direct children** of `Modal.Content` for sticky behavior to work. Use `Modal.Activator` to control focus return when the trigger element unmounts. |
68
+ | `Dialog` | `Dialog.Trigger`, `Dialog.Content`, `Dialog.Header`, `Dialog.Title`, `Dialog.Close`, `Dialog.Body`, `Dialog.Footer`, `Dialog.Actions`, `Dialog.ScrollArea` | `Dialog` > `Dialog.Trigger` + `Dialog.Content` containing `Dialog.Header` (with `Dialog.Title` and `Dialog.Close`), `Dialog.Body`, and `Dialog.Footer` (wrapping `Dialog.Actions`). `Dialog.Header` and `Dialog.Footer` are layout-only slots. Use `finalFocus` to control focus return when the trigger unmounts. |
78
69
  | `Banner` | `Banner.Provider`, `Banner.Content`, `Banner.Icon`, `Banner.DismissButton`, `Banner.Action` | Either the simple `<Banner type="...">children</Banner>` form, or the Provider form: `Banner.Provider` > `Banner.Content` (+ optional `Banner.Icon` / `Banner.Action` / `Banner.DismissButton`). |
79
70
  | `Card` | `Card.Header`, `Card.Body` | `Card` > `Card.Header` + `Card.Body`. The legacy `header` string/element prop still works for simple cases. Use composition for any header that needs richer markup. |
80
71
  | `FilterPicker` | `FilterPicker.Activator`, `FilterPicker.Option`, `FilterPicker.Action` | `FilterPicker` > optional `FilterPicker.Activator`, one or more `FilterPicker.Option`, optional `FilterPicker.Action`. Omitting `FilterPicker.Activator` renders the default activator. |
@@ -100,10 +91,9 @@ parent reads its compound children to wire up state, accessibility, and styling.
100
91
  returns a translated label per state (e.g. `"Next page"`, `"Previous page"`).
101
92
  * **`RadioGroup` options whose `children` aren't text** must provide
102
93
  `aria-label` on the option so it has an accessible name.
103
- * **`Modal` v2 without a `Modal.Header` title** must set either
104
- `modalLabelledBy` (id of an existing element) or `ariaLabel` on the modal so
105
- the dialog has an accessible name. A `Modal.Header` title takes precedence
106
- over `ariaLabel` when both are provided.
94
+ * **`Dialog` must include a `Dialog.Title`** so the dialog has an accessible
95
+ name. `Dialog.Title` is wired to `aria-labelledby` automatically, and
96
+ `Dialog.Body` to `aria-describedby` — do not wire these by hand.
107
97
 
108
98
  ## UNSAFE\_ props
109
99
 
@@ -123,12 +113,14 @@ prefer design tokens inside any custom styles you do write. See
123
113
  * If using two cards next to each other horizontally, ensure they have a gap
124
114
  between them
125
115
 
126
- ### Modal
116
+ ### Dialog
127
117
 
128
- * When using a modal as part of an app, always wrap the inner content of the
129
- modal in the Content component, this is what gives it the padding the form
130
- needs from the edges of the modal.
131
- * Content will also provide the gap necessary between fields
118
+ * Use `Dialog` for overlay content. `Modal` is deprecated — do not generate new
119
+ `Modal` or `Modal.Provider` usage.
120
+ * Put the dialog's inner content in `Dialog.Body`, which supplies the padding
121
+ from the edges of the dialog and the gap between fields.
122
+ * Put action buttons in a `Dialog.Actions` inside a `Dialog.Footer` rather than
123
+ placing bare buttons in the body.
132
124
 
133
125
  ### Color
134
126
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "9.10.4",
3
+ "version": "9.12.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -549,5 +549,5 @@
549
549
  "> 1%",
550
550
  "IE 10"
551
551
  ],
552
- "gitHead": "de19112ccd7ce171f0ee64af0fa4043d040ace45"
552
+ "gitHead": "ae408ecc8d3eecc819118b2932493d653819aa9f"
553
553
  }