braid-design-system 32.4.1 → 32.6.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 (43) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/ToastContext.chunk.cjs +7 -1
  3. package/dist/ToastContext.chunk.mjs +7 -1
  4. package/dist/Toggle.chunk.cjs +91 -8
  5. package/dist/Toggle.chunk.mjs +95 -12
  6. package/dist/index.cjs +2 -0
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.mjs +3 -1
  9. package/dist/playroom/components.cjs +15 -5
  10. package/dist/playroom/components.d.ts +1 -1
  11. package/dist/playroom/components.mjs +16 -6
  12. package/dist/playroom/snippets.cjs +60 -52
  13. package/dist/playroom/snippets.mjs +60 -52
  14. package/dist/reset.d.ts +171 -5
  15. package/dist/side-effects/lib/themes/baseTokens/apac.cjs +42 -28
  16. package/dist/side-effects/lib/themes/baseTokens/apac.mjs +42 -28
  17. package/dist/side-effects/lib/themes/index.cjs +2 -0
  18. package/dist/side-effects/lib/themes/index.mjs +2 -0
  19. package/dist/side-effects/lib/themes/makeRuntimeTokens.cjs +8 -0
  20. package/dist/side-effects/lib/themes/makeRuntimeTokens.mjs +8 -0
  21. package/dist/side-effects/lib/themes/seekJobs/index.cjs +2 -0
  22. package/dist/side-effects/lib/themes/seekJobs/index.mjs +1 -0
  23. package/dist/styles/lib/components/Toggle/Toggle.css.cjs +6 -0
  24. package/dist/styles/lib/components/Toggle/Toggle.css.mjs +6 -0
  25. package/dist/styles/lib/components/private/Field/Field.css.cjs +7 -0
  26. package/dist/styles/lib/components/private/Field/Field.css.mjs +7 -0
  27. package/dist/styles/lib/components/private/InlineField/InlineField.css.cjs +15 -1
  28. package/dist/styles/lib/components/private/InlineField/InlineField.css.mjs +15 -1
  29. package/dist/styles/lib/themes/docs/tokens.cjs +1 -0
  30. package/dist/styles/lib/themes/docs/tokens.mjs +1 -0
  31. package/dist/styles/lib/themes/seekJobs/seekJobs.css.cjs +8 -0
  32. package/dist/styles/lib/themes/seekJobs/seekJobs.css.mjs +9 -0
  33. package/dist/styles/lib/themes/seekJobs/tokens.cjs +190 -0
  34. package/dist/styles/lib/themes/seekJobs/tokens.mjs +191 -0
  35. package/dist/styles/lib/themes/wireframe/tokens.cjs +1 -0
  36. package/dist/styles/lib/themes/wireframe/tokens.mjs +1 -0
  37. package/dist/themes/seekJobs.cjs +3 -0
  38. package/dist/themes/seekJobs.d.ts +1 -0
  39. package/dist/themes/seekJobs.mjs +4 -0
  40. package/dist/themes/wireframe.d.ts +1 -1
  41. package/package.json +10 -2
  42. package/themes/seekJobs/index.d.ts +2 -0
  43. package/themes/seekJobs/package.json +5 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,69 @@
1
1
  # braid-design-system
2
2
 
