@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.
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
+ };