@symbo.ls/uikit 1.2.0 → 1.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/.babelrc.json +3 -0
- package/.eslintrc.js +16 -0
- package/README.md +1 -1
- package/components/Atoms/Animation.js +53 -0
- package/components/Atoms/Block.js +151 -0
- package/components/Atoms/Collection.js +82 -0
- package/components/Atoms/Direction.js +10 -0
- package/components/Atoms/Flex.js +17 -0
- package/components/Atoms/Form.js +11 -0
- package/components/Atoms/Grid.js +30 -0
- package/components/Atoms/Iframe.js +16 -0
- package/components/Atoms/Img.js +17 -0
- package/components/Atoms/Interaction.js +9 -0
- package/components/Atoms/InteractiveComponent.js +78 -0
- package/components/Atoms/Media.js +164 -0
- package/components/Atoms/Overflow.js +7 -0
- package/components/Atoms/Picture.js +31 -0
- package/components/Atoms/Position.js +21 -0
- package/components/Atoms/Pseudo.js +7 -0
- package/components/Atoms/SVG.js +16 -0
- package/components/Atoms/Shape/index.js +42 -0
- package/components/Atoms/Shape/style.js +204 -0
- package/components/Atoms/Text.js +40 -0
- package/components/Atoms/Theme.js +136 -0
- package/components/Atoms/Timing.js +55 -0
- package/components/Atoms/Transform.js +8 -0
- package/components/Atoms/XYZ.js +7 -0
- package/components/Atoms/index.js +25 -0
- package/components/Atoms/package.json +13 -0
- package/components/Avatar/index.js +32 -0
- package/components/Avatar/package.json +12 -0
- package/components/Avatar/style.js +19 -0
- package/components/Banner/index.js +22 -0
- package/components/Banner/package.json +12 -0
- package/components/Banner/style.js +27 -0
- package/components/Box/index.js +44 -0
- package/components/Box/package.json +10 -0
- package/components/Button/README.md +11 -0
- package/components/Button/index.js +48 -0
- package/components/Button/package.json +12 -0
- package/components/ButtonSet/index.js +10 -0
- package/components/ButtonSet/package.json +12 -0
- package/components/Datepicker/index.js +156 -0
- package/components/Datepicker/package.json +13 -0
- package/components/Datepicker/style.js +18 -0
- package/components/Dropdown/index.js +52 -0
- package/components/Dropdown/package.json +12 -0
- package/components/Field/index.js +43 -0
- package/components/Field/package.json +13 -0
- package/components/Field/style.js +30 -0
- package/components/Icon/index.js +50 -0
- package/components/Icon/package.json +11 -0
- package/components/Icon/style.js +8 -0
- package/components/IconText/index.js +16 -0
- package/components/IconText/package.json +14 -0
- package/components/Input/index.js +32 -0
- package/components/Input/package.json +11 -0
- package/components/Label/index.js +25 -0
- package/components/Label/package.json +13 -0
- package/components/Link/index.js +38 -0
- package/components/Link/package.json +12 -0
- package/components/Notification/index.js +47 -0
- package/components/Notification/package.json +16 -0
- package/components/Pills/index.js +25 -0
- package/components/Pills/package.json +11 -0
- package/components/Range/index.js +131 -0
- package/components/Range/package.json +13 -0
- package/components/Select/index.js +36 -0
- package/components/Select/package.json +11 -0
- package/components/Sidebar/index.js +24 -0
- package/components/Sidebar/package.json +12 -0
- package/components/Slider/index.js +105 -0
- package/components/Slider/package.json +13 -0
- package/components/Slider/style.js +19 -0
- package/components/TextArea/index.js +15 -0
- package/components/TextArea/package.json +11 -0
- package/components/Tooltip/index.js +37 -0
- package/components/Tooltip/package.json +11 -0
- package/components/Tooltip/style.js +12 -0
- package/lerna.json +9 -0
- package/package.json +35 -33
- package/packages/react/index.js +5 -0
- package/packages/react/package.json +16 -0
- package/packages/uikit/README.md +38 -0
- package/{index.js → packages/uikit/index.js} +0 -2
- package/packages/uikit/package.json +40 -0
- package/react/box/README.md +114 -0
- package/react/box/index.d.ts +3 -0
- package/react/box/index.js +63 -0
- package/react/box/package.json +33 -0
- package/svgSprite.config.js +7 -0
- package/watch.js +12 -0
package/.babelrc.json
ADDED
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
"extends": "standard",
|
|
3
|
+
"plugins": ["jest"],
|
|
4
|
+
"parser": "@babel/eslint-parser",
|
|
5
|
+
"env": {
|
|
6
|
+
"es6": true,
|
|
7
|
+
"browser": true,
|
|
8
|
+
"node": true,
|
|
9
|
+
"jest": true
|
|
10
|
+
},
|
|
11
|
+
overrides: [{
|
|
12
|
+
files: [ 'test/**/*.test.js' ],
|
|
13
|
+
env: { jest: true },
|
|
14
|
+
plugins: [ 'jest' ]
|
|
15
|
+
}]
|
|
16
|
+
}
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Symbols
|
|
2
2
|
|
|
3
|
-
UI Library in composition of [Scratch](https://github.com/symbo.ls/scratch) and [DOMQL](https://github.com/symbo.ls/domql)
|
|
3
|
+
UI Library in composition of [Scratch](https://github.com/symbo.ls/scratch) and [DOMQL](https://github.com/symbo.ls/domql)
|
|
4
4
|
|
|
5
5
|
Check out the [documentation page](https://docs.symbols.app/).
|
|
6
6
|
|
|
@@ -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
|
+
}
|
|
@@ -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' }
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isNot, isArray, isObject, isObjectLike, diff, deepClone } from '@domql/utils'
|
|
4
|
+
|
|
5
|
+
export const Collection = {
|
|
6
|
+
define: {
|
|
7
|
+
$setCollection: (param, el, state) => {
|
|
8
|
+
if (!param) return
|
|
9
|
+
|
|
10
|
+
let data = isArray(param) ? param : []
|
|
11
|
+
|
|
12
|
+
if (isObject(param)) {
|
|
13
|
+
for (const obj in param) { data.push(param[obj]) }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
data = data.map(item => !isObjectLike(item) ? {
|
|
17
|
+
props: { value: item }
|
|
18
|
+
} : item)
|
|
19
|
+
|
|
20
|
+
if (data.length) {
|
|
21
|
+
const t = setTimeout(() => {
|
|
22
|
+
el.set({ tag: 'fragment', ...data }, { preventDefineUpdate: '$setCollection' })
|
|
23
|
+
clearTimeout(t)
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return data
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
$setStateCollection: (param, el, state) => {
|
|
31
|
+
if (!param) return
|
|
32
|
+
if (param.parse) param = param.parse()
|
|
33
|
+
if (isNot(param)('array', 'object')) return
|
|
34
|
+
|
|
35
|
+
if (el.key === 'cnt') {
|
|
36
|
+
if (el.__stateCollectionCache) {
|
|
37
|
+
const d = diff(param, el.__stateCollectionCache) // eslint-disable-line
|
|
38
|
+
} else {
|
|
39
|
+
el.__stateCollectionCache = deepClone(param)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const obj = { tag: 'fragment' }
|
|
44
|
+
|
|
45
|
+
for (const key in param) {
|
|
46
|
+
const value = param[key]
|
|
47
|
+
obj[key] = { state: isObjectLike(value) ? value : { value } }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const set = () => {
|
|
51
|
+
el.set(obj, { preventDefineUpdate: '$setStateCollection' })
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (el.props.lazyLoad) {
|
|
55
|
+
window.requestAnimationFrame(set)
|
|
56
|
+
} else set()
|
|
57
|
+
|
|
58
|
+
return obj
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
$setPropsCollection: (param, el, state) => {
|
|
62
|
+
if (!param) return
|
|
63
|
+
if (isNot(param)('array', 'object')) return
|
|
64
|
+
|
|
65
|
+
const obj = { tag: 'fragment' }
|
|
66
|
+
for (const key in param) {
|
|
67
|
+
const value = param[key]
|
|
68
|
+
obj[key] = { props: isObjectLike(value) ? value : { value } }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const set = () => {
|
|
72
|
+
el.set(obj, { preventDefineUpdate: '$setStateCollection' })
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (el.props.lazyLoad) {
|
|
76
|
+
window.requestAnimationFrame(set)
|
|
77
|
+
} else set()
|
|
78
|
+
|
|
79
|
+
return obj
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|
+
}
|