@symbo.ls/atoms 1.1.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/Animation.js +53 -0
- package/Block.js +151 -0
- package/Direction.js +10 -0
- package/Flex.js +17 -0
- package/Form.js +11 -0
- package/Grid.js +30 -0
- package/Iframe.js +16 -0
- package/Img.js +17 -0
- package/Interaction.js +9 -0
- package/InteractiveComponent.js +78 -0
- package/Media.js +164 -0
- package/Overflow.js +7 -0
- package/Picture.js +31 -0
- package/Position.js +21 -0
- package/Pseudo.js +7 -0
- package/SVG.js +16 -0
- package/Shape/index.js +42 -0
- package/Shape/style.js +204 -0
- package/Text.js +40 -0
- package/Theme.js +136 -0
- package/Timing.js +55 -0
- package/Transform.js +8 -0
- package/XYZ.js +7 -0
- package/index.js +24 -0
- package/package.json +13 -0
package/Animation.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getTimingByKey, getTimingFunction } from '@symbo.ls/scratch'
|
|
4
|
+
import { isObject } from '@domql/utils'
|
|
5
|
+
import { convertPropsToClass } from './Media' // eslint-disable-line no-unused-vars
|
|
6
|
+
import { emotion } from '@symbo.ls/create-emotion'
|
|
7
|
+
const { keyframes } = emotion
|
|
8
|
+
|
|
9
|
+
const applyAnimationProps = (animation, element) => {
|
|
10
|
+
if (isObject(animation)) return { animationName: keyframes(animation) }
|
|
11
|
+
const { ANIMATION } = element.context && element.context.system
|
|
12
|
+
const record = ANIMATION[animation]
|
|
13
|
+
return keyframes(record)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const Animation = {
|
|
17
|
+
class: {
|
|
18
|
+
animation: (el) => el.props.animation && {
|
|
19
|
+
animationName: applyAnimationProps(el.props.animation, el),
|
|
20
|
+
animationDuration: getTimingByKey(el.props.animationDuration || 'A').timing,
|
|
21
|
+
animationDelay: getTimingByKey(el.props.animationDelay || '0s').timing,
|
|
22
|
+
animationTimingFunction: getTimingFunction(el.props.animationTimingFunction || 'ease'),
|
|
23
|
+
animationFillMode: el.props.animationFillMode || 'both',
|
|
24
|
+
animationPlayState: el.props.animationPlayState,
|
|
25
|
+
animationDirection: el.props.animationDirection
|
|
26
|
+
},
|
|
27
|
+
animationName: (el) => el.props.animationName && {
|
|
28
|
+
animationName: applyAnimationProps(el.props.animationName, el)
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
animationDuration: ({ props }) => props.animationDuration && ({
|
|
32
|
+
animationDuration: getTimingByKey(props.animationDuration).timing
|
|
33
|
+
}),
|
|
34
|
+
animationDelay: ({ props }) => props.animationDelay && ({
|
|
35
|
+
animationDelay: getTimingByKey(props.animationDelay).timing
|
|
36
|
+
}),
|
|
37
|
+
animationTimingFunction: ({ props }) => props.animationTimingFunction && ({
|
|
38
|
+
animationTimingFunction: getTimingFunction(props.animationTimingFunction)
|
|
39
|
+
}),
|
|
40
|
+
animationFillMode: ({ props }) => props.animationFillMode && ({
|
|
41
|
+
animationFillMode: props.animationFillMode
|
|
42
|
+
}),
|
|
43
|
+
animationPlayState: ({ props }) => props.animationPlayState && ({
|
|
44
|
+
animationPlayState: props.animationPlayState
|
|
45
|
+
}),
|
|
46
|
+
animationIterationCount: ({ props }) => props.animationIterationCount && ({
|
|
47
|
+
animationIterationCount: props.animationIterationCount || 1
|
|
48
|
+
}),
|
|
49
|
+
animationDirection: ({ props }) => props.animationDirection && ({
|
|
50
|
+
animationDirection: props.animationDirection
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
}
|
package/Block.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getSpacingBasedOnRatio, getSpacingByKey, isString } from '@symbo.ls/scratch'
|
|
4
|
+
|
|
5
|
+
const transfromGap = gap => isString(gap) && ({
|
|
6
|
+
gap: gap.split(' ').map(v => getSpacingByKey(v, 'gap').gap).join(' ')
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
export const Block = {
|
|
10
|
+
class: {
|
|
11
|
+
boxSizing: ({ props }) => props.boxSizing ? ({ boxSizing: props.boxSizing }) : {
|
|
12
|
+
boxSizing: 'border-box'
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
display: ({ props }) => props.display && ({ display: props.display }),
|
|
16
|
+
|
|
17
|
+
hide: ({ props }) => props.hide && ({ display: 'none' }),
|
|
18
|
+
|
|
19
|
+
width: ({ props }) => props.width && getSpacingBasedOnRatio(props, 'width'),
|
|
20
|
+
height: ({ props }) => props.height && getSpacingBasedOnRatio(props, 'height'),
|
|
21
|
+
boxSize: ({ props }) => {
|
|
22
|
+
if (typeof props.boxSize !== 'string') return
|
|
23
|
+
const [height, width] = props.boxSize.split(' ')
|
|
24
|
+
return {
|
|
25
|
+
...getSpacingByKey(height, 'height'),
|
|
26
|
+
...getSpacingByKey(width || height, 'width')
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
maxWidth: ({ props }) => props.maxWidth && getSpacingBasedOnRatio(props, 'maxWidth'),
|
|
31
|
+
minWidth: ({ props }) => props.minWidth && getSpacingBasedOnRatio(props, 'minWidth'),
|
|
32
|
+
widthRange: ({ props }) => {
|
|
33
|
+
if (typeof props.widthRange !== 'string') return
|
|
34
|
+
const [minWidth, maxWidth] = props.widthRange.split(' ')
|
|
35
|
+
return {
|
|
36
|
+
...getSpacingByKey(minWidth, 'minWidth'),
|
|
37
|
+
...getSpacingByKey(maxWidth || minWidth, 'maxWidth')
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
maxHeight: ({ props }) => props.maxHeight && getSpacingBasedOnRatio(props, 'maxHeight'),
|
|
42
|
+
minHeight: ({ props }) => props.minHeight && getSpacingBasedOnRatio(props, 'minHeight'),
|
|
43
|
+
heightRange: ({ props }) => {
|
|
44
|
+
if (typeof props.heightRange !== 'string') return
|
|
45
|
+
const [minHeight, maxHeight] = props.heightRange.split(' ')
|
|
46
|
+
return {
|
|
47
|
+
...getSpacingByKey(minHeight, 'minHeight'),
|
|
48
|
+
...getSpacingByKey(maxHeight || minHeight, 'maxHeight')
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
direction: ({ props }) => props.direction && ({ direction: props.direction }),
|
|
53
|
+
|
|
54
|
+
aspectRatio: ({ props }) => props.aspectRatio && ({ aspectRatio: props.aspectRatio }),
|
|
55
|
+
|
|
56
|
+
borderWidth: ({ props }) => props.borderWidth ? getSpacingBasedOnRatio(props, 'borderWidth') : null,
|
|
57
|
+
|
|
58
|
+
padding: ({ props }) => props.padding ? getSpacingBasedOnRatio(props, 'padding') : null,
|
|
59
|
+
paddingInline: ({ props }) => {
|
|
60
|
+
if (typeof props.paddingInline !== 'string') return
|
|
61
|
+
const [paddingInlineStart, paddingInlineEnd] = props.paddingInline.split(' ')
|
|
62
|
+
return {
|
|
63
|
+
...getSpacingByKey(paddingInlineStart, 'paddingInlineStart'),
|
|
64
|
+
...getSpacingByKey(paddingInlineEnd || paddingInlineStart, 'paddingInlineEnd')
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
paddingBlock: ({ props }) => {
|
|
68
|
+
if (typeof props.paddingBlock !== 'string') return
|
|
69
|
+
const [paddingBlockStart, paddingBlockEnd] = props.paddingBlock.split(' ')
|
|
70
|
+
return {
|
|
71
|
+
...getSpacingByKey(paddingBlockStart, 'paddingBlockStart'),
|
|
72
|
+
...getSpacingByKey(paddingBlockEnd || paddingBlockStart, 'paddingBlockEnd')
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
paddingInlineStart: ({ props }) => props.paddingInlineStart ? getSpacingBasedOnRatio(props, 'paddingInlineStart') : null,
|
|
76
|
+
paddingInlineEnd: ({ props }) => props.paddingInlineEnd ? getSpacingBasedOnRatio(props, 'paddingInlineEnd') : null,
|
|
77
|
+
paddingBlockStart: ({ props }) => props.paddingBlockStart ? getSpacingBasedOnRatio(props, 'paddingBlockStart') : null,
|
|
78
|
+
paddingBlockEnd: ({ props }) => props.paddingBlockEnd ? getSpacingBasedOnRatio(props, 'paddingBlockEnd') : null,
|
|
79
|
+
|
|
80
|
+
margin: ({ props }) => props.margin ? getSpacingBasedOnRatio(props, 'margin') : null,
|
|
81
|
+
marginInline: ({ props }) => {
|
|
82
|
+
if (typeof props.marginInline !== 'string') return
|
|
83
|
+
const [marginInlineStart, marginInlineEnd] = props.marginInline.split(' ')
|
|
84
|
+
return {
|
|
85
|
+
...getSpacingByKey(marginInlineStart, 'marginInlineStart'),
|
|
86
|
+
...getSpacingByKey(marginInlineEnd || marginInlineStart, 'marginInlineEnd')
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
marginBlock: ({ props }) => {
|
|
90
|
+
if (typeof props.marginBlock !== 'string') return
|
|
91
|
+
const [marginBlockStart, marginBlockEnd] = props.marginBlock.split(' ')
|
|
92
|
+
return {
|
|
93
|
+
...getSpacingByKey(marginBlockStart, 'marginBlockStart'),
|
|
94
|
+
...getSpacingByKey(marginBlockEnd || marginBlockStart, 'marginBlockEnd')
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
marginInlineStart: ({ props }) => props.marginInlineStart ? getSpacingBasedOnRatio(props, 'marginInlineStart') : null,
|
|
98
|
+
marginInlineEnd: ({ props }) => props.marginInlineEnd ? getSpacingBasedOnRatio(props, 'marginInlineEnd') : null,
|
|
99
|
+
marginBlockStart: ({ props }) => props.marginBlockStart ? getSpacingBasedOnRatio(props, 'marginBlockStart') : null,
|
|
100
|
+
marginBlockEnd: ({ props }) => props.marginBlockEnd ? getSpacingBasedOnRatio(props, 'marginBlockEnd') : null,
|
|
101
|
+
|
|
102
|
+
gap: ({ props }) => props.gap ? transfromGap(props.gap) : null,
|
|
103
|
+
gridArea: ({ props }) => props.gridArea && ({ gridArea: props.gridArea }),
|
|
104
|
+
|
|
105
|
+
flex: ({ props }) => props.flex && ({ flex: props.flex }),
|
|
106
|
+
flexDirection: ({ props }) => props.flexDirection && ({ flexDirection: props.flexDirection }),
|
|
107
|
+
alignItems: ({ props }) => props.alignItems && ({ alignItems: props.alignItems }),
|
|
108
|
+
alignContent: ({ props }) => props.alignContent && ({ alignContent: props.alignContent }),
|
|
109
|
+
justifyContent: ({ props }) => props.justifyContent && ({ justifyContent: props.justifyContent }),
|
|
110
|
+
justifyItems: ({ props }) => props.justifyItems && ({ justifyItems: props.justifyItems }),
|
|
111
|
+
alignSelf: ({ props }) => props.alignSelf && ({ alignSelf: props.alignSelf }),
|
|
112
|
+
order: ({ props }) => props.order && ({ order: props.order }),
|
|
113
|
+
|
|
114
|
+
flexWrap: ({ props }) => props.flexWrap && ({
|
|
115
|
+
display: 'flex',
|
|
116
|
+
flexFlow: props.flexWrap
|
|
117
|
+
}),
|
|
118
|
+
flexFlow: ({ props }) => props.flexFlow && ({
|
|
119
|
+
display: 'flex',
|
|
120
|
+
flexFlow: props.flexFlow
|
|
121
|
+
}),
|
|
122
|
+
flexAlign: ({ props }) => {
|
|
123
|
+
if (typeof props.flexAlign !== 'string') return
|
|
124
|
+
const [alignItems, justifyContent] = props.flexAlign.split(' ')
|
|
125
|
+
return {
|
|
126
|
+
display: 'flex',
|
|
127
|
+
alignItems: alignItems,
|
|
128
|
+
justifyContent: justifyContent
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
gridColumn: ({ props }) => props.gridColumn && ({ gridColumn: props.gridColumn }),
|
|
133
|
+
gridColumnStart: ({ props }) => props.columnStart ? ({ gridColumnStart: props.columnStart }) : null,
|
|
134
|
+
gridRow: ({ props }) => props.gridRow && ({ gridRow: props.gridRow }),
|
|
135
|
+
gridRowStart: ({ props }) => props.rowStart ? ({ gridRowStart: props.rowStart }) : null,
|
|
136
|
+
|
|
137
|
+
size: ({ props }) => {
|
|
138
|
+
if (typeof props.heightRange !== 'string') return
|
|
139
|
+
const [minHeight, maxHeight] = props.heightRange.split(' ')
|
|
140
|
+
return {
|
|
141
|
+
...getSpacingByKey(minHeight, 'minHeight'),
|
|
142
|
+
...getSpacingByKey(maxHeight || minHeight, 'maxHeight')
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
columns: ({ props }) => props.columns && ({ columns: props.columns })
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const Span = { tag: 'span' }
|
|
151
|
+
// export const Article = { tag: 'article' }
|
package/Direction.js
ADDED
package/Flex.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
export const Flex = {
|
|
4
|
+
props: {
|
|
5
|
+
display: 'flex'
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
class: {
|
|
9
|
+
flow: ({ props }) => props.flow && ({ flexFlow: props.flow }),
|
|
10
|
+
wrap: ({ props }) => props.wrap && ({ flexWrap: props.wrap }),
|
|
11
|
+
align: ({ props }) => {
|
|
12
|
+
if (typeof props.align !== 'string') return
|
|
13
|
+
const [alignItems, justifyContent] = props.align.split(' ')
|
|
14
|
+
return { alignItems, justifyContent }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
package/Form.js
ADDED
package/Grid.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getSpacingBasedOnRatio } from '@symbo.ls/scratch'
|
|
4
|
+
|
|
5
|
+
export const Grid = {
|
|
6
|
+
props: { display: 'grid' },
|
|
7
|
+
|
|
8
|
+
class: {
|
|
9
|
+
area: ({ props }) => props.area ? ({ gridArea: props.area }) : null,
|
|
10
|
+
template: ({ props }) => props.template ? ({ gridTemplate: props.template }) : null,
|
|
11
|
+
templateAreas: ({ props }) => props.templateAreas ? ({ gridTemplateAreas: props.templateAreas }) : null,
|
|
12
|
+
|
|
13
|
+
column: ({ props }) => props.column ? ({ gridColumn: props.column }) : null,
|
|
14
|
+
columns: ({ props }) => props.columns ? ({ gridTemplateColumns: props.columns }) : null,
|
|
15
|
+
templateColumns: ({ props }) => props.templateColumns ? ({ gridTemplateColumns: props.templateColumns }) : null,
|
|
16
|
+
autoColumns: ({ props }) => props.autoColumns ? ({ gridAutoColumns: props.autoColumns }) : null,
|
|
17
|
+
columnStart: ({ props }) => props.columnStart ? ({ gridColumnStart: props.columnStart }) : null,
|
|
18
|
+
|
|
19
|
+
row: ({ props }) => props.row ? ({ gridRow: props.row }) : null,
|
|
20
|
+
rows: ({ props }) => props.rows ? ({ gridTemplateRows: props.rows }) : null,
|
|
21
|
+
templateRows: ({ props }) => props.templateRows ? ({ gridTemplateRows: props.templateRows }) : null,
|
|
22
|
+
autoRows: ({ props }) => props.autoRows ? ({ gridAutoRows: props.autoRows }) : null,
|
|
23
|
+
rowStart: ({ props }) => props.rowStart ? ({ gridRowStart: props.rowStart }) : null,
|
|
24
|
+
|
|
25
|
+
autoFlow: ({ props }) => props.autoFlow ? ({ gridAutoFlow: props.autoFlow }) : null,
|
|
26
|
+
|
|
27
|
+
columnGap: ({ props }) => props.columnGap ? getSpacingBasedOnRatio(props, 'columnGap') : null,
|
|
28
|
+
rowGap: ({ props }) => props.rowGap ? getSpacingBasedOnRatio(props, 'rowGap') : null
|
|
29
|
+
}
|
|
30
|
+
}
|
package/Iframe.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
export const Iframe = {
|
|
4
|
+
tag: 'iframe',
|
|
5
|
+
props: {
|
|
6
|
+
position: 'relative',
|
|
7
|
+
minWidth: 'H',
|
|
8
|
+
minHeight: 'H'
|
|
9
|
+
},
|
|
10
|
+
attr: {
|
|
11
|
+
src: ({ props }) => props.src,
|
|
12
|
+
loading: ({ props }) => props.loading,
|
|
13
|
+
allowfullscreen: ({ props }) => props.allowfullscreen,
|
|
14
|
+
referrerpolicy: ({ props }) => props.referrerpolicy
|
|
15
|
+
}
|
|
16
|
+
}
|
package/Img.js
ADDED
package/Interaction.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
export const Interaction = {
|
|
4
|
+
class: {
|
|
5
|
+
userSelect: ({ props }) => props.userSelect && ({ userSelect: props.userSelect }),
|
|
6
|
+
pointerEvents: ({ props }) => props.pointerEvents && ({ pointerEvents: props.pointerEvents }),
|
|
7
|
+
cursor: ({ props }) => props.cursor && ({ cursor: props.cursor })
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const style = {
|
|
4
|
+
appearance: 'none',
|
|
5
|
+
border: 'none',
|
|
6
|
+
cursor: 'pointer',
|
|
7
|
+
fontFamily: 'inherit'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const Hoverable = {
|
|
11
|
+
props: {
|
|
12
|
+
transition: 'C defaultBezier',
|
|
13
|
+
transitionProperty: 'opacity, transform',
|
|
14
|
+
opacity: 0.85,
|
|
15
|
+
|
|
16
|
+
':hover': {
|
|
17
|
+
opacity: 0.9,
|
|
18
|
+
transform: 'scale(1.015)'
|
|
19
|
+
},
|
|
20
|
+
':active': {
|
|
21
|
+
opacity: 1,
|
|
22
|
+
transform: 'scale(1.015)'
|
|
23
|
+
},
|
|
24
|
+
'.active': {
|
|
25
|
+
opacity: 1,
|
|
26
|
+
transform: 'scale(1.015)',
|
|
27
|
+
|
|
28
|
+
':hover': { opacity: 1 }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const Clickable = {
|
|
34
|
+
extend: Hoverable,
|
|
35
|
+
props: {
|
|
36
|
+
':active': {
|
|
37
|
+
opacity: 1,
|
|
38
|
+
transform: 'scale(1.015)'
|
|
39
|
+
},
|
|
40
|
+
'.active': {
|
|
41
|
+
opacity: 1
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const Focusable = {
|
|
47
|
+
props: {
|
|
48
|
+
border: 'none',
|
|
49
|
+
outline: 'solid, 0, blue .3',
|
|
50
|
+
':focus-visible': {
|
|
51
|
+
opacity: 1,
|
|
52
|
+
outline: 'solid, X, blue .3'
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
attr: {
|
|
57
|
+
placeholder: ({ props }) => props.placeholder,
|
|
58
|
+
tabIndex: ({ props }) => props.tabIndex
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const FocusableComponent = {
|
|
63
|
+
extend: Focusable,
|
|
64
|
+
tag: 'button',
|
|
65
|
+
props: {
|
|
66
|
+
fontSize: 'A',
|
|
67
|
+
type: 'button',
|
|
68
|
+
border: 'none',
|
|
69
|
+
textDecoration: 'none',
|
|
70
|
+
lineHeight: '1',
|
|
71
|
+
whiteSpace: 'nowrap',
|
|
72
|
+
fontFamily: 'inherit',
|
|
73
|
+
style
|
|
74
|
+
},
|
|
75
|
+
attr: {
|
|
76
|
+
type: ({ props }) => props.type
|
|
77
|
+
}
|
|
78
|
+
}
|
package/Media.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { merge, isArray } from '@domql/utils'
|
|
4
|
+
import { getSystemTheme } from './Theme'
|
|
5
|
+
|
|
6
|
+
const keySetters = {
|
|
7
|
+
'@': (key, props, result, element, isSubtree) => applyMediaProps(key, props, isSubtree ? result : result.media, element),
|
|
8
|
+
':': (key, props, result, element, isSubtree) => applySelectorProps(key, props, isSubtree ? result : result.selector, element),
|
|
9
|
+
'[': (key, props, result, element, isSubtree) => applySelectorProps(key, props, isSubtree ? result : result.selector, element),
|
|
10
|
+
'&': (key, props, result, element, isSubtree) => applySelectorProps(key, props, isSubtree ? result : result.selector, element),
|
|
11
|
+
$: (key, props, result, element, isSubtree) => applyCaseProps(key, props, isSubtree ? result : result.case, element),
|
|
12
|
+
'.': (key, props, result, element, isSubtree) => applyConditionalCaseProps(key, props, isSubtree ? result : result.case, element),
|
|
13
|
+
'!': (key, props, result, element, isSubtree) => applyConditionalFalsyProps(key, props, isSubtree ? result : result.case, element)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const execClass = (key, props, result, element) => {
|
|
17
|
+
const { class: className } = element
|
|
18
|
+
const classnameExec = className[key]
|
|
19
|
+
|
|
20
|
+
if (typeof classnameExec !== 'function') return
|
|
21
|
+
|
|
22
|
+
let classExec = classnameExec({
|
|
23
|
+
props,
|
|
24
|
+
context: element.context,
|
|
25
|
+
state: element.state
|
|
26
|
+
})
|
|
27
|
+
if (isArray(classExec)) {
|
|
28
|
+
classExec = classExec.reduce((a, c) => merge(a, c), {})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
for (const finalProp in classExec) {
|
|
32
|
+
result[finalProp] = classExec[finalProp]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return classExec
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const convertPropsToClass = (props, result, element) => {
|
|
39
|
+
const propsClassObj = {}
|
|
40
|
+
|
|
41
|
+
for (const key in props) {
|
|
42
|
+
const setter = keySetters[key.slice(0, 1)]
|
|
43
|
+
if (setter) {
|
|
44
|
+
setter(key, props[key], propsClassObj, element, true)
|
|
45
|
+
continue
|
|
46
|
+
} else {
|
|
47
|
+
execClass(key, props, propsClassObj, element)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return propsClassObj
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const applyMediaProps = (key, props, result, element) => {
|
|
55
|
+
const { context } = element
|
|
56
|
+
if (!context.system || !context.system.MEDIA) return
|
|
57
|
+
const globalTheme = getSystemTheme(element)
|
|
58
|
+
const { MEDIA } = context.system
|
|
59
|
+
const mediaName = MEDIA[key.slice(1)]
|
|
60
|
+
const generatedClass = convertPropsToClass(props, result, element)
|
|
61
|
+
|
|
62
|
+
const name = key.slice(1)
|
|
63
|
+
const isTheme = ['dark', 'light'].includes(name)
|
|
64
|
+
const matchesGlobal = name === globalTheme
|
|
65
|
+
|
|
66
|
+
if (globalTheme && isTheme) {
|
|
67
|
+
if (matchesGlobal) return merge(result, generatedClass)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const mediaKey = `@media screen and ${mediaName}`
|
|
72
|
+
result[mediaKey] = generatedClass
|
|
73
|
+
return result[mediaKey]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const applySelectorProps = (key, props, result, element) => {
|
|
77
|
+
const selectorKey = `&${key}`
|
|
78
|
+
result[selectorKey] = convertPropsToClass(props, result, element)
|
|
79
|
+
return result[selectorKey]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const applyCaseProps = (key, props, result, element) => {
|
|
83
|
+
const { CASES } = element.context && element.context.system
|
|
84
|
+
const caseKey = key.slice(1)
|
|
85
|
+
const isPropTrue = element.props[caseKey]
|
|
86
|
+
if (!CASES[caseKey] && !isPropTrue) return
|
|
87
|
+
return merge(result, convertPropsToClass(props, result, element))
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const applyConditionalCaseProps = (key, props, result, element) => {
|
|
91
|
+
const caseKey = key.slice(1)
|
|
92
|
+
const isPropTrue = element.props[caseKey] || element.state[caseKey] === true
|
|
93
|
+
if (!isPropTrue) return // remove classname if not here
|
|
94
|
+
return merge(result, convertPropsToClass(props, result, element))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const applyConditionalFalsyProps = (key, props, result, element) => {
|
|
98
|
+
const caseKey = key.slice(1)
|
|
99
|
+
const isPropTrue = element.props[caseKey] || element.state[caseKey] === true
|
|
100
|
+
if (!isPropTrue) return merge(result, convertPropsToClass(props, result, element))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const applyTrueProps = (props, result, element) => merge(result, convertPropsToClass(props, result, element))
|
|
104
|
+
|
|
105
|
+
const beforeClassAssign = (element, s) => {
|
|
106
|
+
const { props, class: className } = element
|
|
107
|
+
|
|
108
|
+
const CLASS_NAMES = {
|
|
109
|
+
media: {},
|
|
110
|
+
selector: {},
|
|
111
|
+
case: {}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
for (const key in props) {
|
|
115
|
+
const setter = keySetters[key.slice(0, 1)]
|
|
116
|
+
if (setter) setter(key, props[key], CLASS_NAMES, element)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
merge(className, CLASS_NAMES)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const initUpdate = element => {
|
|
123
|
+
const { props, class: className } = element
|
|
124
|
+
const globalTheme = getSystemTheme(element)
|
|
125
|
+
|
|
126
|
+
const parentProps = element.parent.props
|
|
127
|
+
if (parentProps && parentProps.spacingRatio && parentProps.inheritSpacingRatio) {
|
|
128
|
+
element.setProps({
|
|
129
|
+
spacingRatio: parentProps.spacingRatio,
|
|
130
|
+
inheritSpacingRatio: true
|
|
131
|
+
}, {
|
|
132
|
+
preventRecursive: true,
|
|
133
|
+
ignoreInitUpdate: true
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (globalTheme) {
|
|
138
|
+
const CLASS_NAMES = {
|
|
139
|
+
media: {},
|
|
140
|
+
selector: {},
|
|
141
|
+
case: {}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const key in props) {
|
|
145
|
+
const setter = keySetters[key.slice(0, 1)]
|
|
146
|
+
if (key === 'theme') {
|
|
147
|
+
props.update({
|
|
148
|
+
themeModifier: globalTheme
|
|
149
|
+
}, { preventRecursive: true, ignoreInitUpdate: true, preventDefineUpdate: '$setStateCollection' })
|
|
150
|
+
} else if (key === 'true') applyTrueProps(props[key], CLASS_NAMES, element)
|
|
151
|
+
if (setter) setter(key, props[key], CLASS_NAMES, element)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (Object.keys(CLASS_NAMES.media).length) {
|
|
155
|
+
className.media = CLASS_NAMES.media
|
|
156
|
+
}
|
|
157
|
+
className.selector = CLASS_NAMES.selector
|
|
158
|
+
className.case = CLASS_NAMES.case
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const Media = {
|
|
163
|
+
on: { beforeClassAssign, initUpdate }
|
|
164
|
+
}
|
package/Overflow.js
ADDED
package/Picture.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getSystemTheme } from './Theme'
|
|
4
|
+
|
|
5
|
+
export const Picture = {
|
|
6
|
+
tag: 'picture',
|
|
7
|
+
|
|
8
|
+
childExtend: {
|
|
9
|
+
tag: 'source',
|
|
10
|
+
attr: {
|
|
11
|
+
media: element => {
|
|
12
|
+
const { props, key, context } = element
|
|
13
|
+
const { MEDIA } = context.system
|
|
14
|
+
const globalTheme = getSystemTheme(element)
|
|
15
|
+
const mediaName = (props.media || key).slice(1)
|
|
16
|
+
|
|
17
|
+
if (mediaName === globalTheme) return '(min-width: 0px)'
|
|
18
|
+
else if (mediaName === 'dark' || mediaName === 'light') return '(max-width: 0px)'
|
|
19
|
+
|
|
20
|
+
return MEDIA[mediaName]
|
|
21
|
+
},
|
|
22
|
+
srcset: ({ props }) => props.srcset
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// Img: ({ props }) => ({
|
|
27
|
+
// width: 'inherit',
|
|
28
|
+
// height: 'inherit',
|
|
29
|
+
// src: props.src
|
|
30
|
+
// })
|
|
31
|
+
}
|
package/Position.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getSpacingByKey } from '@symbo.ls/scratch'
|
|
4
|
+
|
|
5
|
+
export const Position = {
|
|
6
|
+
props: {},
|
|
7
|
+
|
|
8
|
+
class: {
|
|
9
|
+
position: ({ props }) => props.position && ({ position: props.position }),
|
|
10
|
+
inset: ({ props }) => {
|
|
11
|
+
const { inset } = props
|
|
12
|
+
if (typeof inset !== 'string') return
|
|
13
|
+
return { inset: inset.split(' ').map(v => getSpacingByKey(v, 'k').k).join(' ') }
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
left: ({ props }) => getSpacingByKey(props.left, 'left'),
|
|
17
|
+
top: ({ props }) => getSpacingByKey(props.top, 'top'),
|
|
18
|
+
right: ({ props }) => getSpacingByKey(props.right, 'right'),
|
|
19
|
+
bottom: ({ props }) => getSpacingByKey(props.bottom, 'bottom')
|
|
20
|
+
}
|
|
21
|
+
}
|
package/Pseudo.js
ADDED
package/SVG.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const useSVGSymbol = file => `<use xlink:href="${file}" />`
|
|
4
|
+
|
|
5
|
+
// create SVG symbol
|
|
6
|
+
export const SVG = {
|
|
7
|
+
tag: 'svg',
|
|
8
|
+
props: {
|
|
9
|
+
style: { '*': { fill: 'currentColor' } }
|
|
10
|
+
},
|
|
11
|
+
attr: {
|
|
12
|
+
xmlns: 'http://www.w3.org/2000/svg',
|
|
13
|
+
'xmlns:xlink': 'http://www.w3.org/1999/xlink'
|
|
14
|
+
},
|
|
15
|
+
html: ({ key, props }) => useSVGSymbol(props.src)
|
|
16
|
+
}
|
package/Shape/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { exec, isString } from '@domql/utils'
|
|
4
|
+
import { SHAPES } from './style'
|
|
5
|
+
import { getSpacingBasedOnRatio, getMediaColor } from '@symbo.ls/scratch'
|
|
6
|
+
import { Pseudo } from '../Pseudo'
|
|
7
|
+
|
|
8
|
+
const transformBorderRadius = (radius, props, propertyName) => {
|
|
9
|
+
if (!isString(radius)) return
|
|
10
|
+
return {
|
|
11
|
+
borderRadius: radius.split(' ').map((v, k) => getSpacingBasedOnRatio(props, propertyName, v)[propertyName]).join(' ')
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const Shape = {
|
|
16
|
+
extend: Pseudo,
|
|
17
|
+
|
|
18
|
+
class: {
|
|
19
|
+
shape: (element) => {
|
|
20
|
+
const { props } = element
|
|
21
|
+
const { shape } = props
|
|
22
|
+
return shape ? exec(SHAPES[shape], element) : null
|
|
23
|
+
},
|
|
24
|
+
shapeDirection: ({ props }) => {
|
|
25
|
+
const { shape, shapeDirection } = props
|
|
26
|
+
if (!shape || !shapeDirection) return
|
|
27
|
+
const shapeDir = SHAPES[shape + 'Direction']
|
|
28
|
+
return shape && shapeDir ? shapeDir[shapeDirection || 'left'] : null
|
|
29
|
+
},
|
|
30
|
+
shapeDirectionColor: el => {
|
|
31
|
+
const { props } = el
|
|
32
|
+
const { background, backgroundColor } = props
|
|
33
|
+
const borderColor = getMediaColor(background || backgroundColor, 'borderColor')
|
|
34
|
+
return props.shapeDirection ? borderColor : null
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
round: ({ props, key, ...el }) => transformBorderRadius(props.round || props.borderRadius, props, 'round'),
|
|
38
|
+
borderRadius: ({ props, key, ...el }) => transformBorderRadius(props.borderRadius || props.round, props, 'borderRadius')
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default Shape
|
package/Shape/style.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { UNIT, getColor, getTheme } from '@symbo.ls/scratch' // eslint-disable-line no-unused-vars
|
|
4
|
+
import { Timing } from '../Timing'
|
|
5
|
+
|
|
6
|
+
export const depth = {
|
|
7
|
+
4: { boxShadow: `rgba(0,0,0,.10) 0 2${UNIT.default} 4${UNIT.default}` },
|
|
8
|
+
6: { boxShadow: `rgba(0,0,0,.10) 0 3${UNIT.default} 6${UNIT.default}` },
|
|
9
|
+
10: { boxShadow: `rgba(0,0,0,.10) 0 4${UNIT.default} 10${UNIT.default}` },
|
|
10
|
+
16: { boxShadow: `rgba(0,0,0,.10) 0 8${UNIT.default} 16${UNIT.default}` },
|
|
11
|
+
26: { boxShadow: `rgba(0,0,0,.10) 0 14${UNIT.default} 26${UNIT.default}` },
|
|
12
|
+
42: { boxShadow: `rgba(0,0,0,.10) 0 20${UNIT.default} 42${UNIT.default}` }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const getComputedBackgroundColor = ({ props }) => {
|
|
16
|
+
return getColor(props.borderColor) || getColor(props.backgroundColor) || getColor(props.background)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const inheritTransition = (el) => {
|
|
20
|
+
const exec = Timing.class.transition(el)
|
|
21
|
+
return exec && exec['transition']
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const SHAPES = {
|
|
25
|
+
rectangle: {},
|
|
26
|
+
circle: { borderRadius: '100%' },
|
|
27
|
+
bubble: {},
|
|
28
|
+
tv: {
|
|
29
|
+
borderRadius: '1.15em/2.5em'
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
tooltip: el => ({
|
|
33
|
+
position: el.props.position || 'relative',
|
|
34
|
+
'&:before': {
|
|
35
|
+
content: '""',
|
|
36
|
+
display: 'block',
|
|
37
|
+
width: '0px',
|
|
38
|
+
height: '0px',
|
|
39
|
+
border: `.35em solid`,
|
|
40
|
+
borderColor: getComputedBackgroundColor(el),
|
|
41
|
+
transition: inheritTransition(el),
|
|
42
|
+
transitionProperty: 'border-color',
|
|
43
|
+
position: 'absolute',
|
|
44
|
+
borderRadius: '.15em'
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
47
|
+
|
|
48
|
+
tooltipDirection: {
|
|
49
|
+
top: {
|
|
50
|
+
'&:before': {
|
|
51
|
+
top: '0',
|
|
52
|
+
left: '50%',
|
|
53
|
+
transform: 'translate(-50%, -50%) rotate(45deg)'
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
right: {
|
|
57
|
+
'&:before': {
|
|
58
|
+
top: '50%',
|
|
59
|
+
right: '0',
|
|
60
|
+
transform: 'translate(50%, -50%) rotate(45deg)'
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
bottom: {
|
|
64
|
+
'&:before': {
|
|
65
|
+
bottom: '0',
|
|
66
|
+
left: '50%',
|
|
67
|
+
transform: 'translate(-50%, 50%) rotate(45deg)'
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
left: {
|
|
71
|
+
'&:before': {
|
|
72
|
+
top: '50%',
|
|
73
|
+
left: '0',
|
|
74
|
+
transform: 'translate(-50%, -50%) rotate(45deg)'
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
tag: el => ({
|
|
80
|
+
position: 'relative',
|
|
81
|
+
'&:before': {
|
|
82
|
+
content: '""',
|
|
83
|
+
display: 'block',
|
|
84
|
+
background: getComputedBackgroundColor(el),
|
|
85
|
+
transition: inheritTransition(el),
|
|
86
|
+
transitionProperty: 'background',
|
|
87
|
+
borderRadius: '.25em',
|
|
88
|
+
position: 'absolute',
|
|
89
|
+
zIndex: '-1',
|
|
90
|
+
aspectRatio: '1/1',
|
|
91
|
+
top: '50%',
|
|
92
|
+
transformOrigin: '50% 50%',
|
|
93
|
+
height: '73%'
|
|
94
|
+
}
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
tagDirection: {
|
|
98
|
+
top: {
|
|
99
|
+
'&:before': {
|
|
100
|
+
bottom: '100%',
|
|
101
|
+
left: '50%',
|
|
102
|
+
transform: 'translate(-50%, 50%) rotate(45deg)'
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
right: {
|
|
106
|
+
'&:before': {
|
|
107
|
+
top: '50%',
|
|
108
|
+
left: '100%',
|
|
109
|
+
transform: 'translate(-50%, -50%) rotate(45deg)'
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
bottom: {
|
|
113
|
+
'&:before': {
|
|
114
|
+
top: '100%',
|
|
115
|
+
left: '50%',
|
|
116
|
+
transform: 'translate(-50%, -50%) rotate(45deg)'
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
left: {
|
|
120
|
+
'&:before': {
|
|
121
|
+
top: '50%',
|
|
122
|
+
right: '100%',
|
|
123
|
+
transform: 'translate(50%, -50%) rotate(45deg)'
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
hexagon: el => ({
|
|
129
|
+
position: 'relative',
|
|
130
|
+
'&:before, &:after': {
|
|
131
|
+
content: '""',
|
|
132
|
+
display: 'block',
|
|
133
|
+
position: 'absolute',
|
|
134
|
+
zIndex: '-1',
|
|
135
|
+
borderRadius: '.25em',
|
|
136
|
+
aspectRatio: '1/1',
|
|
137
|
+
top: '50%',
|
|
138
|
+
transformOrigin: '50% 50%',
|
|
139
|
+
height: '73%',
|
|
140
|
+
background: getComputedBackgroundColor(el),
|
|
141
|
+
transition: inheritTransition(el),
|
|
142
|
+
transitionProperty: 'background'
|
|
143
|
+
},
|
|
144
|
+
'&:before': {
|
|
145
|
+
left: '0',
|
|
146
|
+
transform: 'translate3d(-50%, -50%, 1px) rotate(45deg)'
|
|
147
|
+
},
|
|
148
|
+
'&:after': {
|
|
149
|
+
left: '100%',
|
|
150
|
+
transform: 'translate3d(-50%, -50%, 1px) rotate(45deg)'
|
|
151
|
+
}
|
|
152
|
+
}),
|
|
153
|
+
|
|
154
|
+
chevron: el => ({
|
|
155
|
+
position: 'relative',
|
|
156
|
+
// overflow: 'hidden',
|
|
157
|
+
'&:before, &:after': {
|
|
158
|
+
content: '""',
|
|
159
|
+
display: 'block',
|
|
160
|
+
position: 'absolute',
|
|
161
|
+
zIndex: '-1',
|
|
162
|
+
aspectRatio: '1/1',
|
|
163
|
+
top: '50%',
|
|
164
|
+
transformOrigin: '50% 50%',
|
|
165
|
+
transition: inheritTransition(el),
|
|
166
|
+
transitionProperty: 'background'
|
|
167
|
+
|
|
168
|
+
},
|
|
169
|
+
'&:before': {
|
|
170
|
+
background: `linear-gradient(225deg, ${getComputedBackgroundColor(el)} 25%, transparent 25%), linear-gradient(315deg, ${getComputedBackgroundColor(el)} 25%, transparent 25%)`
|
|
171
|
+
},
|
|
172
|
+
'&:after': {
|
|
173
|
+
background: getComputedBackgroundColor(el),
|
|
174
|
+
borderRadius: '.25em'
|
|
175
|
+
}
|
|
176
|
+
}),
|
|
177
|
+
|
|
178
|
+
chevronDirection: {
|
|
179
|
+
left: {
|
|
180
|
+
'&:before': {
|
|
181
|
+
height: '100%',
|
|
182
|
+
left: '100%',
|
|
183
|
+
transform: 'translate3d(-1%, -50%, 1px) scale(-1, 1)'
|
|
184
|
+
},
|
|
185
|
+
'&:after': {
|
|
186
|
+
height: '73%',
|
|
187
|
+
left: '0',
|
|
188
|
+
transform: 'translate3d(-50%, -50%, 1px) rotate(45deg)'
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
right: {
|
|
192
|
+
'&:before': {
|
|
193
|
+
height: '100%',
|
|
194
|
+
left: '0',
|
|
195
|
+
transform: 'translate3d(-99%, -50%, 1px)'
|
|
196
|
+
},
|
|
197
|
+
'&:after': {
|
|
198
|
+
height: '73%',
|
|
199
|
+
left: '100%',
|
|
200
|
+
transform: 'translate3d(-50%, -50%, 1px) rotate(45deg)'
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
package/Text.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getFontSizeByKey, getFontFamily } from '@symbo.ls/scratch'
|
|
4
|
+
|
|
5
|
+
export const Text = {
|
|
6
|
+
text: ({ key, props, state }) => {
|
|
7
|
+
if (props.text === true) return (state && state[key]) || (props && props[key])
|
|
8
|
+
return props.text
|
|
9
|
+
},
|
|
10
|
+
class: {
|
|
11
|
+
fontSize: ({ props }) => props.fontSize ? getFontSizeByKey(props.fontSize) : null,
|
|
12
|
+
fontFamily: ({ props }) => props.fontFamily && ({ fontFamily: getFontFamily(props.fontFamily) || props.fontFamily }),
|
|
13
|
+
lineHeight: ({ props }) => props.lineHeight && ({ lineHeight: props.lineHeight }),
|
|
14
|
+
// lineHeight: ({ props }) => props.lineHeight && getSpacingBasedOnRatio(props, 'lineHeight', null, ''),
|
|
15
|
+
textDecoration: ({ props }) => props.textDecoration && ({ textDecoration: props.textDecoration }),
|
|
16
|
+
textTransform: ({ props }) => props.textTransform && ({ textTransform: props.textTransform }),
|
|
17
|
+
whiteSpace: ({ props }) => props.whiteSpace && ({ whiteSpace: props.whiteSpace }),
|
|
18
|
+
letterSpacing: ({ props }) => props.letterSpacing && ({ letterSpacing: props.letterSpacing }),
|
|
19
|
+
textAlign: ({ props }) => props.textAlign && ({ textAlign: props.textAlign }),
|
|
20
|
+
fontWeight: ({ props }) => props.fontWeight && ({
|
|
21
|
+
fontWeight: props.fontWeight,
|
|
22
|
+
fontVariationSettings: '"wght" ' + props.fontWeight
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const H1 = { tag: 'h1' }
|
|
28
|
+
export const H2 = { tag: 'h2' }
|
|
29
|
+
export const H3 = { tag: 'h3' }
|
|
30
|
+
export const H4 = { tag: 'h4' }
|
|
31
|
+
export const H5 = { tag: 'h5' }
|
|
32
|
+
export const H6 = { tag: 'h6' }
|
|
33
|
+
export const P = { tag: 'p' }
|
|
34
|
+
export const Caption = { tag: 'caption' }
|
|
35
|
+
export const Strong = {
|
|
36
|
+
tag: 'strong',
|
|
37
|
+
props: { fontWeight: '700' }
|
|
38
|
+
}
|
|
39
|
+
export const Underline = { tag: 'u' }
|
|
40
|
+
export const Italic = { tag: 'i' }
|
package/Theme.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getSpacingByKey, getMediaTheme, getColor, getMediaColor } from '@symbo.ls/scratch'
|
|
4
|
+
|
|
5
|
+
import { depth } from './Shape/style'
|
|
6
|
+
|
|
7
|
+
const isBorderStyle = str =>
|
|
8
|
+
['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset', 'initial'].some(v => str.includes(v))
|
|
9
|
+
|
|
10
|
+
const transformBorder = border => {
|
|
11
|
+
const arr = border.split(', ')
|
|
12
|
+
return arr.map(v => {
|
|
13
|
+
v = v.trim()
|
|
14
|
+
if (v.slice(0, 2) === '--') return `var(${v})`
|
|
15
|
+
else if (isBorderStyle(v)) return v || 'solid'
|
|
16
|
+
else if (v.slice(-2) === 'px' || v.slice(-2) === 'em') return v // TODO: add map spacing
|
|
17
|
+
else if (getColor(v).length > 2) return getColor(v)
|
|
18
|
+
return getSpacingByKey(v, 'border').border
|
|
19
|
+
}).join(' ')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const transformTextStroke = stroke => ({
|
|
23
|
+
WebkitTextStroke: stroke.split(', ').map(v => {
|
|
24
|
+
if (v.slice(0, 2) === '--') return `var(${v})`
|
|
25
|
+
if (v.includes('px')) return v
|
|
26
|
+
else if (getColor(v)) return getColor(v)
|
|
27
|
+
}).join(' ')
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
export const transformShadow = shadows => shadows.split('|').map(shadow => {
|
|
31
|
+
return shadow.split(', ').map(v => {
|
|
32
|
+
v = v.trim()
|
|
33
|
+
if (v.slice(0, 2) === '--') return `var(${v})`
|
|
34
|
+
if (getColor(v).length > 2) return getColor(v)
|
|
35
|
+
if (v.includes('px') || v.slice(-2) === 'em') return v
|
|
36
|
+
const arr = v.split(' ')
|
|
37
|
+
if (!arr.length) return v
|
|
38
|
+
return arr.map(v => getSpacingByKey(v, 'shadow').shadow).join(' ')
|
|
39
|
+
}).join(' ')
|
|
40
|
+
}).join(',')
|
|
41
|
+
|
|
42
|
+
const transformBackgroundImage = (backgroundImage, ctx, globalTheme) => ({
|
|
43
|
+
backgroundImage: backgroundImage.split(', ').map(v => {
|
|
44
|
+
if (v.slice(0, 2) === '--') return `var(${v})`
|
|
45
|
+
if (v.includes('url') || v.includes('gradient')) return v
|
|
46
|
+
else if (ctx.system.GRADIENT[backgroundImage]) {
|
|
47
|
+
return getMediaColor(backgroundImage, 'backgroundImage', globalTheme)
|
|
48
|
+
}
|
|
49
|
+
return `url(${v})`
|
|
50
|
+
}).join(' ')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
export const getSystemTheme = (element, state) => {
|
|
54
|
+
const { context } = element
|
|
55
|
+
const rootState = element.__root ? element.__root.state : element.state
|
|
56
|
+
return rootState.globalTheme || context.system.globalTheme
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const Theme = {
|
|
60
|
+
class: {
|
|
61
|
+
depth: ({ props }) => depth[props.depth],
|
|
62
|
+
|
|
63
|
+
theme: (element) => {
|
|
64
|
+
const { props } = element
|
|
65
|
+
const globalTheme = getSystemTheme(element)
|
|
66
|
+
if (!props.theme) return
|
|
67
|
+
return getMediaTheme(props.theme, `@${props.themeModifier || globalTheme}`)
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
color: (element) => {
|
|
71
|
+
const { props } = element
|
|
72
|
+
const globalTheme = getSystemTheme(element)
|
|
73
|
+
if (!props.color) return
|
|
74
|
+
return getMediaColor(props.color, 'color', globalTheme)
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
background: (element) => {
|
|
78
|
+
const { props } = element
|
|
79
|
+
const globalTheme = getSystemTheme(element)
|
|
80
|
+
if (!props.background) return
|
|
81
|
+
return getMediaColor(props.background, 'background', globalTheme)
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
backgroundColor: (element) => {
|
|
85
|
+
const { props } = element
|
|
86
|
+
const globalTheme = getSystemTheme(element)
|
|
87
|
+
if (!props.backgroundColor) return
|
|
88
|
+
return getMediaColor(props.backgroundColor, 'backgroundColor', globalTheme)
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
backgroundImage: (element) => {
|
|
92
|
+
const { props, context } = element
|
|
93
|
+
const globalTheme = getSystemTheme(element)
|
|
94
|
+
if (!props.backgroundImage) return
|
|
95
|
+
return transformBackgroundImage(props.backgroundImage, context, globalTheme)
|
|
96
|
+
},
|
|
97
|
+
backgroundSize: ({ props }) => props.backgroundSize ? ({ backgroundSize: props.backgroundSize }) : null,
|
|
98
|
+
backgroundPosition: ({ props }) => props.backgroundPosition ? ({ backgroundPosition: props.backgroundPosition }) : null,
|
|
99
|
+
|
|
100
|
+
textStroke: ({ props }) => props.textStroke ? transformTextStroke(props.textStroke) : null,
|
|
101
|
+
|
|
102
|
+
outline: ({ props }) => props.outline && ({
|
|
103
|
+
outline: transformBorder(props.outline)
|
|
104
|
+
}),
|
|
105
|
+
|
|
106
|
+
border: ({ props }) => props.border && ({
|
|
107
|
+
border: transformBorder(props.border)
|
|
108
|
+
}),
|
|
109
|
+
borderColor: ({ props }) => (props.borderColor) && getMediaColor(props.borderColor, 'borderColor'),
|
|
110
|
+
borderStyle: ({ props }) => props.borderStyle && ({ borderStyle: props.borderStyle }),
|
|
111
|
+
|
|
112
|
+
borderLeft: ({ props }) => props.borderLeft && ({
|
|
113
|
+
borderLeft: transformBorder(props.borderLeft)
|
|
114
|
+
}),
|
|
115
|
+
borderTop: ({ props }) => props.borderTop && ({
|
|
116
|
+
borderTop: transformBorder(props.borderTop)
|
|
117
|
+
}),
|
|
118
|
+
borderRight: ({ props }) => props.borderRight && ({
|
|
119
|
+
borderRight: transformBorder(props.borderRight)
|
|
120
|
+
}),
|
|
121
|
+
borderBottom: ({ props }) => props.borderBottom && ({
|
|
122
|
+
borderBottom: transformBorder(props.borderBottom)
|
|
123
|
+
}),
|
|
124
|
+
|
|
125
|
+
boxShadow: ({ props }) => props.boxShadow && ({
|
|
126
|
+
boxShadow: transformShadow(props.boxShadow)
|
|
127
|
+
}),
|
|
128
|
+
|
|
129
|
+
textShadow: ({ props }) => props.textShadow && ({
|
|
130
|
+
textShadow: transformShadow(props.textShadow)
|
|
131
|
+
}),
|
|
132
|
+
|
|
133
|
+
opacity: ({ props }) => props.opacity && ({ opacity: props.opacity }),
|
|
134
|
+
visibility: ({ props }) => props.visibility && ({ visibility: props.visibility })
|
|
135
|
+
}
|
|
136
|
+
}
|
package/Timing.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isString } from '@domql/utils'
|
|
4
|
+
import { getTimingByKey, getTimingFunction } from '@symbo.ls/scratch'
|
|
5
|
+
|
|
6
|
+
export const transformTransition = transition => {
|
|
7
|
+
const arr = transition.split(' ')
|
|
8
|
+
|
|
9
|
+
if (!arr.length) return transition
|
|
10
|
+
|
|
11
|
+
return arr.map(v => {
|
|
12
|
+
if (v.slice(0, 2) === '--') return `var(${v})`
|
|
13
|
+
if (v.length < 3 || v.includes('ms')) {
|
|
14
|
+
const mapWithSequence = getTimingByKey(v)
|
|
15
|
+
return mapWithSequence.timing || v
|
|
16
|
+
}
|
|
17
|
+
if (getTimingFunction(v)) return getTimingFunction(v)
|
|
18
|
+
return v
|
|
19
|
+
}).join(' ')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const transformDuration = (duration, props, propertyName) => {
|
|
23
|
+
if (!isString(duration)) return
|
|
24
|
+
return duration.split(',').map(v => getTimingByKey(v).timing || v).join(',')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const splitTransition = transition => {
|
|
28
|
+
const arr = transition.split(',')
|
|
29
|
+
if (!arr.length) return
|
|
30
|
+
return arr.map(transformTransition).join(',')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const Timing = {
|
|
34
|
+
class: {
|
|
35
|
+
transition: ({ props }) => props.transition && ({
|
|
36
|
+
transition: splitTransition(props.transition)
|
|
37
|
+
}),
|
|
38
|
+
willChange: ({ props }) => props.willChange && ({
|
|
39
|
+
willChange: props.willChange
|
|
40
|
+
}),
|
|
41
|
+
transitionDuration: ({ props }) => props.transitionDuration && ({
|
|
42
|
+
transitionDuration: transformDuration(props.transitionDuration)
|
|
43
|
+
}),
|
|
44
|
+
transitionDelay: ({ props }) => props.transitionDelay && ({
|
|
45
|
+
transitionDelay: transformDuration(props.transitionDelay)
|
|
46
|
+
}),
|
|
47
|
+
transitionTimingFunction: ({ props }) => props.transitionTimingFunction && ({
|
|
48
|
+
transitionTimingFunction: getTimingFunction(props.transitionTimingFunction)
|
|
49
|
+
}),
|
|
50
|
+
transitionProperty: ({ props }) => props.transitionProperty && ({
|
|
51
|
+
transitionProperty: props.transitionProperty,
|
|
52
|
+
willChange: props.transitionProperty
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
}
|
package/Transform.js
ADDED
package/XYZ.js
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
export * from './Block'
|
|
4
|
+
export * from './Direction'
|
|
5
|
+
export * from './Flex'
|
|
6
|
+
export * from './Grid'
|
|
7
|
+
export * from './Img'
|
|
8
|
+
export * from './Form'
|
|
9
|
+
export * from './Media'
|
|
10
|
+
export * from './Iframe'
|
|
11
|
+
export * from './Interaction'
|
|
12
|
+
export * from './InteractiveComponent'
|
|
13
|
+
export * from './Overflow'
|
|
14
|
+
export * from './Position'
|
|
15
|
+
export * from './Picture'
|
|
16
|
+
export * from './Pseudo'
|
|
17
|
+
export * from './SVG'
|
|
18
|
+
export * from './Shape'
|
|
19
|
+
export * from './Theme'
|
|
20
|
+
export * from './Text'
|
|
21
|
+
export * from './Timing'
|
|
22
|
+
export * from './Transform'
|
|
23
|
+
export * from './XYZ'
|
|
24
|
+
export * from './Animation'
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@symbo.ls/atoms",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"gitHead": "54fa6500c697604b3f48ba33a573545d7bff35fa",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@domql/utils": "latest",
|
|
9
|
+
"@symbo.ls/scratch": "latest",
|
|
10
|
+
"@symbo.ls/create-emotion": "latest"
|
|
11
|
+
},
|
|
12
|
+
"source": "src/index.js"
|
|
13
|
+
}
|