3
+ ## 32.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **PageBlock:** Add new component ([#1307](https://github.com/seek-oss/braid-design-system/pull/1307))
8
+
9
+ Provides a top-level page container, constraining the content width (using `ContentBlock`) while establishing common screen gutters on smaller devices.
10
+
11
+ **EXAMPLE USAGE:**
12
+
13
+ ```jsx
14
+ <PageBlock width="large">...</PageBlock>
15
+ ```
16
+
17
+ - **Button, TextLinkButton:** Add `aria-label` support ([#1304](https://github.com/seek-oss/braid-design-system/pull/1304))
18
+
19
+ Provide support for `aria-label`, enabling additional context to be given to assistive technologies where context is typically visual.
20
+
21
+ **EXAMPLE USAGE:**
22
+
23
+ ```jsx
24
+ <Button aria-label="Save job">Save</Button>
25
+ ```
26
+
27
+ - **IconMessage:** Add new component ([#1303](https://github.com/seek-oss/braid-design-system/pull/1303))
28
+
29
+ Add new `IconMessage` component.
30
+
31
+ **EXAMPLE USAGE:**
32
+
33
+ ```jsx
34
+ <IconMessage />
35
+ ```
36
+
37
+ ## 32.5.0
38
+
39
+ ### Minor Changes
40
+
41
+ - Hide field borders in dark containers ([#1294](https://github.com/seek-oss/braid-design-system/pull/1294))
42
+
43
+ Reduce visual noise when a form field is displayed in a dark container by hiding the default border.
44
+ As fields are light on light backgrounds, the border is used to delineate its bounds against the container, which is not relevant in a dark container.
45
+
46
+ - Add `seekJobs` theme ([#1281](https://github.com/seek-oss/braid-design-system/pull/1281))
47
+
48
+ The `seekJobs` theme encapsulates the system changes necessary to apply and deliver the updated visual design language for SEEK Jobs.
49
+ Through the development of this theme, we have been able improve the fidelity of the various scales in our tokens, while also ensuring that the tokens themselves are consumed and applied more consistently throughout the system itself.
50
+
51
+ **EXAMPLE USAGE:**
52
+
53
+ ```tsx
54
+ import seekJobs from 'braid-design-system/themes/seekJobs';
55
+
56
+ <BraidProvider theme={seekJobs}>...</BraidProvider>;
57
+ ```
58
+
59
+ **MIGRATION**
60
+
61
+ Consumers of the `apac` theme are not recommended to migrate independently. The `seekJobs` theme represents an uplifted visual identity that is part of a wider visual uplift.
62
+ Instead, we’ll be guiding the initial teams through a staged migration in coordination with the centralised team process.
63
+ There are some differences in how certain concepts are applied, whether it's the space scale, or `Card` usage, etc., and we will be documenting these in due course.
64
+
65
+ If you would like to talk about migrating, please reach out to us in our **#braid-support** channel on slack.
66
+
3
67
  ## 32.4.1
4
68
 
5
69
  ### Patch Changes
@@ -1491,10 +1491,12 @@ const ButtonText = ({
1491
1491
  }) => {
1492
1492
  const lightness = useBackgroundLightness();
1493
1493
  const actionsContext = React.useContext(ActionsContext);
1494
+ const isLegacyTheme = sideEffects_lib_components_BraidProvider_BraidProvider_cjs.useBraidTheme().legacy;
1494
1495
  const size = sizeProp ?? (actionsContext == null ? void 0 : actionsContext.size) ?? "standard";
1495
1496
  const stylesForVariant = variants[variant][tone ?? "default"];
1496
1497
  const shouldReducePaddingX = size === "small" || variant === "transparent";
1497
- const labelPaddingX = shouldReducePaddingX ? transparentPaddingX : "medium";
1498
+ const labelPaddingXForTheme = isLegacyTheme ? "medium" : "gutter";
1499
+ const labelPaddingX = shouldReducePaddingX ? transparentPaddingX : labelPaddingXForTheme;
1498
1500
  assert__default.default(
1499
1501
  !icon || icon.props.size === void 0 && icon.props.tone === void 0,
1500
1502
  "Icons cannot set the 'size' or 'tone' prop when passed to a Button component"
@@ -1610,6 +1612,7 @@ const Button = React.forwardRef(
1610
1612
  "aria-controls": ariaControls,
1611
1613
  "aria-expanded": ariaExpanded,
1612
1614
  "aria-describedby": ariaDescribedBy,
1615
+ "aria-label": ariaLabel,
1613
1616
  data,
1614
1617
  ...restProps
1615
1618
  }, ref) => {
@@ -1643,6 +1646,7 @@ const Button = React.forwardRef(
1643
1646
  "aria-controls": ariaControls,
1644
1647
  "aria-expanded": ariaExpanded,
1645
1648
  "aria-describedby": ariaDescribedBy,
1649
+ "aria-label": ariaLabel,
1646
1650
  onClick,
1647
1651
  disabled: loading,
1648
1652
  ...buildDataAttributes({ data, validateRestProps: restProps }),
@@ -2080,6 +2084,7 @@ const TextLinkButton = ({
2080
2084
  "aria-controls": ariaControls,
2081
2085
  "aria-expanded": ariaExpanded,
2082
2086
  "aria-describedby": ariaDescribedBy,
2087
+ "aria-label": ariaLabel,
2083
2088
  tabIndex,
2084
2089
  icon,
2085
2090
  iconPosition,
@@ -2113,6 +2118,7 @@ const TextLinkButton = ({
2113
2118
  "aria-controls": ariaControls,
2114
2119
  "aria-expanded": ariaExpanded,
2115
2120
  "aria-describedby": ariaDescribedBy,
2121
+ "aria-label": ariaLabel,
2116
2122
  id,
2117
2123
  className: classes,
2118
2124
  ...buildDataAttributes({ data, validateRestProps: restProps }),
@@ -1484,10 +1484,12 @@ const ButtonText = ({
1484
1484
  }) => {
1485
1485
  const lightness = useBackgroundLightness();
1486
1486
  const actionsContext = useContext(ActionsContext);
1487
+ const isLegacyTheme = useBraidTheme().legacy;
1487
1488
  const size2 = sizeProp ?? (actionsContext == null ? void 0 : actionsContext.size) ?? "standard";
1488
1489
  const stylesForVariant = variants[variant][tone2 ?? "default"];
1489
1490
  const shouldReducePaddingX = size2 === "small" || variant === "transparent";
1490
- const labelPaddingX = shouldReducePaddingX ? transparentPaddingX : "medium";
1491
+ const labelPaddingXForTheme = isLegacyTheme ? "medium" : "gutter";
1492
+ const labelPaddingX = shouldReducePaddingX ? transparentPaddingX : labelPaddingXForTheme;
1491
1493
  assert(
1492
1494
  !icon || icon.props.size === void 0 && icon.props.tone === void 0,
1493
1495
  "Icons cannot set the 'size' or 'tone' prop when passed to a Button component"
@@ -1603,6 +1605,7 @@ const Button = forwardRef(
1603
1605
  "aria-controls": ariaControls,
1604
1606
  "aria-expanded": ariaExpanded,
1605
1607
  "aria-describedby": ariaDescribedBy,
1608
+ "aria-label": ariaLabel,
1606
1609
  data,
1607
1610
  ...restProps
1608
1611
  }, ref) => {
@@ -1636,6 +1639,7 @@ const Button = forwardRef(
1636
1639
  "aria-controls": ariaControls,
1637
1640
  "aria-expanded": ariaExpanded,
1638
1641
  "aria-describedby": ariaDescribedBy,
1642
+ "aria-label": ariaLabel,
1639
1643
  onClick,
1640
1644
  disabled: loading,
1641
1645
  ...buildDataAttributes({ data, validateRestProps: restProps }),
@@ -2073,6 +2077,7 @@ const TextLinkButton = ({
2073
2077
  "aria-controls": ariaControls,
2074
2078
  "aria-expanded": ariaExpanded,
2075
2079
  "aria-describedby": ariaDescribedBy,
2080
+ "aria-label": ariaLabel,
2076
2081
  tabIndex,
2077
2082
  icon,
2078
2083
  iconPosition,
@@ -2106,6 +2111,7 @@ const TextLinkButton = ({
2106
2111
  "aria-controls": ariaControls,
2107
2112
  "aria-expanded": ariaExpanded,
2108
2113
  "aria-describedby": ariaDescribedBy,
2114
+ "aria-label": ariaLabel,
2109
2115
  id,
2110
2116
  className: classes,
2111
2117
  ...buildDataAttributes({ data, validateRestProps: restProps }),
@@ -961,6 +961,37 @@ const IconMail = (props) => {
961
961
  const iconProps = ToastContext.useIcon(props);
962
962
  return /* @__PURE__ */ jsxRuntime.jsx(ToastContext.Box, { component: IconMailSvg, ...iconProps });
963
963
  };
964
+ const IconMessageSvg = ({ title, titleId, ...props }) => /* @__PURE__ */ jsxRuntime.jsxs(
965
+ "svg",
966
+ {
967
+ xmlns: "http://www.w3.org/2000/svg",
968
+ width: 16,
969
+ height: 16,
970
+ viewBox: "0 0 24 24",
971
+ focusable: "false",
972
+ fill: "currentColor",
973
+ "aria-labelledby": titleId,
974
+ ...props,
975
+ children: [
976
+ title ? /* @__PURE__ */ jsxRuntime.jsx("title", { id: titleId, children: title }) : null,
977
+ /* @__PURE__ */ jsxRuntime.jsx(
978
+ "path",
979
+ {
980
+ d: "M12 3a9 9 0 0 0-7.605 13.815L3 21l4.909-.982A9 9 0 1 0 12 3Z",
981
+ fill: "none",
982
+ stroke: "currentColor",
983
+ strokeLinecap: "round",
984
+ strokeLinejoin: "round",
985
+ strokeWidth: 2
986
+ }
987
+ )
988
+ ]
989
+ }
990
+ );
991
+ const IconMessage = (props) => {
992
+ const iconProps = ToastContext.useIcon(props);
993
+ return /* @__PURE__ */ jsxRuntime.jsx(ToastContext.Box, { component: IconMessageSvg, ...iconProps });
994
+ };
964
995
  const IconMinusSvg = ({ title, titleId, ...props }) => /* @__PURE__ */ jsxRuntime.jsxs(
965
996
  "svg",
966
997
  {
@@ -2263,6 +2294,7 @@ const Alert = ({
2263
2294
  onClose,
2264
2295
  ...restProps
2265
2296
  }) => {
2297
+ const isLegacyTheme = sideEffects_lib_components_BraidProvider_BraidProvider_cjs.useBraidTheme().legacy;
2266
2298
  const parentBackground = ToastContext.useBackground();
2267
2299
  const Icon = icons$1[tone];
2268
2300
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2338,7 +2370,7 @@ const Alert = ({
2338
2370
  }
2339
2371
  ) }) : null
2340
2372
  ] }),
2341
- parentBackground.lightMode !== "surface" && /* @__PURE__ */ jsxRuntime.jsx(
2373
+ isLegacyTheme && parentBackground.lightMode !== "surface" && /* @__PURE__ */ jsxRuntime.jsx(
2342
2374
  ToastContext.Overlay,
2343
2375
  {
2344
2376
  borderRadius: borderRadius$3,
@@ -2543,12 +2575,16 @@ const Field = ({
2543
2575
  const hasValue = typeof value === "string" ? value.length > 0 : value != null;
2544
2576
  const hasVisualLabelOrDescription = "label" in restProps || description;
2545
2577
  const showSecondaryIcon = alwaysShowSecondaryIcon || secondaryIcon && hasValue;
2578
+ const { lightMode } = ToastContext.useBackgroundLightness();
2546
2579
  const overlays = /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
2547
2580
  /* @__PURE__ */ jsxRuntime.jsx(
2548
2581
  ToastContext.FieldOverlay,
2549
2582
  {
2550
2583
  variant: disabled ? "disabled" : "default",
2551
- visible: tone !== "critical" || disabled
2584
+ visible: tone !== "critical" || disabled,
2585
+ className: {
2586
+ [styles_lib_components_private_Field_Field_css_cjs.hideBorderOnDarkBackgroundInLightMode]: lightMode === "dark"
2587
+ }
2552
2588
  }
2553
2589
  ),
2554
2590
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3803,6 +3839,7 @@ const Card = ({
3803
3839
  validCardComponents.includes(component),
3804
3840
  `Invalid Card component: '${component}'. Should be one of [${validCardComponents.map((c) => `'${c}'`).join(", ")}]`
3805
3841
  );
3842
+ const isLegacyTheme = sideEffects_lib_components_BraidProvider_BraidProvider_cjs.useBraidTheme().legacy;
3806
3843
  let resolvedRounding;
3807
3844
  if ("rounded" in restProps) {
3808
3845
  resolvedRounding = borderRadius$2;
@@ -3815,6 +3852,7 @@ const Card = ({
3815
3852
  roundedOnWide ? borderRadius$2 : "none"
3816
3853
  ]);
3817
3854
  }
3855
+ const roundingForTheme = !isLegacyTheme ? borderRadius$2 : resolvedRounding;
3818
3856
  return /* @__PURE__ */ jsxRuntime.jsxs(
3819
3857
  ToastContext.Box,
3820
3858
  {
@@ -3822,11 +3860,12 @@ const Card = ({
3822
3860
  position: "relative",
3823
3861
  background: "surface",
3824
3862
  padding: "gutter",
3825
- borderRadius: resolvedRounding,
3863
+ borderRadius: roundingForTheme,
3864
+ boxShadow: !isLegacyTheme ? "borderNeutralLight" : void 0,
3826
3865
  height: height === "full" ? height : void 0,
3827
3866
  ...ToastContext.buildDataAttributes({ data, validateRestProps: restProps }),
3828
3867
  children: [
3829
- tone ? /* @__PURE__ */ jsxRuntime.jsx(Keyline, { tone, borderRadius: resolvedRounding }) : null,
3868
+ tone ? /* @__PURE__ */ jsxRuntime.jsx(Keyline, { tone, borderRadius: roundingForTheme }) : null,
3830
3869
  children
3831
3870
  ]
3832
3871
  }
@@ -3927,6 +3966,7 @@ const StyledInput = React.forwardRef(
3927
3966
  indeterminateRef.current = isMixed;
3928
3967
  }
3929
3968
  }, [ref, isMixed, isCheckbox]);
3969
+ const { lightMode } = ToastContext.useBackgroundLightness();
3930
3970
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3931
3971
  /* @__PURE__ */ jsxRuntime.jsx(
3932
3972
  ToastContext.Box,
@@ -3979,7 +4019,10 @@ const StyledInput = React.forwardRef(
3979
4019
  {
3980
4020
  variant: disabled ? "disabled" : defaultBorder,
3981
4021
  borderRadius: fieldBorderRadius,
3982
- visible: tone !== "critical" || disabled
4022
+ visible: tone !== "critical" || disabled,
4023
+ className: {
4024
+ [styles_lib_components_private_InlineField_InlineField_css_cjs.hideBorderOnDarkBackgroundInLightMode]: lightMode === "dark"
4025
+ }
3983
4026
  }
3984
4027
  ),
3985
4028
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -5864,6 +5907,33 @@ const Notice = ({
5864
5907
  }
5865
5908
  );
5866
5909
  };
5910
+ const validPageBlockComponents = [
5911
+ "div",
5912
+ "article",
5913
+ "aside",
5914
+ "main",
5915
+ "section",
5916
+ "nav"
5917
+ ];
5918
+ const gutters = { mobile: "xsmall", tablet: "gutter" };
5919
+ const PageBlock = ({
5920
+ children,
5921
+ width = "large",
5922
+ component: componentProp,
5923
+ data,
5924
+ ...restProps
5925
+ }) => {
5926
+ const component = componentProp && validPageBlockComponents.includes(componentProp) ? componentProp : "div";
5927
+ return /* @__PURE__ */ jsxRuntime.jsx(
5928
+ ToastContext.Box,
5929
+ {
5930
+ component,
5931
+ paddingX: gutters,
5932
+ ...ToastContext.buildDataAttributes({ data, validateRestProps: restProps }),
5933
+ children: /* @__PURE__ */ jsxRuntime.jsx(ToastContext.ContentBlock, { width, children })
5934
+ }
5935
+ );
5936
+ };
5867
5937
  const paginate = ({
5868
5938
  page,
5869
5939
  total,
@@ -5931,6 +6001,7 @@ const PageNav = ({
5931
6001
  const tabletButtonSpacing = "xxsmall";
5932
6002
  const Page = ({ number, current }) => {
5933
6003
  const parentBackground = ToastContext.useBackground();
6004
+ const isLegacyTheme = sideEffects_lib_components_BraidProvider_BraidProvider_cjs.useBraidTheme().legacy;
5934
6005
  return /* @__PURE__ */ jsxRuntime.jsxs(
5935
6006
  ToastContext.Box,
5936
6007
  {
@@ -5960,8 +6031,8 @@ const Page = ({ number, current }) => {
5960
6031
  borderRadius,
5961
6032
  boxShadow: "borderFormAccent",
5962
6033
  className: {
5963
- [styles_lib_components_Pagination_Pagination_css_cjs.lightModeCurrentKeyline]: parentBackground.lightMode !== "surface" && current,
5964
- [styles_lib_components_Pagination_Pagination_css_cjs.darkModeCurrentKeyline]: parentBackground.darkMode !== "surface" && current
6034
+ [styles_lib_components_Pagination_Pagination_css_cjs.lightModeCurrentKeyline]: isLegacyTheme && parentBackground.lightMode !== "surface" && current,
6035
+ [styles_lib_components_Pagination_Pagination_css_cjs.darkModeCurrentKeyline]: current
5965
6036
  }
5966
6037
  }
5967
6038
  ),
@@ -8037,7 +8108,6 @@ const Toggle = React.forwardRef(
8037
8108
  {
8038
8109
  position: "absolute",
8039
8110
  background: "surface",
8040
- boxShadow: on ? "borderFormAccent" : "borderField",
8041
8111
  transition: "fast",
8042
8112
  display: "flex",
8043
8113
  alignItems: "center",
@@ -8045,6 +8115,17 @@ const Toggle = React.forwardRef(
8045
8115
  borderRadius: "full",
8046
8116
  className: styles_lib_components_Toggle_Toggle_css_cjs.slider[size],
8047
8117
  children: [
8118
+ /* @__PURE__ */ jsxRuntime.jsx(
8119
+ ToastContext.FieldOverlay,
8120
+ {
8121
+ variant: on ? "formAccent" : "default",
8122
+ borderRadius: "full",
8123
+ visible: true,
8124
+ className: {
8125
+ [styles_lib_components_Toggle_Toggle_css_cjs.hideBorderOnDarkBackgroundInLightMode]: lightness.lightMode === "dark"
8126
+ }
8127
+ }
8128
+ ),
8048
8129
  /* @__PURE__ */ jsxRuntime.jsx(ToastContext.FieldOverlay, { className: styles_lib_components_Toggle_Toggle_css_cjs.icon, children: /* @__PURE__ */ jsxRuntime.jsx(IconTick, { tone: "formAccent", size: "fill" }) }),
8049
8130
  /* @__PURE__ */ jsxRuntime.jsx(
8050
8131
  ToastContext.FieldOverlay,
@@ -8140,6 +8221,7 @@ exports.IconLinkBroken = IconLinkBroken;
8140
8221
  exports.IconList = IconList;
8141
8222
  exports.IconLocation = IconLocation;
8142
8223
  exports.IconMail = IconMail;
8224
+ exports.IconMessage = IconMessage;
8143
8225
  exports.IconMinus = IconMinus;
8144
8226
  exports.IconMobile = IconMobile;
8145
8227
  exports.IconMoney = IconMoney;
@@ -8197,6 +8279,7 @@ exports.MenuRenderer = MenuRenderer;
8197
8279
  exports.MonthPicker = MonthPicker;
8198
8280
  exports.Notice = Notice;
8199
8281
  exports.OverflowMenu = OverflowMenu;
8282
+ exports.PageBlock = PageBlock;
8200
8283
  exports.Pagination = Pagination;
8201
8284
  exports.PasswordField = PasswordField;
8202
8285
  exports.Radio = Radio;
@@ -1,4 +1,4 @@
1
- import { useThemeName, useResponsiveValue, Stack, Box, buildDataAttributes, Divider, useIcon, virtualTouchable, Columns, Column, Inline, Text, Overlay, ActionsContext, useBackground, iconContainerSize, IconClear, IconPositive, IconCritical, TextContext, HeadingContext, textStyles, FieldOverlay, ButtonIcon, Bleed, useColoredBoxClasses, BackgroundProvider, ButtonContainer, useButtonStyles, ButtonOverlays, ButtonText, useBackgroundLightness, resolveResponsiveRangeProps, optimizeResponsiveArray, Typography, BraidPortal, TextLinkButton, AvoidWidowIcon, useDefaultTextProps, flattenChildren, DefaultTextPropsProvider, iconSize, Hidden, useSpace, negativeMargin, resolveResponsiveProp } from "./ToastContext.chunk.mjs";
1
+ import { useThemeName, useResponsiveValue, Stack, Box, buildDataAttributes, Divider, useIcon, virtualTouchable, Columns, Column, Inline, Text, Overlay, ActionsContext, useBackground, iconContainerSize, IconClear, IconPositive, IconCritical, TextContext, HeadingContext, useBackgroundLightness, textStyles, FieldOverlay, ButtonIcon, Bleed, useColoredBoxClasses, BackgroundProvider, ButtonContainer, useButtonStyles, ButtonOverlays, ButtonText, resolveResponsiveRangeProps, optimizeResponsiveArray, Typography, BraidPortal, TextLinkButton, AvoidWidowIcon, useDefaultTextProps, flattenChildren, DefaultTextPropsProvider, iconSize, ContentBlock, Hidden, useSpace, negativeMargin, resolveResponsiveProp } from "./ToastContext.chunk.mjs";
2
2
  import { useBraidTheme, useLinkComponent } from "./side-effects/lib/components/BraidProvider/BraidProvider.mjs";
3
3
  import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
4
4
  import assert from "assert";
@@ -35,7 +35,7 @@ import { isMobile } from "is-mobile";
35
35
  import { field as field$1 } from "./styles/lib/components/Dropdown/Dropdown.css.mjs";
36
36
  import { nativeInput } from "./styles/lib/components/MonthPicker/MonthPicker.css.mjs";
37
37
  import { hover, background, current, lightModeCurrentKeyline, darkModeCurrentKeyline } from "./styles/lib/components/Pagination/Pagination.css.mjs";
38
- import { realField, sizeVars, isMixed, fakeField, selected, focusOverlay as focusOverlay$1, hoverOverlay as hoverOverlay$1, checkboxIndicator, radioIndicator, labelOffset, children } from "./styles/lib/components/private/InlineField/InlineField.css.mjs";
38
+ import { realField, sizeVars, isMixed, fakeField, hideBorderOnDarkBackgroundInLightMode as hideBorderOnDarkBackgroundInLightMode$1, selected, focusOverlay as focusOverlay$1, hoverOverlay as hoverOverlay$1, checkboxIndicator, radioIndicator, labelOffset, children } from "./styles/lib/components/private/InlineField/InlineField.css.mjs";
39
39
  import { starSpacing, textSpacing, lightModeStarColor, darkModeStarColor } from "./styles/lib/components/Rating/Rating.css.mjs";
40
40
  import { step, tone as tone$2, progressTrack, progressTrackCentered, progressLine, progressUnfilled, indicatorContainer, focusOverlay as focusOverlay$2, indicator, highlight, complete, active, inner, tick, stretch, stretchLastAboveTablet } from "./styles/lib/components/Stepper/Stepper.css.mjs";
41
41
  import { tab, cropToIconX, hoveredTab, tabFocusRing, scroll as scroll$1, nowrap, mask, marginAuto, divider, tabUnderline, tabUnderlineActiveDarkMode, underlineLeft, underlineWidth, tabPanel, tabPanelFocusRing } from "./styles/lib/components/Tabs/Tabs.css.mjs";
@@ -45,9 +45,9 @@ import { root as root$4, caution, critical } from "./styles/lib/components/Texta
45
45
  import { highlights, field as field$2 } from "./styles/lib/components/Textarea/Textarea.css.mjs";
46
46
  import { select, focusOverlay as focusOverlay$3 } from "./styles/lib/components/TextDropdown/TextDropdown.css.mjs";
47
47
  import { root as root$1, up, left, right } from "./styles/lib/components/icons/IconChevron/IconChevron.css.mjs";
48
- import { secondaryIconSpace, field, placeholderColor, iconSpace, verticalDivider, focusOverlay, hoverOverlay } from "./styles/lib/components/private/Field/Field.css.mjs";
48
+ import { secondaryIconSpace, field, placeholderColor, iconSpace, verticalDivider, hideBorderOnDarkBackgroundInLightMode, focusOverlay, hoverOverlay } from "./styles/lib/components/private/Field/Field.css.mjs";
49
49
  import { columnsWide, columnsDesktop, columnsTablet, columnsMobile } from "./styles/lib/components/Tiles/Tiles.css.mjs";
50
- import { root as root$5, realField as realField$1, realFieldPosition, fieldSize, slideContainer, slideContainerSize, slideTrack, slideTrackMask, slideTrackBgLightMode, slideTrackBgDarkMode, slideTrackSelected, slider, icon as icon$1, focusOverlay as focusOverlay$4, hoverOverlay as hoverOverlay$2, label } from "./styles/lib/components/Toggle/Toggle.css.mjs";
50
+ import { root as root$5, realField as realField$1, realFieldPosition, fieldSize, slideContainer, slideContainerSize, slideTrack, slideTrackMask, slideTrackBgLightMode, slideTrackBgDarkMode, slideTrackSelected, slider, hideBorderOnDarkBackgroundInLightMode as hideBorderOnDarkBackgroundInLightMode$2, icon as icon$1, focusOverlay as focusOverlay$4, hoverOverlay as hoverOverlay$2, label } from "./styles/lib/components/Toggle/Toggle.css.mjs";
51
51
  const ThemeNameConsumer = ({ children: children2 }) => children2(useThemeName());
52
52
  const useColor = () => useBraidTheme().color;
53
53
  const useBreakpoint = () => {
@@ -953,6 +953,37 @@ const IconMail = (props) => {
953
953
  const iconProps = useIcon(props);
954
954
  return /* @__PURE__ */ jsx(Box, { component: IconMailSvg, ...iconProps });
955
955
  };
956
+ const IconMessageSvg = ({ title, titleId, ...props }) => /* @__PURE__ */ jsxs(
957
+ "svg",
958
+ {
959
+ xmlns: "http://www.w3.org/2000/svg",
960
+ width: 16,
961
+ height: 16,
962
+ viewBox: "0 0 24 24",
963
+ focusable: "false",
964
+ fill: "currentColor",
965
+ "aria-labelledby": titleId,
966
+ ...props,
967
+ children: [
968
+ title ? /* @__PURE__ */ jsx("title", { id: titleId, children: title }) : null,
969
+ /* @__PURE__ */ jsx(
970
+ "path",
971
+ {
972
+ d: "M12 3a9 9 0 0 0-7.605 13.815L3 21l4.909-.982A9 9 0 1 0 12 3Z",
973
+ fill: "none",
974
+ stroke: "currentColor",
975
+ strokeLinecap: "round",
976
+ strokeLinejoin: "round",
977
+ strokeWidth: 2
978
+ }
979
+ )
980
+ ]
981
+ }
982
+ );
983
+ const IconMessage = (props) => {
984
+ const iconProps = useIcon(props);
985
+ return /* @__PURE__ */ jsx(Box, { component: IconMessageSvg, ...iconProps });
986
+ };
956
987
  const IconMinusSvg = ({ title, titleId, ...props }) => /* @__PURE__ */ jsxs(
957
988
  "svg",
958
989
  {
@@ -2255,6 +2286,7 @@ const Alert = ({
2255
2286
  onClose,
2256
2287
  ...restProps
2257
2288
  }) => {
2289
+ const isLegacyTheme = useBraidTheme().legacy;
2258
2290
  const parentBackground = useBackground();
2259
2291
  const Icon = icons$1[tone2];
2260
2292
  return /* @__PURE__ */ jsxs(
@@ -2330,7 +2362,7 @@ const Alert = ({
2330
2362
  }
2331
2363
  ) }) : null
2332
2364
  ] }),
2333
- parentBackground.lightMode !== "surface" && /* @__PURE__ */ jsx(
2365
+ isLegacyTheme && parentBackground.lightMode !== "surface" && /* @__PURE__ */ jsx(
2334
2366
  Overlay,
2335
2367
  {
2336
2368
  borderRadius: borderRadius$3,
@@ -2535,12 +2567,16 @@ const Field = ({
2535
2567
  const hasValue = typeof value === "string" ? value.length > 0 : value != null;
2536
2568
  const hasVisualLabelOrDescription = "label" in restProps || description;
2537
2569
  const showSecondaryIcon = alwaysShowSecondaryIcon || secondaryIcon && hasValue;
2570
+ const { lightMode: lightMode2 } = useBackgroundLightness();
2538
2571
  const overlays = /* @__PURE__ */ jsxs(Fragment, { children: [
2539
2572
  /* @__PURE__ */ jsx(
2540
2573
  FieldOverlay,
2541
2574
  {
2542
2575
  variant: disabled ? "disabled" : "default",
2543
- visible: tone2 !== "critical" || disabled
2576
+ visible: tone2 !== "critical" || disabled,
2577
+ className: {
2578
+ [hideBorderOnDarkBackgroundInLightMode]: lightMode2 === "dark"
2579
+ }
2544
2580
  }
2545
2581
  ),
2546
2582
  /* @__PURE__ */ jsx(
@@ -3795,6 +3831,7 @@ const Card = ({
3795
3831
  validCardComponents.includes(component),
3796
3832
  `Invalid Card component: '${component}'. Should be one of [${validCardComponents.map((c) => `'${c}'`).join(", ")}]`
3797
3833
  );
3834
+ const isLegacyTheme = useBraidTheme().legacy;
3798
3835
  let resolvedRounding;
3799
3836
  if ("rounded" in restProps) {
3800
3837
  resolvedRounding = borderRadius$2;
@@ -3807,6 +3844,7 @@ const Card = ({
3807
3844
  roundedOnWide ? borderRadius$2 : "none"
3808
3845
  ]);
3809
3846
  }
3847
+ const roundingForTheme = !isLegacyTheme ? borderRadius$2 : resolvedRounding;
3810
3848
  return /* @__PURE__ */ jsxs(
3811
3849
  Box,
3812
3850
  {
@@ -3814,11 +3852,12 @@ const Card = ({
3814
3852
  position: "relative",
3815
3853
  background: "surface",
3816
3854
  padding: "gutter",
3817
- borderRadius: resolvedRounding,
3855
+ borderRadius: roundingForTheme,
3856
+ boxShadow: !isLegacyTheme ? "borderNeutralLight" : void 0,
3818
3857
  height: height === "full" ? height : void 0,
3819
3858
  ...buildDataAttributes({ data, validateRestProps: restProps }),
3820
3859
  children: [
3821
- tone2 ? /* @__PURE__ */ jsx(Keyline, { tone: tone2, borderRadius: resolvedRounding }) : null,
3860
+ tone2 ? /* @__PURE__ */ jsx(Keyline, { tone: tone2, borderRadius: roundingForTheme }) : null,
3822
3861
  children2
3823
3862
  ]
3824
3863
  }
@@ -3919,6 +3958,7 @@ const StyledInput = forwardRef(
3919
3958
  indeterminateRef.current = isMixed$1;
3920
3959
  }
3921
3960
  }, [ref, isMixed$1, isCheckbox]);
3961
+ const { lightMode: lightMode2 } = useBackgroundLightness();
3922
3962
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
3923
3963
  /* @__PURE__ */ jsx(
3924
3964
  Box,
@@ -3971,7 +4011,10 @@ const StyledInput = forwardRef(
3971
4011
  {
3972
4012
  variant: disabled ? "disabled" : defaultBorder,
3973
4013
  borderRadius: fieldBorderRadius,
3974
- visible: tone2 !== "critical" || disabled
4014
+ visible: tone2 !== "critical" || disabled,
4015
+ className: {
4016
+ [hideBorderOnDarkBackgroundInLightMode$1]: lightMode2 === "dark"
4017
+ }
3975
4018
  }
3976
4019
  ),
3977
4020
  /* @__PURE__ */ jsx(
@@ -5856,6 +5899,33 @@ const Notice = ({
5856
5899
  }
5857
5900
  );
5858
5901
  };
5902
+ const validPageBlockComponents = [
5903
+ "div",
5904
+ "article",
5905
+ "aside",
5906
+ "main",
5907
+ "section",
5908
+ "nav"
5909
+ ];
5910
+ const gutters = { mobile: "xsmall", tablet: "gutter" };
5911
+ const PageBlock = ({
5912
+ children: children2,
5913
+ width: width2 = "large",
5914
+ component: componentProp,
5915
+ data,
5916
+ ...restProps
5917
+ }) => {
5918
+ const component = componentProp && validPageBlockComponents.includes(componentProp) ? componentProp : "div";
5919
+ return /* @__PURE__ */ jsx(
5920
+ Box,
5921
+ {
5922
+ component,
5923
+ paddingX: gutters,
5924
+ ...buildDataAttributes({ data, validateRestProps: restProps }),
5925
+ children: /* @__PURE__ */ jsx(ContentBlock, { width: width2, children: children2 })
5926
+ }
5927
+ );
5928
+ };
5859
5929
  const paginate = ({
5860
5930
  page,
5861
5931
  total,
@@ -5923,6 +5993,7 @@ const PageNav = ({
5923
5993
  const tabletButtonSpacing = "xxsmall";
5924
5994
  const Page = ({ number, current: current$1 }) => {
5925
5995
  const parentBackground = useBackground();
5996
+ const isLegacyTheme = useBraidTheme().legacy;
5926
5997
  return /* @__PURE__ */ jsxs(
5927
5998
  Box,
5928
5999
  {
@@ -5952,8 +6023,8 @@ const Page = ({ number, current: current$1 }) => {
5952
6023
  borderRadius,
5953
6024
  boxShadow: "borderFormAccent",
5954
6025
  className: {
5955
- [lightModeCurrentKeyline]: parentBackground.lightMode !== "surface" && current$1,
5956
- [darkModeCurrentKeyline]: parentBackground.darkMode !== "surface" && current$1
6026
+ [lightModeCurrentKeyline]: isLegacyTheme && parentBackground.lightMode !== "surface" && current$1,
6027
+ [darkModeCurrentKeyline]: current$1
5957
6028
  }
5958
6029
  }
5959
6030
  ),
@@ -8029,7 +8100,6 @@ const Toggle = forwardRef(
8029
8100
  {
8030
8101
  position: "absolute",
8031
8102
  background: "surface",
8032
- boxShadow: on ? "borderFormAccent" : "borderField",
8033
8103
  transition: "fast",
8034
8104
  display: "flex",
8035
8105
  alignItems: "center",
@@ -8037,6 +8107,17 @@ const Toggle = forwardRef(
8037
8107
  borderRadius: "full",
8038
8108
  className: slider[size2],
8039
8109
  children: [
8110
+ /* @__PURE__ */ jsx(
8111
+ FieldOverlay,
8112
+ {
8113
+ variant: on ? "formAccent" : "default",
8114
+ borderRadius: "full",
8115
+ visible: true,
8116
+ className: {
8117
+ [hideBorderOnDarkBackgroundInLightMode$2]: lightness.lightMode === "dark"
8118
+ }
8119
+ }
8120
+ ),
8040
8121
  /* @__PURE__ */ jsx(FieldOverlay, { className: icon$1, children: /* @__PURE__ */ jsx(IconTick, { tone: "formAccent", size: "fill" }) }),
8041
8122
  /* @__PURE__ */ jsx(
8042
8123
  FieldOverlay,
@@ -8133,6 +8214,7 @@ export {
8133
8214
  IconList,
8134
8215
  IconLocation,
8135
8216
  IconMail,
8217
+ IconMessage,
8136
8218
  IconMinus,
8137
8219
  IconMobile,
8138
8220
  IconMoney,
@@ -8190,6 +8272,7 @@ export {
8190
8272
  MonthPicker,
8191
8273
  Notice,
8192
8274
  OverflowMenu,
8275
+ PageBlock,
8193
8276
  Pagination,
8194
8277
  PasswordField,
8195
8278
  Radio,
package/dist/index.cjs CHANGED
@@ -82,6 +82,7 @@ exports.IconLinkBroken = Toggle.IconLinkBroken;
82
82
  exports.IconList = Toggle.IconList;
83
83
  exports.IconLocation = Toggle.IconLocation;
84
84
  exports.IconMail = Toggle.IconMail;
85
+ exports.IconMessage = Toggle.IconMessage;
85
86
  exports.IconMinus = Toggle.IconMinus;
86
87
  exports.IconMobile = Toggle.IconMobile;
87
88
  exports.IconMoney = Toggle.IconMoney;
@@ -139,6 +140,7 @@ exports.MenuRenderer = Toggle.MenuRenderer;
139
140
  exports.MonthPicker = Toggle.MonthPicker;
140
141
  exports.Notice = Toggle.Notice;
141
142
  exports.OverflowMenu = Toggle.OverflowMenu;
143
+ exports.PageBlock = Toggle.PageBlock;
142
144
  exports.Pagination = Toggle.Pagination;
143
145
  exports.PasswordField = Toggle.PasswordField;
144
146
  exports.Radio = Toggle.Radio;
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { Accordion, AccordionItem, Actions, Alert, Autosuggest, Badge, Bleed, PublicBox as Box, BoxRenderer, BraidPortal, BraidProvider, Button, ButtonIcon, ButtonLink, Card, Checkbox, CheckboxStandalone, Column, Columns, ContentBlock, Dialog, Disclosure, Divider, Drawer, Dropdown, FieldLabel, FieldMessage, Heading, Hidden, HiddenVisually, IconAdd, IconArrow, IconBookmark, IconCaution, IconChevron, IconClear, IconCompany, IconCompose, IconCopy, IconCreditCard, IconCritical, IconDate, IconDelete, IconDesktop, IconDocument, IconDocumentBroken, IconDownload, IconEdit, IconEducation, IconFilter, IconFlag, IconGrid, IconHeart, IconHelp, IconHistory, IconHome, IconImage, IconInfo, IconInvoice, IconLanguage, IconLink, IconLinkBroken, IconList, IconLocation, IconMail, IconMinus, IconMobile, IconMoney, IconNewWindow, IconNote, IconNotification, IconOverflow, IconPeople, IconPersonAdd, IconPersonVerified, IconPhone, IconPlatformAndroid, IconPlatformApple, IconPositive, IconPrint, IconProfile, IconPromote, IconRecommended, IconRefresh, IconRenderer, IconResume, IconSearch, IconSecurity, IconSend, IconSent, IconSettings, IconShare, IconSocialFacebook, IconSocialGitHub, IconSocialInstagram, IconSocialLinkedIn, IconSocialMedium, IconSocialTwitter, IconSocialYouTube, IconStar, IconStatistics, IconSubCategory, IconTag, IconThumb, IconTick, IconTime, IconTip, IconUpload, IconVideo, IconVisibility, IconWorkExperience, IconZoomIn, IconZoomOut, Inline, Link, LinkComponent, List, Loader, MenuItem, MenuItemCheckbox, MenuItemDivider, MenuItemLink, MenuRenderer, MonthPicker, Notice, OverflowMenu, Pagination, PasswordField, Radio, RadioGroup, RadioItem, Rating, Secondary, Stack, Step, Stepper, Strong, Tab, TabPanel, TabPanels, Tabs, TabsProvider, Tag, Text, TextDropdown, TextField, TextLink, TextLinkButton, Textarea, ThemeNameConsumer, Tiles, ToastProvider, Toggle, TooltipRenderer, filterSuggestions, makeLinkComponent, useBreakpoint, useColor, useResponsiveValue, useSpace, useThemeName, useToast } from './reset.js';
1
+ export { Accordion, AccordionItem, Actions, Alert, Autosuggest, Badge, Bleed, PublicBox as Box, BoxRenderer, BraidPortal, BraidProvider, Button, ButtonIcon, ButtonLink, Card, Checkbox, CheckboxStandalone, Column, Columns, ContentBlock, Dialog, Disclosure, Divider, Drawer, Dropdown, FieldLabel, FieldMessage, Heading, Hidden, HiddenVisually, IconAdd, IconArrow, IconBookmark, IconCaution, IconChevron, IconClear, IconCompany, IconCompose, IconCopy, IconCreditCard, IconCritical, IconDate, IconDelete, IconDesktop, IconDocument, IconDocumentBroken, IconDownload, IconEdit, IconEducation, IconFilter, IconFlag, IconGrid, IconHeart, IconHelp, IconHistory, IconHome, IconImage, IconInfo, IconInvoice, IconLanguage, IconLink, IconLinkBroken, IconList, IconLocation, IconMail, IconMessage, IconMinus, IconMobile, IconMoney, IconNewWindow, IconNote, IconNotification, IconOverflow, IconPeople, IconPersonAdd, IconPersonVerified, IconPhone, IconPlatformAndroid, IconPlatformApple, IconPositive, IconPrint, IconProfile, IconPromote, IconRecommended, IconRefresh, IconRenderer, IconResume, IconSearch, IconSecurity, IconSend, IconSent, IconSettings, IconShare, IconSocialFacebook, IconSocialGitHub, IconSocialInstagram, IconSocialLinkedIn, IconSocialMedium, IconSocialTwitter, IconSocialYouTube, IconStar, IconStatistics, IconSubCategory, IconTag, IconThumb, IconTick, IconTime, IconTip, IconUpload, IconVideo, IconVisibility, IconWorkExperience, IconZoomIn, IconZoomOut, Inline, Link, LinkComponent, List, Loader, MenuItem, MenuItemCheckbox, MenuItemDivider, MenuItemLink, MenuRenderer, MonthPicker, Notice, OverflowMenu, PageBlock, Pagination, PasswordField, Radio, RadioGroup, RadioItem, Rating, Secondary, Stack, Step, Stepper, Strong, Tab, TabPanel, TabPanels, Tabs, TabsProvider, Tag, Text, TextDropdown, TextField, TextLink, TextLinkButton, Textarea, ThemeNameConsumer, Tiles, ToastProvider, Toggle, TooltipRenderer, filterSuggestions, makeLinkComponent, useBreakpoint, useColor, useResponsiveValue, useSpace, useThemeName, useToast } from './reset.js';