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
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { Link, LinkProps } from '../Link/Link';
3
3
  import { useMenuItem } from './useMenuItem';
4
4
  import { MenuItemProps } from './MenuItem';
5
+ import { Box } from '../Box/Box';
5
6
 
6
7
  export interface MenuItemLinkProps
7
8
  extends MenuItemProps,
@@ -24,8 +25,14 @@ export const MenuItemLink = ({
24
25
  });
25
26
 
26
27
  return (
27
- <Link {...menuItemProps} href={href} target={target} rel={rel}>
28
+ <Box
29
+ component={Link}
30
+ {...menuItemProps}
31
+ href={href}
32
+ target={target}
33
+ rel={rel}
34
+ >
28
35
  <MenuItemChildren tone={tone}>{children}</MenuItemChildren>
29
- </Link>
36
+ </Box>
30
37
  );
31
38
  };
@@ -7,7 +7,7 @@ import React, {
7
7
  ReactNode,
8
8
  MouseEvent,
9
9
  } from 'react';
10
- import { Box } from '../Box/Box';
10
+ import { Box, BoxProps } from '../Box/Box';
11
11
  import { Text } from '../Text/Text';
12
12
  import { touchableText } from '../../hooks/typography';
13
13
  import { normalizeKey } from '../private/normalizeKey';
@@ -141,6 +141,7 @@ export function useMenuItem<MenuItemElement extends HTMLElement>({
141
141
  onClick();
142
142
  }
143
143
  },
144
+ background: isHighlighted ? hoverBackground : undefined,
144
145
  className: [
145
146
  styles.menuItem,
146
147
  touchableText[menuItemChildrenSize],
@@ -149,14 +150,13 @@ export function useMenuItem<MenuItemElement extends HTMLElement>({
149
150
  alignItems: 'center',
150
151
  width: 'full',
151
152
  paddingX: 'small',
152
- background: isHighlighted ? hoverBackground : undefined,
153
153
  cursor: 'pointer',
154
154
  textAlign: 'left',
155
155
  outline: 'none',
156
156
  }),
157
157
  ],
158
158
  ...buildDataAttributes(data),
159
- } as const,
159
+ } as BoxProps,
160
160
  } as const;
161
161
  }
162
162
 
@@ -166,7 +166,7 @@ interface MenuItemChildrenProps {
166
166
  }
