smbls 0.8.35 → 0.8.38

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "UI Library built on Scratch and DOMQL",
4
4
  "private": false,
5
5
  "author": "symbo.ls",
6
- "version": "0.8.35",
6
+ "version": "0.8.38",
7
7
  "repository": "https://github.com/symbo-ls/smbls",
8
8
  "main": "src/index.js",
9
9
  "files": [
package/src/Box.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- import { Shape, Position, Theme, Block, Text, Overflow, Transition, Transform, Responsive } from '.'
3
+ import { Shape, Position, Theme, Block, Text, Overflow, Transition, Transform, Responsive, Interaction } from '.'
4
4
 
5
5
  const PropsCSS = {
6
6
  class: {
@@ -9,5 +9,5 @@ const PropsCSS = {
9
9
  }
10
10
 
11
11
  export const Box = {
12
- proto: [Shape, Position, Theme, Block, Text, Overflow, Transition, Transform, Responsive, PropsCSS]
12
+ proto: [Shape, Position, Theme, Block, Text, Overflow, Transition, Transform, Responsive, PropsCSS, Interaction]
13
13
  }
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ export const Interaction = {
4
+ class: {
5
+ cursor: ({ props }) => ({ cursor: props.cursor })
6
+ }
7
+ }
package/src/Link.js CHANGED
@@ -1,10 +1,8 @@
1
1
  'use strict'
2
2
 
3
3
  import { exec } from '@domql/utils'
4
- import { Shape, Text } from '.'
5
4
 
6
5
  export const Link = {
7
- proto: [Shape, Text],
8
6
  tag: 'a',
9
7
  props: {
10
8
  // theme: 'link',
@@ -0,0 +1,122 @@
1
+ 'use strict'
2
+
3
+ import { merge, isArray } from '@domql/utils'
4
+ import { CASES as CONFIG_CASES, MEDIA as CONFIG_MEDIA, getTheme } from '@symbo.ls/scratch'
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) => applyCaseProps(key, props, isSubtree ? result : result.case, element),
10
+ '.': (key, props, result, element, isSubtree) => applyConditionalCaseProps(key, props, isSubtree ? result : result.case, element)
11
+ }
12
+
13
+ const execClass = (key, props, result, element) => {
14
+ const { class: className } = element
15
+ const classnameExec = className[key]
16
+
17
+ if (typeof classnameExec !== 'function') return
18
+
19
+ let classExec = classnameExec({ props })
20
+ if (isArray(classExec)) {
21
+ classExec = classExec.reduce((a, c) => merge(a, c), {})
22
+ }
23
+
24
+ for (const finalProp in classExec) {
25
+ result[finalProp] = classExec[finalProp]
26
+ }
27
+ }
28
+
29
+ const convertPropsToClass = (props, result, element) => {
30
+ const propsClassObj = {}
31
+
32
+ for (const key in props) {
33
+ const setter = keySetters[key.slice(0, 1)]
34
+ if (setter) {
35
+ setter(key, props[key], propsClassObj, element, true)
36
+ continue
37
+ } else {
38
+ execClass(key, props, propsClassObj, element)
39
+ }
40
+ }
41
+
42
+ return propsClassObj
43
+ }
44
+
45
+ const applyMediaProps = (key, props, result, element) => {
46
+ const mediaName = CONFIG_MEDIA[key.slice(1)]
47
+ const mediaKey = `@media screen and ${mediaName}`
48
+ result[mediaKey] = convertPropsToClass(props, result, element)
49
+ }
50
+
51
+ const applySelectorProps = (key, props, result, element) => {
52
+ const selectorKey = `&${key}`
53
+ result[selectorKey] = convertPropsToClass(props, result, element)
54
+ }
55
+
56
+ const applyCaseProps = (key, props, result, element) => {
57
+ const caseKey = key.slice(1)
58
+ if (!CONFIG_CASES[caseKey]) return
59
+ merge(result, convertPropsToClass(props, result, element))
60
+ }
61
+
62
+ const applyConditionalCaseProps = (key, props, result, element) => {
63
+ const caseKey = key.slice(1)
64
+ if (!element.props[caseKey]) return // remove classname if not here
65
+ merge(result, convertPropsToClass(props, result, element))
66
+ }
67
+
68
+ const init = (element, s) => {
69
+ const { props, class: className } = element
70
+
71
+ const CLASS_NAMES = {
72
+ media: {},
73
+ selector: {},
74
+ case: {}
75
+ }
76
+
77
+ for (const key in props) {
78
+ const setter = keySetters[key.slice(0, 1)]
79
+ if (setter) setter(key, props[key], CLASS_NAMES, element)
80
+ }
81
+
82
+ merge(className, CLASS_NAMES)
83
+ }
84
+
85
+ export const initUpdate = el => {
86
+ // FORCE STATE UPDATE:
87
+ const { props, class: className } = el
88
+ const rootState = el.__root ? el.__root.state : el.state
89
+ // if (el.key !== 'app') return
90
+ const { props, class: className } = element
91
+
92
+ if (props.theme) {
93
+ for (const key in convertTheme) {
94
+ if (key.includes('dark') || key.includes('light')) {
95
+ const parse = key.split(': ')[1].split(')')[0]
96
+ if (rootState.globalTheme === parse) {
97
+ props.theme = getTheme(theme[key])
98
+ } else props.theme = theme
99
+ className.MEDIA_FORCED_BY_STATE = props.theme
100
+ }
101
+ }
102
+ // console.groupEnd(props.theme)
103
+ }
104
+
105
+ for (const screen in props) {
106
+ if (screen.slice(0, 1) === '@') {
107
+ const mediaName = screen.slice(1)
108
+ const mediaKey = `@media screen and ${CONFIG_MEDIA[mediaName]}`
109
+ if (mediaName === 'dark' || mediaName === 'light') {
110
+ const { MEDIA_FORCE } = className
111
+ if (!MEDIA_FORCE) className.media = {}
112
+ if (rootState.globalTheme === mediaName) {
113
+ className.MEDIA_FORCED = className.MEDIA[mediaKey]
114
+ } else className.MEDIA_FORCED = {}
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ export const Responsive = {
121
+ on: { init, initUpdate }
122
+ }
package/src/Media.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  import { merge, isArray } from '@domql/utils'
4
- import { CASES as CONFIG_CASES, MEDIA as CONFIG_MEDIA, getTheme } from '@symbo.ls/scratch'
4
+ import { CASES as CONFIG_CASES, MEDIA as CONFIG_MEDIA } from '@symbo.ls/scratch'
5
5
 
6
6
  const keySetters = {
7
7
  '@': (key, props, result, element, isSubtree) => applyMediaProps(key, props, isSubtree ? result : result.media, element),
@@ -24,6 +24,8 @@ const execClass = (key, props, result, element) => {
24
24
  for (const finalProp in classExec) {
25
25
  result[finalProp] = classExec[finalProp]
26
26
  }
27
+
28
+ return classExec
27
29
  }
28
30
 
29
31
  const convertPropsToClass = (props, result, element) => {
@@ -44,28 +46,42 @@ const convertPropsToClass = (props, result, element) => {
44
46
 
45
47
  const applyMediaProps = (key, props, result, element) => {
46
48
  const mediaName = CONFIG_MEDIA[key.slice(1)]
49
+ const generatedClass = convertPropsToClass(props, result, element)
50
+ const rootState = element.__root ? element.__root.state : element.state
51
+ const { globalTheme } = rootState
52
+ const name = key.slice(1)
53
+ const matchesGlobal = name === globalTheme
54
+
55
+ if (globalTheme) {
56
+ if (matchesGlobal) merge(result, generatedClass)
57
+ return
58
+ }
59
+
47
60
  const mediaKey = `@media screen and ${mediaName}`
48
- result[mediaKey] = convertPropsToClass(props, result, element)
61
+ result[mediaKey] = generatedClass
62
+ return result[mediaKey]
49
63
  }
50
64
 
51
65
  const applySelectorProps = (key, props, result, element) => {
52
66
  const selectorKey = `&${key}`
53
67
  result[selectorKey] = convertPropsToClass(props, result, element)
68
+ return result[selectorKey]
54
69
  }
55
70
 
56
71
  const applyCaseProps = (key, props, result, element) => {
57
72
  const caseKey = key.slice(1)
58
73
  if (!CONFIG_CASES[caseKey]) return
59
- merge(result, convertPropsToClass(props, result, element))
74
+ return merge(result, convertPropsToClass(props, result, element))
60
75
  }
61
76
 
62
77
  const applyConditionalCaseProps = (key, props, result, element) => {
63
78
  const caseKey = key.slice(1)
64
- if (!element.props[caseKey]) return // remove classname if not here
65
- merge(result, convertPropsToClass(props, result, element))
79
+ const isPropTrue = element.props[caseKey]
80
+ if (!isPropTrue) return // remove classname if not here
81
+ return merge(result, convertPropsToClass(props, result, element))
66
82
  }
67
83
 
68
- const init = (element, s) => {
84
+ const beforeClassAssign = (element, s) => {
69
85
  const { props, class: className } = element
70
86
 
71
87
  const CLASS_NAMES = {
@@ -82,45 +98,46 @@ const init = (element, s) => {
82
98
  merge(className, CLASS_NAMES)
83
99
  }
84
100
 
85
- export const Responsive = {
86
- on: { init }
87
- }
101
+ export const initUpdate = element => {
102
+ const { props, class: className } = element
103
+ const rootState = element.__root ? element.__root.state : element.state
104
+ const { globalTheme } = rootState
88
105
 
89
- export const initUpdate = el => {
90
- // FORCE STATE UPDATE:
91
- const { props, class: className } = el
92
- const rootState = el.__root ? el.__root.state : el.state
93
- if (el.key !== 'app') return
94
-
95
- if (props.theme) {
96
- const { theme } = props
97
- // console.group(props.theme)
98
-
99
- const convertTheme = getTheme(theme)
100
-
101
- for (const key in convertTheme) {
102
- if (key.includes('dark') || key.includes('light')) {
103
- const parse = key.split(': ')[1].split(')')[0]
104
- if (rootState.globalTheme === parse) {
105
- props.theme = getTheme(theme[key])
106
- } else props.theme = theme
107
- className.MEDIA_FORCED_BY_STATE = props.theme
108
- }
109
- }
110
- // console.groupEnd(props.theme)
106
+ if (!globalTheme) return
107
+
108
+ const CLASS_NAMES = {
109
+ media: {},
110
+ selector: {},
111
+ case: {}
111
112
  }
112
113
 
113
- for (const screen in props) {
114
- if (screen.slice(0, 1) === '@') {
115
- const mediaName = screen.slice(1)
116
- const mediaKey = `@media screen and ${CONFIG_MEDIA[mediaName]}`
117
- if (mediaName === 'dark' || mediaName === 'light') {
118
- const { MEDIA_FORCE } = className
119
- if (!MEDIA_FORCE) className.media = {}
120
- if (rootState.globalTheme === mediaName) {
121
- className.MEDIA_FORCED = className.MEDIA[mediaKey]
122
- } else className.MEDIA_FORCED = {}
123
- }
114
+ for (const key in props) {
115
+ const setter = keySetters[key.slice(0, 1)]
116
+ if (key === 'theme') {
117
+ props.update({ themeModifier: globalTheme }, { preventRecursive: true, ignoreInitUpdate: true })
124
118
  }
119
+ if (setter) setter(key, props[key], CLASS_NAMES, element)
125
120
  }
121
+
122
+ if (Object.keys(CLASS_NAMES.media).length) className.media = CLASS_NAMES.media
123
+ className.selector = CLASS_NAMES.selector
124
+ className.case = CLASS_NAMES.case
125
+
126
+ // for (const screen in props) {
127
+ // if (screen.slice(0, 1) === '@') {
128
+ // const mediaName = screen.slice(1)
129
+ // const mediaKey = `@media screen and ${CONFIG_MEDIA[mediaName]}`
130
+ // if (mediaName === 'dark' || mediaName === 'light') {
131
+ // const { MEDIA_FORCE } = className
132
+ // if (!MEDIA_FORCE) className.media = {}
133
+ // if (globalTheme === mediaName) {
134
+ // className.MEDIA_FORCED = className.MEDIA[mediaKey]
135
+ // } else className.MEDIA_FORCED = {}
136
+ // }
137
+ // }
138
+ // }
139
+ }
140
+
141
+ export const Responsive = {
142
+ on: { beforeClassAssign, initUpdate }
126
143
  }
package/src/SVG.js CHANGED
@@ -5,6 +5,9 @@ const useSVGSymbol = file => `<use xlink:href="${file}" />`
5
5
  // create SVG symbol
6
6
  export const SVG = {
7
7
  tag: 'svg',
8
+ props: {
9
+ css: { '*': { fill: 'currentColor' } }
10
+ },
8
11
  attr: {
9
12
  xmlns: 'http://www.w3.org/2000/svg',
10
13
  'xmlns:xlink': 'http://www.w3.org/1999/xlink'
package/src/Theme.js CHANGED
@@ -33,9 +33,9 @@ export const Theme = {
33
33
  round: ({ props, key, ...el }) => props.round ? (mapSpacing(props.round, 'borderRadius') || ({ borderRadius: props.round })) : null,
34
34
  borderRadius: ({ props, key, ...el }) => props.borderRadius ? (mapSpacing(props.borderRadius, 'borderRadius') || ({ borderRadius: props.borderRadius })) : null,
35
35
 
36
- theme: ({ props }) => {
36
+ theme: ({ props, key }) => {
37
37
  if (!props.theme) return
38
- return getTheme(props.theme)
38
+ return getTheme(props.theme, props.themeModifier)
39
39
  },
40
40
 
41
41
  color: ({ props }) => props.color ? ({ color: getColor(props.color) }) : null,
package/src/index.js CHANGED
@@ -16,6 +16,7 @@ export * from './Overflow'
16
16
  export * from './Transform'
17
17
  export * from './Transition'
18
18
  export * from './Media'
19
+ export * from './Interaction'
19
20
 
20
21
  export * from './Box'
21
22