braid-design-system 31.0.0 → 31.2.2

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 (106) hide show
  1. package/.nvmrc +1 -1
  2. package/CHANGELOG.md +58 -0
  3. package/color-mode/index.ts +9 -0
  4. package/css/atoms.docs.tsx +26 -20
  5. package/css/colorModeStyle.docs.tsx +81 -0
  6. package/css/index.ts +5 -1
  7. package/lib/components/Alert/Alert.css.ts +19 -0
  8. package/lib/components/Alert/Alert.docs.tsx +17 -5
  9. package/lib/components/Alert/Alert.tsx +61 -30
  10. package/lib/components/Badge/Badge.tsx +11 -31
  11. package/lib/components/Box/BackgroundContext.tsx +34 -17
  12. package/lib/components/Box/Box.docs.tsx +34 -14
  13. package/lib/components/Box/Box.playroom.tsx +37 -0
  14. package/lib/components/Box/Box.tsx +38 -7
  15. package/lib/components/Box/BoxRenderer.tsx +28 -9
  16. package/lib/components/Box/ColoredBox.tsx +168 -13
  17. package/lib/components/BraidPortal/BraidPortal.tsx +4 -1
  18. package/lib/components/BraidProvider/BraidProvider.tsx +11 -3
  19. package/lib/components/BraidProvider/VanillaThemeContainer.tsx +24 -0
  20. package/lib/components/Button/Button.css.ts +38 -5
  21. package/lib/components/Button/Button.screenshots.tsx +4 -1
  22. package/lib/components/Button/Button.tsx +102 -70
  23. package/lib/components/Card/Card.tsx +2 -13
  24. package/lib/components/Checkbox/Checkbox.screenshots.tsx +17 -8
  25. package/lib/components/Divider/Divider.css.ts +45 -4
  26. package/lib/components/Divider/Divider.tsx +20 -14
  27. package/lib/components/Dropdown/Dropdown.docs.tsx +0 -1
  28. package/lib/components/FieldLabel/FieldLabel.docs.tsx +1 -1
  29. package/lib/components/FieldMessage/FieldMessage.screenshots.tsx +6 -0
  30. package/lib/components/Heading/Heading.docs.tsx +6 -4
  31. package/lib/components/Heading/Heading.screenshots.tsx +4 -1
  32. package/lib/components/Loader/Loader.css.ts +3 -4
  33. package/lib/components/Loader/Loader.screenshots.tsx +4 -1
  34. package/lib/components/Loader/Loader.tsx +27 -30
  35. package/lib/components/MenuItem/MenuItemLink.tsx +9 -2
  36. package/lib/components/MenuItem/useMenuItem.tsx +4 -4
  37. package/lib/components/MenuItemCheckbox/MenuItemCheckbox.tsx +3 -1
  38. package/lib/components/MenuRenderer/testHelper.tsx +5 -2
  39. package/lib/components/Pagination/Pagination.css.ts +17 -3
  40. package/lib/components/Pagination/Pagination.tsx +6 -5
  41. package/lib/components/Rating/Rating.css.ts +16 -3
  42. package/lib/components/Rating/Rating.screenshots.tsx +4 -1
  43. package/lib/components/Rating/Rating.tsx +6 -1
  44. package/lib/components/Tabs/Tab.tsx +6 -2
  45. package/lib/components/Tabs/Tabs.css.ts +9 -1
  46. package/lib/components/Tabs/Tabs.tsx +4 -1
  47. package/lib/components/Text/Text.docs.tsx +4 -0
  48. package/lib/components/Text/Text.screenshots.tsx +8 -1
  49. package/lib/components/TextField/TextField.docs.tsx +0 -1
  50. package/lib/components/TextLink/TextLink.css.ts +139 -0
  51. package/lib/components/TextLink/TextLink.docs.tsx +1 -1
  52. package/lib/components/TextLink/TextLink.screenshots.tsx +3 -1
  53. package/lib/components/TextLink/TextLink.tsx +45 -37
  54. package/lib/components/Textarea/Highlight/Highlight.tsx +1 -1
  55. package/lib/components/Textarea/Textarea.docs.tsx +0 -1
  56. package/lib/components/Toggle/Toggle.css.ts +34 -7
  57. package/lib/components/Toggle/Toggle.tsx +8 -3
  58. package/lib/components/iconButtons/IconButton.css.ts +0 -32
  59. package/lib/components/iconButtons/IconButton.tsx +26 -48
  60. package/lib/components/icons/IconTip/IconTip.docs.tsx +20 -0
  61. package/lib/components/icons/IconTip/IconTip.tsx +12 -0
  62. package/lib/components/icons/IconTip/IconTipSvg.tsx +21 -0
  63. package/lib/components/icons/IconZoomIn/IconZoomIn.docs.tsx +20 -0
  64. package/lib/components/icons/IconZoomIn/IconZoomIn.tsx +12 -0
  65. package/lib/components/icons/IconZoomIn/IconZoomInSvg.tsx +20 -0
  66. package/lib/components/icons/IconZoomOut/IconZoomOut.docs.tsx +20 -0
  67. package/lib/components/icons/IconZoomOut/IconZoomOut.tsx +12 -0
  68. package/lib/components/icons/IconZoomOut/IconZoomOutSvg.tsx +20 -0
  69. package/lib/components/icons/Icons.screenshots.tsx +2 -2
  70. package/lib/components/icons/index.ts +3 -0
  71. package/lib/components/index.ts +3 -1
  72. package/lib/components/private/Field/Field.css.ts +2 -1
  73. package/lib/components/private/Field/Field.tsx +4 -6
  74. package/lib/components/private/InlineField/InlineField.css.ts +6 -6
  75. package/lib/components/private/InlineField/StyledInput.tsx +14 -9
  76. package/lib/components/private/Keyline/Keyline.css.ts +70 -0
  77. package/lib/components/private/Keyline/Keyline.tsx +38 -0
  78. package/lib/components/private/Placeholder/Placeholder.css.ts +44 -12
  79. package/lib/components/private/Placeholder/Placeholder.tsx +7 -3
  80. package/lib/components/private/touchable/debugTouchable.ts +7 -7
  81. package/lib/components/private/touchable/virtualTouchable.css.ts +12 -12
  82. package/lib/components/useToast/Toast.tsx +2 -8
  83. package/lib/css/atoms/atomicProperties.ts +7 -2
  84. package/lib/css/atoms/sprinkles.css.ts +24 -0
  85. package/lib/css/colorModeStyle.ts +33 -0
  86. package/lib/css/reset/reset.css.ts +12 -8
  87. package/lib/hooks/typography/index.ts +8 -61
  88. package/lib/hooks/typography/typography.css.ts +95 -93
  89. package/lib/hooks/useIcon/index.ts +4 -2
  90. package/lib/playroom/FrameComponent.tsx +50 -17
  91. package/lib/playroom/components.ts +1 -0
  92. package/lib/playroom/useScope.ts +44 -1
  93. package/lib/stories/all.stories.tsx +61 -30
  94. package/lib/themes/baseTokens/apac.ts +8 -0
  95. package/lib/themes/catho/tokens.ts +23 -6
  96. package/lib/themes/docs/tokens.ts +8 -0
  97. package/lib/themes/makeBraidTheme.ts +4 -1
  98. package/lib/themes/occ/tokens.ts +25 -5
  99. package/lib/themes/seekAnz/tokens.ts +25 -5
  100. package/lib/themes/tokenType.ts +8 -0
  101. package/lib/themes/wireframe/tokens.ts +22 -5
  102. package/package.json +2 -2
  103. package/sku.config.js +1 -0
  104. package/sku.routes.js +2 -0
  105. package/tsconfig.json +1 -0
  106. package/lib/components/Card/Card.css.ts +0 -6
