@descope/web-components-ui 1.0.35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/README.md +191 -0
  2. package/dist/cjs/index.cjs.js +95 -0
  3. package/dist/cjs/index.cjs.js.map +1 -0
  4. package/dist/cjs/package.json +1 -0
  5. package/dist/index.esm.js +703 -0
  6. package/dist/index.esm.js.map +1 -0
  7. package/dist/umd/146.js +1 -0
  8. package/dist/umd/221.js +37 -0
  9. package/dist/umd/221.js.LICENSE.txt +11 -0
  10. package/dist/umd/511.js +573 -0
  11. package/dist/umd/511.js.LICENSE.txt +23 -0
  12. package/dist/umd/54.js +971 -0
  13. package/dist/umd/54.js.LICENSE.txt +33 -0
  14. package/dist/umd/599.js +1 -0
  15. package/dist/umd/729.js +1 -0
  16. package/dist/umd/840.js +356 -0
  17. package/dist/umd/840.js.LICENSE.txt +61 -0
  18. package/dist/umd/9.js +312 -0
  19. package/dist/umd/9.js.LICENSE.txt +21 -0
  20. package/dist/umd/descope-button-js.js +1 -0
  21. package/dist/umd/descope-combo-js.js +1 -0
  22. package/dist/umd/descope-date-picker-js.js +1 -0
  23. package/dist/umd/descope-text-field-js.js +1 -0
  24. package/dist/umd/index.js +1 -0
  25. package/package.json +45 -0
  26. package/src/components/descope-button.js +39 -0
  27. package/src/components/descope-combo.js +26 -0
  28. package/src/components/descope-date-picker.js +19 -0
  29. package/src/components/descope-text-field.js +36 -0
  30. package/src/componentsHelpers/createProxy/helpers.js +33 -0
  31. package/src/componentsHelpers/createProxy/index.js +82 -0
  32. package/src/componentsHelpers/createStyleMixin/helpers.js +66 -0
  33. package/src/componentsHelpers/createStyleMixin/index.js +22 -0
  34. package/src/componentsHelpers/draggableMixin.js +32 -0
  35. package/src/componentsHelpers/index.js +11 -0
  36. package/src/componentsHelpers/inputMixin.js +46 -0
  37. package/src/constants.js +1 -0
  38. package/src/dev/index.js +6 -0
  39. package/src/helpers.js +8 -0
  40. package/src/index.cjs.js +3 -0
  41. package/src/index.js +8 -0
  42. package/src/index.umd.js +7 -0
  43. package/src/theme/components/button.js +86 -0
  44. package/src/theme/components/index.js +7 -0
  45. package/src/theme/components/textField.js +50 -0
  46. package/src/theme/globals.js +66 -0
  47. package/src/theme/index.js +4 -0
  48. package/src/themeHelpers/index.js +76 -0
  49. 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
+ }
@@ -0,0 +1 @@
1
+ export const DESCOPE_PREFIX = 'descope'
@@ -0,0 +1,6 @@
1
+ import theme from '../theme'
2
+ import { themeToStyle } from "../themeHelpers";
3
+
4
+ // this file is used for exposing stuff to the dev env only
5
+
6
+ export const getDefaultThemeStyles = (themeName) => themeToStyle(theme, themeName)
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)}`
@@ -0,0 +1,3 @@
1
+ // CJS is used by screen-renderer-service, we cannot load vaadin there,
2
+ // so we are exporting only the css generation stuff
3
+ export * from './themeHelpers'
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'
@@ -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,7 @@
1
+ import button from './button';
2
+ import textField from './textField';
3
+
4
+ export default {
5
+ button,
6
+ textField
7
+ }
@@ -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,4 @@
1
+ import globals from "./globals"
2
+ import components from './components';
3
+
4
+ export default { globals, components }
@@ -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
+ };