@descope/web-components-ui 1.0.35
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 +191 -0
- package/dist/cjs/index.cjs.js +95 -0
- package/dist/cjs/index.cjs.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/index.esm.js +703 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/umd/146.js +1 -0
- package/dist/umd/221.js +37 -0
- package/dist/umd/221.js.LICENSE.txt +11 -0
- package/dist/umd/511.js +573 -0
- package/dist/umd/511.js.LICENSE.txt +23 -0
- package/dist/umd/54.js +971 -0
- package/dist/umd/54.js.LICENSE.txt +33 -0
- package/dist/umd/599.js +1 -0
- package/dist/umd/729.js +1 -0
- package/dist/umd/840.js +356 -0
- package/dist/umd/840.js.LICENSE.txt +61 -0
- package/dist/umd/9.js +312 -0
- package/dist/umd/9.js.LICENSE.txt +21 -0
- package/dist/umd/descope-button-js.js +1 -0
- package/dist/umd/descope-combo-js.js +1 -0
- package/dist/umd/descope-date-picker-js.js +1 -0
- package/dist/umd/descope-text-field-js.js +1 -0
- package/dist/umd/index.js +1 -0
- package/package.json +45 -0
- package/src/components/descope-button.js +39 -0
- package/src/components/descope-combo.js +26 -0
- package/src/components/descope-date-picker.js +19 -0
- package/src/components/descope-text-field.js +36 -0
- package/src/componentsHelpers/createProxy/helpers.js +33 -0
- package/src/componentsHelpers/createProxy/index.js +82 -0
- package/src/componentsHelpers/createStyleMixin/helpers.js +66 -0
- package/src/componentsHelpers/createStyleMixin/index.js +22 -0
- package/src/componentsHelpers/draggableMixin.js +32 -0
- package/src/componentsHelpers/index.js +11 -0
- package/src/componentsHelpers/inputMixin.js +46 -0
- package/src/constants.js +1 -0
- package/src/dev/index.js +6 -0
- package/src/helpers.js +8 -0
- package/src/index.cjs.js +3 -0
- package/src/index.js +8 -0
- package/src/index.umd.js +7 -0
- package/src/theme/components/button.js +86 -0
- package/src/theme/components/index.js +7 -0
- package/src/theme/components/textField.js +50 -0
- package/src/theme/globals.js +66 -0
- package/src/theme/index.js +4 -0
- package/src/themeHelpers/index.js +76 -0
- package/src/themeHelpers/processColors.js +29 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
import { getCssVarName, kebabCase } from "../../helpers"
|
2
|
+
|
3
|
+
const createCssVarFallback = (first, ...rest) => `var(${first}${rest.length ? ` , ${createCssVarFallback(...rest)}` : ''})`;
|
4
|
+
|
5
|
+
const createCssSelector = (wrappedComponentName = '', relativeSelectorOrSelectorFn = '') =>
|
6
|
+
typeof relativeSelectorOrSelectorFn === 'function' ?
|
7
|
+
relativeSelectorOrSelectorFn(wrappedComponentName) :
|
8
|
+
`${wrappedComponentName}${relativeSelectorOrSelectorFn}`;
|
9
|
+
|
10
|
+
class StyleBuilder {
|
11
|
+
constructor() {
|
12
|
+
this.styleMap = new Map()
|
13
|
+
}
|
14
|
+
|
15
|
+
add(selector, property, value) {
|
16
|
+
if (!this.styleMap.has(selector)) {
|
17
|
+
this.styleMap.set(selector, [])
|
18
|
+
}
|
19
|
+
|
20
|
+
this.styleMap.set(selector, [...this.styleMap.get(selector), { property, value }])
|
21
|
+
}
|
22
|
+
|
23
|
+
toString() {
|
24
|
+
return Array.from(this.styleMap.entries()).reduce((style, [selector, propValArr]) =>
|
25
|
+
style += `${selector} { \n${propValArr.map(({ property, value }) => `${property}: ${value}`).join(';\n')} \n}\n\n`
|
26
|
+
, '')
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
const normalizeConfig = (attr, config) => {
|
31
|
+
const defaultMapping = { selector: '', property: kebabCase(attr) }
|
32
|
+
|
33
|
+
if (!config || !Object.keys(config).length) return [defaultMapping];
|
34
|
+
|
35
|
+
if (Array.isArray(config)) return config.map(entry => Object.assign({}, defaultMapping, entry));
|
36
|
+
|
37
|
+
return [Object.assign({}, defaultMapping, config)];
|
38
|
+
}
|
39
|
+
|
40
|
+
export const createStyle = (componentName, wrappedComponentName, mappings) => {
|
41
|
+
const style = new StyleBuilder();
|
42
|
+
|
43
|
+
Object.keys(mappings).forEach((attr) => {
|
44
|
+
const attrConfig = normalizeConfig(attr, mappings[attr])
|
45
|
+
|
46
|
+
const cssVarName = getCssVarName(componentName, attr)
|
47
|
+
|
48
|
+
attrConfig.forEach(({ selector: relativeSelectorOrSelectorFn, property }) => {
|
49
|
+
style.add(
|
50
|
+
createCssSelector(wrappedComponentName, relativeSelectorOrSelectorFn),
|
51
|
+
property,
|
52
|
+
createCssVarFallback(cssVarName)
|
53
|
+
)
|
54
|
+
})
|
55
|
+
})
|
56
|
+
|
57
|
+
return style.toString();
|
58
|
+
}
|
59
|
+
|
60
|
+
export const createCssVarsList = (componentName, mappings) =>
|
61
|
+
Object.keys(mappings).reduce(
|
62
|
+
(acc, attr) => Object.assign(acc, { [attr]: getCssVarName(componentName, attr) }),
|
63
|
+
{}
|
64
|
+
)
|
65
|
+
|
66
|
+
export const matchHostStyle = (mappingObj) => [mappingObj, {...mappingObj, selector: () => `:host${mappingObj.selector || ''}`}];
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { createStyle, createCssVarsList } from './helpers';
|
2
|
+
|
3
|
+
export const createStyleMixin = ({ mappings = {} }) => (superclass) => {
|
4
|
+
return class CustomStyleMixinClass extends superclass {
|
5
|
+
static get cssVarList() {
|
6
|
+
return createCssVarsList(superclass.componentName, mappings)
|
7
|
+
}
|
8
|
+
|
9
|
+
constructor() {
|
10
|
+
super();
|
11
|
+
|
12
|
+
this.#createComponentStyle()
|
13
|
+
}
|
14
|
+
|
15
|
+
#createComponentStyle() {
|
16
|
+
const themeStyle = document.createElement('style');
|
17
|
+
themeStyle.id = 'style-mixin'
|
18
|
+
themeStyle.innerHTML = createStyle(this.componentName, this.wrappedComponentName, mappings)
|
19
|
+
this.shadowRoot.prepend(themeStyle);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
export const draggableMixin = (superclass) =>
|
2
|
+
class DraggableMixinClass extends superclass {
|
3
|
+
|
4
|
+
#styleEle = null;
|
5
|
+
|
6
|
+
static get observedAttributes() {
|
7
|
+
const superAttrs = superclass.observedAttributes || []
|
8
|
+
return [...superAttrs, 'draggable']
|
9
|
+
}
|
10
|
+
|
11
|
+
constructor() {
|
12
|
+
super();
|
13
|
+
|
14
|
+
this.#styleEle = document.createElement('style');
|
15
|
+
this.#styleEle.innerText = `${this.wrappedComponentName} { cursor: inherit }`;
|
16
|
+
}
|
17
|
+
|
18
|
+
#handleDraggableStyle(isDraggable) {
|
19
|
+
if (isDraggable) {
|
20
|
+
this.shadowRoot.appendChild(this.#styleEle)
|
21
|
+
} else {
|
22
|
+
this.#styleEle.remove();
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
attributeChangedCallback(attrName, oldValue, newValue) {
|
27
|
+
super.attributeChangedCallback(attrName, oldValue, newValue);
|
28
|
+
if (attrName === 'draggable') {
|
29
|
+
this.#handleDraggableStyle(newValue === 'true')
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { DESCOPE_PREFIX } from "../constants";
|
2
|
+
import { kebabCaseJoin } from "../helpers";
|
3
|
+
|
4
|
+
export const getComponentName = (name) => kebabCaseJoin(DESCOPE_PREFIX, name)
|
5
|
+
|
6
|
+
export const compose = (...fns) => (val) => fns.reduceRight((res, fn) => fn(res), val);
|
7
|
+
|
8
|
+
export { createStyleMixin } from './createStyleMixin'
|
9
|
+
export { draggableMixin } from './draggableMixin'
|
10
|
+
export { createProxy } from './createProxy'
|
11
|
+
export { inputMixin } from './inputMixin'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
export const inputMixin = (superclass) =>
|
2
|
+
class InputMixinClass extends superclass {
|
3
|
+
static get formAssociated() {
|
4
|
+
return true;
|
5
|
+
}
|
6
|
+
|
7
|
+
#internals
|
8
|
+
|
9
|
+
constructor() {
|
10
|
+
super();
|
11
|
+
|
12
|
+
this.#internals = this.attachInternals();
|
13
|
+
|
14
|
+
// this is needed in order to make sure the form input validation is working
|
15
|
+
if (!this.hasAttribute('tabindex')) {
|
16
|
+
this.setAttribute('tabindex', 0);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
formAssociatedCallback() {
|
21
|
+
this.setValidity?.();
|
22
|
+
}
|
23
|
+
|
24
|
+
connectedCallback() {
|
25
|
+
super.connectedCallback();
|
26
|
+
|
27
|
+
// vaadin does not expose all those validation attributes so we need to take it from the input
|
28
|
+
// https://github.com/vaadin/web-components/issues/1177
|
29
|
+
const input = this.proxyElement.querySelector('input')
|
30
|
+
if (!input) throw Error('no input was found')
|
31
|
+
|
32
|
+
this.checkValidity = () => input.checkValidity()
|
33
|
+
this.reportValidity = () => input.reportValidity()
|
34
|
+
this.validity = input.validity
|
35
|
+
|
36
|
+
this.setValidity = () => {
|
37
|
+
this.#internals.setValidity(input.validity, input.validationMessage);
|
38
|
+
}
|
39
|
+
|
40
|
+
input.oninput = () => {
|
41
|
+
this.value = input.value
|
42
|
+
this.setValidity()
|
43
|
+
}
|
44
|
+
|
45
|
+
}
|
46
|
+
}
|
package/src/constants.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export const DESCOPE_PREFIX = 'descope'
|
package/src/dev/index.js
ADDED
package/src/helpers.js
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
export const kebabCase = str => str
|
2
|
+
.replace(/([a-z])([A-Z])/g, "$1-$2")
|
3
|
+
.replace(/[\s_.]+/g, '-')
|
4
|
+
.toLowerCase();
|
5
|
+
|
6
|
+
export const kebabCaseJoin = (...args) => kebabCase(args.join('-'))
|
7
|
+
|
8
|
+
export const getCssVarName = (...args) => `--${kebabCaseJoin(...args)}`
|
package/src/index.cjs.js
ADDED
package/src/index.js
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
import "./components/descope-button";
|
2
|
+
import "./components/descope-combo";
|
3
|
+
import "./components/descope-text-field";
|
4
|
+
import "./components/descope-date-picker";
|
5
|
+
|
6
|
+
export { globalsThemeToStyle, componentsThemeToStyle, themeToStyle } from './themeHelpers'
|
7
|
+
export { genColor } from './themeHelpers/processColors'
|
8
|
+
export { default as defaultTheme } from './theme'
|
package/src/index.umd.js
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
const components = import.meta.webpackContext('./components', { recursive: true, regExp: /.js$/, mode: 'lazy', chunkName: '[request]', prefetch: true });
|
2
|
+
module.exports = components.keys().reduce((acc, key) => {
|
3
|
+
const componentName = key.replace(/.*?([^\/]+)\.js$/, '$1')
|
4
|
+
acc[componentName] = () => components(key)
|
5
|
+
|
6
|
+
return acc;
|
7
|
+
}, {})
|
@@ -0,0 +1,86 @@
|
|
1
|
+
import globals from "../globals";
|
2
|
+
import { getThemeRefs } from "../../themeHelpers";
|
3
|
+
|
4
|
+
const globalRefs = getThemeRefs(globals);
|
5
|
+
|
6
|
+
const mode = {
|
7
|
+
primary: {
|
8
|
+
main: globalRefs.colors.primary.main,
|
9
|
+
dark: 'darkblue',
|
10
|
+
light: 'lightblue',
|
11
|
+
contrast: 'white'
|
12
|
+
},
|
13
|
+
secondary: globalRefs.colors.secondary,
|
14
|
+
success: globalRefs.colors.success,
|
15
|
+
error: globalRefs.colors.error,
|
16
|
+
surface: globalRefs.colors.surface,
|
17
|
+
}
|
18
|
+
|
19
|
+
const colorRef = getThemeRefs(mode.primary, 'button')
|
20
|
+
|
21
|
+
const button = {
|
22
|
+
borderRadius: globalRefs.radius.lg,
|
23
|
+
cursor: 'pointer',
|
24
|
+
|
25
|
+
size: {
|
26
|
+
xs: {
|
27
|
+
height: '10px',
|
28
|
+
fontSize: '10px',
|
29
|
+
padding: `0 ${globalRefs.spacing.xs}`
|
30
|
+
},
|
31
|
+
sm: {
|
32
|
+
height: '20px',
|
33
|
+
fontSize: '10px',
|
34
|
+
padding: `0 ${globalRefs.spacing.sm}`
|
35
|
+
},
|
36
|
+
md: {
|
37
|
+
height: '30px',
|
38
|
+
fontSize: '14px',
|
39
|
+
padding: `0 ${globalRefs.spacing.md}`
|
40
|
+
},
|
41
|
+
lg: {
|
42
|
+
height: '40px',
|
43
|
+
fontSize: '20px',
|
44
|
+
padding: `0 ${globalRefs.spacing.lg}`
|
45
|
+
},
|
46
|
+
xl: {
|
47
|
+
height: '50px',
|
48
|
+
fontSize: '25px',
|
49
|
+
padding: `0 ${globalRefs.spacing.xl}`
|
50
|
+
},
|
51
|
+
},
|
52
|
+
|
53
|
+
_fullwidth: {
|
54
|
+
width: '100%'
|
55
|
+
},
|
56
|
+
|
57
|
+
mode,
|
58
|
+
|
59
|
+
variant: {
|
60
|
+
contained: {
|
61
|
+
color: colorRef.contrast,
|
62
|
+
backgroundColor: colorRef.main,
|
63
|
+
_hover: {
|
64
|
+
backgroundColor: colorRef.dark,
|
65
|
+
},
|
66
|
+
},
|
67
|
+
outline: {
|
68
|
+
color: colorRef.main,
|
69
|
+
borderColor: colorRef.main,
|
70
|
+
borderWidth: '2px',
|
71
|
+
borderStyle: 'solid',
|
72
|
+
_hover: {
|
73
|
+
color: colorRef.dark,
|
74
|
+
borderColor: colorRef.dark,
|
75
|
+
_error: {
|
76
|
+
color: 'red',
|
77
|
+
}
|
78
|
+
}
|
79
|
+
},
|
80
|
+
link: {
|
81
|
+
color: colorRef.main,
|
82
|
+
},
|
83
|
+
}
|
84
|
+
};
|
85
|
+
|
86
|
+
export default button;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import globals from "../globals";
|
2
|
+
import { getThemeRefs } from "../../themeHelpers";
|
3
|
+
|
4
|
+
const globalRefs = getThemeRefs(globals);
|
5
|
+
|
6
|
+
const textField = {
|
7
|
+
borderRadius: globalRefs.radius.lg,
|
8
|
+
color: globalRefs.colors.surface.contrast,
|
9
|
+
backgroundColor: globalRefs.colors.surface.light,
|
10
|
+
borderWidth: globalRefs.border.small,
|
11
|
+
borderStyle: 'solid',
|
12
|
+
borderColor: globalRefs.colors.surface.dark,
|
13
|
+
labelColor: globalRefs.colors.surface.contrast,
|
14
|
+
placeholderColor: globalRefs.colors.surface.dark,
|
15
|
+
_invalid: {
|
16
|
+
backgroundColor: globalRefs.colors.error.light,
|
17
|
+
borderColor: globalRefs.colors.error.dark,
|
18
|
+
},
|
19
|
+
|
20
|
+
size: {
|
21
|
+
sm: {
|
22
|
+
height: '20px',
|
23
|
+
fontSize: '10px',
|
24
|
+
padding: `0 ${globalRefs.spacing.xs}`
|
25
|
+
},
|
26
|
+
md: {
|
27
|
+
height: '30px',
|
28
|
+
fontSize: '14px',
|
29
|
+
padding: `0 ${globalRefs.spacing.sm}`
|
30
|
+
},
|
31
|
+
lg: {
|
32
|
+
height: '40px',
|
33
|
+
fontSize: '20px',
|
34
|
+
padding: `0 ${globalRefs.spacing.sm}`
|
35
|
+
},
|
36
|
+
xl: {
|
37
|
+
height: '50px',
|
38
|
+
fontSize: '25px',
|
39
|
+
padding: `0 ${globalRefs.spacing.md}`
|
40
|
+
},
|
41
|
+
},
|
42
|
+
|
43
|
+
_fullwidth: {
|
44
|
+
width: '100%'
|
45
|
+
},
|
46
|
+
};
|
47
|
+
|
48
|
+
export default textField
|
49
|
+
|
50
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import { genColors } from "../themeHelpers/processColors";
|
2
|
+
|
3
|
+
export const colors = genColors({
|
4
|
+
surface: {
|
5
|
+
main: 'lightgray',
|
6
|
+
light: '#e1e1e1'
|
7
|
+
},
|
8
|
+
primary: "#0082B5",
|
9
|
+
secondary: "#7D14EB",
|
10
|
+
success: "green",
|
11
|
+
error: "red",
|
12
|
+
});
|
13
|
+
|
14
|
+
const typography = {
|
15
|
+
h1: {
|
16
|
+
font: ["Courier New", "Arial", "sans-serif"],
|
17
|
+
weight: "700",
|
18
|
+
size: "48px",
|
19
|
+
},
|
20
|
+
h2: {
|
21
|
+
font: ["Courier New", "sans-serif"],
|
22
|
+
weight: "500",
|
23
|
+
size: "38px",
|
24
|
+
},
|
25
|
+
h3: {
|
26
|
+
font: ["Courier New", "sans-serif"],
|
27
|
+
weight: "300",
|
28
|
+
size: "28px",
|
29
|
+
},
|
30
|
+
};
|
31
|
+
|
32
|
+
const spacing = {
|
33
|
+
xs: '2px',
|
34
|
+
sm: '4px',
|
35
|
+
md: '8px',
|
36
|
+
lg: '16px',
|
37
|
+
xl: '32px',
|
38
|
+
};
|
39
|
+
|
40
|
+
const border = {
|
41
|
+
sm: "1px",
|
42
|
+
md: "2px",
|
43
|
+
lg: "3px",
|
44
|
+
};
|
45
|
+
|
46
|
+
const radius = {
|
47
|
+
sm: "5px",
|
48
|
+
md: "25px",
|
49
|
+
lg: "50px",
|
50
|
+
};
|
51
|
+
|
52
|
+
const shadow = {
|
53
|
+
color: colors.primary.main,
|
54
|
+
size: {
|
55
|
+
sm: `0 0 10px`,
|
56
|
+
},
|
57
|
+
};
|
58
|
+
|
59
|
+
export default {
|
60
|
+
colors,
|
61
|
+
typography,
|
62
|
+
spacing,
|
63
|
+
border,
|
64
|
+
radius,
|
65
|
+
shadow,
|
66
|
+
};
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import merge from "lodash.merge";
|
2
|
+
import set from "lodash.set";
|
3
|
+
import { DESCOPE_PREFIX } from "../constants";
|
4
|
+
import { getCssVarName } from "../helpers";
|
5
|
+
import { getComponentName } from "../componentsHelpers";
|
6
|
+
|
7
|
+
const getVarName = (path) => getCssVarName(DESCOPE_PREFIX, ...path)
|
8
|
+
|
9
|
+
const transformTheme = (theme, path, getTransformation) => {
|
10
|
+
return Object.entries(theme).reduce((acc, [key, val]) => {
|
11
|
+
if (val?.constructor !== Object) {
|
12
|
+
return merge(acc, getTransformation(path.concat(key), val));
|
13
|
+
} else {
|
14
|
+
return merge(acc, transformTheme(val, [...path, key], getTransformation));
|
15
|
+
}
|
16
|
+
}, {});
|
17
|
+
};
|
18
|
+
|
19
|
+
const stringifyArray = (strArr) => strArr.map((str) => (str.includes(" ") ? `"${str}"` : str)).join(", ")
|
20
|
+
|
21
|
+
export const themeToCSSVarsObj = (theme) =>
|
22
|
+
transformTheme(theme, [], (path, val) => ({
|
23
|
+
[getVarName(path)]: Array.isArray(val) ? stringifyArray(val) : val,
|
24
|
+
}));
|
25
|
+
|
26
|
+
export const getThemeRefs = (theme, prefix) =>
|
27
|
+
transformTheme(theme, [], (path) => set({}, path, `var(${getVarName(prefix ? [prefix, ...path] : path)})`));
|
28
|
+
|
29
|
+
export const globalsThemeToStyle = (theme, themeName = '') => `
|
30
|
+
*[data-theme="${themeName}"] {
|
31
|
+
${Object.entries(themeToCSSVarsObj(theme)).reduce(
|
32
|
+
(acc, entry) => (acc += `${entry.join(":")};\n`), ''
|
33
|
+
)}
|
34
|
+
}
|
35
|
+
`
|
36
|
+
|
37
|
+
const componentsThemeToStyleObj = (componentsTheme) =>
|
38
|
+
transformTheme(componentsTheme, [], (path, val) => {
|
39
|
+
const [component, ...restPath] = path
|
40
|
+
const property = restPath.pop()
|
41
|
+
|
42
|
+
// do not start with underscore -> key:value, must have 2 no underscore attrs in a row
|
43
|
+
// starts with underscore -> attribute selector
|
44
|
+
|
45
|
+
const attrsSelector = restPath.reduce((acc, section, idx) => {
|
46
|
+
if (section.startsWith('_')) return acc += `[${section.replace(/^_/, '')}]`;
|
47
|
+
|
48
|
+
const nextSection = restPath[idx + 1];
|
49
|
+
|
50
|
+
if (typeof nextSection !== 'string' || nextSection.startsWith('_')) {
|
51
|
+
console.error('theme generator', `your theme structure is invalid, attribute "${section}" is followed by "${nextSection}" which is not allowed`)
|
52
|
+
return acc;
|
53
|
+
}
|
54
|
+
|
55
|
+
return acc += `[${section}="${restPath.splice(idx + 1, 1).join('')}"]`;
|
56
|
+
}, '');
|
57
|
+
|
58
|
+
let selector = `${getComponentName(component)}${attrsSelector}`
|
59
|
+
|
60
|
+
return {
|
61
|
+
[selector]: {
|
62
|
+
[getVarName([component, property])]: val
|
63
|
+
}
|
64
|
+
}
|
65
|
+
});
|
66
|
+
|
67
|
+
export const componentsThemeToStyle = (componentsTheme, themeName = '') =>
|
68
|
+
Object.entries(componentsThemeToStyleObj(componentsTheme)).reduce(
|
69
|
+
(acc, [selector, vars]) => (acc += `*[data-theme="${themeName}"] ${selector} { \n${Object.entries(vars).map(([key, val]) => `${key}: ${val}`).join(';\n')} \n}\n\n`),
|
70
|
+
''
|
71
|
+
);
|
72
|
+
|
73
|
+
export const themeToStyle = ({ globals, components }, themeName) => `
|
74
|
+
${globalsThemeToStyle(globals, themeName)}
|
75
|
+
${componentsThemeToStyle(components, themeName)}
|
76
|
+
`
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import Color from "color";
|
2
|
+
|
3
|
+
const genDark = (c, percentage = 0.5) => c.darken(percentage).hex();
|
4
|
+
const genLight = (c, percentage = 0.5) => c.lighten(percentage).hex();
|
5
|
+
const genContrast = (c, percentage = 0.9) => {
|
6
|
+
const isDark = c.isDark();
|
7
|
+
return c.mix(Color(isDark ? 'white' : 'black'), percentage).saturate(1).hex();
|
8
|
+
};
|
9
|
+
|
10
|
+
export const genColor = (color) => {
|
11
|
+
const mainColor = new Color(color.main || color);
|
12
|
+
|
13
|
+
return {
|
14
|
+
main: mainColor.hex(),
|
15
|
+
dark: color.dark || genDark(mainColor),
|
16
|
+
light: color.light || genLight(mainColor),
|
17
|
+
contrast: color.contrast || genContrast(mainColor),
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
export const genColors = (colors) => {
|
22
|
+
return Object.keys(colors).reduce((acc, colorName) => {
|
23
|
+
const currentColor = colors[colorName];
|
24
|
+
|
25
|
+
return Object.assign(acc, {
|
26
|
+
[colorName]: genColor(currentColor),
|
27
|
+
})
|
28
|
+
}, {});
|
29
|
+
};
|