@marigold/system 0.0.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +95 -0
- package/dist/Box.d.ts +14 -0
- package/dist/Global.d.ts +2 -0
- package/dist/SVG.d.ts +6 -0
- package/dist/index.d.ts +7 -4
- package/dist/normalize.d.ts +143 -5
- package/dist/system.cjs.development.js +334 -159
- 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 +324 -156
- package/dist/system.esm.js.map +1 -1
- package/dist/theme.d.ts +136 -0
- package/dist/types.d.ts +8 -0
- package/dist/useTheme.d.ts +15 -5
- package/dist/variant.d.ts +29 -0
- package/package.json +6 -8
- package/src/Box.test.tsx +308 -0
- package/src/Box.tsx +199 -0
- package/src/Colors.stories.mdx +492 -448
- package/src/Global.test.tsx +57 -0
- package/src/Global.tsx +34 -0
- package/src/SVG.stories.mdx +55 -0
- package/src/SVG.test.tsx +82 -0
- package/src/SVG.tsx +24 -0
- package/src/concepts-principles.mdx +1 -1
- package/src/index.ts +7 -4
- package/src/normalize.test.tsx +15 -0
- package/src/normalize.ts +79 -93
- package/src/theme.ts +157 -0
- package/src/types.ts +14 -0
- package/src/useTheme.test.tsx +92 -17
- package/src/useTheme.tsx +45 -6
- package/src/variant.test.ts +93 -0
- package/src/variant.ts +54 -0
- package/dist/categories.d.ts +0 -169
- package/dist/system.d.ts +0 -37
- package/dist/useClassname.d.ts +0 -2
- package/dist/useStyles.d.ts +0 -10
- package/src/categories.ts +0 -203
- package/src/system.test.tsx +0 -84
- package/src/system.tsx +0 -55
- package/src/useClassname.test.tsx +0 -61
- package/src/useClassname.ts +0 -8
- package/src/useStyles.test.tsx +0 -313
- package/src/useStyles.ts +0 -56
- package/src/writeComponent.stories.mdx +0 -126
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import { ThemeProvider } from './useTheme';
|
|
4
|
+
|
|
5
|
+
import { Global } from './Global';
|
|
6
|
+
|
|
7
|
+
test('applies normlaization to html and body', () => {
|
|
8
|
+
const root = render(<Global />);
|
|
9
|
+
|
|
10
|
+
const html = window.getComputedStyle(root.baseElement.parentElement!);
|
|
11
|
+
expect(html.height).toBe('100%');
|
|
12
|
+
const body = window.getComputedStyle(root.baseElement);
|
|
13
|
+
expect(body.height).toBe('100%');
|
|
14
|
+
expect(body.lineHeight).toBe('1.5');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('applies global styles for body and html based on `theme.root`', () => {
|
|
18
|
+
const theme = {
|
|
19
|
+
colors: {
|
|
20
|
+
background: '#fff',
|
|
21
|
+
},
|
|
22
|
+
fonts: {
|
|
23
|
+
body: 'Inter',
|
|
24
|
+
},
|
|
25
|
+
lineHeights: {
|
|
26
|
+
body: 2.5,
|
|
27
|
+
},
|
|
28
|
+
fontWeights: {
|
|
29
|
+
body: 500,
|
|
30
|
+
html: 700,
|
|
31
|
+
},
|
|
32
|
+
root: {
|
|
33
|
+
body: {
|
|
34
|
+
fontFamily: 'body',
|
|
35
|
+
lineHeight: 'body',
|
|
36
|
+
fontWeight: 'body',
|
|
37
|
+
},
|
|
38
|
+
html: {
|
|
39
|
+
bg: 'background',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const root = render(
|
|
45
|
+
<ThemeProvider theme={theme}>
|
|
46
|
+
<Global />
|
|
47
|
+
</ThemeProvider>
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const html = root.baseElement.parentElement;
|
|
51
|
+
expect(html).toHaveStyle(`background: ${theme.colors.background}`);
|
|
52
|
+
|
|
53
|
+
const body = root.baseElement;
|
|
54
|
+
expect(body).toHaveStyle(`font-family: ${theme.fonts.body}`);
|
|
55
|
+
expect(body).toHaveStyle(`line-height: ${theme.lineHeights.body}`);
|
|
56
|
+
expect(body).toHaveStyle(`font-weight: ${theme.fontWeights.body}`);
|
|
57
|
+
});
|
package/src/Global.tsx
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Global as EmotionGlobal } from '@emotion/react';
|
|
3
|
+
import { useTheme } from './useTheme';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CSS snippet and idea from:
|
|
7
|
+
* https://css-tricks.com/revisiting-prefers-reduced-motion-the-reduced-motion-media-query/
|
|
8
|
+
*/
|
|
9
|
+
const reduceMotionStyles = {
|
|
10
|
+
'@media screen and (prefers-reduced-motion: reduce), (update: slow)': {
|
|
11
|
+
'*': {
|
|
12
|
+
animationDuration: '0.001ms !important',
|
|
13
|
+
animationIterationCount: '1 !important',
|
|
14
|
+
transitionDuration: '0.001ms !important',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const Global = () => {
|
|
20
|
+
const { css } = useTheme();
|
|
21
|
+
const styles = css({
|
|
22
|
+
html: {
|
|
23
|
+
height: '100%',
|
|
24
|
+
variant: 'root.html',
|
|
25
|
+
},
|
|
26
|
+
body: {
|
|
27
|
+
height: '100%',
|
|
28
|
+
lineHeight: 1.5,
|
|
29
|
+
WebkitFontSmoothing: 'antialiased',
|
|
30
|
+
variant: 'root.body',
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
return <EmotionGlobal styles={{ reduceMotionStyles, ...styles }} />;
|
|
34
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
|
|
2
|
+
import { SVG } from './SVG';
|
|
3
|
+
|
|
4
|
+
<Meta
|
|
5
|
+
title="Components/SVG"
|
|
6
|
+
argTypes={{
|
|
7
|
+
variant: {
|
|
8
|
+
control: {
|
|
9
|
+
type: 'text',
|
|
10
|
+
},
|
|
11
|
+
table: {
|
|
12
|
+
defaultValue: {
|
|
13
|
+
summary: 'icon',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
control: {
|
|
19
|
+
type: 'range',
|
|
20
|
+
min: 0,
|
|
21
|
+
max: 96,
|
|
22
|
+
step: 2,
|
|
23
|
+
},
|
|
24
|
+
table: {
|
|
25
|
+
defaultValue: {
|
|
26
|
+
summary: 24,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
fill: {
|
|
31
|
+
control: {
|
|
32
|
+
type: 'text',
|
|
33
|
+
},
|
|
34
|
+
table: {
|
|
35
|
+
defaultValue: {
|
|
36
|
+
summary: 'currentColor',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
# SVG
|
|
44
|
+
|
|
45
|
+
export const Template = args => (
|
|
46
|
+
<SVG {...args}>
|
|
47
|
+
<path d="M9.9 20.113V13.8415H14.1V20.113H19.35V11.751H22.5L12 2.34375L1.5 11.751H4.65V20.113H9.9Z" />
|
|
48
|
+
</SVG>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
<Canvas>
|
|
52
|
+
<Story name="Default">{Template.bind({})}</Story>
|
|
53
|
+
</Canvas>
|
|
54
|
+
|
|
55
|
+
<ArgsTable story="Default" />
|
package/src/SVG.test.tsx
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { SVG } from './SVG';
|
|
4
|
+
|
|
5
|
+
test('renders svg', () => {
|
|
6
|
+
render(<SVG data-testid="svg" />);
|
|
7
|
+
const svg = screen.getByTestId('svg');
|
|
8
|
+
expect(svg instanceof SVGElement).toBeTruthy();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('normalizes <svg>', () => {
|
|
12
|
+
render(<SVG data-testid="svg" />);
|
|
13
|
+
const svg = screen.getByTestId('svg');
|
|
14
|
+
expect(svg).toHaveStyle('display: block');
|
|
15
|
+
expect(svg).toHaveStyle('max-width: 100%');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('supports default fill color', () => {
|
|
19
|
+
render(
|
|
20
|
+
<SVG data-testid="svg">
|
|
21
|
+
<path d="M9.9 20.113V13.8415H14" />
|
|
22
|
+
</SVG>
|
|
23
|
+
);
|
|
24
|
+
const svg = screen.getByTestId(/svg/);
|
|
25
|
+
|
|
26
|
+
expect(svg.getAttribute('fill')).toEqual('currentcolor');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('supports default size', () => {
|
|
30
|
+
render(
|
|
31
|
+
<SVG data-testid="svg">
|
|
32
|
+
<path d="M9.9 20.113V13.8415H14" />
|
|
33
|
+
</SVG>
|
|
34
|
+
);
|
|
35
|
+
const svg = screen.getByTestId(/svg/);
|
|
36
|
+
|
|
37
|
+
expect(svg.getAttribute('width')).toEqual('24');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('supports size prop', () => {
|
|
41
|
+
render(
|
|
42
|
+
<SVG data-testid="svg" size={30}>
|
|
43
|
+
<path d="M9.9 20.113V13.8415H14" />
|
|
44
|
+
</SVG>
|
|
45
|
+
);
|
|
46
|
+
const svg = screen.getByTestId(/svg/);
|
|
47
|
+
|
|
48
|
+
expect(svg.getAttribute('width')).toEqual('30');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('supports fill prop', () => {
|
|
52
|
+
render(
|
|
53
|
+
<SVG data-testid="svg" fill="#fafafa">
|
|
54
|
+
<path d="M9.9 20.113V13.8415H14" />
|
|
55
|
+
</SVG>
|
|
56
|
+
);
|
|
57
|
+
const svg = screen.getByTestId(/svg/);
|
|
58
|
+
|
|
59
|
+
expect(svg.getAttribute('fill')).toEqual('#fafafa');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('accepts custom styles prop className', () => {
|
|
63
|
+
render(
|
|
64
|
+
<SVG data-testid="svg" className="custom-class-name">
|
|
65
|
+
<path d="M9.9 20.113V13.8415H14" />
|
|
66
|
+
</SVG>
|
|
67
|
+
);
|
|
68
|
+
const svg = screen.getByTestId(/svg/);
|
|
69
|
+
|
|
70
|
+
expect(svg.getAttribute('class')).toMatch(/custom-class-name/);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('renders <svg> element', () => {
|
|
74
|
+
render(
|
|
75
|
+
<SVG data-testid="svg">
|
|
76
|
+
<path d="M9.9 20.113V13.8415H14" />
|
|
77
|
+
</SVG>
|
|
78
|
+
);
|
|
79
|
+
const svg = screen.getByTestId(/svg/);
|
|
80
|
+
|
|
81
|
+
expect(svg instanceof SVGElement).toBeTruthy();
|
|
82
|
+
});
|
package/src/SVG.tsx
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { jsx } from '@emotion/react';
|
|
3
|
+
import { ComponentProps } from '@marigold/types';
|
|
4
|
+
import { getNormalizedStyles } from '@marigold/system';
|
|
5
|
+
|
|
6
|
+
const css = getNormalizedStyles('svg');
|
|
7
|
+
|
|
8
|
+
export type SVGProps = {
|
|
9
|
+
size?: number;
|
|
10
|
+
} & ComponentProps<'svg'>;
|
|
11
|
+
|
|
12
|
+
export const SVG: React.FC<SVGProps> = ({ size = 24, children, ...props }) =>
|
|
13
|
+
jsx(
|
|
14
|
+
'svg',
|
|
15
|
+
{
|
|
16
|
+
width: size,
|
|
17
|
+
height: size,
|
|
18
|
+
viewBox: '0 0 24 24',
|
|
19
|
+
fill: 'currentcolor',
|
|
20
|
+
...props,
|
|
21
|
+
css,
|
|
22
|
+
},
|
|
23
|
+
children
|
|
24
|
+
);
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
1
|
+
export * from './Box';
|
|
2
|
+
export * from './Global';
|
|
3
|
+
export * from './normalize';
|
|
4
|
+
export * from './SVG';
|
|
5
|
+
export * from './theme';
|
|
6
|
+
export * from './types';
|
|
5
7
|
export * from './useTheme';
|
|
8
|
+
export * from './variant';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { normalize, getNormalizedStyles } from './normalize';
|
|
2
|
+
|
|
3
|
+
test.each(Object.entries(normalize))('base is included in %p', (_, value) => {
|
|
4
|
+
expect(value).toMatchObject(normalize.base);
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test('get normalized styles', () => {
|
|
8
|
+
expect(getNormalizedStyles('a')).toMatchObject(normalize.a);
|
|
9
|
+
expect(getNormalizedStyles('p')).toMatchObject(normalize.p);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('return base normalzation for arbitrary components', () => {
|
|
13
|
+
const Component = () => null;
|
|
14
|
+
expect(getNormalizedStyles(Component)).toMatchObject(normalize.base);
|
|
15
|
+
});
|
package/src/normalize.ts
CHANGED
|
@@ -1,114 +1,100 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Normalize styling of certain elements between browsers.
|
|
3
|
+
* Based on https://www.joshwcomeau.com/css/custom-css-reset/
|
|
4
|
+
*/
|
|
5
|
+
import { ElementType } from 'react';
|
|
2
6
|
|
|
3
7
|
const base = {
|
|
4
8
|
boxSizing: 'border-box',
|
|
5
9
|
margin: 0,
|
|
6
|
-
padding: 0,
|
|
7
10
|
minWidth: 0,
|
|
8
|
-
|
|
9
|
-
font: 'inherit',
|
|
10
|
-
verticalAlign: 'baseline',
|
|
11
|
-
WebkitTapHighlightColor: 'transparent',
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const block = {
|
|
15
|
-
display: 'block',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const body = {
|
|
19
|
-
lineHeight: 1,
|
|
20
|
-
};
|
|
11
|
+
} as const;
|
|
21
12
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
const a = {
|
|
14
|
+
...base,
|
|
15
|
+
textDecoration: 'none',
|
|
16
|
+
} as const;
|
|
25
17
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
content: "''",
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
};
|
|
18
|
+
const text = {
|
|
19
|
+
...base,
|
|
20
|
+
overflowWrap: 'break-word',
|
|
21
|
+
} as const;
|
|
34
22
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
const media = {
|
|
24
|
+
...base,
|
|
25
|
+
display: 'block',
|
|
26
|
+
maxWidth: '100%',
|
|
27
|
+
} as const;
|
|
39
28
|
|
|
40
|
-
const
|
|
29
|
+
const button = {
|
|
30
|
+
...base,
|
|
31
|
+
display: 'block',
|
|
41
32
|
appearance: 'none',
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const mark = {
|
|
47
|
-
backgroundColor: 'transparent',
|
|
48
|
-
color: 'inherit',
|
|
49
|
-
};
|
|
33
|
+
font: 'inherit',
|
|
34
|
+
background: 'transparent',
|
|
35
|
+
textAlign: 'center',
|
|
36
|
+
} as const;
|
|
50
37
|
|
|
51
|
-
const
|
|
52
|
-
...
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
38
|
+
const input = {
|
|
39
|
+
...base,
|
|
40
|
+
display: 'block',
|
|
41
|
+
appearance: 'none',
|
|
42
|
+
font: 'inherit',
|
|
43
|
+
'&::-ms-clear': {
|
|
44
|
+
display: 'none',
|
|
59
45
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const input = [
|
|
63
|
-
...field,
|
|
64
|
-
{
|
|
65
|
-
selectors: {
|
|
66
|
-
'&::-ms-clear': {
|
|
67
|
-
display: 'none',
|
|
68
|
-
},
|
|
69
|
-
'&::-webkit-search-cancel-button': {
|
|
70
|
-
WebkitAppearance: 'none',
|
|
71
|
-
},
|
|
72
|
-
},
|
|
46
|
+
'&::-webkit-search-cancel-button': {
|
|
47
|
+
WebkitAppearance: 'none',
|
|
73
48
|
},
|
|
74
|
-
|
|
49
|
+
} as const;
|
|
75
50
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
51
|
+
const select = {
|
|
52
|
+
...base,
|
|
53
|
+
display: 'block',
|
|
54
|
+
appearance: 'none',
|
|
55
|
+
font: 'inherit',
|
|
56
|
+
'&::-ms-expand': {
|
|
57
|
+
display: 'none',
|
|
58
|
+
},
|
|
59
|
+
} as const;
|
|
79
60
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
61
|
+
const textarea = {
|
|
62
|
+
...base,
|
|
63
|
+
display: 'block',
|
|
64
|
+
appearance: 'none',
|
|
65
|
+
font: 'inherit',
|
|
66
|
+
} as const;
|
|
83
67
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
details: block,
|
|
88
|
-
figcaption: block,
|
|
89
|
-
figure: block,
|
|
90
|
-
footer: block,
|
|
91
|
-
header: block,
|
|
92
|
-
hgroup: block,
|
|
93
|
-
menu: block,
|
|
94
|
-
nav: block,
|
|
95
|
-
section: block,
|
|
96
|
-
ul: list,
|
|
97
|
-
ol: list,
|
|
98
|
-
blockquote: quote,
|
|
99
|
-
q: quote,
|
|
100
|
-
body,
|
|
101
|
-
a,
|
|
68
|
+
// Normalize
|
|
69
|
+
// ---------------
|
|
70
|
+
export const normalize = {
|
|
102
71
|
base,
|
|
103
|
-
|
|
104
|
-
|
|
72
|
+
a,
|
|
73
|
+
p: text,
|
|
74
|
+
h1: text,
|
|
75
|
+
h2: text,
|
|
76
|
+
h3: text,
|
|
77
|
+
h4: text,
|
|
78
|
+
h5: text,
|
|
79
|
+
h6: text,
|
|
80
|
+
img: media,
|
|
81
|
+
picture: media,
|
|
82
|
+
video: media,
|
|
83
|
+
canvas: media,
|
|
84
|
+
svg: media,
|
|
105
85
|
select,
|
|
106
|
-
p: list,
|
|
107
86
|
button,
|
|
108
|
-
textarea
|
|
87
|
+
textarea,
|
|
109
88
|
input,
|
|
110
|
-
};
|
|
89
|
+
} as const;
|
|
90
|
+
|
|
91
|
+
export type NormalizedElement = keyof typeof normalize;
|
|
111
92
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Type-safe helper to get normalization. If no normalization is found,
|
|
95
|
+
* returns the *base* normalization.
|
|
96
|
+
*/
|
|
97
|
+
export const getNormalizedStyles = (val?: ElementType) =>
|
|
98
|
+
typeof val === 'string' && val in normalize
|
|
99
|
+
? normalize[val as NormalizedElement] // Typescript doesn't infer this correctly
|
|
100
|
+
: normalize.base;
|
package/src/theme.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import * as CSS from 'csstype';
|
|
2
|
+
import { NestedScaleDict } from '@theme-ui/css';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Value used to define a scale.
|
|
6
|
+
*
|
|
7
|
+
* Can be nested to support a default value.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* Given a theme
|
|
11
|
+
* ```
|
|
12
|
+
* {
|
|
13
|
+
* colors: {
|
|
14
|
+
* primary: { __default: '#00f', light: '#33f' }
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
* `css{{ color: 'primary' }}` resolves to `color: #00f`.
|
|
19
|
+
*/
|
|
20
|
+
export type ScaleValue<T> = T | T[] | NestedScaleDict<T> | undefined;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Scales are a set of named, pre-defined CSS values which are used
|
|
24
|
+
* to create consitency in sizing across visual elements. They give
|
|
25
|
+
* plain values semantics meaning.
|
|
26
|
+
*
|
|
27
|
+
* Marigold uses a plain object to define scales, where the key should be a
|
|
28
|
+
* descriptive name for the scale (e.g. `small`/`medium`/.. or `body`/`heading`/...),
|
|
29
|
+
* and the value is the CSS value.
|
|
30
|
+
*/
|
|
31
|
+
export type Scale<T> = {
|
|
32
|
+
[key: string]: ScaleValue<T>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Predefined {@link Scale} scale which uses size values.
|
|
37
|
+
*/
|
|
38
|
+
export type SizeScale<T> = {
|
|
39
|
+
xxsmall?: ScaleValue<T>;
|
|
40
|
+
xsmall?: ScaleValue<T>;
|
|
41
|
+
small?: ScaleValue<T>;
|
|
42
|
+
medium?: ScaleValue<T>;
|
|
43
|
+
large?: ScaleValue<T>;
|
|
44
|
+
xlarge?: ScaleValue<T>;
|
|
45
|
+
xxlarge?: ScaleValue<T>;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A {@link SizeScale} that also includes a required `none` value, which is
|
|
50
|
+
* usually used to define the blank value (e.g `0`).
|
|
51
|
+
*/
|
|
52
|
+
export type ZeroScale<T> = {
|
|
53
|
+
none: ScaleValue<T>;
|
|
54
|
+
} & Scale<T>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Base theme with typings for available scales properties.
|
|
58
|
+
*/
|
|
59
|
+
export interface Theme {
|
|
60
|
+
/**
|
|
61
|
+
* To configure the default breakpoints used in responsive array values,
|
|
62
|
+
* add a breakpoints array to your theme.
|
|
63
|
+
*
|
|
64
|
+
* Each breakpoint should be a string with a CSS length unit included or a
|
|
65
|
+
* string including a CSS media query. String values with a CSS length unit
|
|
66
|
+
* will be used to generate a mobile-first (i.e. min-width) media query.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* {
|
|
71
|
+
* breakpoints: [
|
|
72
|
+
* '40em', '@media (min-width: 56em) and (orientation: landscape)', '64em',
|
|
73
|
+
* ],
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
breakpoints?: Array<string>;
|
|
78
|
+
|
|
79
|
+
colors?: Scale<CSS.Property.Color | NestedScaleDict<CSS.Property.Color>>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Used to define a scale for whitspace values,
|
|
83
|
+
* like `padding`, `margin`, `gap`, etc.
|
|
84
|
+
*/
|
|
85
|
+
space?: ZeroScale<CSS.Property.Margin<number | string>>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Used to define a `font-size` scale.
|
|
89
|
+
*/
|
|
90
|
+
fontSizes?: Scale<CSS.Property.FontSize<number>>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Used to define a `font-family` scale.
|
|
94
|
+
*/
|
|
95
|
+
fonts?: Scale<CSS.Property.FontFamily>;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Used to define a `font-weight` scale.
|
|
99
|
+
*/
|
|
100
|
+
fontWeights?: Scale<CSS.Property.FontWeight>;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Used to define a `line-height` scale.
|
|
104
|
+
*/
|
|
105
|
+
lineHeights?: Scale<CSS.Property.LineHeight<string | 0 | number>>;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Used to define a `letter-spacing` scale.
|
|
109
|
+
*/
|
|
110
|
+
letterSpacings?: ZeroScale<CSS.Property.LetterSpacing<string | 0 | number>>;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Used to define a scale for size values,
|
|
114
|
+
* like `height`, `width`, `flexBasis`, etc.
|
|
115
|
+
*/
|
|
116
|
+
sizes?: ZeroScale<CSS.Property.Height<{}> | CSS.Property.Width<{}>>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Used to define different `border` styles.
|
|
120
|
+
*/
|
|
121
|
+
borders?: ZeroScale<CSS.Property.Border<{}>>;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Used to define `border-style` styles.
|
|
125
|
+
*/
|
|
126
|
+
borderStyles?: Scale<CSS.Property.Border<{}>>;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Used to define `border-width` styles.
|
|
130
|
+
*/
|
|
131
|
+
borderWidths?: ZeroScale<CSS.Property.BorderWidth<string | 0 | number>>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Used to define `border-radius` styles.
|
|
135
|
+
*/
|
|
136
|
+
radii?: ZeroScale<CSS.Property.BorderRadius<string | 0 | number>>;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Used to define `Shadow` styles.
|
|
140
|
+
*/
|
|
141
|
+
shadows?: ZeroScale<CSS.Property.BoxShadow>;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Used to define a `z-index` scake.
|
|
145
|
+
*/
|
|
146
|
+
zIndices?: Scale<CSS.Property.ZIndex>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Used to define a `opacity` scale.
|
|
150
|
+
*/
|
|
151
|
+
opacities?: Scale<CSS.Property.Opacity>;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Used to define a `transition` styles.
|
|
155
|
+
*/
|
|
156
|
+
transitions?: ZeroScale<CSS.Property.Transition>;
|
|
157
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create type aliases for `theme-ui` so that it doesn't leak too much into our code.
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
ThemeUIStyleObject,
|
|
6
|
+
ThemeUICSSObject,
|
|
7
|
+
ThemeUICSSProperties,
|
|
8
|
+
ResponsiveStyleValue as RSV,
|
|
9
|
+
} from '@theme-ui/css';
|
|
10
|
+
|
|
11
|
+
export type ResponsiveStyleValue<T> = RSV<T>;
|
|
12
|
+
export type StyleObject = ThemeUIStyleObject;
|
|
13
|
+
export type CSSObject = ThemeUICSSObject;
|
|
14
|
+
export type CSSProperties = ThemeUICSSProperties;
|