@jobber/components 8.30.0 → 9.1.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 (92) hide show
  1. package/dist/Autocomplete/Autocomplete.messages.d.ts +10 -0
  2. package/dist/Autocomplete/index.cjs +2 -0
  3. package/dist/Autocomplete/index.mjs +2 -0
  4. package/dist/Autocomplete-cjs.js +17 -4
  5. package/dist/Autocomplete-es.js +18 -5
  6. package/dist/ButtonDismiss-cjs.js +1 -1
  7. package/dist/ButtonDismiss-es.js +1 -1
  8. package/dist/Card/index.cjs +2 -0
  9. package/dist/Card/index.mjs +2 -0
  10. package/dist/Chip/index.cjs +2 -0
  11. package/dist/Chip/index.mjs +2 -0
  12. package/dist/Chip-cjs.js +19 -1
  13. package/dist/Chip-es.js +19 -2
  14. package/dist/Chips/Chips.messages.d.ts +14 -0
  15. package/dist/Chips/InternalChipDismissible/index.cjs +2 -0
  16. package/dist/Chips/InternalChipDismissible/index.mjs +2 -0
  17. package/dist/Chips/index.cjs +3 -1
  18. package/dist/Chips/index.mjs +3 -1
  19. package/dist/DataDump/index.cjs +2 -0
  20. package/dist/DataDump/index.mjs +2 -0
  21. package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +2 -0
  22. package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +2 -0
  23. package/dist/DataList/components/DataListFilters/index.cjs +2 -0
  24. package/dist/DataList/components/DataListFilters/index.mjs +2 -0
  25. package/dist/DataList/components/DataListSearch/index.cjs +2 -0
  26. package/dist/DataList/components/DataListSearch/index.mjs +2 -0
  27. package/dist/DataList/index.cjs +2 -0
  28. package/dist/DataList/index.mjs +2 -0
  29. package/dist/DataListSearch-cjs.js +1 -1
  30. package/dist/DataListSearch-es.js +1 -1
  31. package/dist/DataTable/index.cjs +2 -0
  32. package/dist/DataTable/index.mjs +2 -0
  33. package/dist/Dialog/dialogComposableShared.d.ts +1 -1
  34. package/dist/FilterPicker/components/FilterPickerActivator/index.cjs +2 -0
  35. package/dist/FilterPicker/components/FilterPickerActivator/index.mjs +2 -0
  36. package/dist/FilterPicker/components/FilterPickerTrigger/index.cjs +2 -0
  37. package/dist/FilterPicker/components/FilterPickerTrigger/index.mjs +2 -0
  38. package/dist/FilterPicker/index.cjs +2 -0
  39. package/dist/FilterPicker/index.mjs +2 -0
  40. package/dist/FilterPickerContentSearch-cjs.js +1 -1
  41. package/dist/FilterPickerContentSearch-es.js +1 -1
  42. package/dist/FormField/components/FormField.messages.d.ts +6 -0
  43. package/dist/FormField/index.cjs +2 -0
  44. package/dist/FormField/index.mjs +2 -0
  45. package/dist/FormFieldWrapper-cjs.js +11 -2
  46. package/dist/FormFieldWrapper-es.js +11 -2
  47. package/dist/Icon/Icon.d.ts +1 -0
  48. package/dist/Icon/index.cjs +9 -1
  49. package/dist/Icon/index.mjs +1 -1
  50. package/dist/Icon-cjs.js +9 -23
  51. package/dist/Icon-es.js +9 -23
  52. package/dist/InputAvatar/InputAvatar.messages.d.ts +10 -0
  53. package/dist/InputAvatar/index.cjs +2 -0
  54. package/dist/InputAvatar/index.mjs +2 -0
  55. package/dist/InputAvatar-cjs.js +15 -2
  56. package/dist/InputAvatar-es.js +15 -2
  57. package/dist/InputDate/index.cjs +1 -0
  58. package/dist/InputDate/index.mjs +1 -0
  59. package/dist/InputEmail/index.cjs +2 -0
  60. package/dist/InputEmail/index.mjs +2 -0
  61. package/dist/InputPhoneNumber/index.cjs +2 -0
  62. package/dist/InputPhoneNumber/index.mjs +2 -0
  63. package/dist/InputText/index.cjs +2 -0
  64. package/dist/InputText/index.mjs +2 -0
  65. package/dist/InputTime/index.cjs +2 -0
  66. package/dist/InputTime/index.mjs +2 -0
  67. package/dist/InternalChipDismissible-cjs.js +10 -6
  68. package/dist/InternalChipDismissible-es.js +11 -7
  69. package/dist/LegacySelect/index.cjs +2 -0
  70. package/dist/LegacySelect/index.mjs +2 -0
  71. package/dist/Menu/Menu.messages.d.ts +14 -0
  72. package/dist/Menu/index.cjs +2 -0
  73. package/dist/Menu/index.mjs +2 -0
  74. package/dist/Menu-cjs.js +20 -2
  75. package/dist/Menu-es.js +21 -3
  76. package/dist/Modal/index.mjs +1 -1
  77. package/dist/Page/index.cjs +2 -0
  78. package/dist/Page/index.mjs +2 -0
  79. package/dist/dialogReturnFocus-cjs.js +2 -2
  80. package/dist/dialogReturnFocus-es.js +2 -2
  81. package/dist/docs/ActivityIndicator/ActivityIndicator.md +11 -11
  82. package/dist/docs/Dialog/Dialog.md +16 -14
  83. package/dist/docs/Icon/Icon.md +19 -1
  84. package/dist/docs/InputNumberExperimental/InputNumberExperimental.md +1 -1
  85. package/dist/docs/empty-states/empty-states.md +13 -5
  86. package/dist/floating-ui.react-es.js +1 -1
  87. package/dist/index.cjs +10 -2
  88. package/dist/index.mjs +2 -2
  89. package/dist/showToast-cjs.js +1 -1
  90. package/dist/showToast-es.js +1 -1
  91. package/dist/styles.css +1 -2
  92. package/package.json +3 -3
