css-in-props 0.0.2 → 0.8.30

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/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # css-in-props
2
+
3
+ UI Library in composition of [Scratch](https://github.com/smbo-ls/scratch) and [DOMQL](https://github.com/domql/domql)
4
+
5
+ [![npm version](https://badge.fury.io/js/smbls.svg)](https://badge.fury.io/js/smbls)
6
+
7
+ ### Setup
8
+
9
+ 1. Installation
10
+ ```
11
+ yarn add css-in-props
12
+ ```
13
+
14
+ 2. Import the component from Symbols
15
+ ```
16
+ import { transformClassname, transformEmotion } from 'css-in-props'
17
+ ```
18
+
19
+ 3. Use it inside your DOMQL code
20
+ ```
21
+ const Box = ({ children, ...props }) => <div className={
22
+ transformEmotion(transformClassname(props))
23
+ }>{children}</div>
24
+ ```
package/package.json CHANGED
@@ -1,19 +1,41 @@
1
1
  {
2
2
  "name": "css-in-props",
3
- "version": "0.0.2",
4
- "description": "",
5
- "main": "index.js",
3
+ "description": "Utilize props as CSS methods",
4
+ "private": false,
5
+ "author": "symbo.ls",
6
+ "version": "0.8.30",
7
+ "repository": "https://github.com/symbo-ls/smbls",
8
+ "main": "src/index.js",
9
+ "files": [
10
+ "src"
11
+ ],
12
+ "publishConfig": {
13
+ "registry": "https://registry.npmjs.org"
14
+ },
6
15
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
16
+ "prestart": "rm -rf dist .cache",
17
+ "start": "parcel index.html",
18
+ "build": "parcel build index.html --public-url .",
19
+ "deploy": "yarn build && gh-pages -d dist",
20
+ "clean": "rm yarn.lock && rm -rf node_modules && rm -rf dist && rm -rf .cache",
21
+ "reinstall": "rm yarn.lock && rm -rf node_modules/rackai && yarn",
22
+ "bump": "npx np"
8
23
  },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/symbo-ls/css-in-props.git"
24
+ "dependencies": {
25
+ "@domql/utils": "^2.2.1",
26
+ "@emotion/css": "^11.10.0",
27
+ "@symbo.ls/scratch": "^0.3.19"
12
28
  },
13
- "author": "symbo.ls",
14
- "license": "ISC",
15
- "bugs": {
16
- "url": "https://github.com/symbo-ls/css-in-props/issues"
29
+ "devDependencies": {
30
+ "@babel/core": "^7.14.6",
31
+ "babel-eslint": "^10.0.3",
32
+ "emotion": "^10.0.27",
33
+ "np": "^7.2.0",
34
+ "parcel-bundler": "^1.12.3",
35
+ "parcel-plugin-svg-sprite": "^1.4.1",
36
+ "standard": "^13.1.0"
17
37
  },
18
- "homepage": "https://github.com/symbo-ls/css-in-props#readme"
38
+ "standard": {
39
+ "parser": "babel-eslint"
40
+ }
19
41
  }
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const methods = {
4
+ shape: (element) => {
5
+ const { props } = element
6
+ const { shape } = props
7
+ return shape ? exec(SHAPES[shape], element) : null
8
+ },
9
+ shapeDirection: ({ props }) => {
10
+ const { shape, shapeDirection } = props
11
+ if (!shape || !shapeDirection) return
12
+ const shapeDir = SHAPES[shape + 'Direction']
13
+ return shape ? shapeDir[shapeDirection || 'top'] : null
14
+ },
15
+ shapeDirectionColor: ({ props, ...el }) => props.shapeDirection ? { '&:before': { borderColor: el.class.backgroundColor } } : null,
16
+ depth: ({ props }) => depth[props.depth],
17
+ round: ({ props, key, ...el }) => props.round ? (mapSpacing(props.round, 'borderRadius') || ({ borderRadius: props.round })) : null,
18
+ borderRadius: ({ props, key, ...el }) => props.borderRadius ? (mapSpacing(props.borderRadius, 'borderRadius') || ({ borderRadius: props.borderRadius })) : null,
19
+
20
+ theme: ({ props }) => {
21
+ if (!props.theme) return
22
+ return getTheme(props.theme)
23
+ },
24
+
25
+ color: ({ props }) => props.color ? ({ color: getColor(props.color) }) : null,
26
+ background: ({ props }) => props.background ? ({ backgroundColor: getColor(props.background) }) : null,
27
+
28
+ textStroke: ({ props }) => props.textStroke ? diffStroke(props.textStroke) : null,
29
+
30
+ border: ({ props }) => props.border ? diffBorder(props.border) : null,
31
+ borderColor: ({ props }) => props.borderColor ? ({ borderColor: getColor(props.borderColor) }) : null,
32
+ borderStyle: ({ props }) => props.borderStyle && ({ borderStyle: props.borderStyle }),
33
+
34
+ borderLeft: ({ props }) => props.borderLeft ? diffBorder(props.borderLeft, 'borderLeft') : null,
35
+ borderTop: ({ props }) => props.borderTop ? diffBorder(props.borderTop, 'borderTop') : null,
36
+ borderRight: ({ props }) => props.borderRight ? diffBorder(props.borderRight, 'borderRight') : null,
37
+ borderBottom: ({ props }) => props.borderBottom ? diffBorder(props.borderBottom, 'borderBottom') : null,
38
+
39
+ opacity: ({ props }) => props.opacity && ({ opacity: props.opacity }),
40
+ visibility: ({ props }) => execClass({ visibility: props.visibility })
41
+ }
42
+ const execClass = (prop, element, state) => {
43
+ const { props } = element
44
+ if (props[prop]) return { prop }
45
+ }
package/src/index.js ADDED
@@ -0,0 +1,4 @@
1
+ 'use strict'
2
+
3
+ export { set } from '@symbo.ls/scratch'
4
+ export * from './transform'
@@ -0,0 +1,216 @@
1
+ 'use strict'
2
+
3
+ import { isArray, isObject } from '@domql/utils'
4
+ import { getColor, mapSpacing, getTheme, SPACING, mapFontSize, getFontFamily, FONT_FAMILY } from '@symbo.ls/scratch'
5
+
6
+ export const mapBasedOnRatio = (props, prop, unit) => {
7
+ const { spacingRatio } = props
8
+ const val = props[prop]
9
+ // TODO: move this to mapSpacing
10
+ if (spacingRatio) {
11
+ const params = SPACING[spacingRatio]
12
+
13
+ if (!params) {
14
+ SPACING[spacingRatio] = {
15
+ base: SPACING.base,
16
+ type: 'spacing',
17
+ ratio: spacingRatio,
18
+ range: [-5, +7],
19
+ subSequence: true,
20
+ sequence: {},
21
+ scales: {}
22
+ }
23
+ }
24
+
25
+ return mapSpacing(val, prop, params, unit)
26
+ }
27
+ return mapSpacing(val, prop, null, unit)
28
+ }
29
+
30
+ const isBorderStyle = str =>
31
+ ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset', 'initial'].some(v => str.includes(v))
32
+
33
+ const diffBorder = (border, key = 'border') => {
34
+ const obj = {}
35
+ const arr = isObject(border) ? Object.values(border) : isArray(border) ? border : border.split(', ')
36
+ arr.map(v => {
37
+ if (v.includes('px')) obj[`${key}Width`] = v // TODO: add map spacing
38
+ else if (isBorderStyle(v)) obj[`${key}Style`] = v || 'solid'
39
+ else if (getColor(v)) obj[`${key}Color`] = getColor(v)
40
+ })
41
+ return obj
42
+ }
43
+
44
+ const diffStroke = stroke => {
45
+ const WebkitTextStroke = stroke.split(', ').map(v => {
46
+ if (v.includes('px')) return v
47
+ else if (getColor(v)) return getColor(v)
48
+ }).join(' ')
49
+ return { WebkitTextStroke }
50
+ }
51
+
52
+ export const grid = {
53
+ columns: props => props.columns ? ({ gridTemplateColumns: props.columns }) : null,
54
+ rows: props => props.rows ? ({ gridTemplateRows: props.rows }) : null,
55
+ area: props => props.area ? ({ gridArea: props.area }) : null,
56
+ template: props => props.template ? ({ gridTemplate: props.template }) : null,
57
+ templateAreas: props => props.templateAreas ? ({ gridTemplateAreas: props.templateAreas }) : null,
58
+ gap: props => props.gap ? mapBasedOnRatio(props, 'gap') : null,
59
+ columnGap: props => props.template ? mapBasedOnRatio(props, 'columnGap') : null,
60
+ rowGap: props => props.template ? mapBasedOnRatio(props, 'rowGap') : null
61
+ }
62
+
63
+ export const theme = {
64
+ theme: props => props.theme ? getTheme(props.theme) : null,
65
+
66
+ color: props => props.color ? ({ color: getColor(props.color) }) : null,
67
+ background: props => props.background ? ({ backgroundColor: getColor(props.background) }) : null,
68
+
69
+ textStroke: props => props.textStroke ? diffStroke(props.textStroke) : null,
70
+
71
+ border: props => props.border ? diffBorder(props.border) : null,
72
+ borderColor: props => props.borderColor ? ({ borderColor: getColor(props.borderColor) }) : null,
73
+ borderStyle: props => props.borderStyle && ({ borderStyle: props.borderStyle }),
74
+
75
+ borderLeft: props => props.borderLeft ? diffBorder(props.borderLeft, 'borderLeft') : null,
76
+ borderTop: props => props.borderTop ? diffBorder(props.borderTop, 'borderTop') : null,
77
+ borderRight: props => props.borderRight ? diffBorder(props.borderRight, 'borderRight') : null,
78
+ borderBottom: props => props.borderBottom ? diffBorder(props.borderBottom, 'borderBottom') : null,
79
+
80
+ opacity: props => props.opacity && ({ opacity: props.opacity }),
81
+ visibility: props => ({ visibility: props.visibility })
82
+ }
83
+
84
+ export const block = {
85
+ round: ({ props, key }) => props.round ? (mapSpacing(props.round, 'borderRadius') || ({ borderRadius: props.round })) : null,
86
+ borderRadius: ({ props, key }) => props.borderRadius ? (mapSpacing(props.borderRadius, 'borderRadius') || ({ borderRadius: props.borderRadius })) : null,
87
+
88
+ transition: props => props.transition && ({ transition: props.transition }),
89
+ transitionProperty: props => props.transitionProperty && ({
90
+ transitionProperty: props.transitionProperty,
91
+ willChange: props.transitionProperty
92
+ }),
93
+
94
+ boxSizing: props => props.boxSizing ? ({ display: props.boxSizing }) : {
95
+ boxSizing: 'border-box'
96
+ },
97
+
98
+ display: props => props.display && ({ display: props.display }),
99
+
100
+ hide: props => props.hide && ({ display: 'none' }),
101
+
102
+ width: props => props.width && mapBasedOnRatio(props, 'width'),
103
+ height: props => props.height && mapBasedOnRatio(props, 'height'),
104
+ boxSize: props => {
105
+ if (typeof props.boxSize !== 'string') return
106
+ const [height, width] = props.boxSize.split(' ')
107
+ return {
108
+ ...mapSpacing(height, 'height'),
109
+ ...mapSpacing(width, 'width')
110
+ }
111
+ },
112
+
113
+ maxWidth: props => props.maxWidth && mapBasedOnRatio(props, 'maxWidth'),
114
+ minWidth: props => props.minWidth && mapBasedOnRatio(props, 'minWidth'),
115
+ widthRange: props => {
116
+ if (typeof props.widthRange !== 'string') return
117
+ const [minWidth, maxWidth] = props.widthRange.split(' ')
118
+ return {
119
+ ...mapSpacing(minWidth, 'minWidth'),
120
+ ...mapSpacing(maxWidth, 'maxWidth')
121
+ }
122
+ },
123
+
124
+ maxHeight: props => props.maxHeight && mapBasedOnRatio(props, 'maxHeight'),
125
+ minHeight: props => props.minHeight && mapBasedOnRatio(props, 'minHeight'),
126
+ heightRange: props => {
127
+ if (typeof props.heightRange !== 'string') return
128
+ const [minHeight, maxHeight] = props.heightRange.split(' ')
129
+ return {
130
+ ...mapSpacing(minHeight, 'minHeight'),
131
+ ...mapSpacing(maxHeight, 'maxHeight')
132
+ }
133
+ },
134
+
135
+ aspectRatio: props => props.aspectRatio && ({ aspectRatio: props.aspectRatio }),
136
+
137
+ borderWidth: props => props.borderWidth ? mapBasedOnRatio(props, 'borderWidth') : null,
138
+
139
+ padding: props => props.padding ? mapBasedOnRatio(props, 'padding') : null,
140
+ margin: props => props.margin ? mapBasedOnRatio(props, 'margin') : null,
141
+
142
+ gap: props => props.gap ? mapBasedOnRatio(props, 'gap') : null,
143
+ gridArea: props => props.gridArea && ({ gridArea: props.gridArea })
144
+ }
145
+
146
+ export const flex = {
147
+ flexFlow: props => props.flexFlow && ({
148
+ display: 'flex',
149
+ flexFlow: props.flexFlow
150
+ }),
151
+ flexAlign: props => {
152
+ if (typeof props.flexAlign !== 'string') return
153
+ const [alignItems, justifyContent] = props.flexAlign.split(' ')
154
+ return {
155
+ display: 'flex',
156
+ alignItems: alignItems,
157
+ justifyContent: justifyContent
158
+ }
159
+ },
160
+
161
+ flex: props => props.flex && ({ flex: props.flex }),
162
+ alignItems: props => props.alignItems && ({ alignItems: props.alignItems }),
163
+ alignContent: props => props.alignContent && ({ alignContent: props.alignContent }),
164
+ justifyContent: props => props.justifyContent && ({ justifyContent: props.justifyContent })
165
+ }
166
+
167
+ export const position = {
168
+ position: props => props.position && ({ position: props.position }),
169
+ inset: props => {
170
+ const { inset } = props
171
+ if (typeof inset !== 'string') return
172
+ return { inset: inset.split(' ').map(v => mapSpacing(v, 'k').k).join(' ') }
173
+ },
174
+
175
+ left: props => mapSpacing(props.left, 'left'),
176
+ top: props => mapSpacing(props.top, 'top'),
177
+ right: props => mapSpacing(props.right, 'right'),
178
+ bottom: props => mapSpacing(props.bottom, 'bottom')
179
+ }
180
+
181
+ export const text = {
182
+ fontSize: props => props.fontSize ? mapFontSize(props.fontSize) : null,
183
+ fontFamily: props => props.fontFamily && ({ fontFamily: getFontFamily(FONT_FAMILY, props.fontFamily) || props.fontFamily }),
184
+ lineHeight: props => props.lineHeight && ({ lineHeight: props.lineHeight }),
185
+ // lineHeight: props => props.lineHeight && mapBasedOnRatio(props, 'lineHeight', null, ''),
186
+ textDecoration: props => props.textDecoration && ({ textDecoration: props.textDecoration }),
187
+ textTransform: props => props.textTransform && ({ textTransform: props.textTransform }),
188
+ textAlign: props => props.textAlign && ({ textAlign: props.textAlign }),
189
+ fontWeight: props => props.fontWeight && ({ fontWeight: props.fontWeight })
190
+ }
191
+
192
+ export const registry = {
193
+ style: props => props.style,
194
+
195
+ ...theme,
196
+ ...block,
197
+ ...flex,
198
+ ...position,
199
+ ...text,
200
+
201
+ gridColumn: props => props.gridColumn && ({ gridColumn: props.gridColumn }),
202
+ gridRow: props => props.gridRow && ({ gridRow: props.gridRow }),
203
+
204
+ size: props => {
205
+ if (typeof props.heightRange !== 'string') return
206
+ const [minHeight, maxHeight] = props.heightRange.split(' ')
207
+ return {
208
+ ...mapSpacing(minHeight, 'minHeight'),
209
+ ...mapSpacing(maxHeight, 'maxHeight')
210
+ }
211
+ },
212
+
213
+ overflow: props => props.overflow && ({ overflow: props.overflow }),
214
+
215
+ transform: props => props.transform && ({ transform: props.transform })
216
+ }
@@ -0,0 +1,21 @@
1
+ 'use strict'
2
+
3
+ import { merge, isFunction } from '@domql/utils'
4
+ import { keySetters } from './subProps'
5
+
6
+ import { registry } from '../registry'
7
+
8
+ export const transformClassname = props => {
9
+ const CLASS_NAMES = {}
10
+
11
+ for (const key in props) {
12
+ const setter = keySetters[key.slice(0, 1)]
13
+ const hasCSS = registry[key]
14
+
15
+ if (setter) setter(key, props[key], CLASS_NAMES)
16
+ else if (isFunction(hasCSS)) merge(CLASS_NAMES, hasCSS(props))
17
+ }
18
+
19
+
20
+ return CLASS_NAMES
21
+ }
@@ -0,0 +1,20 @@
1
+ 'use strict'
2
+
3
+ import createEmotion from '@emotion/css/create-instance'
4
+ // const ENV = process.env.NODE_ENV
5
+
6
+ export const {
7
+ flush,
8
+ hydrate,
9
+ cx,
10
+ getRegisteredStyles,
11
+ injectGlobal,
12
+ keyframes,
13
+ css,
14
+ sheet,
15
+ cache
16
+ } = createEmotion({
17
+ key: 'smbls'
18
+ })
19
+
20
+ export const transformEmotion = props => css(props)
@@ -0,0 +1,5 @@
1
+ 'use strict'
2
+
3
+ export * from './emotion'
4
+ export * from './classname'
5
+ export * from './subProps'
@@ -0,0 +1,68 @@
1
+
2
+ import { isArray, merge } from '@domql/utils'
3
+ import { CASES as CONFIG_CASES, MEDIA as CONFIG_MEDIA } from '@symbo.ls/scratch'
4
+ import { registry } from '../registry'
5
+
6
+ const execClass = (key, props, result, rootProps) => {
7
+ const className = registry[key]
8
+
9
+ if (typeof className !== 'function') return
10
+
11
+ let classExec = className(props)
12
+ if (isArray(classExec)) {
13
+ classExec = classExec.reduce((a, c) => merge(a, c), {})
14
+ }
15
+
16
+ for (const finalProp in classExec) {
17
+ result[finalProp] = classExec[finalProp]
18
+ }
19
+ }
20
+
21
+ export const transformProps = (props, result, rootProps) => {
22
+ const propsClassObj = {}
23
+
24
+ for (const key in props) {
25
+ const setter = keySetters[key.slice(0, 1)]
26
+ if (setter) {
27
+ setter(key, props[key], propsClassObj, rootProps)
28
+ continue
29
+ } else {
30
+ execClass(key, props, propsClassObj, rootProps)
31
+ }
32
+ }
33
+
34
+ return propsClassObj
35
+ }
36
+
37
+ export const transformMedia = (key, props, result, rootProps) => {
38
+ const mediaName = CONFIG_MEDIA[key.slice(1)]
39
+ const mediaKey = `@media screen and ${mediaName}`
40
+ // result[mediaKey] = transformProps(props, result, rootProps)
41
+ const obj = { [mediaKey]: transformProps(props, result, rootProps) }
42
+ merge(result, obj)
43
+ }
44
+
45
+ export const transformSelector = (key, props, result, rootProps) => {
46
+ const selectorKey = `&${key}`
47
+ const obj = { [selectorKey]: transformProps(props, result, rootProps) }
48
+ merge(result, obj)
49
+ }
50
+
51
+ export const transformCases = (key, props, result, rootProps) => {
52
+ const caseKey = key.slice(1)
53
+ if (!CONFIG_CASES[caseKey]) return
54
+ merge(result, transformProps(props, result, rootProps))
55
+ }
56
+
57
+ export const transformConditionalCases = (key, props, result, rootProps) => {
58
+ const caseKey = key.slice(1)
59
+ if (!rootProps[caseKey]) return // remove classname if not here
60
+ merge(result, transformProps(props, result, rootProps))
61
+ }
62
+
63
+ export const keySetters = {
64
+ '@': transformMedia,
65
+ ':': transformSelector,
66
+ $: transformCases,
67
+ '.': transformConditionalCases
68
+ }