@marigold/system 0.0.3 → 0.3.1
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/CHANGELOG.md +57 -0
- package/dist/Box.d.ts +14 -0
- package/dist/Global.d.ts +2 -0
- package/dist/SVG.d.ts +6 -0
- package/dist/SVG.stories.d.ts +5 -0
- package/dist/index.d.ts +6 -3
- package/dist/normalize.d.ts +144 -0
- package/dist/system.cjs.development.js +348 -132
- package/dist/system.cjs.development.js.map +1 -1
- package/dist/system.cjs.production.min.js +1 -1
- package/dist/system.cjs.production.min.js.map +1 -1
- package/dist/system.esm.js +341 -129
- package/dist/system.esm.js.map +1 -1
- package/dist/theme.d.ts +136 -0
- package/dist/types.d.ts +2 -3
- package/dist/useTheme.d.ts +15 -5
- package/dist/variant.d.ts +29 -0
- package/package.json +4 -6
- package/src/Box.test.tsx +308 -0
- package/src/Box.tsx +199 -0
- package/src/Global.test.tsx +57 -0
- package/src/Global.tsx +34 -0
- package/src/SVG.stories.tsx +48 -0
- package/src/SVG.test.tsx +82 -0
- package/src/SVG.tsx +24 -0
- package/src/index.ts +6 -3
- package/src/normalize.test.tsx +15 -0
- package/src/normalize.ts +100 -0
- package/src/theme.ts +157 -0
- package/src/types.ts +2 -3
- package/src/useTheme.test.tsx +43 -18
- package/src/useTheme.tsx +45 -7
- package/src/variant.test.ts +93 -0
- package/src/variant.ts +54 -0
- package/dist/cache.d.ts +0 -4
- package/dist/reset.d.ts +0 -24
- package/dist/useClassname.d.ts +0 -2
- package/dist/useStyles.d.ts +0 -15
- package/src/Colors.stories.mdx +0 -455
- package/src/cache.ts +0 -4
- package/src/concepts-principles.mdx +0 -84
- package/src/reset.ts +0 -106
- package/src/useClassname.test.tsx +0 -70
- package/src/useClassname.ts +0 -24
- package/src/useStyles.test.tsx +0 -286
- package/src/useStyles.ts +0 -55
- package/src/writeComponent.stories.mdx +0 -126
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import * as CSS from 'csstype';
|
|
2
|
+
import { NestedScaleDict } from '@theme-ui/css';
|
|
3
|
+
/**
|
|
4
|
+
* Value used to define a scale.
|
|
5
|
+
*
|
|
6
|
+
* Can be nested to support a default value.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* Given a theme
|
|
10
|
+
* ```
|
|
11
|
+
* {
|
|
12
|
+
* colors: {
|
|
13
|
+
* primary: { __default: '#00f', light: '#33f' }
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
* `css{{ color: 'primary' }}` resolves to `color: #00f`.
|
|
18
|
+
*/
|
|
19
|
+
export declare type ScaleValue<T> = T | T[] | NestedScaleDict<T> | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Scales are a set of named, pre-defined CSS values which are used
|
|
22
|
+
* to create consitency in sizing across visual elements. They give
|
|
23
|
+
* plain values semantics meaning.
|
|
24
|
+
*
|
|
25
|
+
* Marigold uses a plain object to define scales, where the key should be a
|
|
26
|
+
* descriptive name for the scale (e.g. `small`/`medium`/.. or `body`/`heading`/...),
|
|
27
|
+
* and the value is the CSS value.
|
|
28
|
+
*/
|
|
29
|
+
export declare type Scale<T> = {
|
|
30
|
+
[key: string]: ScaleValue<T>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Predefined {@link Scale} scale which uses size values.
|
|
34
|
+
*/
|
|
35
|
+
export declare type SizeScale<T> = {
|
|
36
|
+
xxsmall?: ScaleValue<T>;
|
|
37
|
+
xsmall?: ScaleValue<T>;
|
|
38
|
+
small?: ScaleValue<T>;
|
|
39
|
+
medium?: ScaleValue<T>;
|
|
40
|
+
large?: ScaleValue<T>;
|
|
41
|
+
xlarge?: ScaleValue<T>;
|
|
42
|
+
xxlarge?: ScaleValue<T>;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* A {@link SizeScale} that also includes a required `none` value, which is
|
|
46
|
+
* usually used to define the blank value (e.g `0`).
|
|
47
|
+
*/
|
|
48
|
+
export declare type ZeroScale<T> = {
|
|
49
|
+
none: ScaleValue<T>;
|
|
50
|
+
} & Scale<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Base theme with typings for available scales properties.
|
|
53
|
+
*/
|
|
54
|
+
export interface Theme {
|
|
55
|
+
/**
|
|
56
|
+
* To configure the default breakpoints used in responsive array values,
|
|
57
|
+
* add a breakpoints array to your theme.
|
|
58
|
+
*
|
|
59
|
+
* Each breakpoint should be a string with a CSS length unit included or a
|
|
60
|
+
* string including a CSS media query. String values with a CSS length unit
|
|
61
|
+
* will be used to generate a mobile-first (i.e. min-width) media query.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* {
|
|
66
|
+
* breakpoints: [
|
|
67
|
+
* '40em', '@media (min-width: 56em) and (orientation: landscape)', '64em',
|
|
68
|
+
* ],
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
breakpoints?: Array<string>;
|
|
73
|
+
colors?: Scale<CSS.Property.Color | NestedScaleDict<CSS.Property.Color>>;
|
|
74
|
+
/**
|
|
75
|
+
* Used to define a scale for whitspace values,
|
|
76
|
+
* like `padding`, `margin`, `gap`, etc.
|
|
77
|
+
*/
|
|
78
|
+
space?: ZeroScale<CSS.Property.Margin<number | string>>;
|
|
79
|
+
/**
|
|
80
|
+
* Used to define a `font-size` scale.
|
|
81
|
+
*/
|
|
82
|
+
fontSizes?: Scale<CSS.Property.FontSize<number>>;
|
|
83
|
+
/**
|
|
84
|
+
* Used to define a `font-family` scale.
|
|
85
|
+
*/
|
|
86
|
+
fonts?: Scale<CSS.Property.FontFamily>;
|
|
87
|
+
/**
|
|
88
|
+
* Used to define a `font-weight` scale.
|
|
89
|
+
*/
|
|
90
|
+
fontWeights?: Scale<CSS.Property.FontWeight>;
|
|
91
|
+
/**
|
|
92
|
+
* Used to define a `line-height` scale.
|
|
93
|
+
*/
|
|
94
|
+
lineHeights?: Scale<CSS.Property.LineHeight<string | 0 | number>>;
|
|
95
|
+
/**
|
|
96
|
+
* Used to define a `letter-spacing` scale.
|
|
97
|
+
*/
|
|
98
|
+
letterSpacings?: ZeroScale<CSS.Property.LetterSpacing<string | 0 | number>>;
|
|
99
|
+
/**
|
|
100
|
+
* Used to define a scale for size values,
|
|
101
|
+
* like `height`, `width`, `flexBasis`, etc.
|
|
102
|
+
*/
|
|
103
|
+
sizes?: ZeroScale<CSS.Property.Height<{}> | CSS.Property.Width<{}>>;
|
|
104
|
+
/**
|
|
105
|
+
* Used to define different `border` styles.
|
|
106
|
+
*/
|
|
107
|
+
borders?: ZeroScale<CSS.Property.Border<{}>>;
|
|
108
|
+
/**
|
|
109
|
+
* Used to define `border-style` styles.
|
|
110
|
+
*/
|
|
111
|
+
borderStyles?: Scale<CSS.Property.Border<{}>>;
|
|
112
|
+
/**
|
|
113
|
+
* Used to define `border-width` styles.
|
|
114
|
+
*/
|
|
115
|
+
borderWidths?: ZeroScale<CSS.Property.BorderWidth<string | 0 | number>>;
|
|
116
|
+
/**
|
|
117
|
+
* Used to define `border-radius` styles.
|
|
118
|
+
*/
|
|
119
|
+
radii?: ZeroScale<CSS.Property.BorderRadius<string | 0 | number>>;
|
|
120
|
+
/**
|
|
121
|
+
* Used to define `Shadow` styles.
|
|
122
|
+
*/
|
|
123
|
+
shadows?: ZeroScale<CSS.Property.BoxShadow>;
|
|
124
|
+
/**
|
|
125
|
+
* Used to define a `z-index` scake.
|
|
126
|
+
*/
|
|
127
|
+
zIndices?: Scale<CSS.Property.ZIndex>;
|
|
128
|
+
/**
|
|
129
|
+
* Used to define a `opacity` scale.
|
|
130
|
+
*/
|
|
131
|
+
opacities?: Scale<CSS.Property.Opacity>;
|
|
132
|
+
/**
|
|
133
|
+
* Used to define a `transition` styles.
|
|
134
|
+
*/
|
|
135
|
+
transitions?: ZeroScale<CSS.Property.Transition>;
|
|
136
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Create type aliases for `theme-ui` so that it doesn't leak too much into our code.
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
export
|
|
4
|
+
import { ThemeUIStyleObject, ThemeUICSSObject, ThemeUICSSProperties, ResponsiveStyleValue as RSV } from '@theme-ui/css';
|
|
5
|
+
export declare type ResponsiveStyleValue<T> = RSV<T>;
|
|
6
6
|
export declare type StyleObject = ThemeUIStyleObject;
|
|
7
7
|
export declare type CSSObject = ThemeUICSSObject;
|
|
8
8
|
export declare type CSSProperties = ThemeUICSSProperties;
|
|
9
|
-
export declare type Theme = ThemeUITheme;
|
package/dist/useTheme.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Theme } from './theme';
|
|
3
|
+
import { StyleObject } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare const __defaultTheme: Theme;
|
|
8
|
+
export declare const useTheme: () => {
|
|
9
|
+
theme: Theme;
|
|
10
|
+
css: (style: StyleObject) => import("@theme-ui/css").CSSObject;
|
|
5
11
|
};
|
|
6
|
-
export declare
|
|
12
|
+
export declare type ThemeProviderProps<T extends Theme> = {
|
|
13
|
+
theme: T;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
};
|
|
16
|
+
export declare function ThemeProvider<T extends Theme>({ theme, children, }: ThemeProviderProps<T>): JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensures that the `val` is an array. Will return an empty array if `val` is falsy.
|
|
3
|
+
*/
|
|
4
|
+
export declare const ensureArray: <T>(val?: T | T[] | undefined) => T[];
|
|
5
|
+
/**
|
|
6
|
+
* Removes trailing dot from variant, if necessary. This is necessary to support
|
|
7
|
+
* `__default` styles. See https://github.com/system-ui/theme-ui/pull/951
|
|
8
|
+
*/
|
|
9
|
+
export declare const ensureVariantDefault: (val: string) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Ensures that the `variant` is an array and supports the `__default` key.
|
|
12
|
+
*/
|
|
13
|
+
export declare const ensureArrayVariant: <T extends string>(variant?: T | T[] | undefined) => string[];
|
|
14
|
+
export declare type State = {
|
|
15
|
+
checked?: boolean;
|
|
16
|
+
focus?: boolean;
|
|
17
|
+
hover?: boolean;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
error?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Appends given `state` to a `variant`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const appendVariantState: (variant: string, state: keyof State) => string;
|
|
25
|
+
/**
|
|
26
|
+
* Create a variant array from a `variant` and `state` containing
|
|
27
|
+
* passed states, if they are truthy.
|
|
28
|
+
*/
|
|
29
|
+
export declare const conditional: (variant: string, { disabled, ...states }: State) => string[];
|
package/package.json
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marigold/system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Marigold System Library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/system.esm.js",
|
|
7
7
|
"typings": "dist/index.d.ts",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@emotion/
|
|
11
|
-
"@theme-ui/css": "0.
|
|
10
|
+
"@emotion/react": "11.7.1",
|
|
11
|
+
"@theme-ui/css": "0.13.1",
|
|
12
|
+
"csstype": "3.0.10"
|
|
12
13
|
},
|
|
13
14
|
"peerDependencies": {
|
|
14
15
|
"react": "^16.x || ^17.0.0",
|
|
15
16
|
"react-dom": "^16.x || ^17.0.0"
|
|
16
17
|
},
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"csstype": "3.0.8"
|
|
19
|
-
},
|
|
20
18
|
"scripts": {
|
|
21
19
|
"build": "tsdx build --tsconfig tsconfig.build.json --transpileOnly",
|
|
22
20
|
"watch": "tsdx watch --tsconfig tsconfig.build.json --transpileOnly"
|
package/src/Box.test.tsx
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { ThemeProvider } from './useTheme';
|
|
4
|
+
import { Box, StyleProps } from './Box';
|
|
5
|
+
import { normalize } from './normalize';
|
|
6
|
+
|
|
7
|
+
const theme = {
|
|
8
|
+
colors: {
|
|
9
|
+
primary: 'black',
|
|
10
|
+
secondary: 'hotpink',
|
|
11
|
+
black: '#000',
|
|
12
|
+
white: '#fff',
|
|
13
|
+
blue: 'cornflowerblue',
|
|
14
|
+
},
|
|
15
|
+
fontSizes: {
|
|
16
|
+
body: 16,
|
|
17
|
+
small: 12,
|
|
18
|
+
large: 24,
|
|
19
|
+
},
|
|
20
|
+
space: {
|
|
21
|
+
none: 0,
|
|
22
|
+
xsmall: 2,
|
|
23
|
+
small: 4,
|
|
24
|
+
medium: 8,
|
|
25
|
+
large: 16,
|
|
26
|
+
},
|
|
27
|
+
sizes: {
|
|
28
|
+
none: 0,
|
|
29
|
+
small: 8,
|
|
30
|
+
medium: 16,
|
|
31
|
+
large: 32,
|
|
32
|
+
},
|
|
33
|
+
borders: { none: 'none', regular: '1px solid black' },
|
|
34
|
+
radii: { none: 0, small: 2, medium: 4 },
|
|
35
|
+
opacities: {
|
|
36
|
+
hidden: 0,
|
|
37
|
+
faded: 0.5,
|
|
38
|
+
visible: 1,
|
|
39
|
+
},
|
|
40
|
+
transitions: { none: 'none', regular: '1s opacity' },
|
|
41
|
+
shadows: {
|
|
42
|
+
none: 'none',
|
|
43
|
+
regular: '3px 3px 5px 6px #ccc',
|
|
44
|
+
inset: 'inset 0 0 10px #000000',
|
|
45
|
+
},
|
|
46
|
+
text: {
|
|
47
|
+
body: {
|
|
48
|
+
fontSize: 'body',
|
|
49
|
+
color: 'primary',
|
|
50
|
+
bg: 'white',
|
|
51
|
+
},
|
|
52
|
+
headline1: {
|
|
53
|
+
fontSize: 'large',
|
|
54
|
+
color: 'secondary',
|
|
55
|
+
},
|
|
56
|
+
whitespace: {
|
|
57
|
+
p: 'medium',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
variant: {
|
|
61
|
+
spacing: {
|
|
62
|
+
m: 'large',
|
|
63
|
+
p: 'large',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
test('renders a <div> by default', () => {
|
|
69
|
+
render(<Box>Test</Box>);
|
|
70
|
+
const testelem = screen.getByText('Test');
|
|
71
|
+
|
|
72
|
+
expect(testelem instanceof HTMLDivElement).toBeTruthy();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('changes rendered element via "as" prop', () => {
|
|
76
|
+
render(<Box as="p">Test</Box>);
|
|
77
|
+
const testelem = screen.getByText('Test');
|
|
78
|
+
|
|
79
|
+
expect(testelem instanceof HTMLParagraphElement).toBeTruthy();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('supports custom className', () => {
|
|
83
|
+
render(<Box className="my-custom-class">Test</Box>);
|
|
84
|
+
const element = screen.getByText('Test');
|
|
85
|
+
|
|
86
|
+
expect(element.getAttribute('class')).toMatch('my-custom-class');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('passes down HTML attributes', () => {
|
|
90
|
+
render(
|
|
91
|
+
<Box className="my-custom-class" id="element-id" disabled>
|
|
92
|
+
Test
|
|
93
|
+
</Box>
|
|
94
|
+
);
|
|
95
|
+
const element = screen.getByText('Test');
|
|
96
|
+
|
|
97
|
+
expect(element.getAttribute('id')).toEqual('element-id');
|
|
98
|
+
expect(element.getAttribute('disabled')).toMatch('');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('forwards ref', () => {
|
|
102
|
+
const ref = React.createRef<HTMLButtonElement>();
|
|
103
|
+
render(
|
|
104
|
+
<Box as="button" ref={ref}>
|
|
105
|
+
button
|
|
106
|
+
</Box>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
expect(ref.current instanceof HTMLButtonElement).toBeTruthy();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('apply normalized styles', () => {
|
|
113
|
+
render(<Box>Test</Box>);
|
|
114
|
+
const element = screen.getByText('Test');
|
|
115
|
+
const { base } = normalize;
|
|
116
|
+
|
|
117
|
+
// Smoketest
|
|
118
|
+
expect(element).toHaveStyle(`box-sizing: ${base.boxSizing}`);
|
|
119
|
+
expect(element).toHaveStyle(`margin: ${base.margin}px`);
|
|
120
|
+
expect(element).toHaveStyle(`min-width: ${base.minWidth}`);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('base normalization is always applied', () => {
|
|
124
|
+
render(<Box as="button">Test</Box>);
|
|
125
|
+
const element = screen.getByText('Test');
|
|
126
|
+
const { base } = normalize;
|
|
127
|
+
|
|
128
|
+
expect(element).toHaveStyle(`box-sizing: ${base.boxSizing}`);
|
|
129
|
+
expect(element).toHaveStyle(`margin: ${base.margin}px`);
|
|
130
|
+
expect(element).toHaveStyle(`min-width: ${base.minWidth}`);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('apply normalized styles based on element', () => {
|
|
134
|
+
render(<Box as="h1">Test</Box>);
|
|
135
|
+
const element = screen.getByText('Test');
|
|
136
|
+
const { h1 } = normalize;
|
|
137
|
+
|
|
138
|
+
expect(element).toHaveStyle(`overflow-wrap: ${h1.overflowWrap}`);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('accepts default styling via "__baseCSS" prop', () => {
|
|
142
|
+
render(<Box __baseCSS={{ color: 'hotpink' }}>Test</Box>);
|
|
143
|
+
const element = screen.getByText('Test');
|
|
144
|
+
|
|
145
|
+
expect(element).toHaveStyle('color: hotpink');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('default styling overrides normalization', () => {
|
|
149
|
+
render(
|
|
150
|
+
<ThemeProvider theme={theme}>
|
|
151
|
+
<Box __baseCSS={{ m: 'medium' }}>Test</Box>
|
|
152
|
+
</ThemeProvider>
|
|
153
|
+
);
|
|
154
|
+
const element = screen.getByText('Test');
|
|
155
|
+
|
|
156
|
+
expect(element).toHaveStyle(`margin: ${theme.space.medium}px`);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('variants are applied correctly', () => {
|
|
160
|
+
render(
|
|
161
|
+
<ThemeProvider theme={theme}>
|
|
162
|
+
<Box variant="text.body">Test</Box>
|
|
163
|
+
</ThemeProvider>
|
|
164
|
+
);
|
|
165
|
+
const element = screen.getByText('Test');
|
|
166
|
+
|
|
167
|
+
expect(element).toHaveStyle(`font-size: ${theme.fontSizes.body}px`);
|
|
168
|
+
expect(element).toHaveStyle(`color: ${theme.colors.primary}`);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('accept an array of variants', () => {
|
|
172
|
+
render(
|
|
173
|
+
<ThemeProvider theme={theme}>
|
|
174
|
+
<Box as="p" variant={['text.headline1', 'text.whitespace']}>
|
|
175
|
+
Test
|
|
176
|
+
</Box>
|
|
177
|
+
</ThemeProvider>
|
|
178
|
+
);
|
|
179
|
+
const element = screen.getByText('Test');
|
|
180
|
+
|
|
181
|
+
expect(element).toHaveStyle(`font-size: ${theme.fontSizes.large}px`);
|
|
182
|
+
expect(element).toHaveStyle(`color: ${theme.colors.secondary}`);
|
|
183
|
+
expect(element).toHaveStyle(`padding: ${theme.space.medium}px`);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test('variants override normalization and default styles', () => {
|
|
187
|
+
render(
|
|
188
|
+
<ThemeProvider theme={theme}>
|
|
189
|
+
<Box __baseCSS={{ p: 'small' }} variant="variant.spacing">
|
|
190
|
+
Test
|
|
191
|
+
</Box>
|
|
192
|
+
</ThemeProvider>
|
|
193
|
+
);
|
|
194
|
+
const element = screen.getByText('Test');
|
|
195
|
+
|
|
196
|
+
expect(element).toHaveStyle(`margin: ${theme.space.large}px`);
|
|
197
|
+
expect(element).toHaveStyle(`padding: ${theme.space.large}px`);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
test.each([
|
|
201
|
+
[{ display: 'flex' }, 'display: flex'],
|
|
202
|
+
[{ height: 'small' }, 'height: 8px'],
|
|
203
|
+
[{ width: 'medium' }, 'width: 16px'],
|
|
204
|
+
[{ minWidth: 'small' }, 'min-width: 8px'],
|
|
205
|
+
[{ maxWidth: 'large' }, 'max-width: 32px'],
|
|
206
|
+
[{ position: 'absolute' }, 'position: absolute'],
|
|
207
|
+
[{ top: 'none' }, 'top: 0px'],
|
|
208
|
+
[{ bottom: 'xsmall' }, 'bottom: 2px'],
|
|
209
|
+
[{ right: 'medium' }, 'right: 8px'],
|
|
210
|
+
[{ left: 'small' }, 'left: 4px'],
|
|
211
|
+
[{ zIndex: 1000 }, 'z-index: 1000'],
|
|
212
|
+
[{ p: 'xsmall' }, 'padding: 2px'],
|
|
213
|
+
[{ px: 'xsmall' }, 'padding-left: 2px', 'padding-right: 2px'],
|
|
214
|
+
[{ py: 'small' }, 'padding-top: 4px', 'padding-bottom: 4px'],
|
|
215
|
+
[{ pt: 'xsmall' }, 'padding-top: 2px'],
|
|
216
|
+
[{ pb: 'xsmall' }, 'padding-bottom: 2px'],
|
|
217
|
+
[{ pl: 'xsmall' }, 'padding-left: 2px'],
|
|
218
|
+
[{ pr: 'xsmall' }, 'padding-right: 2px'],
|
|
219
|
+
[{ m: 'xsmall' }, 'margin: 2px'],
|
|
220
|
+
[{ mx: 'xsmall' }, 'margin-left: 2px', 'margin-right: 2px'],
|
|
221
|
+
[{ my: 'small' }, 'margin-top: 4px', 'margin-bottom: 4px'],
|
|
222
|
+
[{ mt: 'xsmall' }, 'margin-top: 2px'],
|
|
223
|
+
[{ mb: 'xsmall' }, 'margin-bottom: 2px'],
|
|
224
|
+
[{ ml: 'xsmall' }, 'margin-left: 2px'],
|
|
225
|
+
[{ mr: 'xsmall' }, 'margin-right: 2px'],
|
|
226
|
+
[{ flexDirection: 'column' }, 'flex-direction: column'],
|
|
227
|
+
[{ flexWrap: 'wrap' }, 'flex-wrap: wrap'],
|
|
228
|
+
[{ flexShrink: 5 }, 'flex-shrink: 5'],
|
|
229
|
+
[{ flexGrow: 1 }, 'flex-grow: 1'],
|
|
230
|
+
[{ alignItems: 'baseline' }, 'align-items: baseline'],
|
|
231
|
+
[{ justifyContent: 'space-between' }, 'justify-content: space-between'],
|
|
232
|
+
[{ bg: 'secondary' }, 'background-color: hotpink'],
|
|
233
|
+
[{ border: 'regular' }, 'border: 1px solid black'],
|
|
234
|
+
[{ borderRadius: 'medium' }, 'border-radius: 4px'],
|
|
235
|
+
[{ boxShadow: 'regular' }, 'box-shadow: 3px 3px 5px 6px #ccc'],
|
|
236
|
+
[{ opacity: 'faded' }, 'opacity: 0.5'],
|
|
237
|
+
[{ overflow: 'hidden' }, 'overflow: hidden'],
|
|
238
|
+
[{ transition: 'regular' }, 'transition: 1s opacity'],
|
|
239
|
+
])('supports style prop (%o)', (...args) => {
|
|
240
|
+
const props = args.shift() as StyleProps;
|
|
241
|
+
|
|
242
|
+
render(
|
|
243
|
+
<ThemeProvider theme={theme}>
|
|
244
|
+
<Box {...props}>What's in the box!</Box>
|
|
245
|
+
</ThemeProvider>
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
const box = screen.getByText(`What's in the box!`);
|
|
249
|
+
args.forEach((style: any) => {
|
|
250
|
+
expect(box).toHaveStyle(style);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('style props override normalization, defaults and variants', () => {
|
|
255
|
+
render(
|
|
256
|
+
<ThemeProvider theme={theme}>
|
|
257
|
+
<Box
|
|
258
|
+
__baseCSS={{ p: 'small' }}
|
|
259
|
+
variant="text.body"
|
|
260
|
+
bg="blue"
|
|
261
|
+
m="medium"
|
|
262
|
+
p="large"
|
|
263
|
+
>
|
|
264
|
+
Test
|
|
265
|
+
</Box>
|
|
266
|
+
</ThemeProvider>
|
|
267
|
+
);
|
|
268
|
+
const element = screen.getByText('Test');
|
|
269
|
+
|
|
270
|
+
expect(element).toHaveStyle(`margin: ${theme.space.medium}px`); // overrides normalization
|
|
271
|
+
expect(element).toHaveStyle(`padding: ${theme.space.large}px`); // overrides default
|
|
272
|
+
expect(element).toHaveStyle(`background: ${theme.colors.blue}`); // overrides variant
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test('apply custom styling via css prop', () => {
|
|
276
|
+
render(
|
|
277
|
+
<ThemeProvider theme={theme}>
|
|
278
|
+
<Box css={{ color: 'secondary', padding: '1rem' }}>Test</Box>
|
|
279
|
+
</ThemeProvider>
|
|
280
|
+
);
|
|
281
|
+
const element = screen.getByText('Test');
|
|
282
|
+
|
|
283
|
+
expect(element).toHaveStyle(`padding: 1rem`);
|
|
284
|
+
expect(element).toHaveStyle(`color: ${theme.colors.secondary}`);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test('custom styling overrides normalization, defaults, variants and style props', () => {
|
|
288
|
+
render(
|
|
289
|
+
<ThemeProvider theme={theme}>
|
|
290
|
+
<Box
|
|
291
|
+
__baseCSS={{ p: 'small' }}
|
|
292
|
+
variant="text.body"
|
|
293
|
+
bg="black"
|
|
294
|
+
css={{ fontSize: 'large', m: 'small', p: 'large', bg: 'blue' }}
|
|
295
|
+
>
|
|
296
|
+
Test
|
|
297
|
+
</Box>
|
|
298
|
+
</ThemeProvider>
|
|
299
|
+
);
|
|
300
|
+
const element = screen.getByText('Test');
|
|
301
|
+
|
|
302
|
+
expect(element).toHaveStyle(`margin: ${theme.space.small}px`); // overrides normalization
|
|
303
|
+
expect(element).toHaveStyle(`padding: ${theme.space.large}px`); // overrides default
|
|
304
|
+
expect(element).toHaveStyle(`font-size: ${theme.fontSizes.large}px`); // overrides variant
|
|
305
|
+
expect(element).toHaveStyle(`background: ${theme.colors.blue}`); // overrides style prop
|
|
306
|
+
|
|
307
|
+
expect(element).not.toHaveStyle(`color: ${theme.colors.primary}px`); // variant part that is not overriden
|
|
308
|
+
});
|