167
167
  function MenuItemChildren({ tone, children }: MenuItemChildrenProps) {
168
168
  return (
169
- <Box userSelect="none">
169
+ <Box component="span" userSelect="none">
170
170
  <Text
171
171
  size={menuItemChildrenSize}
172
172
  baseline={false}
@@ -32,14 +32,16 @@ export const MenuItemCheckbox = ({
32
32
  display="flex"
33
33
  >
34
34
  <Box
35
+ component="span"
35
36
  borderRadius="standard"
36
37
  boxShadow="borderField"
37
38
  position="relative"
38
- background="surface"
39
+ background={{ lightMode: 'surface' }}
39
40
  marginRight="xsmall"
40
41
  className={styles.checkboxBorder}
41
42
  >
42
43
  <Box
44
+ component="span"
43
45
  position="absolute"
44
46
  width="full"
45
47
  height="full"
@@ -213,13 +213,16 @@ export const menuTestSuite = ({ name, Component }: MenuTestSuiteParams) => {
213
213
 
214
214
  userEvent.click(menuItemCheckbox);
215
215
 
216
- expect(menuItemCheckbox.getAttribute('aria-checked')).toBe('true');
216
+ const updatedElements = getElements({ getAllByRole });
217
+ const updatedMenuItem = updatedElements.menuItems[2];
218
+
219
+ expect(updatedMenuItem.getAttribute('aria-checked')).toBe('true');
217
220
 
218
221
  expect(menu).toBeVisible();
219
222
  expect(openHandler).not.toHaveBeenCalled();
220
223
  expect(closeHandler).not.toHaveBeenCalled();
221
224
  expect(menuItemHandler).toHaveBeenNthCalledWith(1, 'MenuItemCheckbox');
222
- expect(menuItemCheckbox).toHaveFocus();
225
+ expect(updatedMenuItem).toHaveFocus();
223
226
  });
224
227
  });
225
228
 
@@ -1,10 +1,24 @@
1
1
  import { style } from '@vanilla-extract/css';
2
+ import { colorModeStyle } from '../../css/colorModeStyle';
2
3
 
3
4
  export const hover = style({});
4
5
 
5
- export const currentKeyline = style({
6
- opacity: 0.3,
7
- });
6
+ export const lightModeCurrentKeyline = style(
7
+ colorModeStyle({
8
+ lightMode: {
9
+ opacity: 0.3,
10
+ },
11
+ }),
12
+ );
13
+
14
+ export const darkModeCurrentKeyline = style(
15
+ colorModeStyle({
16
+ darkMode: {
17
+ opacity: 0.3,
18
+ },
19
+ }),
20
+ );
21
+
8
22
  export const current = style({
9
23
  opacity: 0.075,
10
24
  });
@@ -102,11 +102,12 @@ const Page = ({ number, current }: { number: number; current: boolean }) => {
102
102
  component="span"
103
103
  borderRadius={borderRadius}
104
104
  boxShadow="borderFormAccent"
105
- className={
106
- parentBackground !== 'surface' && current
107
- ? styles.currentKeyline
108
- : undefined
109
- }
105
+ className={{
106
+ [styles.lightModeCurrentKeyline]:
107
+ parentBackground.lightMode !== 'surface' && current,
108
+ [styles.darkModeCurrentKeyline]:
109
+ parentBackground.darkMode !== 'surface' && current,
110
+ }}
110
111
  />
111
112
  <Box component="span" zIndex={1} userSelect="none">
112
113
  <Text
@@ -1,9 +1,22 @@
1
1
  import { style } from '@vanilla-extract/css';
2
+ import { colorModeStyle } from '../../css/colorModeStyle';
2
3
  import { vars } from '../../themes/vars.css';
3
4
 
4
- export const starColor = style({
5
- color: vars.foregroundColor.rating,
6
- });
5
+ export const lightModeStarColor = style(
6
+ colorModeStyle({
7
+ lightMode: {
8
+ color: vars.foregroundColor.rating,
9
+ },
10
+ }),
11
+ );
12
+
13
+ export const darkModeStarColor = style(
14
+ colorModeStyle({
15
+ darkMode: {
16
+ color: vars.foregroundColor.rating,
17
+ },
18
+ }),
19
+ );
7
20
 
8
21
  export const starSpacing = style({
9
22
  paddingRight: '1px',
@@ -1,6 +1,9 @@
1
1
  import React, { Fragment } from 'react';
2
2
  import { ComponentScreenshot } from '../../../site/src/types';
3
- import { Box, Rating } from '../';
3
+ import { Rating } from '../';
4
+ // TODO: COLORMODE RELEASE
5
+ // Use public import
6
+ import { Box } from '../Box/Box';
4
7
  import { backgrounds } from '../../utils/docsHelpers';
5
8
 
6
9
  export const screenshots: ComponentScreenshot = {
@@ -36,7 +36,12 @@ const RatingStar = ({ percent, ...restProps }: RatingStar) => {
36
36
  className={[
37
37
  className,
38
38
  {
39
- [styles.starColor]: currentBg === 'body' || currentBg === 'surface',
39
+ [styles.lightModeStarColor]:
40
+ currentBg.lightMode === 'body' || currentBg.lightMode === 'surface',
41
+ },
42
+ {
43
+ [styles.darkModeStarColor]:
44
+ currentBg.darkMode === 'body' || currentBg.darkMode === 'surface',
40
45
  },
41
46
  ]}
42
47
  />
@@ -31,6 +31,7 @@ import buildDataAttributes, {
31
31
  import { TabListContext } from './TabListContext';
32
32
  import { Overlay } from '../private/Overlay/Overlay';
33
33
  import { BadgeProps, Badge } from '../Badge/Badge';
34
+ import { Divider } from '../Divider/Divider';
34
35
  import { useResponsiveValue } from '../useResponsiveValue/useResponsiveValue';
35
36
  import { smoothScroll, smoothScrollIntoView } from '../private/smoothScroll';
36
37
  import { useSpace } from '../useSpace/useSpace';
@@ -244,10 +245,12 @@ export const Tab = ({ children, data, badge, item }: TabProps) => {
244
245
  right={0}
245
246
  bottom={0}
246
247
  className={styles.divider}
247
- />
248
+ >
249
+ <Divider />
250
+ </Box>
248
251
  ) : null}
249
252
  <Box
250
- background="neutral"
253
+ background={{ lightMode: 'neutral', darkMode: 'neutralLight' }}
251
254
  position="absolute"
252
255
  zIndex={2}
253
256
  transition="fast"
@@ -271,6 +274,7 @@ export const Tab = ({ children, data, badge, item }: TabProps) => {
271
274
  bottom={0}
272
275
  className={[
273
276
  styles.tabUnderline,
277
+ styles.tabUnderlineActiveDarkMode,
274
278
  !isSelected ? styles.tabUnderlineAnimation : undefined,
275
279
  tabListItemIndex > 0 ? styles.hairlineMarginLeft : null,
276
280
  ]}
@@ -1,4 +1,5 @@
1
1
  import { style } from '@vanilla-extract/css';
2
+ import { colorModeStyle } from '../../css/colorModeStyle';
2
3
  import { vars } from '../../themes/vars.css';
3
4
 
4
5
  export const tab = style({
@@ -54,6 +55,14 @@ export const tabUnderline = style({
54
55
  height: 2,
55
56
  });
56
57
 
58
+ export const tabUnderlineActiveDarkMode = style(
59
+ colorModeStyle({
60
+ darkMode: {
61
+ background: vars.borderColor.formAccentLight,
62
+ },
63
+ }),
64
+ );
65
+
57
66
  export const tabUnderlineHover = style({
58
67
  selectors: {
59
68
  [`${tab}:hover &`]: {
@@ -77,6 +86,5 @@ export const tabPanelFocusRing = style({
77
86
  });
78
87
 
79
88
  export const divider = style({
80
- background: vars.borderColor.neutralLight,
81
89
  height: vars.borderWidth.standard,
82
90
  });
@@ -9,6 +9,7 @@ import React, {
9
9
  import assert from 'assert';
10
10
  import flattenChildren from 'react-keyed-flatten-children';
11
11
  import { Box } from '../Box/Box';
12
+ import { Divider } from '../Divider/Divider';
12
13
  import type { ResponsiveSpace } from '../../css/atoms/atoms';
13
14
  import { TAB_LIST_UPDATED } from './Tabs.actions';
14
15
  import buildDataAttributes, {
@@ -146,7 +147,9 @@ export const Tabs = (props: TabsProps) => {
146
147
  left={0}
147
148
  right={0}
148
149
  className={styles.divider}
149
- />
150
+ >
151
+ <Divider />
152
+ </Box>
150
153
  ) : null}
151
154
  </Box>
152
155
  </Box>
@@ -235,6 +235,10 @@ const docs: ComponentDocs = {
235
235
  <Text>Neutral text</Text>
236
236
  <Text tone="secondary">Secondary text</Text>
237
237
  <Text tone="critical">Critical text</Text>
238
+ <Text tone="caution">Caution text</Text>
239
+ <Text tone="positive">Positive text</Text>
240
+ <Text tone="info">Info text</Text>
241
+ <Text tone="promote">Promote text</Text>
238
242
  <Text tone="formAccent">FormAccent text</Text>
239
243
  <Text tone="brandAccent">BrandAccent text</Text>
240
244
  </Stack>,
@@ -1,7 +1,10 @@
1
1
  import React, { Fragment, ReactNode } from 'react';
2
2
  import { titleCase } from 'title-case';
3
3
  import { ComponentScreenshot } from '../../../site/src/types';
4
- import { Box, Text, Stack, Column, Columns, IconPositive } from '../';
4
+ import { Text, Stack, Column, Columns, IconPositive } from '../';
5
+ // TODO: COLORMODE RELEASE
6
+ // Use public import
7
+ import { Box } from '../Box/Box';
5
8
  import { text as textSizes } from '../../hooks/typography/typography.css';
6
9
  import { backgrounds, textAlignments } from '../../utils/docsHelpers';
7
10
 
@@ -38,6 +41,10 @@ export const screenshots: ComponentScreenshot = {
38
41
  <Text>Neutral text</Text>
39
42
  <Text tone="secondary">Secondary text</Text>
40
43
  <Text tone="critical">Critical text</Text>
44
+ <Text tone="caution">Caution text</Text>
45
+ <Text tone="positive">Positive text</Text>
46
+ <Text tone="info">Info text</Text>
47
+ <Text tone="promote">Promote text</Text>
41
48
  <Text tone="formAccent">FormAccent text</Text>
42
49
  <Text tone="brandAccent">BrandAccent text</Text>
43
50
  </Stack>
@@ -149,7 +149,6 @@ const docs: ComponentDocs = {
149
149
  <Strong>disabled</Strong> prop.
150
150
  </Text>
151
151
  ),
152
- background: 'surface',
153
152
  Example: ({ id, setState }) =>
154
153
  source(
155
154
  <TextField
@@ -0,0 +1,139 @@
1
+ import {
2
+ assignVars,
3
+ createThemeContract,
4
+ style,
5
+ styleVariants,
6
+ } from '@vanilla-extract/css';
7
+ import { darkMode } from '../../css/atoms/sprinkles.css';
8
+ import { vars } from '../../themes/vars.css';
9
+
10
+ const textLinkVars = createThemeContract({
11
+ color: null,
12
+ colorHover: null,
13
+ fontWeight: null,
14
+ textDecoration: null,
15
+ textDecorationHover: null,
16
+ });
17
+
18
+ const lightModeRegularLinkVars = assignVars(textLinkVars, {
19
+ color: vars.foregroundColor.link,
20
+ colorHover: vars.foregroundColor.linkHover,
21
+ fontWeight: vars.textWeight.medium,
22
+ textDecoration: 'none',
23
+ textDecorationHover: 'underline',
24
+ });
25
+
26
+ const darkModeRegularLinkVars = assignVars(textLinkVars, {
27
+ color: vars.foregroundColor.linkLight,
28
+ colorHover: vars.foregroundColor.linkLight,
29
+ fontWeight: vars.textWeight.medium,
30
+ textDecoration: 'none',
31
+ textDecorationHover: 'underline',
32
+ });
33
+
34
+ const weakLinkVars = assignVars(textLinkVars, {
35
+ color: 'inherit',
36
+ colorHover: 'inherit',
37
+ fontWeight: 'inherit',
38
+ textDecoration: 'underline',
39
+ textDecorationHover: 'underline',
40
+ });
41
+
42
+ export const base = style({
43
+ color: textLinkVars.color,
44
+ fontWeight: textLinkVars.fontWeight,
45
+ textDecoration: textLinkVars.textDecoration,
46
+ ':hover': {
47
+ color: textLinkVars.colorHover,
48
+ textDecoration: textLinkVars.textDecorationHover,
49
+ },
50
+ ':focus': {
51
+ color: textLinkVars.colorHover,
52
+ },
53
+ });
54
+
55
+ export const weakLink = style({
56
+ vars: weakLinkVars,
57
+ });
58
+
59
+ export const inheritLinkColor = style({});
60
+
61
+ export const regularLinkLightMode = styleVariants({
62
+ light: {
63
+ selectors: {
64
+ [`html:not(${darkMode}) &`]: {
65
+ vars: lightModeRegularLinkVars,
66
+ },
67
+ [`html:not(${darkMode}) ${inheritLinkColor} > &`]: {
68
+ vars: weakLinkVars,
69
+ },
70
+ },
71
+ },
72
+ dark: {
73
+ selectors: {
74
+ [`html:not(${darkMode}) &`]: {
75
+ vars: darkModeRegularLinkVars,
76
+ },
77
+ [`html:not(${darkMode}) ${inheritLinkColor} > &`]: {
78
+ vars: weakLinkVars,
79
+ },
80
+ },
81
+ },
82
+ });
83
+
84
+ export const regularLinkDarkMode = styleVariants({
85
+ light: {
86
+ selectors: {
87
+ [`html${darkMode} &`]: {
88
+ vars: lightModeRegularLinkVars,
89
+ },
90
+ [`html${darkMode} ${inheritLinkColor} > &`]: {
91
+ vars: weakLinkVars,
92
+ },
93
+ },
94
+ },
95
+ dark: {
96
+ selectors: {
97
+ [`html${darkMode} &`]: {
98
+ vars: darkModeRegularLinkVars,
99
+ },
100
+ [`html${darkMode} ${inheritLinkColor} > &`]: {
101
+ vars: weakLinkVars,
102
+ },
103
+ },
104
+ },
105
+ });
106
+
107
+ export const visitedLightMode = styleVariants({
108
+ light: {
109
+ selectors: {
110
+ [`html:not(${darkMode}) &:visited`]: {
111
+ color: vars.foregroundColor.linkVisited,
112
+ },
113
+ },
114
+ },
115
+ dark: {
116
+ selectors: {
117
+ [`html:not(${darkMode}) &:visited`]: {
118
+ color: vars.foregroundColor.linkLightVisited,
119
+ },
120
+ },
121
+ },
122
+ });
123
+
124
+ export const visitedDarkMode = styleVariants({
125
+ light: {
126
+ selectors: {
127
+ [`html${darkMode} &:visited`]: {
128
+ color: vars.foregroundColor.linkVisited,
129
+ },
130
+ },
131
+ },
132
+ dark: {
133
+ selectors: {
134
+ [`html${darkMode} &:visited`]: {
135
+ color: vars.foregroundColor.linkLightVisited,
136
+ },
137
+ },
138
+ },
139
+ });
@@ -103,7 +103,7 @@ const docs: ComponentDocs = {
103
103
  </Text>
104
104
  </>
105
105
  ),
106
- background: 'surface',
106
+ background: { lightMode: 'surface', darkMode: 'bodyDark' },
107
107
  Example: () =>
108
108
  source(
109
109
  <Stack space="large">
@@ -1,7 +1,6 @@
1
1
  import React, { Fragment } from 'react';
2
2
  import { ComponentScreenshot } from '../../../site/src/types';
3
3
  import {
4
- Box,
5
4
  Heading,
6
5
  IconNewWindow,
7
6
  IconChevron,
@@ -10,6 +9,9 @@ import {
10
9
  Columns,
11
10
  Column,
12
11
  } from '../';
12
+ // TODO: COLORMODE RELEASE
13
+ // Use public import
14
+ import { Box } from '../Box/Box';
13
15
  import { backgrounds } from '../../utils/docsHelpers';
14
16
 
15
17
  export const screenshots: ComponentScreenshot = {
@@ -1,18 +1,20 @@
1
1
  import clsx from 'clsx';
2
- import React, { forwardRef, useContext } from 'react';
2
+ import React, { forwardRef } from 'react';
3
3
  import { atoms, Atoms } from '../../css/atoms/atoms';
4
- import { useBackground } from '../Box/BackgroundContext';
4
+ import {
5
+ useBackgroundLightness,
6
+ useBackground,
7
+ } from '../Box/BackgroundContext';
8
+ import { BoxBackgroundVariant } from '../Box/Box';
5
9
  import {
6
10
  useLinkComponent,
7
11
  LinkComponentProps,
8
12
  } from '../BraidProvider/BraidProvider';
9
- import HeadingContext from '../Heading/HeadingContext';
10
- import { TextContext } from '../Text/TextContext';
11
13
  import buildDataAttributes, {
12
14
  DataAttributeMap,
13
15
  } from '../private/buildDataAttributes';
14
16
  import { virtualTouchable } from '../private/touchable/virtualTouchable';
15
- import * as typographyStyles from '../../hooks/typography/typography.css';
17
+ import * as styles from './TextLink.css';
16
18
 
17
19
  export interface TextLinkStyles {
18
20
  weight?: 'regular' | 'weak';
@@ -27,46 +29,52 @@ export interface TextLinkProps
27
29
  }
28
30
 
29
31
  const isPlainBackground = (
30
- backgroundContext: ReturnType<typeof useBackground>,
32
+ backgroundContext: BoxBackgroundVariant,
33
+ contrast: 'dark' | 'light',
31
34
  ) =>
32
- backgroundContext === 'body' ||
33
- backgroundContext === 'surface' ||
34
- backgroundContext === 'neutralLight' ||
35
- backgroundContext === 'neutralSoft';
36
-
37
- function useDefaultLinkWeight() {
38
- const backgroundContext = useBackground();
39
- const inHeading = useContext(HeadingContext);
40
- const textContext = useContext(TextContext);
41
-
42
- const inPlainText =
43
- !textContext ||
44
- textContext.tone === undefined ||
45
- textContext.tone === 'neutral' ||
46
- textContext.tone === 'secondary';
47
-
48
- return isPlainBackground(backgroundContext) && (inHeading || inPlainText)
49
- ? 'regular'
50
- : 'weak';
51
- }
35
+ (contrast === 'light' &&
36
+ (backgroundContext === 'body' ||
37
+ backgroundContext === 'surface' ||
38
+ backgroundContext === 'neutralLight')) ||
39
+ (contrast === 'dark' &&
40
+ (backgroundContext === 'bodyDark' ||
41
+ backgroundContext === 'surfaceDark' ||
42
+ backgroundContext === 'neutral'));
52
43
 
53
- export function useLinkStyles({
44
+ export const useLinkStyles = ({
54
45
  reset = 'a',
55
- weight: weightProp,
46
+ weight,
56
47
  showVisited = false,
57
48
  hitArea = 'standard',
58
49
  }: Pick<TextLinkProps, 'weight' | 'showVisited' | 'hitArea'> & {
59
50
  reset?: Atoms['reset'] | false;
60
- }) {
61
- const defaultWeight = useDefaultLinkWeight();
62
- const weight = weightProp ?? defaultWeight;
51
+ }) => {
52
+ const backgroundLightness = useBackgroundLightness();
53
+ const backgroundContext = useBackground();
63
54
 
64
- return clsx(
65
- typographyStyles.textLink,
55
+ const linkStyles =
66
56
  weight === 'weak'
67
- ? typographyStyles.weakLink
68
- : typographyStyles.regularLink,
69
- showVisited ? typographyStyles.textLinkVisited : null,
57
+ ? styles.weakLink
58
+ : [
59
+ isPlainBackground(backgroundContext.lightMode, 'light') ||
60
+ weight === 'regular'
61
+ ? styles.regularLinkLightMode[backgroundLightness.lightMode]
62
+ : styles.weakLink,
63
+ isPlainBackground(backgroundContext.darkMode, 'dark') ||
64
+ weight === 'regular'
65
+ ? styles.regularLinkDarkMode[backgroundLightness.darkMode]
66
+ : styles.weakLink,
67
+ ];
68
+
69
+ return clsx(
70
+ styles.base,
71
+ linkStyles,
72
+ showVisited
73
+ ? [
74
+ styles.visitedLightMode[backgroundLightness.lightMode],
75
+ styles.visitedDarkMode[backgroundLightness.darkMode],
76
+ ]
77
+ : '',
70
78
  reset !== false
71
79
  ? atoms({
72
80
  reset: typeof reset === 'string' ? reset : 'a',
@@ -77,7 +85,7 @@ export function useLinkStyles({
77
85
  }),
78
86
  hitArea === 'large' && virtualTouchable(),
79
87
  );
80
- }
88
+ };
81
89
 
82
90
  export const TextLink = forwardRef<HTMLAnchorElement, TextLinkProps>(
83
91
  ({ weight, showVisited, hitArea, data, ...props }, ref) => {
@@ -10,7 +10,7 @@ export const Highlight = ({ children }: HighlightProps) => (
10
10
  <Box
11
11
  component="mark"
12
12
  borderRadius="standard"
13
- background="criticalLight"
13
+ background={{ lightMode: 'criticalLight', darkMode: 'critical' }}
14
14
  className={styles.root}
15
15
  >
16
16
  {children}
@@ -140,7 +140,6 @@ const docs: ComponentDocs = {
140
140
  <Strong>disabled</Strong> prop.
141
141
  </Text>
142
142
  ),
143
- background: 'surface',
144
143
  Example: ({ id, setState }) =>
145
144
  source(
146
145
  <Textarea