@descope/web-components-ui 1.0.35
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
};
|