package/dist/Menu-cjs.js CHANGED
@@ -5,6 +5,7 @@ var jobberHooks = require('@jobber/hooks');
5
5
  var classnames = require('classnames');
6
6
  var framerMotion = require('framer-motion');
7
7
  var floatingUi_react = require('./floating-ui.react-cjs.js');
8
+ var useAtlantisI18n = require('./useAtlantisI18n-cjs.js');
8
9
  var Button = require('./Button-cjs.js');
9
10
  var Typography = require('./Typography-cjs.js');
10
11
  var Icon = require('./Icon-cjs.js');
@@ -37,6 +38,21 @@ const OVERLAY_ANIMATION_CONFIG = {
37
38
  type: "tween",
38
39
  };
39
40
 
41
+ const menuMessages = useAtlantisI18n.defineMessages({
42
+ moreActions: {
43
+ en: "More Actions",
44
+ es: "Más acciones",
45
+ },
46
+ back: {
47
+ en: "Back",
48
+ es: "Atrás",
49
+ },
50
+ "Back to {title}": {
51
+ en: "Back to {title}",
52
+ es: "Volver a {title}",
53
+ },
54
+ });
55
+
40
56
  function isMobileDevice() {
41
57
  if (typeof window === "undefined") {
42
58
  return false;
@@ -58,6 +74,7 @@ const animationVariation = {
58
74
  // eslint-disable-next-line max-statements
59
75
  function MenuLegacy({ activator, items, UNSAFE_className, UNSAFE_style, }) {
60
76
  var _a;
77
+ const { t } = useAtlantisI18n.useAtlantisI18n(menuMessages);
61
78
  const [visible, setVisible] = React.useState(false);
62
79
  const [referenceElement, setReferenceElement] = React.useState(null);
63
80
  const [activeIndex, setActiveIndex] = React.useState(null);
@@ -122,7 +139,7 @@ function MenuLegacy({ activator, items, UNSAFE_className, UNSAFE_style, }) {
122
139
  }
123
140
  : {};
124
141
  if (!activator) {
125
- activator = (React.createElement(Button.Button, { fullWidth: true, label: "More Actions", icon: "more", type: "secondary" }));
142
+ activator = (React.createElement(Button.Button, { fullWidth: true, label: t("moreActions"), icon: "more", type: "secondary" }));
126
143
  }
127
144
  let itemIndexCounter = 0;
128
145
  const renderedSections = items === null || items === void 0 ? void 0 : items.map((item, key) => (React.createElement("div", { key: key, className: styles$2.legacySection },
@@ -640,6 +657,7 @@ const BottomSheetSubmenuTrigger = React.forwardRef(function BottomSheetSubmenuTr
640
657
  React.createElement(Icon.Icon, { color: "icon", name: "arrowRight" }))) : null));
641
658
  });
642
659
  function BottomSheetSubmenuContent({ children, className, style, UNSAFE_style, UNSAFE_className, }) {
660
+ const { t } = useAtlantisI18n.useAtlantisI18n(menuMessages);
643
661
  const { titleRef } = useBottomSheetSubmenuContext();
644
662
  const title = titleRef.current;
645
663
  const { focusModalityRef } = useBottomSheetContext();
@@ -655,7 +673,7 @@ function BottomSheetSubmenuContent({ children, className, style, UNSAFE_style, U
655
673
  React.createElement(BottomSheet.BottomSheet.Content, { style: bottomSheetStyle },
656
674
  title ? (React.createElement(DrawerTitle.DrawerTitle, { className: styles.screenReaderOnly }, title)) : null,
657
675
  React.createElement("div", { className: styles$1.submenuHeader },
658
- React.createElement(DrawerTitle.DrawerClose, { "aria-label": title ? `Back to ${title}` : "Back", render: React.createElement(Button.Button, { ariaLabel: title ? `Back to ${title}` : "Back", icon: "arrowLeft", type: "tertiary", variation: "subtle" }) }),
676
+ React.createElement(DrawerTitle.DrawerClose, { "aria-label": title ? t("Back to {title}", { title }) : t("back"), render: React.createElement(Button.Button, { ariaLabel: title ? t("Back to {title}", { title }) : t("back"), icon: "arrowLeft", type: "tertiary", variation: "subtle" }) }),
659
677
  title ? (React.createElement("div", { className: styles$1.submenuTitle },
660
678
  React.createElement(Typography.Typography, { element: "span", size: "base", fontWeight: "semiBold", textColor: "text" }, title))) : null),
661
679
  React.createElement(BottomSheetMenuSurface, { menuRef: menuRef, className: classnames(styles.bottomSheetSubmenuBody, styles.composableSection, resolvedBaseProps.className) }, children))));
package/dist/Menu-es.js CHANGED
@@ -2,7 +2,8 @@ import React__default, { useState, useRef, useId, useMemo } from 'react';
2
2
  import { useWindowDimensions, useRefocusOnActivator } from '@jobber/hooks';
3
3
  import classnames from 'classnames';
4
4
  import { AnimatePresence, motion } from 'framer-motion';
5
- import { u as useFloating, c as useDismiss, g as useListNavigation, d as useInteractions, F as FloatingPortal } from './floating-ui.react-es.js';
5
+ import { u as useFloating, c as useDismiss, j as useListNavigation, d as useInteractions, F as FloatingPortal } from './floating-ui.react-es.js';
6
+ import { d as defineMessages, u as useAtlantisI18n } from './useAtlantisI18n-es.js';
6
7
  import { B as Button } from './Button-es.js';
7
8
  import { T as Typography } from './Typography-es.js';
8
9
  import { I as Icon } from './Icon-es.js';
@@ -35,6 +36,21 @@ const OVERLAY_ANIMATION_CONFIG = {
35
36
  type: "tween",
36
37
  };
37
38
 
39
+ const menuMessages = defineMessages({
40
+ moreActions: {
41
+ en: "More Actions",
42
+ es: "Más acciones",
43
+ },
44
+ back: {
45
+ en: "Back",
46
+ es: "Atrás",
47
+ },
48
+ "Back to {title}": {
49
+ en: "Back to {title}",
50
+ es: "Volver a {title}",
51
+ },
52
+ });
53
+
38
54
  function isMobileDevice() {
39
55
  if (typeof window === "undefined") {
40
56
  return false;
@@ -56,6 +72,7 @@ const animationVariation = {
56
72
  // eslint-disable-next-line max-statements
57
73
  function MenuLegacy({ activator, items, UNSAFE_className, UNSAFE_style, }) {
58
74
  var _a;
75
+ const { t } = useAtlantisI18n(menuMessages);
59
76
  const [visible, setVisible] = useState(false);
60
77
  const [referenceElement, setReferenceElement] = useState(null);
61
78
  const [activeIndex, setActiveIndex] = useState(null);
@@ -120,7 +137,7 @@ function MenuLegacy({ activator, items, UNSAFE_className, UNSAFE_style, }) {
120
137
  }
121
138
  : {};
122
139
  if (!activator) {
123
- activator = (React__default.createElement(Button, { fullWidth: true, label: "More Actions", icon: "more", type: "secondary" }));
140
+ activator = (React__default.createElement(Button, { fullWidth: true, label: t("moreActions"), icon: "more", type: "secondary" }));
124
141
  }
125
142
  let itemIndexCounter = 0;
126
143
  const renderedSections = items === null || items === void 0 ? void 0 : items.map((item, key) => (React__default.createElement("div", { key: key, className: styles$2.legacySection },
@@ -638,6 +655,7 @@ const BottomSheetSubmenuTrigger = React__default.forwardRef(function BottomSheet
638
655
  React__default.createElement(Icon, { color: "icon", name: "arrowRight" }))) : null));
639
656
  });
640
657
  function BottomSheetSubmenuContent({ children, className, style, UNSAFE_style, UNSAFE_className, }) {
658
+ const { t } = useAtlantisI18n(menuMessages);
641
659
  const { titleRef } = useBottomSheetSubmenuContext();
642
660
  const title = titleRef.current;
643
661
  const { focusModalityRef } = useBottomSheetContext();
@@ -653,7 +671,7 @@ function BottomSheetSubmenuContent({ children, className, style, UNSAFE_style, U
653
671
  React__default.createElement(BottomSheet.Content, { style: bottomSheetStyle },
654
672
  title ? (React__default.createElement(DrawerTitle, { className: styles.screenReaderOnly }, title)) : null,
655
673
  React__default.createElement("div", { className: styles$1.submenuHeader },
656
- React__default.createElement(DrawerClose, { "aria-label": title ? `Back to ${title}` : "Back", render: React__default.createElement(Button, { ariaLabel: title ? `Back to ${title}` : "Back", icon: "arrowLeft", type: "tertiary", variation: "subtle" }) }),
674
+ React__default.createElement(DrawerClose, { "aria-label": title ? t("Back to {title}", { title }) : t("back"), render: React__default.createElement(Button, { ariaLabel: title ? t("Back to {title}", { title }) : t("back"), icon: "arrowLeft", type: "tertiary", variation: "subtle" }) }),
657
675
  title ? (React__default.createElement("div", { className: styles$1.submenuTitle },
658
676
  React__default.createElement(Typography, { element: "span", size: "base", fontWeight: "semiBold", textColor: "text" }, title))) : null),
659
677
  React__default.createElement(BottomSheetMenuSurface, { menuRef: menuRef, className: classnames(styles.bottomSheetSubmenuBody, styles.composableSection, resolvedBaseProps.className) }, children))));
@@ -8,7 +8,7 @@ import { H as Heading } from '../Heading-es.js';
8
8
  import { B as Button } from '../Button-es.js';
9
9
  import { B as ButtonDismiss } from '../ButtonDismiss-es.js';
10
10
  import { n as noop } from '../noop-es.js';
11
- import { b as useFloatingNodeId, u as useFloating, c as useDismiss, h as useRole, d as useInteractions, a as useFloatingParentNodeId, e as FloatingTree, f as FloatingNode, F as FloatingPortal, i as FloatingFocusManager, j as FloatingOverlay } from '../floating-ui.react-es.js';
11
+ import { b as useFloatingNodeId, u as useFloating, c as useDismiss, g as useRole, d as useInteractions, a as useFloatingParentNodeId, e as FloatingTree, f as FloatingNode, F as FloatingPortal, h as FloatingFocusManager, i as FloatingOverlay } from '../floating-ui.react-es.js';
12
12
  import { b as identity } from '../identity-es.js';
13
13
  import { A as AtlantisPortalContent } from '../AtlantisPortalContent-es.js';
14
14
  import '../Typography-es.js';
@@ -24,6 +24,8 @@ require('../floating-ui.utils.dom-cjs.js');
24
24
  require('../floating-ui.utils-cjs.js');
25
25
  require('react-dom');
26
26
  require('../floating-ui.react-dom-cjs.js');
27
+ require('../useAtlantisI18n-cjs.js');
28
+ require('../AtlantisContext-cjs.js');
27
29
  require('../useFormFieldFocus-cjs.js');
28
30
  require('../maxHeight-cjs.js');
29
31
  require('../useRenderElement-cjs.js');
@@ -22,6 +22,8 @@ import '../floating-ui.utils.dom-es.js';
22
22
  import '../floating-ui.utils-es.js';
23
23
  import 'react-dom';
24
24
  import '../floating-ui.react-dom-es.js';
25
+ import '../useAtlantisI18n-es.js';
26
+ import '../AtlantisContext-es.js';
25
27
  import '../useFormFieldFocus-es.js';
26
28
  import '../maxHeight-es.js';
27
29
  import '../useRenderElement-es.js';
@@ -55,7 +55,7 @@ function resolveComposableTriggerRender({ children, render, }) {
55
55
  /**
56
56
  * Resolves the dismiss element for `Dialog.Close`, mirroring
57
57
  * `resolveComposableTriggerRender` so a custom render works in both shells.
58
- * Falls back to the subtle "remove" `ButtonDismiss` when neither `render` nor
58
+ * Falls back to the subtle "cross" `ButtonDismiss` when neither `render` nor
59
59
  * `children` are supplied. An Atlantis `<Button>`/`<ButtonDismiss>` passed via
60
60
  * `render` or `children` is adapted; any other valid element is used as-is.
61
61
  */
@@ -80,7 +80,7 @@ function resolveComposableCloseRender({ children, render, }) {
80
80
  return children;
81
81
  }
82
82
  return buttonRenderAdapter.renderAtlantisButtonTarget(React.createElement(Button.Button, { type: "tertiary", variation: "subtle", ariaLabel: "Close dialog" },
83
- React.createElement(Button.Button.Icon, { name: "remove" })));
83
+ React.createElement(Button.Button.Icon, { name: "cross" })));
84
84
  }
85
85
  /**
86
86
  * Adapts a `Dialog.Content` `render` for the bottom sheet's drawer popup. A
@@ -53,7 +53,7 @@ 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 "remove" `ButtonDismiss` when neither `render` nor
56
+ * Falls back to the subtle "cross" `ButtonDismiss` when neither `render` nor
57
57
  * `children` are supplied. An Atlantis `<Button>`/`<ButtonDismiss>` passed via
58
58
  * `render` or `children` is adapted; any other valid element is used as-is.
59
59
  */
@@ -78,7 +78,7 @@ function resolveComposableCloseRender({ children, render, }) {
78
78
  return children;
79
79
  }
80
80
  return renderAtlantisButtonTarget(React__default.createElement(Button, { type: "tertiary", variation: "subtle", ariaLabel: "Close dialog" },
81
- React__default.createElement(Button.Icon, { name: "remove" })));
81
+ React__default.createElement(Button.Icon, { name: "cross" })));
82
82
  }
83
83
  /**
84
84
  * Adapts a `Dialog.Content` `render` for the bottom sheet's drawer popup. A
@@ -65,19 +65,19 @@ cases. The `small` size (16px) should be used on individual elements of an
65
65
  interface (e.g. inside a `Button` or `Card`) or when sitting next to short
66
66
  inline text.
67
67
 
68
- Layout is the consumer's responsibility — `ActivityIndicator` does not expose
69
- an `inline` prop. Place it inside your own flex / inline-block container, or
70
- pass a `className` / `style`, to control surrounding layout.
68
+ Layout is the consumer's responsibility — `ActivityIndicator` does not expose an
69
+ `inline` prop. Place it inside your own flex / inline-block container, or pass a
70
+ `className` / `style`, to control surrounding layout.
71
71
 
72
72
  ## Accessibility
73
73
 
74
74
  `ActivityIndicator` announces itself politely to assistive technology:
75
75
 
76
- * `role="status"` marks the element as a polite live region, appropriate for
77
- a non-urgent loading state.
78
- * `aria-label` defaults to the literal English string `"Loading"`. Pass a
79
- custom `ariaLabel` to localize or to describe the specific activity
80
- (e.g. `ariaLabel="Uploading file"`).
76
+ * `role="status"` marks the element as a polite live region, appropriate for a
77
+ non-urgent loading state.
78
+ * `aria-label` defaults to the literal English string `"Loading"`. Pass a custom
79
+ `ariaLabel` to localize or to describe the specific activity (e.g.
80
+ `ariaLabel="Uploading file"`).
81
81
 
82
82
  The indicator does not participate in the keyboard tab order.
83
83
 
@@ -85,9 +85,9 @@ The indicator does not participate in the keyboard tab order.
85
85
 
86
86
  When the user's operating system reports
87
87
  [`prefers-reduced-motion: reduce`](https://developer.mozilla.org/docs/Web/CSS/@media/prefers-reduced-motion),
88
- the indicator hides its rocking and rotating layers, repaints a single
89
- static ring in the icon foreground colour, and gently pulses its opacity so
90
- the indicator still reads as "busy" without rotational motion.
88
+ the indicator hides its rocking and rotating layers, repaints a single static
89
+ ring in the icon foreground colour, and gently pulses its opacity so the
90
+ indicator still reads as "busy" without rotational motion.
91
91
 
92
92
  ## Relationship to Spinner
93
93
 
@@ -106,14 +106,14 @@ instead.
106
106
  These build on the general [Voice & tone](../voice-and-tone/voice-and-tone.md) and
107
107
  [Formatting](../formatting/formatting.md) guidelines.
108
108
 
109
- A dialog interrupts the user, so every word should earn its place:
110
- name the task, state the outcome, and give a clear way out.
109
+ A dialog interrupts the user, so every word should earn its place: name the
110
+ task, state the outcome, and give a clear way out.
111
111
 
112
112
  #### Title
113
113
 
114
- The title names the task as opposed to the component. Use verbs when the
115
- dialog is asking the user to actually do something. Be specific. Use a noun
116
- when you're presenting information. Don't phrase confirmation requests as questions.
114
+ The title names the task as opposed to the component. Use verbs when the dialog
115
+ is asking the user to actually do something. Be specific. Use a noun when you're
116
+ presenting information. Don't phrase confirmation requests as questions.
117
117
 
118
118
  | Do | Don't |
119
119
  | ------------------ | -------------------------------------------- |
@@ -125,9 +125,10 @@ when you're presenting information. Don't phrase confirmation requests as questi
125
125
 
126
126
  #### Body
127
127
 
128
- Body copy needs to expand on the title by providing what the title can't. It shouldn't
129
- repeat the title and should provide useful information such as explaining the impact of
130
- any action the user might be taking. For a routine task, one short sentence is often enough.
128
+ Body copy needs to expand on the title by providing what the title can't. It
129
+ shouldn't repeat the title and should provide useful information such as
130
+ explaining the impact of any action the user might be taking. For a routine
131
+ task, one short sentence is often enough.
131
132
 
132
133
  | Do | Don't |
133
134
  | ---------------------------------------------- | -------------------------------------------------------------- |
@@ -135,9 +136,9 @@ any action the user might be taking. For a routine task, one short sentence is o
135
136
 
136
137
  #### Actions
137
138
 
138
- Primary action lables will need to lead with a verb and match the action taking place.
139
- They shouldn't be generic such as "Confirm" or "Yes". The action needs to be clearly
140
- intentional. Also, remember that buttons are title case.
139
+ Primary action lables will need to lead with a verb and match the action taking
140
+ place. They shouldn't be generic such as "Confirm" or "Yes". The action needs to
141
+ be clearly intentional. Also, remember that buttons are title case.
141
142
 
142
143
  | Do | Don't |
143
144
  | ------------------- | ------- |
@@ -147,9 +148,10 @@ intentional. Also, remember that buttons are title case.
147
148
 
148
149
  #### Alert dialogs
149
150
 
150
- As `alertdialog` can't be dismissed by clicking outside, the way out needs to be clear. We should not be reliant on
151
- users pressing ESC. When relevant, cancel actions need to be considered alonsgside confirmation actions and
152
- should be just as easy to find. Ideally via secondary CTAs.
151
+ As `alertdialog` can't be dismissed by clicking outside, the way out needs to be
152
+ clear. We should not be reliant on users pressing ESC. When relevant, cancel
153
+ actions need to be considered alonsgside confirmation actions and should be just
154
+ as easy to find. Ideally via secondary CTAs.
153
155
 
154
156
  ## Do's and Don'ts
155
157
 
@@ -427,7 +427,6 @@ export function IconSizesExample() {
427
427
  | | `import` |
428
428
  | | `merge` |
429
429
  | | `redo` |
430
- | | `remove` |
431
430
  | | `search` |
432
431
  | | `sort` |
433
432
  | | `sync` |
@@ -512,6 +511,25 @@ export function IconSizesExample() {
512
511
  | | `plus2` |
513
512
 
514
513
 
514
+ ## Validating icon names at runtime
515
+
516
+ When icon names arrive as runtime data (API responses, configuration, user
517
+ input), validate them before rendering with the exports from
518
+ `@jobber/components` (also available from `@jobber/design`):
519
+
520
+ * `iconNames`: a readonly array of every valid icon name
521
+ * `isIconName(value)`: a type guard that narrows a value to `IconNames`
522
+
523
+ ```tsx
524
+ import { Icon, isIconName } from "@jobber/components";
525
+
526
+ function StatusIcon({ iconName }: { readonly iconName: string }) {
527
+ if (!isIconName(iconName)) return null;
528
+
529
+ return <Icon name={iconName} />;
530
+ }
531
+ ```
532
+
515
533
  ## Component customization
516
534
 
517
535
  ### UNSAFE\_ props (advanced usage)
@@ -112,7 +112,7 @@ export function InputNumberExperimentalAffixesExample() {
112
112
  <InputNumberExperimental
113
113
  label="Repetitions"
114
114
  suffix={{
115
- icon: "remove",
115
+ icon: "cross",
116
116
  ariaLabel: "Clear value",
117
117
  onClick: () => setReps(null),
118
118
  }}
@@ -21,7 +21,8 @@ for the “emptiness” may include, but are not limited to…
21
21
  * Search results with no match
22
22
  * An error has resulted in the user not being able to access content they
23
23
  otherwise could
24
- * A specific field doesn't have a value (for example, a custom field that the user hasn't populated)
24
+ * A specific field doesn't have a value (for example, a custom field that the
25
+ user hasn't populated)
25
26
 
26
27
  ## Solution
27
28
 
@@ -70,22 +71,29 @@ When a field doesn't have a value, use a dash to indicate the lack of a value.
70
71
  This provides:
71
72
 
72
73
  * confirmation that nothing was entered
73
- * confirmation that something *can* be entered there should the information require an update
74
+ * confirmation that something *can* be entered there should the information
75
+ require an update
74
76
 
75
77
  ```tsx
76
78
  <Card>
77
79
  <Content>
78
80
  <Heading level={4}>Additional details</Heading>
79
81
  <Stack gap="smallest">
80
- <Text size="small" variation="subdued">Preferred service date</Text>
82
+ <Text size="small" variation="subdued">
83
+ Preferred service date
84
+ </Text>
81
85
  <Text>June 25, 2026</Text>
82
86
  </Stack>
83
87
  <Stack gap="smallest">
84
- <Text size="small" variation="subdued">Gate code</Text>
88
+ <Text size="small" variation="subdued">
89
+ Gate code
90
+ </Text>
85
91
  <Text>—</Text>
86
92
  </Stack>
87
93
  <Stack gap="smallest">
88
- <Text size="small" variation="subdued">Additional requests</Text>
94
+ <Text size="small" variation="subdued">
95
+ Additional requests
96
+ </Text>
89
97
  <Text>—</Text>
90
98
  </Stack>
91
99
  </Content>
@@ -3809,4 +3809,4 @@ function useTransitionStyles(context, props) {
3809
3809
  };
3810
3810
  }
3811
3811
 
3812
- export { FloatingPortal as F, useFloatingParentNodeId as a, useFloatingNodeId as b, useDismiss as c, useInteractions as d, FloatingTree as e, FloatingNode as f, useListNavigation as g, useRole as h, FloatingFocusManager as i, FloatingOverlay as j, useClick as k, useTransitionStyles as l, FloatingArrow as m, useFloating as u };
3812
+ export { FloatingPortal as F, useFloatingParentNodeId as a, useFloatingNodeId as b, useDismiss as c, useInteractions as d, FloatingTree as e, FloatingNode as f, useRole as g, FloatingFocusManager as h, FloatingOverlay as i, useListNavigation as j, useClick as k, useTransitionStyles as l, FloatingArrow as m, useFloating as u };
package/dist/index.cjs CHANGED
@@ -89,8 +89,8 @@ var Tiles = require('./Tiles-cjs.js');
89
89
  var showToast = require('./showToast-cjs.js');
90
90
  var Tooltip = require('./Tooltip-cjs.js');
91
91
  var Typography = require('./Typography-cjs.js');
92
+ var design = require('@jobber/design');
92
93
  require('classnames');
93
- require('@jobber/design');
94
94
  require('./_commonjsHelpers-cjs.js');
95
95
  require('./identity-cjs.js');
96
96
  require('./isTypedArray-cjs.js');
@@ -107,11 +107,11 @@ require('react/jsx-runtime');
107
107
  require('react-dom');
108
108
  require('./floating-ui.react-dom-cjs.js');
109
109
  require('./maxHeight-cjs.js');
110
+ require('./useAtlantisI18n-cjs.js');
110
111
  require('./mergeRefs-cjs.js');
111
112
  require('./filterDataAttributes-cjs.js');
112
113
  require('color');
113
114
  require('./tslib.es6-cjs.js');
114
- require('./useAtlantisI18n-cjs.js');
115
115
  require('react-router-dom');
116
116
  require('./getMappedAtlantisSpaceToken-cjs.js');
117
117
  require('./useChildComponent-cjs.js');
@@ -360,4 +360,12 @@ exports.Toast = showToast.Toast;
360
360
  exports.showToast = showToast.showToast;
361
361
  exports.Tooltip = Tooltip.Tooltip;
362
362
  exports.Typography = Typography.Typography;
363
+ Object.defineProperty(exports, "iconNames", {
364
+ enumerable: true,
365
+ get: function () { return design.iconNames; }
366
+ });
367
+ Object.defineProperty(exports, "isIconName", {
368
+ enumerable: true,
369
+ get: function () { return design.isIconName; }
370
+ });
363
371
  exports.isNormalClick = isNormalClick;
package/dist/index.mjs CHANGED
@@ -87,8 +87,8 @@ export { T as Tiles } from './Tiles-es.js';
87
87
  export { T as Toast, s as showToast } from './showToast-es.js';
88
88
  export { T as Tooltip } from './Tooltip-es.js';
89
89
  export { T as Typography } from './Typography-es.js';
90
+ export { iconNames, isIconName } from '@jobber/design';
90
91
  import 'classnames';
91
- import '@jobber/design';
92
92
  import './_commonjsHelpers-es.js';
93
93
  import './identity-es.js';
94
94
  import './isTypedArray-es.js';
@@ -105,11 +105,11 @@ import 'react/jsx-runtime';
105
105
  import 'react-dom';
106
106
  import './floating-ui.react-dom-es.js';
107
107
  import './maxHeight-es.js';
108
+ import './useAtlantisI18n-es.js';
108
109
  import './mergeRefs-es.js';
109
110
  import './filterDataAttributes-es.js';
110
111
  import 'color';
111
112
  import './tslib.es6-es.js';
112
- import './useAtlantisI18n-es.js';
113
113
  import 'react-router-dom';
114
114
  import './getMappedAtlantisSpaceToken-es.js';
115
115
  import './useChildComponent-es.js';
@@ -26,7 +26,7 @@ function Toast({ message, variation = "success", action, actionLabel, }) {
26
26
  React.createElement(Typography.Typography, { element: "span", size: "large" }, message),
27
27
  action && (React.createElement(Button.Button, { label: `${actionLabel}`, onClick: action, type: "tertiary" })),
28
28
  React.createElement("div", { className: styles.button },
29
- React.createElement(Button.Button, { icon: "remove", ariaLabel: "Hide Notification", onClick: handleToastClose, type: "tertiary", variation: "subtle" })))))));
29
+ React.createElement(Button.Button, { icon: "cross", ariaLabel: "Hide Notification", onClick: handleToastClose, type: "tertiary", variation: "subtle" })))))));
30
30
  function startTimer() {
31
31
  timer = setTimeout(() => handleToastClose(), getTimeout());
32
32
  }
@@ -24,7 +24,7 @@ function Toast({ message, variation = "success", action, actionLabel, }) {
24
24
  React__default.createElement(Typography, { element: "span", size: "large" }, message),
25
25
  action && (React__default.createElement(Button, { label: `${actionLabel}`, onClick: action, type: "tertiary" })),
26
26
  React__default.createElement("div", { className: styles.button },
27
- React__default.createElement(Button, { icon: "remove", ariaLabel: "Hide Notification", onClick: handleToastClose, type: "tertiary", variation: "subtle" })))))));
27
+ React__default.createElement(Button, { icon: "cross", ariaLabel: "Hide Notification", onClick: handleToastClose, type: "tertiary", variation: "subtle" })))))));
28
28
  function startTimer() {
29
29
  timer = setTimeout(() => handleToastClose(), getTimeout());
30
30
  }
package/dist/styles.css CHANGED
@@ -10759,8 +10759,7 @@ h2.react-datepicker__current-month {
10759
10759
  }
10760
10760
  .ZZ3XuxGv6ow- > *,
10761
10761
  .ZZ3XuxGv6ow- > .BrXAnQBttWE- > *,
10762
- .ZZ3XuxGv6ow- > .nslrozOH-v4- > *
10763
- {
10762
+ .ZZ3XuxGv6ow- > .nslrozOH-v4- > * {
10764
10763
  -ms-flex: 1 1 0px;
10765
10764
  flex: 1 1 0;
10766
10765
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "8.30.0",
3
+ "version": "9.1.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -491,7 +491,7 @@
491
491
  "devDependencies": {
492
492
  "@apollo/client": "^3.7.10",
493
493
  "@csstools/postcss-global-data": "^1.0.3",
494
- "@jobber/design": "0.110.0",
494
+ "@jobber/design": "0.111.0",
495
495
  "@jobber/hooks": "2.21.0",
496
496
  "@rollup/plugin-alias": "^5.1.0",
497
497
  "@rollup/plugin-commonjs": "^25.0.7",
@@ -545,5 +545,5 @@
545
545
  "> 1%",
546
546
  "IE 10"
547
547
  ],
548
- "gitHead": "899477f724a451b575e667d2565080cac5cc10e5"
548
+ "gitHead": "e887305a950c2e207016a1b039df2e8e992acc45"
549
549
  }