package/.nvmrc CHANGED
@@ -1 +1 @@
1
- 12.14.1
1
+ 16.13.0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # braid-design-system
2
2
 
3
+ ## 31.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - **BraidProvider:** Add `backgroundColor` to html node when `styleBody` is set (defaults to `true`) ([#1047](https://github.com/seek-oss/braid-design-system/pull/1047))
8
+
9
+ ## 31.2.1
10
+
11
+ ### Patch Changes
12
+
13
+ - useIcon: Return props compatible with public Box component ([#1045](https://github.com/seek-oss/braid-design-system/pull/1045))
14
+
15
+ ## 31.2.0
16
+
17
+ ### Minor Changes
18
+
19
+ - **vars:** Add light variant foreground colors ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
20
+
21
+ **New foregrounds**
22
+ The following foregrounds are now available on the `vars.foregroundColor` theme object:
23
+
24
+ - `cautionLight`
25
+ - `infoLight`
26
+ - `linkLight`
27
+ - `linkLightVisited`
28
+ - `positiveLight`
29
+ - `promoteLight`
30
+
31
+ - **Text:** Improve contrast of `caution`, `positive`, `info`, `promote` and `link` tones ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
32
+
33
+ When using any of the above tones in a dark container, a lighter colour will be used to improve the text contrast against the background.
34
+
35
+ ### Patch Changes
36
+
37
+ - **OverflowMenu:** Use `neutral` tone button style ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
38
+
39
+ - **Alert, Card, Toast:** Improve highlight keyline ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
40
+
41
+ Ensures that components using a highlight keyline have the correct border radius and mask their overflow correctly.
42
+
43
+ - **Alert, Autosuggest, Tag, TextField:** Use `neutral` tone button style for clear action ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
44
+
45
+ - **Box:** Reset background color on `input` and `select` elements ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
46
+
47
+ When specifying a `component` of `input` or `select` the background color was not being reset, falling through to the user agent styles. Reseting it to `transparent` to ensure predicatble styles across browsers and colour modes.
48
+
49
+ - **MenuItem, MenuItemLink, MenuItemCheckbox:** Use `span` elements internally for more valid HTML. ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
50
+
51
+ - **Loader:** Use current text color ([#1042](https://github.com/seek-oss/braid-design-system/pull/1042))
52
+
53
+ ## 31.1.0
54
+
55
+ ### Minor Changes
56
+
57
+ - **IconTip:** Add tip icon ([#1040](https://github.com/seek-oss/braid-design-system/pull/1040))
58
+
59
+ - **IconZoomIn, IconZoomOut:** Add zoom in/out icons ([#1035](https://github.com/seek-oss/braid-design-system/pull/1035))
60
+
3
61
  ## 31.0.0
4
62
 
5
63
  ### Major Changes
@@ -0,0 +1,9 @@
1
+ import { darkMode } from '../lib/css/atoms/sprinkles.css';
2
+ const flag = '_bdsdm=1';
3
+ // TODO: COLORMODE RELEASE
4
+ // Finalise import contract
5
+ export const __experimentalDarkMode__ = `
6
+ <script>
7
+ ((l,p)=>{try{r=new RegExp(\`[\?&]\${p}\`);if(r.test(l.search)){history.replaceState(null,null,l.pathname+l.search.replace(r,'').replace(/^&/,'?')+l.hash);if(matchMedia('(prefers-color-scheme:dark)').matches)document.documentElement.classList.add('${darkMode}')}}catch(e){}})(location,'${flag}')
8
+ </script>
9
+ `;
@@ -9,9 +9,8 @@ import {
9
9
  UnresponsiveProperties,
10
10
  BoxShadow,
11
11
  } from '../lib/css/atoms/atomicProperties';
12
- import { atoms } from '../lib/css/atoms/atoms';
12
+ import { atoms } from '../css';
13
13
  import {
14
- Box,
15
14
  Stack,
16
15
  Columns,
17
16
  Column,
@@ -22,6 +21,9 @@ import {
22
21
  Strong,
23
22
  Alert,
24
23
  } from '../lib/components';
24
+ // TODO: COLORMODE RELEASE
25
+ // Use public import
26
+ import { Box } from '../lib/components/Box/Box';
25
27
  import source from '../lib/utils/source.macro';
26
28
  import Code from '../site/src/App/Code/Code';
27
29
  import { ThemedExample } from '../site/src/App/ThemeSetting';
@@ -134,17 +136,13 @@ const docs: CssDoc = {
134
136
  Object.keys(
135
137
  unresponsiveProperties,
136
138
  ) as Array<UnresponsiveProperties>
137
- )
138
- // filtering out `background` as it’s not public api due to
139
- // impact on context related contrast handling..
140
- .filter((prop) => prop !== 'background')
141
- .map((prop) => (
142
- <AtomicProperty
143
- key={prop}
144
- name={prop}
145
- values={Object.keys(unresponsiveProperties[prop])}
146
- />
147
- ))}
139
+ ).map((prop) => (
140
+ <AtomicProperty
141
+ key={prop}
142
+ name={prop}
143
+ values={Object.keys(unresponsiveProperties[prop])}
144
+ />
145
+ ))}
148
146
  </Tiles>
149
147
  </Box>
150
148
  </>
@@ -173,7 +171,7 @@ const docs: CssDoc = {
173
171
  };
174
172
  `}
175
173
  </Code>
176
- <ThemedExample background="body">
174
+ <ThemedExample>
177
175
  <Stack space="gutter" align="center">
178
176
  <Inline space="gutter" align="center" alignY="center">
179
177
  <Box
@@ -318,7 +316,7 @@ const docs: CssDoc = {
318
316
  };
319
317
  `}
320
318
  </Code>
321
- <ThemedExample background="body">
319
+ <ThemedExample>
322
320
  <Inline space="medium" align="center">
323
321
  <Box
324
322
  background="formAccentHover"
@@ -377,7 +375,7 @@ const docs: CssDoc = {
377
375
  ways when upgrading Braid.
378
376
  </Text>
379
377
  </Alert>
380
- <ThemedExample background="body">
378
+ <ThemedExample>
381
379
  <Tiles space="large" columns={{ mobile: 1, desktop: 2 }}>
382
380
  {Object.entries(
383
381
  validateBoxShadows({
@@ -432,14 +430,22 @@ const docs: CssDoc = {
432
430
  <Columns key={boxShadow} space="medium" alignY="center">
433
431
  <Column width="content">
434
432
  <Box
435
- background={
436
- boxShadow.includes('Inverted') ? 'brand' : 'surface'
437
- }
433
+ background={{
434
+ lightMode: boxShadow.includes('Inverted')
435
+ ? 'neutral'
436
+ : 'surface',
437
+ darkMode: /^border|outline/.test(boxShadow)
438
+ ? 'surfaceDark'
439
+ : 'surface',
440
+ }}
438
441
  borderRadius="standard"
439
442
  padding="gutter"
440
443
  >
441
444
  <Box
442
- boxShadow={boxShadow as keyof BoxShadowDocs}
445
+ boxShadow={{
446
+ lightMode: boxShadow as keyof BoxShadowDocs,
447
+ darkMode: boxShadow as keyof BoxShadowDocs,
448
+ }}
443
449
  borderRadius="standard"
444
450
  padding="gutter"
445
451
  />
@@ -0,0 +1,81 @@
1
+ import dedent from 'dedent';
2
+ import React from 'react';
3
+ import { colorModeStyle, vars } from '.';
4
+ import { Strong, Text, TextLink } from '../lib/components';
5
+ import source from '../lib/utils/source.macro';
6
+ import Code from '../site/src/App/Code/Code';
7
+ import { CssDoc } from '../site/src/types';
8
+
9
+ const docs: CssDoc = {
10
+ usage: (
11
+ <Code>{`import { colorModeStyle } from 'braid-design-system/css';`}</Code>
12
+ ),
13
+ description: (
14
+ <Text>
15
+ A utility to make authoring color mode specific styles in{' '}
16
+ <TextLink href="https://vanilla-extract.style">vanilla-extract</TextLink>{' '}
17
+ stylesheets easier.
18
+ </Text>
19
+ ),
20
+ additional: [
21
+ {
22
+ label: 'Authoring styles by color mode',
23
+ description: (
24
+ <>
25
+ <Text>
26
+ The <Strong>colorModeStyle</Strong> function is a convenience for
27
+ authoring color mode specific styling rules. It accepts sets of
28
+ rules for each mode, e.g. <Strong>lightMode</Strong> and{' '}
29
+ <Strong>darkMode</Strong>, and returns them scoped to the
30
+ corresponding CSS selector.
31
+ </Text>
32
+ <Text>
33
+ The returned object must be passed through one of
34
+ vanilla-extract&rsquo;s{' '}
35
+ <TextLink href="https://vanilla-extract.style/documentation/styling-api/">
36
+ styling apis
37
+ </TextLink>
38
+ , e.g. <Strong>style</Strong>, to create the actual styles.
39
+ </Text>
40
+ <Code>
41
+ {dedent`
42
+ // styles.css.ts
43
+ import { style } from '@vanilla-extract/css';
44
+ import { vars, colorModeStyle } from 'braid-design-system/css';
45
+
46
+ export const className = style(${
47
+ source(
48
+ colorModeStyle({
49
+ lightMode: { borderColor: vars.borderColor.positiveLight },
50
+ darkMode: { borderColor: vars.borderColor.neutral },
51
+ }),
52
+ ).code
53
+ });
54
+
55
+ // is equivalent to
56
+ import { style } from '@vanilla-extract/css';
57
+ import { vars, breakpoints } from 'braid-design-system/css';
58
+
59
+ // The dark mode class name is not public api,
60
+ // this is a placeholder class name for the example:
61
+ const darkModeClass = "🌙";
62
+
63
+ export const className = style({
64
+ selectors: {
65
+ ${'[`html:not(${darkModeClass}) &`]: {'}
66
+ borderColor: vars.borderColor.positiveLight
67
+ },
68
+ ${'[`html${darkModeClass} &`]: {'}
69
+ borderColor: vars.borderColor.neutral
70
+ },
71
+ }
72
+ });
73
+ `}
74
+ </Code>
75
+ </>
76
+ ),
77
+ },
78
+ ],
79
+ };
80
+
81
+ export default docs;
package/css/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { vars as internalVars } from '../lib/themes/vars.css';
2
2
  import { atoms as internalAtoms, Atoms } from '../lib/css/atoms/atoms';
3
+ import { colorModeStyle } from '../lib/css/colorModeStyle';
3
4
  import { responsiveStyle } from '../lib/css/responsiveStyle';
4
5
  import { breakpoints } from '../lib/css/breakpoints';
5
6
  import { globalHeadingStyle, globalTextStyle } from '../lib/hooks/typography';
@@ -9,7 +10,9 @@ const {
9
10
  grid,
10
11
  space,
11
12
  touchableSize,
12
- backgroundColor,
13
+ // TODO: COLORMODE RELEASE
14
+ // Release new backgrounds
15
+ backgroundColor: { surfaceDark: _, bodyDark: __, ...backgroundColor },
13
16
  foregroundColor,
14
17
  textWeight,
15
18
  borderColor,
@@ -46,6 +49,7 @@ export {
46
49
  atoms,
47
50
  breakpoints,
48
51
  responsiveStyle,
52
+ colorModeStyle,
49
53
  globalTextStyle,
50
54
  globalHeadingStyle,
51
55
  };
@@ -0,0 +1,19 @@
1
+ import { style } from '@vanilla-extract/css';
2
+
3
+ export const closeButton = style({});
4
+
5
+ export const closeButtonFocus = style({
6
+ selectors: {
7
+ [`${closeButton}:focus &`]: {
8
+ opacity: 1,
9
+ },
10
+ },
11
+ });
12
+
13
+ export const closeButtonHover = style({
14
+ selectors: {
15
+ [`${closeButton}:focus &, ${closeButton}:hover &`]: {
16
+ opacity: 1,
17
+ },
18
+ },
19
+ });
@@ -118,11 +118,23 @@ const docs: ComponentDocs = {
118
118
  {
119
119
  label: 'Contextual design',
120
120
  description: (
121
- <Text>
122
- When outside of a <TextLink href="/components/Card">Card</TextLink>,
123
- an outline is used to provide sufficient contrast against the
124
- background.
125
- </Text>
121
+ <>
122
+ <Text>
123
+ When outside of a <TextLink href="/components/Card">Card</TextLink>,
124
+ an outline is used to provide sufficient contrast against the
125
+ background.
126
+ </Text>
127
+ {/*
128
+ TODO: COLORMODE RELEASE
129
+ <Notice>
130
+ <Text>
131
+ This only applies in a light context, i.e. when the soft
132
+ background colours require differentiation from the surrounding
133
+ background colour.
134
+ </Text>
135
+ </Notice>
136
+ */}
137
+ </>
126
138
  ),
127
139
  Example: () =>
128
140
  source(
@@ -6,9 +6,9 @@ import {
6
6
  IconPositive,
7
7
  IconPromote,
8
8
  IconCaution,
9
+ IconClear,
9
10
  } from '../icons';
10
11
  import { AllOrNone } from '../private/AllOrNone';
11
- import { ClearButton } from '../iconButtons/ClearButton/ClearButton';
12
12
  import { Columns } from '../Columns/Columns';
13
13
  import { Column } from '../Column/Column';
14
14
  import { Overlay } from '../private/Overlay/Overlay';
@@ -18,6 +18,10 @@ import buildDataAttributes, {
18
18
  DataAttributeMap,
19
19
  } from '../private/buildDataAttributes';
20
20
  import { BoxShadow } from '../../css/atoms/atomicProperties';
21
+ import { Keyline } from '../private/Keyline/Keyline';
22
+ import { virtualTouchable } from '../private/touchable/virtualTouchable';
23
+ import { iconContainerSize } from '../../hooks/useIcon';
24
+ import * as styles from './Alert.css';
21
25
 
22
26
  type Tone = 'promote' | 'info' | 'positive' | 'caution' | 'critical';
23
27
 
@@ -56,8 +60,6 @@ const icons = {
56
60
  critical: IconCritical,
57
61
  };
58
62
 
59
- const highlightBarSize = 'xxsmall';
60
-
61
63
  export const Alert = ({
62
64
  tone = 'info',
63
65
  children,
@@ -81,40 +83,69 @@ export const Alert = ({
81
83
  aria-live="polite"
82
84
  {...(data ? buildDataAttributes(data) : undefined)}
83
85
  >
84
- <Box paddingLeft={highlightBarSize}>
85
- <Columns space="small">
86
+ <Columns space="small">
87
+ <Column width="content">
88
+ <Icon tone={tone} />
89
+ </Column>
90
+ <Column>
91
+ <Box className={textAlignedToIcon.standard}>{children}</Box>
92
+ </Column>
93
+ {onClose ? (
86
94
  <Column width="content">
87
- <Icon tone={tone} />
88
- </Column>
89
- <Column>
90
- <Box className={textAlignedToIcon.standard}>{children}</Box>
91
- </Column>
92
- {onClose ? (
93
- <Column width="content">
94
- <ClearButton
95
- tone="neutral"
96
- label={closeLabel}
97
- onClick={onClose}
95
+ <Box
96
+ component="button"
97
+ aria-label={closeLabel}
98
+ borderRadius="full"
99
+ cursor="pointer"
100
+ position="relative"
101
+ onClick={onClose}
102
+ outline="none"
103
+ transition="touchable"
104
+ transform={{ active: 'touchable' }}
105
+ display="flex"
106
+ alignItems="center"
107
+ justifyContent="center"
108
+ className={[
109
+ styles.closeButton,
110
+ iconContainerSize(),
111
+ virtualTouchable(),
112
+ ]}
113
+ >
114
+ <Overlay
115
+ component="span"
116
+ boxShadow="outlineFocus"
117
+ transition="fast"
118
+ onlyVisibleForKeyboardNavigation
119
+ borderRadius="full"
120
+ className={styles.closeButtonFocus}
98
121
  />
99
- </Column>
100
- ) : null}
101
- </Columns>
102
- </Box>
103
- {parentBackground !== 'surface' && (
122
+ <Overlay
123
+ component="span"
124
+ background="surface"
125
+ transition="fast"
126
+ borderRadius="full"
127
+ className={styles.closeButtonHover}
128
+ />
129
+ <Box
130
+ component="span"
131
+ display="block"
132
+ zIndex={1}
133
+ position="relative"
134
+ >
135
+ <IconClear size="fill" tone={tone} />
136
+ </Box>
137
+ </Box>
138
+ </Column>
139
+ ) : null}
140
+ </Columns>
141
+ {parentBackground.lightMode !== 'surface' && (
104
142
  <Overlay
105
143
  borderRadius={borderRadius}
106
- boxShadow={borderForTone[tone]}
144
+ boxShadow={{ lightMode: borderForTone[tone] }}
107
145
  visible
108
146
  />
109
147
  )}
110
- <Box
111
- background={tone}
112
- paddingLeft={highlightBarSize}
113
- position="absolute"
114
- top={0}
115
- bottom={0}
116
- left={0}
117
- />
148
+ <Keyline tone={tone} borderRadius={borderRadius} />
118
149
  </Box>
119
150
  );
120
151
  };
@@ -30,35 +30,14 @@ export interface BadgeProps {
30
30
  'aria-describedby'?: string;
31
31
  }
32
32
 
33
- const backgroundForTone = (tone: Tone, weight: BadgeWeight) => {
34
- if (weight === 'strong') {
35
- return tone;
36
- }
37
-
38
- if (tone === 'positive') {
39
- return 'positiveLight';
40
- }
41
-
42
- if (tone === 'critical') {
43
- return 'criticalLight';
44
- }
45
-
46
- if (tone === 'info') {
47
- return 'infoLight';
48
- }
49
-
50
- if (tone === 'promote') {
51
- return 'promoteLight';
52
- }
53
-
54
- if (tone === 'neutral') {
55
- return 'neutralLight';
56
- }
57
-
58
- if (tone === 'caution') {
59
- return 'cautionLight';
60
- }
61
- };
33
+ const lightModeBackgroundForTone = {
34
+ positive: 'positiveLight',
35
+ critical: 'criticalLight',
36
+ info: 'infoLight',
37
+ promote: 'promoteLight',
38
+ neutral: 'neutralLight',
39
+ caution: 'cautionLight',
40
+ } as const;
62
41
 
63
42
  export const Badge = forwardRef<HTMLDivElement, BadgeProps>(
64
43
  (
@@ -103,7 +82,9 @@ export const Badge = forwardRef<HTMLDivElement, BadgeProps>(
103
82
  tabIndex={tabIndex}
104
83
  aria-describedby={ariaDescribedBy}
105
84
  title={title ?? (!ariaDescribedBy ? children : undefined)}
106
- background={backgroundForTone(tone, weight)}
85
+ background={
86
+ weight === 'strong' ? tone : lightModeBackgroundForTone[tone]
87
+ }
107
88
  paddingX="xsmall"
108
89
  borderRadius="large"
109
90
  overflow="hidden"
@@ -112,7 +93,6 @@ export const Badge = forwardRef<HTMLDivElement, BadgeProps>(
112
93
  component="span"
113
94
  size={styles.constants.textSize}
114
95
  weight="medium"
115
- tone={weight === 'regular' ? tone : undefined}
116
96
  truncate
117
97
  baseline={false}
118
98
  >
@@ -1,18 +1,20 @@
1
- import React, { createContext, useContext, ReactElement } from 'react';
1
+ import { createContext, useContext } from 'react';
2
2
  import { BoxBackgroundVariant } from './Box';
3
3
  import { useBraidTheme } from '../BraidProvider/BraidThemeContext';
4
+ import { mapColorModeValue } from '../../css/atoms/sprinkles.css';
4
5
 
5
- export type BackgroundContextValue = BoxBackgroundVariant;
6
+ type BackgroundContextValue = {
7
+ lightMode: BoxBackgroundVariant;
8
+ darkMode: BoxBackgroundVariant;
9
+ };
6
10
 
7
- const backgroundContext = createContext<BackgroundContextValue>('body');
11
+ const backgroundContext = createContext<BackgroundContextValue>({
12
+ lightMode: 'body',
13
+ darkMode: 'bodyDark',
14
+ });
8
15
 
9
16
  export const BackgroundProvider = backgroundContext.Provider;
10
17
 
11
- export const renderBackgroundProvider = (
12
- background: BoxBackgroundVariant,
13
- element: ReactElement | null,
14
- ) => <BackgroundProvider value={background}>{element}</BackgroundProvider>;
15
-
16
18
  export const useBackground = () => useContext(backgroundContext);
17
19
 
18
20
  export const useBackgroundLightness = (
@@ -21,14 +23,29 @@ export const useBackgroundLightness = (
21
23
  const backgroundFromContext = useBackground();
22
24
  const background = backgroundOverride || backgroundFromContext;
23
25
  const { backgroundLightness } = useBraidTheme();
26
+ const lightnessMap = {
27
+ ...backgroundLightness,
28
+ customDark: 'dark',
29
+ customLight: 'light',
30
+ } as const;
31
+
32
+ return {
33
+ lightMode: lightnessMap[background.lightMode],
34
+ darkMode: lightnessMap[background.darkMode],
35
+ };
36
+ };
24
37
 
25
- if (background === 'customDark') {
26
- return 'dark';
27
- }
28
-
29
- if (background === 'customLight') {
30
- return 'light';
31
- }
32
-
33
- return backgroundLightness[background];
38
+ export type ColorContrastValue<Value> =
39
+ | { light: Value; dark: Value }
40
+ | ((contrast: 'light' | 'dark', background: BoxBackgroundVariant) => Value);
41
+ export const useColorContrast = () => {
42
+ const background = useBackground();
43
+ const backgroundLightness = useBackgroundLightness();
44
+
45
+ return <Value extends string>(map: ColorContrastValue<Value>) =>
46
+ mapColorModeValue(backgroundLightness, (lightness, mode) =>
47
+ typeof map === 'function'
48
+ ? map(lightness, background[mode])
49
+ : map[lightness],
50
+ );
34
51
  };