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.
- package/.nvmrc +1 -1
- package/CHANGELOG.md +58 -0
- package/color-mode/index.ts +9 -0
- package/css/atoms.docs.tsx +26 -20
- package/css/colorModeStyle.docs.tsx +81 -0
- package/css/index.ts +5 -1
- package/lib/components/Alert/Alert.css.ts +19 -0
- package/lib/components/Alert/Alert.docs.tsx +17 -5
- package/lib/components/Alert/Alert.tsx +61 -30
- package/lib/components/Badge/Badge.tsx +11 -31
- package/lib/components/Box/BackgroundContext.tsx +34 -17
- package/lib/components/Box/Box.docs.tsx +34 -14
- package/lib/components/Box/Box.playroom.tsx +37 -0
- package/lib/components/Box/Box.tsx +38 -7
- package/lib/components/Box/BoxRenderer.tsx +28 -9
- package/lib/components/Box/ColoredBox.tsx +168 -13
- package/lib/components/BraidPortal/BraidPortal.tsx +4 -1
- package/lib/components/BraidProvider/BraidProvider.tsx +11 -3
- package/lib/components/BraidProvider/VanillaThemeContainer.tsx +24 -0
- package/lib/components/Button/Button.css.ts +38 -5
- package/lib/components/Button/Button.screenshots.tsx +4 -1
- package/lib/components/Button/Button.tsx +102 -70
- package/lib/components/Card/Card.tsx +2 -13
- package/lib/components/Checkbox/Checkbox.screenshots.tsx +17 -8
- package/lib/components/Divider/Divider.css.ts +45 -4
- package/lib/components/Divider/Divider.tsx +20 -14
- package/lib/components/Dropdown/Dropdown.docs.tsx +0 -1
- package/lib/components/FieldLabel/FieldLabel.docs.tsx +1 -1
- package/lib/components/FieldMessage/FieldMessage.screenshots.tsx +6 -0
- package/lib/components/Heading/Heading.docs.tsx +6 -4
- package/lib/components/Heading/Heading.screenshots.tsx +4 -1
- package/lib/components/Loader/Loader.css.ts +3 -4
- package/lib/components/Loader/Loader.screenshots.tsx +4 -1
- package/lib/components/Loader/Loader.tsx +27 -30
- package/lib/components/MenuItem/MenuItemLink.tsx +9 -2
- package/lib/components/MenuItem/useMenuItem.tsx +4 -4
- package/lib/components/MenuItemCheckbox/MenuItemCheckbox.tsx +3 -1
- package/lib/components/MenuRenderer/testHelper.tsx +5 -2
- package/lib/components/Pagination/Pagination.css.ts +17 -3
- package/lib/components/Pagination/Pagination.tsx +6 -5
- package/lib/components/Rating/Rating.css.ts +16 -3
- package/lib/components/Rating/Rating.screenshots.tsx +4 -1
- package/lib/components/Rating/Rating.tsx +6 -1
- package/lib/components/Tabs/Tab.tsx +6 -2
- package/lib/components/Tabs/Tabs.css.ts +9 -1
- package/lib/components/Tabs/Tabs.tsx +4 -1
- package/lib/components/Text/Text.docs.tsx +4 -0
- package/lib/components/Text/Text.screenshots.tsx +8 -1
- package/lib/components/TextField/TextField.docs.tsx +0 -1
- package/lib/components/TextLink/TextLink.css.ts +139 -0
- package/lib/components/TextLink/TextLink.docs.tsx +1 -1
- package/lib/components/TextLink/TextLink.screenshots.tsx +3 -1
- package/lib/components/TextLink/TextLink.tsx +45 -37
- package/lib/components/Textarea/Highlight/Highlight.tsx +1 -1
- package/lib/components/Textarea/Textarea.docs.tsx +0 -1
- package/lib/components/Toggle/Toggle.css.ts +34 -7
- package/lib/components/Toggle/Toggle.tsx +8 -3
- package/lib/components/iconButtons/IconButton.css.ts +0 -32
- package/lib/components/iconButtons/IconButton.tsx +26 -48
- package/lib/components/icons/IconTip/IconTip.docs.tsx +20 -0
- package/lib/components/icons/IconTip/IconTip.tsx +12 -0
- package/lib/components/icons/IconTip/IconTipSvg.tsx +21 -0
- package/lib/components/icons/IconZoomIn/IconZoomIn.docs.tsx +20 -0
- package/lib/components/icons/IconZoomIn/IconZoomIn.tsx +12 -0
- package/lib/components/icons/IconZoomIn/IconZoomInSvg.tsx +20 -0
- package/lib/components/icons/IconZoomOut/IconZoomOut.docs.tsx +20 -0
- package/lib/components/icons/IconZoomOut/IconZoomOut.tsx +12 -0
- package/lib/components/icons/IconZoomOut/IconZoomOutSvg.tsx +20 -0
- package/lib/components/icons/Icons.screenshots.tsx +2 -2
- package/lib/components/icons/index.ts +3 -0
- package/lib/components/index.ts +3 -1
- package/lib/components/private/Field/Field.css.ts +2 -1
- package/lib/components/private/Field/Field.tsx +4 -6
- package/lib/components/private/InlineField/InlineField.css.ts +6 -6
- package/lib/components/private/InlineField/StyledInput.tsx +14 -9
- package/lib/components/private/Keyline/Keyline.css.ts +70 -0
- package/lib/components/private/Keyline/Keyline.tsx +38 -0
- package/lib/components/private/Placeholder/Placeholder.css.ts +44 -12
- package/lib/components/private/Placeholder/Placeholder.tsx +7 -3
- package/lib/components/private/touchable/debugTouchable.ts +7 -7
- package/lib/components/private/touchable/virtualTouchable.css.ts +12 -12
- package/lib/components/useToast/Toast.tsx +2 -8
- package/lib/css/atoms/atomicProperties.ts +7 -2
- package/lib/css/atoms/sprinkles.css.ts +24 -0
- package/lib/css/colorModeStyle.ts +33 -0
- package/lib/css/reset/reset.css.ts +12 -8
- package/lib/hooks/typography/index.ts +8 -61
- package/lib/hooks/typography/typography.css.ts +95 -93
- package/lib/hooks/useIcon/index.ts +4 -2
- package/lib/playroom/FrameComponent.tsx +50 -17
- package/lib/playroom/components.ts +1 -0
- package/lib/playroom/useScope.ts +44 -1
- package/lib/stories/all.stories.tsx +61 -30
- package/lib/themes/baseTokens/apac.ts +8 -0
- package/lib/themes/catho/tokens.ts +23 -6
- package/lib/themes/docs/tokens.ts +8 -0
- package/lib/themes/makeBraidTheme.ts +4 -1
- package/lib/themes/occ/tokens.ts +25 -5
- package/lib/themes/seekAnz/tokens.ts +25 -5
- package/lib/themes/tokenType.ts +8 -0
- package/lib/themes/wireframe/tokens.ts +22 -5
- package/package.json +2 -2
- package/sku.config.js +1 -0
- package/sku.routes.js +2 -0
- package/tsconfig.json +1 -0
- package/lib/components/Card/Card.css.ts +0 -6
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentDocs } from '../../../site/src/types';
|
|
3
3
|
import {
|
|
4
|
-
Box,
|
|
5
4
|
Text,
|
|
6
5
|
TextLink,
|
|
7
6
|
Stack,
|
|
@@ -12,6 +11,10 @@ import {
|
|
|
12
11
|
Strong,
|
|
13
12
|
Alert,
|
|
14
13
|
} from '../';
|
|
14
|
+
// TODO: COLORMODE RELEASE
|
|
15
|
+
// Use public import
|
|
16
|
+
import { Box } from './Box';
|
|
17
|
+
import type { SimpleBackground } from './Box';
|
|
15
18
|
import source from '../../utils/source.macro';
|
|
16
19
|
import Code from '../../../site/src/App/Code/Code';
|
|
17
20
|
import {
|
|
@@ -23,15 +26,12 @@ import {
|
|
|
23
26
|
PseudoProperties,
|
|
24
27
|
BoxShadow,
|
|
25
28
|
} from '../../css/atoms/atomicProperties';
|
|
26
|
-
import { vars } from '../../themes/vars.css';
|
|
27
29
|
import { ThemedExample } from '../../../site/src/App/ThemeSetting';
|
|
28
30
|
|
|
29
|
-
type BackgroundDocs = Required<
|
|
30
|
-
Record<keyof typeof vars.backgroundColor, string>
|
|
31
|
-
>;
|
|
31
|
+
type BackgroundDocs = Required<Record<SimpleBackground, string>>;
|
|
32
32
|
const validateBackgrounds = (backgrounds: BackgroundDocs) => backgrounds;
|
|
33
33
|
|
|
34
|
-
type BoxShadowDocs = Required<Record<
|
|
34
|
+
type BoxShadowDocs = Required<Record<BoxShadow, string>>;
|
|
35
35
|
const validateBoxShadows = (boxShadows: BoxShadowDocs) => boxShadows;
|
|
36
36
|
|
|
37
37
|
interface AtomicPropertyProps {
|
|
@@ -466,6 +466,9 @@ const docs: ComponentDocs = {
|
|
|
466
466
|
{Object.entries(
|
|
467
467
|
validateBackgrounds({
|
|
468
468
|
body: 'Used for elements that need to match the body background.',
|
|
469
|
+
// TODO: COLORMODE RELEASE
|
|
470
|
+
// bodyDark:
|
|
471
|
+
// 'Used for elements that need to match the body background in dark context.',
|
|
469
472
|
brand: 'Used for branding larger areas of the screen.',
|
|
470
473
|
brandAccent: 'Used for hero elements on the screen.',
|
|
471
474
|
brandAccentHover: 'Hover colour for “brandAccent” elements.',
|
|
@@ -508,6 +511,9 @@ const docs: ComponentDocs = {
|
|
|
508
511
|
neutralSoftActive: 'Active colour for "neutralSoft" elements',
|
|
509
512
|
neutralSoftHover: 'Hover colour for "neutralSoft" elements',
|
|
510
513
|
surface: 'Used for surfaces that sit on top of body elements',
|
|
514
|
+
// TODO: COLORMODE RELEASE
|
|
515
|
+
// surfaceDark:
|
|
516
|
+
// 'Used for surfaces that sit on top of body elements in a dark context',
|
|
511
517
|
}),
|
|
512
518
|
).map(([background, description]) => (
|
|
513
519
|
<Columns key={background} space="medium" alignY="center">
|
|
@@ -518,11 +524,17 @@ const docs: ComponentDocs = {
|
|
|
518
524
|
padding="gutter"
|
|
519
525
|
>
|
|
520
526
|
<Box
|
|
521
|
-
background={
|
|
527
|
+
background={{
|
|
528
|
+
lightMode: background as keyof BackgroundDocs,
|
|
529
|
+
darkMode: background as keyof BackgroundDocs,
|
|
530
|
+
}}
|
|
522
531
|
boxShadow={
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
532
|
+
(
|
|
533
|
+
{
|
|
534
|
+
surface: { lightMode: 'borderNeutralLight' },
|
|
535
|
+
surfaceDark: { darkMode: 'borderNeutral' },
|
|
536
|
+
} as const
|
|
537
|
+
)[background]
|
|
526
538
|
}
|
|
527
539
|
borderRadius="large"
|
|
528
540
|
padding="gutter"
|
|
@@ -632,14 +644,22 @@ const docs: ComponentDocs = {
|
|
|
632
644
|
<Columns key={boxShadow} space="medium" alignY="center">
|
|
633
645
|
<Column width="content">
|
|
634
646
|
<Box
|
|
635
|
-
background={
|
|
636
|
-
boxShadow.includes('Inverted')
|
|
637
|
-
|
|
647
|
+
background={{
|
|
648
|
+
lightMode: boxShadow.includes('Inverted')
|
|
649
|
+
? 'neutral'
|
|
650
|
+
: 'surface',
|
|
651
|
+
darkMode: /^border|outline/.test(boxShadow)
|
|
652
|
+
? 'surfaceDark'
|
|
653
|
+
: 'surface',
|
|
654
|
+
}}
|
|
638
655
|
borderRadius="large"
|
|
639
656
|
padding="gutter"
|
|
640
657
|
>
|
|
641
658
|
<Box
|
|
642
|
-
boxShadow={
|
|
659
|
+
boxShadow={{
|
|
660
|
+
lightMode: boxShadow as keyof BoxShadowDocs,
|
|
661
|
+
darkMode: boxShadow as keyof BoxShadowDocs,
|
|
662
|
+
}}
|
|
643
663
|
borderRadius="large"
|
|
644
664
|
padding="gutter"
|
|
645
665
|
/>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { atoms, Atoms } from '../../css/atoms/atoms';
|
|
3
|
+
import { sprinkles } from '../../css/atoms/sprinkles.css';
|
|
4
|
+
import { Box as BraidBox, BoxProps } from './Box';
|
|
5
|
+
|
|
6
|
+
export const Box = forwardRef<HTMLElement, BoxProps>((props, ref) => {
|
|
7
|
+
const sprinklesProps: Record<string, unknown> = {};
|
|
8
|
+
const otherProps: Record<string, unknown> = {};
|
|
9
|
+
|
|
10
|
+
for (const key in props) {
|
|
11
|
+
if (sprinkles.properties.has(key as keyof Omit<Atoms, 'reset'>)) {
|
|
12
|
+
const value = props[key as keyof typeof props];
|
|
13
|
+
try {
|
|
14
|
+
// Try passing to atoms, if sprinkle property but value is not
|
|
15
|
+
// valid, property will be left out until value is valid.
|
|
16
|
+
atoms({ [key]: value });
|
|
17
|
+
sprinklesProps[key] = value;
|
|
18
|
+
} catch (e) {
|
|
19
|
+
if (key === 'background') {
|
|
20
|
+
if (
|
|
21
|
+
(typeof value === 'string' &&
|
|
22
|
+
/^customDark|customLight$/.test(value)) ||
|
|
23
|
+
(typeof value === 'object' && (value.darkMode || value.lightMode))
|
|
24
|
+
) {
|
|
25
|
+
sprinklesProps[key] = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
otherProps[key] = props[key as keyof typeof props];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return <BraidBox ref={ref} {...sprinklesProps} {...otherProps} />;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
Box.displayName = 'Box';
|
|
@@ -9,15 +9,15 @@ import React, {
|
|
|
9
9
|
import dedent from 'dedent';
|
|
10
10
|
import { base as baseReset } from '../../css/reset/reset.css';
|
|
11
11
|
import { atoms, Atoms } from '../../css/atoms/atoms';
|
|
12
|
-
import { sprinkles } from '../../css/atoms/sprinkles.css';
|
|
12
|
+
import { sprinkles, ColorModeValue } from '../../css/atoms/sprinkles.css';
|
|
13
13
|
import { ColoredBox } from './ColoredBox';
|
|
14
|
-
import { Background } from '../../css/atoms/atomicProperties';
|
|
14
|
+
import { Background, BoxShadow } from '../../css/atoms/atomicProperties';
|
|
15
15
|
|
|
16
16
|
export type BoxBackgroundVariant = Background | 'customDark' | 'customLight';
|
|
17
17
|
|
|
18
18
|
export interface BoxBaseProps extends Omit<Atoms, 'reset' | 'background'> {
|
|
19
19
|
className?: ClassValue;
|
|
20
|
-
background?: BoxBackgroundVariant
|
|
20
|
+
background?: ColorModeValue<BoxBackgroundVariant>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export interface BoxProps
|
|
@@ -27,7 +27,7 @@ export interface BoxProps
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export const Box = forwardRef<HTMLElement, BoxProps>(
|
|
30
|
-
({ component = 'div', className, ...props }, ref) => {
|
|
30
|
+
({ component = 'div', className, background, boxShadow, ...props }, ref) => {
|
|
31
31
|
const atomProps: Record<string, unknown> = {};
|
|
32
32
|
const nativeProps: Record<string, unknown> = {};
|
|
33
33
|
|
|
@@ -61,17 +61,17 @@ export const Box = forwardRef<HTMLElement, BoxProps>(
|
|
|
61
61
|
const atomicClasses = atoms({
|
|
62
62
|
reset: typeof component === 'string' ? component : 'div',
|
|
63
63
|
...atomProps,
|
|
64
|
-
background: undefined,
|
|
65
64
|
});
|
|
66
65
|
|
|
67
66
|
const combinedClasses = `${atomicClasses}${
|
|
68
67
|
userClasses ? ` ${userClasses}` : ''
|
|
69
68
|
}`;
|
|
70
69
|
|
|
71
|
-
return
|
|
70
|
+
return background || boxShadow ? (
|
|
72
71
|
<ColoredBox
|
|
73
72
|
component={component}
|
|
74
|
-
background={
|
|
73
|
+
background={background}
|
|
74
|
+
boxShadow={boxShadow}
|
|
75
75
|
className={combinedClasses}
|
|
76
76
|
ref={ref}
|
|
77
77
|
{...nativeProps}
|
|
@@ -87,3 +87,34 @@ export const Box = forwardRef<HTMLElement, BoxProps>(
|
|
|
87
87
|
);
|
|
88
88
|
|
|
89
89
|
Box.displayName = 'Box';
|
|
90
|
+
|
|
91
|
+
// TODO: COLORMODE RELEASE
|
|
92
|
+
// Remove PublicBox
|
|
93
|
+
export type SimpleBackground = Exclude<Background, 'bodyDark' | 'surfaceDark'>;
|
|
94
|
+
export interface PublicBoxProps extends BoxProps {
|
|
95
|
+
background?: SimpleBackground | 'customDark' | 'customLight';
|
|
96
|
+
boxShadow?: BoxShadow;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const PublicBox = forwardRef<HTMLElement, PublicBoxProps>(
|
|
100
|
+
(props, ref) => {
|
|
101
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
102
|
+
if (
|
|
103
|
+
typeof props.background !== 'undefined' &&
|
|
104
|
+
typeof props.background !== 'string'
|
|
105
|
+
) {
|
|
106
|
+
throw new Error('Conditional backgrounds are not suppported');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (
|
|
110
|
+
typeof props.boxShadow !== 'undefined' &&
|
|
111
|
+
typeof props.boxShadow !== 'string'
|
|
112
|
+
) {
|
|
113
|
+
throw new Error('Conditional boxShadows are not suppported');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return <Box {...props} ref={ref} />;
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
PublicBox.displayName = 'Box';
|
|
@@ -1,28 +1,42 @@
|
|
|
1
1
|
import React, { ReactElement } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import {
|
|
3
|
+
import { BackgroundProvider } from './BackgroundContext';
|
|
4
4
|
import { atoms, Atoms } from '../../css/atoms/atoms';
|
|
5
|
-
import { BoxBaseProps } from './Box';
|
|
6
|
-
import {
|
|
5
|
+
import { BoxBaseProps, SimpleBackground } from './Box';
|
|
6
|
+
import { useColoredBoxClasses } from './ColoredBox';
|
|
7
|
+
import { BoxShadow } from '../../css/atoms/atomicProperties';
|
|
7
8
|
|
|
8
9
|
export interface BoxRendererProps extends BoxBaseProps {
|
|
9
10
|
component?: Atoms['reset'];
|
|
11
|
+
// TODO: COLORMODE RELEASE
|
|
12
|
+
// Remove overrides
|
|
13
|
+
background?: SimpleBackground | 'customDark' | 'customLight';
|
|
14
|
+
boxShadow?: BoxShadow;
|
|
10
15
|
children: (className: string) => ReactElement | null;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
const ColoredBoxRenderer = ({
|
|
14
19
|
background,
|
|
20
|
+
boxShadow,
|
|
15
21
|
children,
|
|
16
22
|
className,
|
|
17
23
|
}: {
|
|
18
|
-
background:
|
|
24
|
+
background: BoxRendererProps['background'];
|
|
25
|
+
boxShadow: BoxRendererProps['boxShadow'];
|
|
19
26
|
children: BoxRendererProps['children'];
|
|
20
27
|
className: string;
|
|
21
28
|
}) => {
|
|
22
|
-
const
|
|
23
|
-
|
|
29
|
+
const { backgroundContext, classList } = useColoredBoxClasses({
|
|
30
|
+
background,
|
|
31
|
+
boxShadow,
|
|
32
|
+
});
|
|
33
|
+
const element = children(clsx(className, classList));
|
|
24
34
|
|
|
25
|
-
return
|
|
35
|
+
return backgroundContext ? (
|
|
36
|
+
<BackgroundProvider value={backgroundContext}>{element}</BackgroundProvider>
|
|
37
|
+
) : (
|
|
38
|
+
element
|
|
39
|
+
);
|
|
26
40
|
};
|
|
27
41
|
|
|
28
42
|
export const BoxRenderer = ({
|
|
@@ -30,12 +44,17 @@ export const BoxRenderer = ({
|
|
|
30
44
|
component = 'div',
|
|
31
45
|
className,
|
|
32
46
|
background,
|
|
47
|
+
boxShadow,
|
|
33
48
|
...props
|
|
34
49
|
}: BoxRendererProps) => {
|
|
35
50
|
const classes = clsx(className, atoms({ reset: component, ...props }));
|
|
36
51
|
|
|
37
|
-
return background ? (
|
|
38
|
-
<ColoredBoxRenderer
|
|
52
|
+
return background || boxShadow ? (
|
|
53
|
+
<ColoredBoxRenderer
|
|
54
|
+
background={background}
|
|
55
|
+
boxShadow={boxShadow}
|
|
56
|
+
className={classes}
|
|
57
|
+
>
|
|
39
58
|
{children}
|
|
40
59
|
</ColoredBoxRenderer>
|
|
41
60
|
) : (
|
|
@@ -1,23 +1,172 @@
|
|
|
1
|
-
import { createElement, forwardRef } from 'react';
|
|
1
|
+
import React, { createElement, forwardRef } from 'react';
|
|
2
2
|
import { atoms } from '../../css/atoms/atoms';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { useBraidTheme } from '../BraidProvider/BraidThemeContext';
|
|
4
|
+
import {
|
|
5
|
+
BackgroundProvider,
|
|
6
|
+
useBackground,
|
|
7
|
+
useBackgroundLightness,
|
|
8
|
+
} from './BackgroundContext';
|
|
9
|
+
import { BoxBackgroundVariant, BoxProps } from './Box';
|
|
10
|
+
import { Background, BoxShadow } from '../../css/atoms/atomicProperties';
|
|
11
|
+
import * as typographyStyles from '../../hooks/typography/typography.css';
|
|
5
12
|
|
|
6
13
|
export interface ColoredBoxProps extends BoxProps {
|
|
7
14
|
component: NonNullable<BoxProps['component']>;
|
|
8
|
-
background: NonNullable<BoxProps['background']>;
|
|
9
15
|
}
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
const adaptiveBackgrounds: Partial<Record<BoxBackgroundVariant, Background>> = {
|
|
18
|
+
body: 'bodyDark',
|
|
19
|
+
surface: 'surfaceDark',
|
|
20
|
+
brand: 'neutral',
|
|
21
|
+
promoteLight: 'neutral',
|
|
22
|
+
infoLight: 'neutral',
|
|
23
|
+
positiveLight: 'neutral',
|
|
24
|
+
cautionLight: 'neutral',
|
|
25
|
+
criticalLight: 'neutral',
|
|
26
|
+
neutralLight: 'neutral',
|
|
27
|
+
formAccentSoft: 'neutral',
|
|
28
|
+
formAccentSoftActive: 'neutralActive',
|
|
29
|
+
formAccentSoftHover: 'neutralHover',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const adaptiveBoxShadow: Partial<Record<BoxShadow, BoxShadow>> = {
|
|
33
|
+
borderBrandAccentLarge: 'borderBrandAccentLightLarge',
|
|
34
|
+
borderCaution: 'borderCautionLight',
|
|
35
|
+
borderCritical: 'borderCriticalLight',
|
|
36
|
+
borderCriticalLarge: 'borderCriticalLightLarge',
|
|
37
|
+
borderFormAccent: 'borderFormAccentLight',
|
|
38
|
+
borderFormAccentLarge: 'borderFormAccentLightLarge',
|
|
39
|
+
borderInfo: 'borderInfoLight',
|
|
40
|
+
borderNeutral: 'borderNeutralInverted',
|
|
41
|
+
borderNeutralLarge: 'borderNeutralInvertedLarge',
|
|
42
|
+
borderNeutralLight: 'borderNeutral',
|
|
43
|
+
borderPositive: 'borderPositiveLight',
|
|
44
|
+
borderPromote: 'borderPromoteLight',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const normaliseBackground = (background: ColoredBoxProps['background']) => ({
|
|
48
|
+
lightMode: typeof background === 'object' ? background.lightMode : background,
|
|
49
|
+
darkMode:
|
|
50
|
+
typeof background === 'object'
|
|
51
|
+
? background.darkMode
|
|
52
|
+
: adaptiveBackgrounds[background!] || background,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const normalisedBoxShadow = (boxShadow: ColoredBoxProps['boxShadow']) => ({
|
|
56
|
+
lightMode: typeof boxShadow === 'object' ? boxShadow.lightMode : boxShadow,
|
|
57
|
+
darkMode: typeof boxShadow === 'object' ? boxShadow.darkMode : boxShadow,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const useColoredBoxClasses = ({
|
|
61
|
+
background,
|
|
62
|
+
boxShadow,
|
|
63
|
+
}: {
|
|
64
|
+
background?: ColoredBoxProps['background'];
|
|
65
|
+
boxShadow?: ColoredBoxProps['boxShadow'];
|
|
66
|
+
}) => {
|
|
67
|
+
const parentLightness = useBackgroundLightness();
|
|
68
|
+
const currentBackgroundContext = useBackground();
|
|
69
|
+
const { backgroundLightness } = useBraidTheme();
|
|
70
|
+
const lightnessMap = {
|
|
71
|
+
...backgroundLightness,
|
|
72
|
+
customDark: 'dark',
|
|
73
|
+
customLight: 'light',
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
const classList: Array<string> = [];
|
|
77
|
+
|
|
78
|
+
if (boxShadow) {
|
|
79
|
+
const normalisedBoxShadows = normalisedBoxShadow(boxShadow);
|
|
80
|
+
const isSemantic = typeof boxShadow === 'string';
|
|
81
|
+
|
|
82
|
+
classList.push(
|
|
83
|
+
atoms({
|
|
84
|
+
boxShadow: {
|
|
85
|
+
lightMode:
|
|
86
|
+
isSemantic && parentLightness.lightMode === 'dark'
|
|
87
|
+
? adaptiveBoxShadow[normalisedBoxShadows.lightMode!] ||
|
|
88
|
+
normalisedBoxShadows.lightMode
|
|
89
|
+
: normalisedBoxShadows.lightMode,
|
|
90
|
+
darkMode:
|
|
91
|
+
isSemantic && parentLightness.darkMode === 'dark'
|
|
92
|
+
? adaptiveBoxShadow[normalisedBoxShadows.darkMode!] ||
|
|
93
|
+
normalisedBoxShadows.darkMode
|
|
94
|
+
: normalisedBoxShadows.darkMode,
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (background) {
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// Normalise simple background to populated conditional value
|
|
103
|
+
const { lightMode, darkMode } = normaliseBackground(background);
|
|
104
|
+
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// Assign text tone vars based on the lightness context
|
|
107
|
+
classList.push(typographyStyles.lightModeTone[lightnessMap[lightMode!]]);
|
|
108
|
+
classList.push(typographyStyles.darkModeTone[lightnessMap[darkMode!]]);
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Override `neutral` text tone based on the lightness context
|
|
112
|
+
|
|
113
|
+
// 1. If `neutral` background, check background tone in opposite color mode
|
|
114
|
+
const lightModeTone = lightMode === 'neutral' ? darkMode : lightMode;
|
|
115
|
+
const darkModeTone = darkMode === 'neutral' ? lightMode : darkMode;
|
|
116
|
+
|
|
117
|
+
// 2. If neutral text override exists for background, apply it
|
|
118
|
+
if (
|
|
119
|
+
lightModeTone &&
|
|
120
|
+
typographyStyles.lightModeNeutralOverride[lightModeTone]
|
|
121
|
+
) {
|
|
122
|
+
classList.push(typographyStyles.lightModeNeutralOverride[lightModeTone]);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (
|
|
126
|
+
darkModeTone &&
|
|
127
|
+
typographyStyles.darkModeNeutralOverride[darkModeTone]
|
|
128
|
+
) {
|
|
129
|
+
classList.push(typographyStyles.darkModeNeutralOverride[darkModeTone]);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Set background atoms classes
|
|
134
|
+
classList.push(
|
|
135
|
+
atoms({
|
|
136
|
+
background: {
|
|
137
|
+
lightMode:
|
|
138
|
+
lightMode === 'customDark' || lightMode === 'customLight'
|
|
139
|
+
? undefined
|
|
140
|
+
: lightMode,
|
|
141
|
+
darkMode:
|
|
142
|
+
darkMode === 'customDark' || darkMode === 'customLight'
|
|
143
|
+
? undefined
|
|
144
|
+
: darkMode,
|
|
145
|
+
},
|
|
146
|
+
}),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
// Return updated background context and class list
|
|
151
|
+
return {
|
|
152
|
+
backgroundContext: {
|
|
153
|
+
lightMode: lightMode || currentBackgroundContext.lightMode,
|
|
154
|
+
darkMode: darkMode || currentBackgroundContext.darkMode,
|
|
155
|
+
},
|
|
156
|
+
classList: classList.join(' '),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
classList: classList.join(' '),
|
|
162
|
+
};
|
|
163
|
+
};
|
|
17
164
|
|
|
18
165
|
export const ColoredBox = forwardRef<HTMLElement, ColoredBoxProps>(
|
|
19
|
-
({ component, background, className, ...props }, ref) => {
|
|
20
|
-
const colorClasses =
|
|
166
|
+
({ component, background, boxShadow, className, ...props }, ref) => {
|
|
167
|
+
const { backgroundContext, classList: colorClasses } = useColoredBoxClasses(
|
|
168
|
+
{ background, boxShadow },
|
|
169
|
+
);
|
|
21
170
|
|
|
22
171
|
const element = createElement(component, {
|
|
23
172
|
className: `${className}${colorClasses ? ` ${colorClasses}` : ''}`,
|
|
@@ -25,7 +174,13 @@ export const ColoredBox = forwardRef<HTMLElement, ColoredBoxProps>(
|
|
|
25
174
|
ref,
|
|
26
175
|
});
|
|
27
176
|
|
|
28
|
-
return
|
|
177
|
+
return backgroundContext ? (
|
|
178
|
+
<BackgroundProvider value={backgroundContext}>
|
|
179
|
+
{element}
|
|
180
|
+
</BackgroundProvider>
|
|
181
|
+
) : (
|
|
182
|
+
element
|
|
183
|
+
);
|
|
29
184
|
},
|
|
30
185
|
);
|
|
31
186
|
|
|
@@ -2,6 +2,7 @@ import React, { ReactNode } from 'react';
|
|
|
2
2
|
import { createPortal } from 'react-dom';
|
|
3
3
|
import { TextContext } from '../Text/TextContext';
|
|
4
4
|
import { useBraidTheme } from '../BraidProvider/BraidThemeContext';
|
|
5
|
+
import { VanillaThemeContainer } from '../BraidProvider/VanillaThemeContainer';
|
|
5
6
|
|
|
6
7
|
export interface BraidPortalProps {
|
|
7
8
|
children: ReactNode;
|
|
@@ -13,7 +14,9 @@ export const BraidPortal = ({ children, container }: BraidPortalProps) => {
|
|
|
13
14
|
|
|
14
15
|
return createPortal(
|
|
15
16
|
<TextContext.Provider value={false}>
|
|
16
|
-
<
|
|
17
|
+
<VanillaThemeContainer theme={vanillaTheme} setDefaultTextTones>
|
|
18
|
+
{children}
|
|
19
|
+
</VanillaThemeContainer>
|
|
17
20
|
</TextContext.Provider>,
|
|
18
21
|
container ?? document.body,
|
|
19
22
|
);
|
|
@@ -17,6 +17,8 @@ import { BraidTestProviderContext } from '../BraidTestProvider/BraidTestProvider
|
|
|
17
17
|
import { BreakpointProvider } from './BreakpointContext';
|
|
18
18
|
import { BraidThemeContext } from './BraidThemeContext';
|
|
19
19
|
import { BraidTheme } from '../../themes/BraidTheme';
|
|
20
|
+
import { darkMode } from '../../css/atoms/sprinkles.css';
|
|
21
|
+
import { VanillaThemeContainer } from './VanillaThemeContainer';
|
|
20
22
|
|
|
21
23
|
if (process.env.NODE_ENV === 'development') {
|
|
22
24
|
ensureResetImported();
|
|
@@ -92,9 +94,15 @@ export const BraidProvider = ({
|
|
|
92
94
|
<BraidThemeContext.Provider value={theme}>
|
|
93
95
|
<TreatProvider theme={theme.treatTheme}>
|
|
94
96
|
{styleBody ? (
|
|
95
|
-
<style type="text/css">{`
|
|
97
|
+
<style type="text/css">{`
|
|
98
|
+
html,body{margin:0;padding:0;background:${theme.background.lightMode}}
|
|
99
|
+
html.${darkMode},html.${darkMode} body{color-scheme:dark;background:${theme.background.darkMode}}
|
|
100
|
+
`}</style>
|
|
96
101
|
) : null}
|
|
97
|
-
<
|
|
102
|
+
<VanillaThemeContainer
|
|
103
|
+
theme={theme.vanillaTheme}
|
|
104
|
+
setDefaultTextTones={!alreadyInBraidProvider}
|
|
105
|
+
>
|
|
98
106
|
<LinkComponentContext.Provider
|
|
99
107
|
value={linkComponent || linkComponentFromContext}
|
|
100
108
|
>
|
|
@@ -104,7 +112,7 @@ export const BraidProvider = ({
|
|
|
104
112
|
<BreakpointProvider>{children}</BreakpointProvider>
|
|
105
113
|
)}
|
|
106
114
|
</LinkComponentContext.Provider>
|
|
107
|
-
</
|
|
115
|
+
</VanillaThemeContainer>
|
|
108
116
|
</TreatProvider>
|
|
109
117
|
</BraidThemeContext.Provider>
|
|
110
118
|
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import * as typographyStyles from '../../hooks/typography/typography.css';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
theme: string;
|
|
8
|
+
setDefaultTextTones: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const textTones = [
|
|
12
|
+
typographyStyles.lightModeTone.light,
|
|
13
|
+
typographyStyles.darkModeTone.dark,
|
|
14
|
+
].join(' ');
|
|
15
|
+
|
|
16
|
+
export const VanillaThemeContainer = ({
|
|
17
|
+
children,
|
|
18
|
+
theme,
|
|
19
|
+
setDefaultTextTones,
|
|
20
|
+
}: Props) => (
|
|
21
|
+
<div className={`${theme}${setDefaultTextTones ? ` ${textTones}` : ''}`}>
|
|
22
|
+
{children}
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { keyframes, style, styleVariants } from '@vanilla-extract/css';
|
|
2
2
|
import { calc } from '@vanilla-extract/css-utils';
|
|
3
3
|
import { rgba } from 'polished';
|
|
4
|
+
import { colorModeStyle } from '../../css/colorModeStyle';
|
|
4
5
|
import { responsiveStyle } from '../../css/responsiveStyle';
|
|
5
6
|
import { vars } from '../../themes/vars.css';
|
|
6
7
|
|
|
@@ -12,9 +13,11 @@ export const root = style({
|
|
|
12
13
|
textDecoration: 'none',
|
|
13
14
|
});
|
|
14
15
|
|
|
16
|
+
export const forceActive = style({});
|
|
17
|
+
|
|
15
18
|
export const activeOverlay = style({
|
|
16
19
|
selectors: {
|
|
17
|
-
[`${root}:active &`]: {
|
|
20
|
+
[`${root}:active &, ${forceActive}&`]: {
|
|
18
21
|
opacity: 1,
|
|
19
22
|
},
|
|
20
23
|
},
|
|
@@ -121,8 +124,38 @@ export const loadingDot = style({
|
|
|
121
124
|
},
|
|
122
125
|
});
|
|
123
126
|
|
|
124
|
-
export const
|
|
125
|
-
soft: {
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
export const invertedBackgroundsLightMode = styleVariants({
|
|
128
|
+
soft: colorModeStyle({
|
|
129
|
+
lightMode: {
|
|
130
|
+
background: rgba('#fff', 0.1),
|
|
131
|
+
},
|
|
132
|
+
}),
|
|
133
|
+
hover: colorModeStyle({
|
|
134
|
+
lightMode: {
|
|
135
|
+
background: rgba('#fff', 0.15),
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
active: colorModeStyle({
|
|
139
|
+
lightMode: {
|
|
140
|
+
background: rgba('#fff', 0.15),
|
|
141
|
+
},
|
|
142
|
+
}),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export const invertedBackgroundsDarkMode = styleVariants({
|
|
146
|
+
soft: colorModeStyle({
|
|
147
|
+
darkMode: {
|
|
148
|
+
background: rgba('#fff', 0.1),
|
|
149
|
+
},
|
|
150
|
+
}),
|
|
151
|
+
hover: colorModeStyle({
|
|
152
|
+
darkMode: {
|
|
153
|
+
background: rgba('#fff', 0.15),
|
|
154
|
+
},
|
|
155
|
+
}),
|
|
156
|
+
active: colorModeStyle({
|
|
157
|
+
darkMode: {
|
|
158
|
+
background: rgba('#fff', 0.15),
|
|
159
|
+
},
|
|
160
|
+
}),
|
|
128
161
|
});
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React, { Fragment } from 'react';
|
|
2
2
|
import { ComponentScreenshot } from '../../../site/src/types';
|
|
3
|
-
import {
|
|
3
|
+
import { Button } from '../';
|
|
4
|
+
// TODO: COLORMODE RELEASE
|
|
5
|
+
// Use public import
|
|
6
|
+
import { Box } from '../Box/Box';
|
|
4
7
|
import { Inline } from '../Inline/Inline';
|
|
5
8
|
import { Heading } from '../Heading/Heading';
|
|
6
9
|
import { backgrounds } from '../../utils/docsHelpers';
|