@descope/web-components-ui 1.0.418 → 1.0.420

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 (233) hide show
  1. package/dist/cjs/index.cjs.js +1439 -1355
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/index.d.ts +0 -2
  4. package/dist/index.esm.js +1983 -1091
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/umd/1172.js +240 -0
  7. package/dist/umd/{8162.js → 1396.js} +3 -3
  8. package/dist/umd/1402.js +1 -0
  9. package/dist/umd/1484.js +148 -0
  10. package/dist/umd/{5026.js → 189.js} +5 -117
  11. package/dist/umd/{6637.js → 201.js} +5 -5
  12. package/dist/umd/{1053.js → 2159.js} +13 -13
  13. package/dist/umd/2540.js +1 -0
  14. package/dist/umd/2570.js +338 -0
  15. package/dist/umd/2666.js +148 -0
  16. package/dist/umd/3110.js +275 -0
  17. package/dist/umd/{9167.js → 3191.js} +66 -12
  18. package/dist/umd/3437.js +2 -0
  19. package/dist/umd/{6418.js → 3638.js} +2 -2
  20. package/dist/umd/{7212.js → 404.js} +8 -8
  21. package/dist/umd/4114.js +124 -0
  22. package/dist/umd/{7607.js → 4127.js} +9 -9
  23. package/dist/umd/4187.js +2 -0
  24. package/dist/umd/4218.js +129 -0
  25. package/dist/umd/4455.js +422 -0
  26. package/dist/umd/4480.js +1 -1
  27. package/dist/umd/{5086.js → 4554.js} +5 -5
  28. package/dist/umd/{4834.js → 4574.js} +5 -5
  29. package/dist/umd/4619.js +1 -1
  30. package/dist/umd/4902.js +170 -0
  31. package/dist/umd/{5273.js → 507.js} +5 -5
  32. package/dist/umd/5096.js +109 -0
  33. package/dist/umd/5318.js +1 -0
  34. package/dist/umd/5414.js +2 -0
  35. package/dist/umd/5414.js.LICENSE.txt +1 -0
  36. package/dist/umd/{8164.js → 5563.js} +5 -5
  37. package/dist/umd/{7824.js → 7097.js} +5 -117
  38. package/dist/umd/7150.js +2 -0
  39. package/dist/umd/7150.js.LICENSE.txt +485 -0
  40. package/dist/umd/731.js +832 -0
  41. package/dist/umd/742.js +2 -0
  42. package/dist/umd/{351.js → 7979.js} +10 -10
  43. package/dist/umd/8823.js +1 -0
  44. package/dist/umd/{6474.js → 9030.js} +12 -12
  45. package/dist/umd/9243.js +202 -0
  46. package/dist/umd/9243.js.LICENSE.txt +51 -0
  47. package/dist/umd/{5443.js → 9478.js} +5 -117
  48. package/dist/umd/DescopeDev.js +1 -2
  49. package/dist/umd/boolean-fields-descope-checkbox-index-js.js +1 -1
  50. package/dist/umd/boolean-fields-descope-switch-toggle-index-js.js +1 -1
  51. package/dist/umd/button-selection-group-fields-descope-button-multi-selection-group-index-js.js +1 -1
  52. package/dist/umd/button-selection-group-fields-descope-button-selection-group-index-js.js +1 -1
  53. package/dist/umd/button-selection-group-fields-descope-button-selection-group-item-index-js.js +1 -1
  54. package/dist/umd/descope-alert-index-js.js +1 -1
  55. package/dist/umd/descope-apps-list-index-js.js +1 -1
  56. package/dist/umd/descope-avatar.js +1 -0
  57. package/dist/umd/descope-button-index-js.js +4 -116
  58. package/dist/umd/descope-code-snippet-index-js.js +1 -1
  59. package/dist/umd/descope-combo-box-index-js.js +5 -5
  60. package/dist/umd/descope-date-field-descope-calendar-index-js.js +1 -1
  61. package/dist/umd/descope-date-field-index-js.js +1 -1
  62. package/dist/umd/descope-divider-index-js.js +1 -1
  63. package/dist/umd/descope-email-field-index-js.js +4 -4
  64. package/dist/umd/descope-enriched-text-index-js.js +1 -1
  65. package/dist/umd/descope-grid-descope-grid-custom-column-index-js.js +4 -4
  66. package/dist/umd/descope-grid-descope-grid-item-details-column-index-js.js +19 -4
  67. package/dist/umd/descope-grid-descope-grid-item-details-column-index-js.js.LICENSE.txt +12 -0
  68. package/dist/umd/descope-grid-descope-grid-selection-column-index-js.js +1 -1
  69. package/dist/umd/descope-grid-descope-grid-text-column-index-js.js +4 -4
  70. package/dist/umd/descope-grid-index-js.js +1 -1
  71. package/dist/umd/descope-hybrid-field-index-js.js +3 -3
  72. package/dist/umd/descope-icon-index-js.js +1 -1
  73. package/dist/umd/descope-link-index-js.js +1 -1
  74. package/dist/umd/descope-modal-index-js.js +1 -1
  75. package/dist/umd/descope-multi-select-combo-box-index-js.js +1 -1
  76. package/dist/umd/descope-new-password-index-js.js +1 -1
  77. package/dist/umd/descope-notification-descope-notification-card-index-js.js +1 -1
  78. package/dist/umd/descope-notification-index-js.js +1 -1
  79. package/dist/umd/descope-number-field-index-js.js +1 -1
  80. package/dist/umd/descope-passcode-descope-passcode-internal-index-js.js +1 -1
  81. package/dist/umd/descope-passcode-index-js.js +1 -1
  82. package/dist/umd/descope-password-index-js.js +1 -1
  83. package/dist/umd/descope-radio-group-index-js.js +1 -1
  84. package/dist/umd/descope-scopes-list-index-js.js +1 -1
  85. package/dist/umd/descope-security-questions-setup-index-js.js +1 -1
  86. package/dist/umd/descope-security-questions-verify-index-js.js +2 -2
  87. package/dist/umd/descope-text-area-index-js.js +1 -1
  88. package/dist/umd/descope-text-field-index-js.js +2 -2
  89. package/dist/umd/descope-text.js +1 -0
  90. package/dist/umd/descope-third-party-app-logo-index-js.js +1 -1
  91. package/dist/umd/descope-upload-file-index-js.js +1 -1
  92. package/dist/umd/descope-user-attribute-index-js.js +1 -1
  93. package/dist/umd/descope-user-auth-method-index-js.js +1 -1
  94. package/dist/umd/index.js +1 -1
  95. package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +1 -1
  96. package/dist/umd/mapping-fields-descope-saml-group-mappings-index-js.js +1 -1
  97. package/dist/umd/phone-fields-descope-phone-field-descope-phone-field-internal-index-js.js +1 -1
  98. package/dist/umd/phone-fields-descope-phone-field-index-js.js +1 -1
  99. package/dist/umd/phone-fields-descope-phone-input-box-field-descope-phone-input-box-internal-index-js.js +2 -2
  100. package/dist/umd/phone-fields-descope-phone-input-box-field-index-js.js +7 -7
  101. package/node_modules/common/.eslintrc.json +18 -0
  102. package/node_modules/common/README.md +7 -0
  103. package/node_modules/common/package.json +34 -0
  104. package/node_modules/common/project.json +7 -0
  105. package/node_modules/common/src/baseClasses/baseClasses/createBaseClass.js +66 -0
  106. package/node_modules/common/src/baseClasses/baseClasses/createBaseInputClass.js +14 -0
  107. package/node_modules/common/src/baseClasses/baseClasses/createCssVarImageClass.js +55 -0
  108. package/node_modules/common/src/baseClasses/index.js +3 -0
  109. package/node_modules/common/src/componentsHelpers/index.js +95 -0
  110. package/node_modules/common/src/componentsMixins/helpers/mixinsHelpers.js +10 -0
  111. package/node_modules/common/src/componentsMixins/index.js +1 -0
  112. package/node_modules/common/src/componentsMixins/mixins/activableMixin.js +14 -0
  113. package/node_modules/common/src/componentsMixins/mixins/changeMixin.js +22 -0
  114. package/node_modules/common/src/componentsMixins/mixins/componentNameValidationMixin.js +23 -0
  115. package/node_modules/common/src/componentsMixins/mixins/componentsContextMixin.js +12 -0
  116. package/node_modules/common/src/componentsMixins/mixins/createDynamicDataMixin.js +100 -0
  117. package/node_modules/common/src/componentsMixins/mixins/createProxy.js +58 -0
  118. package/node_modules/common/src/componentsMixins/mixins/createStyleMixin/helpers.js +106 -0
  119. package/node_modules/common/src/componentsMixins/mixins/createStyleMixin/index.js +167 -0
  120. package/node_modules/common/src/componentsMixins/mixins/draggableMixin.js +62 -0
  121. package/node_modules/common/src/componentsMixins/mixins/externalInputHelpers.js +93 -0
  122. package/node_modules/common/src/componentsMixins/mixins/externalInputMixin.js +170 -0
  123. package/node_modules/common/src/componentsMixins/mixins/hoverableMixin.js +13 -0
  124. package/node_modules/common/src/componentsMixins/mixins/index.js +14 -0
  125. package/node_modules/common/src/componentsMixins/mixins/inputEventsDispatchingMixin.js +76 -0
  126. package/node_modules/common/src/componentsMixins/mixins/inputValidationMixin.js +210 -0
  127. package/node_modules/common/src/componentsMixins/mixins/lifecycleEventsMixin.js +23 -0
  128. package/node_modules/common/src/componentsMixins/mixins/normalizeBooleanAttributesMixin.js +57 -0
  129. package/node_modules/common/src/componentsMixins/mixins/portalMixin.js +112 -0
  130. package/node_modules/common/src/componentsMixins/mixins/proxyInputMixin.js +242 -0
  131. package/node_modules/common/src/constants.js +4 -0
  132. package/node_modules/common/src/icons/errorMessageIconBase64.js +1 -0
  133. package/node_modules/common/src/sbControls.js +302 -0
  134. package/node_modules/common/src/themeHelpers/colorsHelpers.js +94 -0
  135. package/node_modules/common/src/themeHelpers/index.js +176 -0
  136. package/node_modules/common/src/utils/index.js +68 -0
  137. package/node_modules/descope-avatar/e2e/descope-avatar.spec.ts +54 -0
  138. package/node_modules/descope-avatar/package.json +34 -0
  139. package/node_modules/descope-avatar/project.json +7 -0
  140. package/{src/components/descope-avatar → node_modules/descope-avatar/src/component}/AvatarClass.js +4 -4
  141. package/{src/theme/components/avatar.js → node_modules/descope-avatar/src/theme.js} +3 -3
  142. package/node_modules/descope-avatar/stories/avatar.jpeg +0 -0
  143. package/node_modules/descope-avatar/stories/descope-avatar.stories.js +32 -0
  144. package/node_modules/descope-text/e2e/descope-text.spec.ts +35 -0
  145. package/node_modules/descope-text/package.json +31 -0
  146. package/node_modules/descope-text/project.json +7 -0
  147. package/{src/components/descope-text → node_modules/descope-text/src/component}/TextClass.js +4 -4
  148. package/{src/theme/components/text.js → node_modules/descope-text/src/theme.js} +3 -3
  149. package/node_modules/descope-text/stories/descope-text.stories.js +55 -0
  150. package/package.json +52 -43
  151. package/src/components/descope-alert/AlertClass.js +1 -1
  152. package/src/components/descope-apps-list/AppsListClass.js +1 -1
  153. package/src/components/descope-apps-list/index.js +2 -2
  154. package/src/components/descope-divider/DividerClass.js +1 -1
  155. package/src/components/descope-divider/index.js +1 -1
  156. package/src/components/descope-link/LinkClass.js +1 -1
  157. package/src/components/descope-link/index.js +1 -1
  158. package/src/components/descope-security-questions-verify/SecurityQuestionsVerifyClass.js +1 -1
  159. package/src/components/descope-security-questions-verify/index.js +1 -1
  160. package/src/components/descope-user-attribute/UserAttributeClass.js +1 -1
  161. package/src/components/descope-user-attribute/index.js +1 -1
  162. package/src/components/descope-user-auth-method/UserAuthMethodClass.js +1 -1
  163. package/src/components/descope-user-auth-method/index.js +1 -1
  164. package/src/components/mapping-fields/descope-mappings-field/MappingsFieldClass.js +1 -1
  165. package/src/components/mapping-fields/descope-mappings-field/index.js +1 -1
  166. package/src/helpers/themeHelpers/index.js +1 -1
  167. package/src/index.cjs.js +2 -2
  168. package/src/index.d.ts +0 -2
  169. package/src/index.js +2 -2
  170. package/src/index.umd.js +3 -1
  171. package/src/mixins/createStyleMixin/index.js +1 -1
  172. package/src/theme/components/alert.js +1 -1
  173. package/src/theme/components/comboBox.js +2 -2
  174. package/src/theme/components/enrichedText.js +1 -1
  175. package/src/theme/components/index.js +2 -2
  176. package/dist/umd/1033.js +0 -2
  177. package/dist/umd/1414.js +0 -352
  178. package/dist/umd/1437.js +0 -422
  179. package/dist/umd/1672.js +0 -1
  180. package/dist/umd/2566.js +0 -2
  181. package/dist/umd/2838.js +0 -2
  182. package/dist/umd/2838.js.LICENSE.txt +0 -1
  183. package/dist/umd/286.js +0 -148
  184. package/dist/umd/2919.js +0 -832
  185. package/dist/umd/3222.js +0 -282
  186. package/dist/umd/3607.js +0 -2
  187. package/dist/umd/3711.js +0 -123
  188. package/dist/umd/5412.js +0 -109
  189. package/dist/umd/650.js +0 -1
  190. package/dist/umd/6726.js +0 -148
  191. package/dist/umd/7407.js +0 -450
  192. package/dist/umd/8980.js +0 -143
  193. package/dist/umd/8980.js.LICENSE.txt +0 -29
  194. package/dist/umd/9632.js +0 -275
  195. package/dist/umd/9878.js +0 -1
  196. package/dist/umd/9895.js +0 -17
  197. package/dist/umd/DescopeDev.js.LICENSE.txt +0 -1
  198. package/dist/umd/bcdfe87ae253c2cf789c9a737f8d8c22.woff +0 -0
  199. package/dist/umd/descope-avatar-index-js.js +0 -1
  200. package/dist/umd/descope-text-index-js.js +0 -1
  201. /package/dist/umd/{1414.js.LICENSE.txt → 1172.js.LICENSE.txt} +0 -0
  202. /package/dist/umd/{1437.js.LICENSE.txt → 1396.js.LICENSE.txt} +0 -0
  203. /package/dist/umd/{6726.js.LICENSE.txt → 1484.js.LICENSE.txt} +0 -0
  204. /package/dist/umd/{286.js.LICENSE.txt → 189.js.LICENSE.txt} +0 -0
  205. /package/dist/umd/{6637.js.LICENSE.txt → 201.js.LICENSE.txt} +0 -0
  206. /package/dist/umd/{1053.js.LICENSE.txt → 2159.js.LICENSE.txt} +0 -0
  207. /package/dist/umd/{351.js.LICENSE.txt → 2570.js.LICENSE.txt} +0 -0
  208. /package/dist/umd/{5026.js.LICENSE.txt → 2666.js.LICENSE.txt} +0 -0
  209. /package/dist/umd/{9632.js.LICENSE.txt → 3110.js.LICENSE.txt} +0 -0
  210. /package/dist/umd/{9167.js.LICENSE.txt → 3191.js.LICENSE.txt} +0 -0
  211. /package/dist/umd/{1033.js.LICENSE.txt → 3437.js.LICENSE.txt} +0 -0
  212. /package/dist/umd/{6418.js.LICENSE.txt → 3638.js.LICENSE.txt} +0 -0
  213. /package/dist/umd/{7212.js.LICENSE.txt → 404.js.LICENSE.txt} +0 -0
  214. /package/dist/umd/{3711.js.LICENSE.txt → 4114.js.LICENSE.txt} +0 -0
  215. /package/dist/umd/{7607.js.LICENSE.txt → 4127.js.LICENSE.txt} +0 -0
  216. /package/dist/umd/{3607.js.LICENSE.txt → 4187.js.LICENSE.txt} +0 -0
  217. /package/dist/umd/{3222.js.LICENSE.txt → 4218.js.LICENSE.txt} +0 -0
  218. /package/dist/umd/{5086.js.LICENSE.txt → 4455.js.LICENSE.txt} +0 -0
  219. /package/dist/umd/{5273.js.LICENSE.txt → 4554.js.LICENSE.txt} +0 -0
  220. /package/dist/umd/{4834.js.LICENSE.txt → 4574.js.LICENSE.txt} +0 -0
  221. /package/dist/umd/{9895.js.LICENSE.txt → 4902.js.LICENSE.txt} +0 -0
  222. /package/dist/umd/{5443.js.LICENSE.txt → 507.js.LICENSE.txt} +0 -0
  223. /package/dist/umd/{5412.js.LICENSE.txt → 5096.js.LICENSE.txt} +0 -0
  224. /package/dist/umd/{8164.js.LICENSE.txt → 5563.js.LICENSE.txt} +0 -0
  225. /package/dist/umd/{7407.js.LICENSE.txt → 7097.js.LICENSE.txt} +0 -0
  226. /package/dist/umd/{2919.js.LICENSE.txt → 731.js.LICENSE.txt} +0 -0
  227. /package/dist/umd/{2566.js.LICENSE.txt → 742.js.LICENSE.txt} +0 -0
  228. /package/dist/umd/{7824.js.LICENSE.txt → 7979.js.LICENSE.txt} +0 -0
  229. /package/dist/umd/{6474.js.LICENSE.txt → 9030.js.LICENSE.txt} +0 -0
  230. /package/dist/umd/{8162.js.LICENSE.txt → 9478.js.LICENSE.txt} +0 -0
  231. /package/{src/helpers → node_modules/common/src}/themeHelpers/componentsThemeManager.js +0 -0
  232. /package/{src/components/descope-avatar → node_modules/descope-avatar/src/component}/index.js +0 -0
  233. /package/{src/components/descope-text → node_modules/descope-text/src/component}/index.js +0 -0
@@ -0,0 +1,58 @@
1
+ import { createBaseClass } from '../../baseClasses';
2
+ import { isFunction } from '../../utils';
3
+ import { forwardProps, syncAttrs } from '../../componentsHelpers';
4
+ import { createDispatchEvent } from '../../componentsMixins/helpers/mixinsHelpers';
5
+
6
+ export const createProxy = ({
7
+ componentName,
8
+ wrappedEleName,
9
+ slots = [],
10
+ style,
11
+ excludeAttrsSync = [],
12
+ includeAttrsSync = [],
13
+ includeForwardProps = [],
14
+ delegatesFocus = true,
15
+ }) => {
16
+ class ProxyClass extends createBaseClass({ componentName, baseSelector: wrappedEleName }) {
17
+ #dispatchBlur = createDispatchEvent.bind(this, 'blur');
18
+
19
+ #dispatchFocus = createDispatchEvent.bind(this, 'focus');
20
+
21
+ constructor() {
22
+ super().attachShadow({ mode: 'open', delegatesFocus }).innerHTML = `
23
+ <style id="create-proxy">${(isFunction(style) ? style() : style) || ''}</style>
24
+ <${wrappedEleName}>
25
+ ${slots
26
+ .map(
27
+ (
28
+ slot // when slot is an empty string, we will create the default slot (without a name)
29
+ ) => `<slot ${slot ? `name="${slot}" slot="${slot}"` : ''}></slot>`
30
+ )
31
+ .join('')}
32
+ </${wrappedEleName}>
33
+ `;
34
+ }
35
+
36
+ init() {
37
+ super.init?.();
38
+
39
+ this.baseElement.addEventListener('blur', (_) => {
40
+ this.#dispatchBlur();
41
+ });
42
+
43
+ this.baseElement.addEventListener('focus', (_) => {
44
+ this.#dispatchFocus();
45
+ });
46
+
47
+ // this is needed for components that uses props, such as combo box
48
+ forwardProps(this.baseElement, this, includeForwardProps);
49
+
50
+ syncAttrs(this.baseElement, this, {
51
+ excludeAttrs: excludeAttrsSync,
52
+ includeAttrs: includeAttrsSync,
53
+ });
54
+ }
55
+ }
56
+
57
+ return ProxyClass;
58
+ };
@@ -0,0 +1,106 @@
1
+ import { camelCaseJoin, isFunction, kebabCase, kebabCaseJoin } from '../../../utils';
2
+ import { getCssVarName } from '../../../componentsHelpers';
3
+
4
+ const createCssVar = (varName, fallback) => `var(${varName}${fallback ? `, ${fallback}` : ''})`;
5
+
6
+ const createCssSelector = (baseSelector = '', relativeSelectorOrSelectorFn = '') =>
7
+ isFunction(relativeSelectorOrSelectorFn)
8
+ ? relativeSelectorOrSelectorFn(baseSelector)
9
+ : `${baseSelector}${
10
+ /^[A-Za-z]/.test(relativeSelectorOrSelectorFn)
11
+ ? ` ${relativeSelectorOrSelectorFn}`
12
+ : relativeSelectorOrSelectorFn
13
+ }`;
14
+
15
+ class StyleBuilder {
16
+ constructor() {
17
+ this.styleMap = new Map();
18
+ }
19
+
20
+ add(selector, property, value) {
21
+ if (!this.styleMap.has(selector)) {
22
+ this.styleMap.set(selector, []);
23
+ }
24
+
25
+ this.styleMap.set(selector, [...this.styleMap.get(selector), { property, value }]);
26
+ }
27
+
28
+ toString() {
29
+ return Array.from(this.styleMap.entries()).reduce((acc, [selector, propValArr]) => {
30
+ const properties = propValArr
31
+ .map(({ property, value }) => `${property}: ${value}`)
32
+ .join(';\n');
33
+
34
+ return `${acc}${selector} { \n${properties} \n}\n\n`;
35
+ }, '');
36
+ }
37
+ }
38
+
39
+ const normalizeConfig = (attr, config) => {
40
+ const defaultMapping = { selector: '', property: kebabCase(attr) };
41
+
42
+ if (!config || !Object.keys(config).length) return [defaultMapping];
43
+
44
+ if (Array.isArray(config)) return config.map((entry) => ({ ...defaultMapping, ...entry }));
45
+
46
+ return [{ ...defaultMapping, ...config }];
47
+ };
48
+
49
+ const getFallbackVarName = (origVarName, suffix = 'fallback') => kebabCaseJoin(origVarName, suffix);
50
+
51
+ export const createStyle = (componentName, baseSelector, mappings) => {
52
+ const style = new StyleBuilder();
53
+ const createFallbackVar = (fallback, origVarName) => {
54
+ if (!fallback) return '';
55
+ if (typeof fallback === 'string') return fallback;
56
+
57
+ const fallbackVarName = getFallbackVarName(origVarName, fallback?.suffix);
58
+ return createCssVar(fallbackVarName, createFallbackVar(fallback.fallback, fallbackVarName));
59
+ };
60
+
61
+ Object.keys(mappings).forEach((attr) => {
62
+ const attrConfig = normalizeConfig(attr, mappings[attr]);
63
+
64
+ const cssVarName = getCssVarName(componentName, attr);
65
+
66
+ attrConfig.forEach(
67
+ ({ selector: relativeSelectorOrSelectorFn, property, important, fallback }) => {
68
+ const fallbackValue = createFallbackVar(fallback, cssVarName);
69
+ style.add(
70
+ createCssSelector(baseSelector, relativeSelectorOrSelectorFn),
71
+ isFunction(property) ? property() : property,
72
+ createCssVar(cssVarName, fallbackValue) + (important ? '!important' : '')
73
+ );
74
+ }
75
+ );
76
+ });
77
+
78
+ return style.toString();
79
+ };
80
+
81
+ const getFallbackVarsNames = (attr, origVarName, { fallback }) => {
82
+ if (!fallback) return {};
83
+
84
+ const fallbackVarName = getFallbackVarName(origVarName, fallback.suffix);
85
+ const fallbackAttrName = camelCaseJoin(attr, fallback.suffix || 'fallback');
86
+ return {
87
+ [fallbackAttrName]: fallbackVarName,
88
+ ...getFallbackVarsNames(fallbackAttrName, fallbackVarName, fallback),
89
+ };
90
+ };
91
+
92
+ export const createCssVarsList = (componentName, mappings) =>
93
+ Object.keys(mappings).reduce((acc, attr) => {
94
+ const varName = getCssVarName(componentName, attr);
95
+
96
+ return Object.assign(
97
+ acc,
98
+ { [attr]: varName },
99
+ getFallbackVarsNames(attr, varName, mappings[attr])
100
+ );
101
+ }, {});
102
+
103
+ // on some cases we need a selector to be more specific than another
104
+ // for this we have this fn that generate a class selector multiple times
105
+ export const createClassSelectorSpecifier = (className, numOfRepeats) =>
106
+ Array(numOfRepeats).fill(`.${className}`).join('');
@@ -0,0 +1,167 @@
1
+ import { BASE_THEME_SECTION, CSS_SELECTOR_SPECIFIER_MULTIPLY } from '../../../constants';
2
+ import { kebabCaseJoin } from '../../../utils';
3
+ import { getCssVarName, observeAttributes } from '../../../componentsHelpers';
4
+ import { componentsThemeManager } from '../../../themeHelpers';
5
+ import { createStyle, createCssVarsList, createClassSelectorSpecifier } from './helpers';
6
+
7
+ const STYLE_OVERRIDE_ATTR_PREFIX = 'st';
8
+
9
+ export const createStyleMixin =
10
+ ({ mappings = {}, componentNameOverride = '' }) =>
11
+ (superclass) => {
12
+ const componentName = componentNameOverride || superclass.componentName;
13
+
14
+ return class CustomStyleMixinClass extends superclass {
15
+ static get cssVarList() {
16
+ return {
17
+ ...superclass.cssVarList,
18
+ ...createCssVarsList(componentName, {
19
+ ...mappings,
20
+ }),
21
+ };
22
+ }
23
+
24
+ #overrideStyleEle;
25
+
26
+ #themeStyleEle;
27
+
28
+ #disconnectThemeManager;
29
+
30
+ #componentNameSuffix;
31
+
32
+ #themeSection;
33
+
34
+ #rootElement;
35
+
36
+ #baseSelector;
37
+
38
+ #styleAttributes;
39
+
40
+ #getRootElement;
41
+
42
+ // we are using this mixin also for portalMixin
43
+ // so we should be able to inject styles to other DOM elements
44
+ // this is why we need to support these overrides
45
+ constructor({
46
+ getRootElement,
47
+ componentNameSuffix = '',
48
+ themeSection = BASE_THEME_SECTION,
49
+ baseSelector,
50
+ } = {}) {
51
+ super();
52
+ this.#componentNameSuffix = componentNameSuffix;
53
+ this.#themeSection = themeSection;
54
+ this.#baseSelector = baseSelector ?? this.baseSelector;
55
+ this.#getRootElement = getRootElement;
56
+
57
+ this.#styleAttributes = Object.keys(CustomStyleMixinClass.cssVarList).map((key) =>
58
+ kebabCaseJoin(STYLE_OVERRIDE_ATTR_PREFIX, componentNameSuffix, key)
59
+ );
60
+ }
61
+
62
+ // eslint-disable-next-line class-methods-use-this
63
+ get #componentTheme() {
64
+ return componentsThemeManager.currentTheme?.[componentName] || '';
65
+ }
66
+
67
+ #onComponentThemeChange() {
68
+ this.#themeStyleEle.innerHTML = this.#componentTheme[this.#themeSection];
69
+ }
70
+
71
+ #createComponentTheme() {
72
+ this.#themeStyleEle = document.createElement('style');
73
+ this.#themeStyleEle.id = `style-mixin-theme__${componentName}`;
74
+ this.#rootElement.prepend(this.#themeStyleEle);
75
+ this.#disconnectThemeManager = componentsThemeManager.onCurrentThemeChange(
76
+ this.#onComponentThemeChange.bind(this)
77
+ );
78
+ this.#onComponentThemeChange();
79
+ }
80
+
81
+ #createOverridesStyle() {
82
+ if (this.#styleAttributes.length) {
83
+ this.#overrideStyleEle = document.createElement('style');
84
+ this.#overrideStyleEle.id = `style-mixin-overrides__${componentName}`;
85
+
86
+ const classSpecifier = createClassSelectorSpecifier(
87
+ componentName,
88
+ CSS_SELECTOR_SPECIFIER_MULTIPLY
89
+ );
90
+
91
+ this.#overrideStyleEle.innerText = `:host(${classSpecifier}) {}`;
92
+ this.#rootElement.append(this.#overrideStyleEle);
93
+ }
94
+ }
95
+
96
+ #setAttrOverride(attrName, value) {
97
+ const style = this.#overrideStyleEle?.sheet?.cssRules[0].style;
98
+ if (!style) return;
99
+
100
+ const varName = getCssVarName(
101
+ componentName,
102
+ attrName.replace(new RegExp(`^${STYLE_OVERRIDE_ATTR_PREFIX}-`), '')
103
+ );
104
+
105
+ if (value) style?.setProperty(varName, value);
106
+ else {
107
+ style?.removeProperty(varName);
108
+ this.removeAttribute(attrName);
109
+ }
110
+ }
111
+
112
+ #updateOverridesStyle(attrs = []) {
113
+ let shouldUpdate = false;
114
+
115
+ attrs.forEach((attr) => {
116
+ if (this.#styleAttributes.includes(attr)) {
117
+ this.#setAttrOverride(attr, this.getAttribute(attr));
118
+ shouldUpdate = true;
119
+ }
120
+ });
121
+
122
+ if (shouldUpdate) {
123
+ // we are rewriting the style back to the style tag
124
+ this.#overrideStyleEle.innerHTML = this.#overrideStyleEle?.sheet?.cssRules[0].cssText;
125
+ }
126
+ }
127
+
128
+ #createMappingStyle() {
129
+ if (Object.keys(mappings).length) {
130
+ const themeStyle = document.createElement('style');
131
+ themeStyle.id = `style-mixin-mappings__${componentName}`;
132
+ themeStyle.innerHTML = createStyle(
133
+ kebabCaseJoin(componentName, this.#componentNameSuffix),
134
+ this.#baseSelector,
135
+ mappings
136
+ );
137
+ this.#rootElement.prepend(themeStyle);
138
+ }
139
+ }
140
+
141
+ #addClassName(className) {
142
+ (this.#rootElement.classList || this.#rootElement.host.classList).add(className);
143
+ }
144
+
145
+ async init() {
146
+ super.init?.();
147
+ if (this.shadowRoot.isConnected) {
148
+ this.#rootElement = (await this.#getRootElement?.(this)) || this.shadowRoot;
149
+
150
+ this.#addClassName(componentName);
151
+
152
+ this.#createMappingStyle();
153
+ this.#createComponentTheme();
154
+ this.#createOverridesStyle();
155
+
156
+ // this is instead attributeChangedCallback because we cannot use static methods in this case
157
+ observeAttributes(this, this.#updateOverridesStyle.bind(this), {});
158
+ }
159
+ }
160
+
161
+ disconnectedCallback() {
162
+ super.disconnectedCallback?.();
163
+
164
+ this.#disconnectThemeManager?.();
165
+ }
166
+ };
167
+ };
@@ -0,0 +1,62 @@
1
+ export const draggableMixin = (superclass) =>
2
+ class DraggableMixinClass extends superclass {
3
+ #styleEle = null;
4
+
5
+ static get observedAttributes() {
6
+ const superAttrs = superclass.observedAttributes || [];
7
+ return [...superAttrs, 'draggable'];
8
+ }
9
+
10
+ constructor() {
11
+ super();
12
+
13
+ this.#styleEle = document.createElement('style');
14
+ this.#styleEle.innerText = `* { cursor: inherit!important }`;
15
+ }
16
+
17
+ #handleDraggableStyle(isDraggable) {
18
+ if (isDraggable) {
19
+ this.shadowRoot.appendChild(this.#styleEle);
20
+ } else {
21
+ this.#styleEle.remove();
22
+ }
23
+ }
24
+
25
+ get isDraggable() {
26
+ return this.hasAttribute('draggable') && this.getAttribute('draggable') !== 'false';
27
+ }
28
+
29
+ init() {
30
+ // because we are delegating the focus from the outer component,
31
+ // the D&D is not working well in the page editor
32
+ // in order to solve it we are making the inner component focusable on mouse down
33
+ // and removing it on complete
34
+ this.addEventListener('mousedown', (e) => {
35
+ if (this.isDraggable) {
36
+ const prevTabIndex = this.baseElement.getAttribute('tabindex');
37
+ this.baseElement.setAttribute('tabindex', '-1');
38
+
39
+ const onComplete = () => {
40
+ prevTabIndex
41
+ ? this.baseElement.setAttribute('tabindex', prevTabIndex)
42
+ : this.baseElement.removeAttribute('tabindex');
43
+
44
+ e.target.removeEventListener('mouseup', onComplete);
45
+ e.target.removeEventListener('dragend', onComplete);
46
+ };
47
+
48
+ e.target.addEventListener('mouseup', onComplete, { once: true });
49
+ e.target.addEventListener('dragend', onComplete, { once: true });
50
+ }
51
+ });
52
+
53
+ super.init?.();
54
+ }
55
+
56
+ attributeChangedCallback(attrName, oldValue, newValue) {
57
+ super.attributeChangedCallback?.(attrName, oldValue, newValue);
58
+ if (attrName === 'draggable') {
59
+ this.#handleDraggableStyle(newValue === 'true');
60
+ }
61
+ }
62
+ };
@@ -0,0 +1,93 @@
1
+ // since on load we can only sample the color of the placeholder,
2
+ // we need to temporarily populate the input in order to sample the value color
3
+ const getValueColor = (ele, computedStyle) => {
4
+ // to support setting dynamic values, we have to store the existing value
5
+ // and re-set it if we are returning from this hack
6
+ const origVal = ele.value;
7
+
8
+ // eslint-disable-next-line no-param-reassign
9
+ ele.value = '_';
10
+
11
+ const valueColor = computedStyle.getPropertyValue('color');
12
+
13
+ if (ele.value === '_') {
14
+ // eslint-disable-next-line no-param-reassign
15
+ ele.value = origVal;
16
+ }
17
+
18
+ return valueColor;
19
+ };
20
+
21
+ export const createExternalInputSlot = (slotName, targetSlotName) => {
22
+ const slotEle = document.createElement('slot');
23
+
24
+ slotEle.setAttribute('name', slotName);
25
+ slotEle.setAttribute('slot', targetSlotName);
26
+
27
+ return slotEle;
28
+ };
29
+
30
+ export const createExternalInputEle = (targetSlotName, type, autocompleteType, inputName) => {
31
+ const inputEle = document.createElement('input');
32
+
33
+ inputEle.setAttribute('slot', targetSlotName);
34
+ inputEle.setAttribute('type', type);
35
+ inputEle.setAttribute('name', inputName);
36
+ inputEle.setAttribute('data-hidden-input', 'true');
37
+ inputEle.setAttribute('autocomplete', autocompleteType);
38
+
39
+ return inputEle;
40
+ };
41
+
42
+ // We apply the original input's style to the external-input.
43
+ // Eventually, the user should interact directly with the external input.
44
+ // We keep the original input
45
+ export const applyExternalInputStyles = (sourceInputEle, targetInputEle, labelType) => {
46
+ // We set a timeout here to avoid "Double Print" cases,
47
+ // caused by sampling the computed style before it's ready.
48
+ setTimeout(() => {
49
+ const computedStyle = getComputedStyle(sourceInputEle);
50
+ // Get minimal set of computed theme properties to set on external input
51
+ const height = computedStyle.getPropertyValue('height');
52
+ const paddingLeft = computedStyle.getPropertyValue('padding-left');
53
+ const paddingRight = computedStyle.getPropertyValue('padding-right');
54
+ const fontSize = computedStyle.getPropertyValue('font-size');
55
+ const fontFamily = computedStyle.getPropertyValue('font-family');
56
+ const letterSpacing = computedStyle.getPropertyValue('letter-spacing');
57
+ const caretColor = computedStyle.getPropertyValue('caret-color');
58
+
59
+ const valueColor = getValueColor(sourceInputEle, computedStyle);
60
+
61
+ const commonThemeStyles = [
62
+ ['all', 'unset'],
63
+ ['position', 'absolute'],
64
+ ['background-color', 'transparent'],
65
+ ['height', height],
66
+ ['left', paddingLeft],
67
+ ['right', paddingRight],
68
+ ['font-size', fontSize],
69
+ ['font-family', fontFamily],
70
+ ['letter-spacing', letterSpacing],
71
+ ['caret-color', caretColor], // this is for seeing caret when focusing on external input
72
+ ['color', valueColor],
73
+ ];
74
+
75
+ commonThemeStyles.forEach(([key, val]) =>
76
+ targetInputEle.style.setProperty(key, val, 'important')
77
+ );
78
+
79
+ // Handle floating label theme properties
80
+ if (labelType === 'floating') {
81
+ const marginBottom = computedStyle.getPropertyValue('margin-bottom');
82
+ targetInputEle.style.setProperty('margin-bottom', marginBottom, 'important');
83
+ }
84
+
85
+ // sample and apply width only after original input is ready and fully rendered
86
+ const width = computedStyle.getPropertyValue('width');
87
+ targetInputEle.style.setProperty(
88
+ 'width',
89
+ `calc(${width} - ${paddingLeft} - ${paddingRight}`,
90
+ 'important'
91
+ );
92
+ }, 0);
93
+ };
@@ -0,0 +1,170 @@
1
+ import { syncAttrs } from '../../componentsHelpers';
2
+ import {
3
+ applyExternalInputStyles,
4
+ createExternalInputEle,
5
+ createExternalInputSlot,
6
+ } from './externalInputHelpers';
7
+
8
+ export const externalInputMixin =
9
+ ({ inputType, inputName, autocompleteType, includeAttrs = [], noBlurDispatch = false }) =>
10
+ (superclass) =>
11
+ class ExternalInputMixinClass extends superclass {
12
+ #timers = [];
13
+
14
+ get isExternalInput() {
15
+ return this.getAttribute('external-input') === 'true';
16
+ }
17
+
18
+ createExternalInput() {
19
+ if (!this.isExternalInput || this.isReadOnly || this.isDisabled) {
20
+ return null;
21
+ }
22
+
23
+ // use original input element as reference
24
+ const origInput = this.baseElement.querySelector('input');
25
+
26
+ if (!origInput) {
27
+ return null;
28
+ }
29
+
30
+ // to avoid focus loop between external-input and origInput
31
+ // we set origInput's tabindex to -1
32
+ // otherwise, shift-tab will never leave the component focus
33
+ origInput.setAttribute('tabindex', '-1');
34
+
35
+ // create external slot
36
+ const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
37
+
38
+ // append external slot to base element
39
+ this.baseElement.appendChild(externalInputSlot);
40
+
41
+ this.externalInput = createExternalInputEle(
42
+ 'external-input',
43
+ inputType,
44
+ this.getAutocompleteType(),
45
+ inputName
46
+ );
47
+
48
+ // apply original input's styles to external input
49
+ setTimeout(() => {
50
+ applyExternalInputStyles(origInput, this.externalInput, this.getAttribute('label-type'));
51
+ });
52
+
53
+ // 1Password catches the internal input, so we forward the value to the external input
54
+ this.forwardInputValue(origInput, this.externalInput);
55
+
56
+ syncAttrs(origInput, this.externalInput, {
57
+ includeAttrs,
58
+ });
59
+
60
+ // We disable Vaadin's original `_setFocused` function, and use handleFocusEvents
61
+ // and handleBlurEvents functions
62
+ this.baseElement
63
+ .querySelector('input')
64
+ .addEventListener('focusout', (e) => e.stopImmediatePropagation(), true);
65
+
66
+ // In order to manage focus/blur events when moving between parts of the component
67
+ // we're managing the event dispatching by ourselves, with the following strategy:
68
+ // - If one of the component parts is focused - it means that the component is still focused - so we stop the blur events.
69
+ // - When none of the component parts is focused, we dispatch blur event.
70
+ this.handleFocusEvents();
71
+ this.handleBlurEvents();
72
+
73
+ // sync input value
74
+ this.handlelInputEvents(this.externalInput);
75
+
76
+ // append external input to component's DOM
77
+ this.appendChild(this.externalInput);
78
+
79
+ return this.externalInput;
80
+ }
81
+
82
+ clearBlurTimers() {
83
+ this.#timers.forEach((timer) => clearTimeout(timer));
84
+ this.#timers.length = 0;
85
+ }
86
+
87
+ dispatchBlur() {
88
+ return setTimeout(() => {
89
+ this.dispatchEvent(new Event('blur', { bubbles: true, composed: true }));
90
+ this.removeAttribute('focused');
91
+ });
92
+ }
93
+
94
+ handleFocusEvents() {
95
+ // on baseElement `focus` we forward the focus to the external input.
96
+ // also, in order to avoid any blur within the component, we clear the blur timers.
97
+ this.baseElement.addEventListener('focus', () => {
98
+ this.externalInput.focus();
99
+ this.clearBlurTimers();
100
+ });
101
+
102
+ // on `focus` of the external input, we manually set the `focused` attribute
103
+ this.externalInput.addEventListener('focus', () => {
104
+ this.clearBlurTimers();
105
+ setTimeout(() => this.baseElement.setAttribute('focused', 'true'));
106
+ });
107
+ }
108
+
109
+ handleBlurEvents() {
110
+ this.baseElement.addEventListener(
111
+ 'blur',
112
+ (e) => {
113
+ e.stopImmediatePropagation();
114
+ // some components do not require this synthetic blur dispatch (e.g. Password)
115
+ // so we allow them to override this dispatch
116
+ if (noBlurDispatch) return;
117
+ this.#timers.push(this.dispatchBlur());
118
+ },
119
+ true
120
+ );
121
+
122
+ this.externalInput.addEventListener(
123
+ 'blur',
124
+ (e) => {
125
+ e.stopImmediatePropagation();
126
+ this.#timers.push(this.dispatchBlur());
127
+ },
128
+ true
129
+ );
130
+ }
131
+
132
+ handlelInputEvents(externalInput) {
133
+ // sync value of insible input back to original input
134
+ externalInput.addEventListener('input', (e) => {
135
+ this.value = e.target.value;
136
+ });
137
+
138
+ // handle has-value attr
139
+ externalInput.addEventListener('input', (e) => {
140
+ if (!e.target.value) {
141
+ this.removeAttribute('has-value');
142
+ } else {
143
+ this.setAttribute('has-value', 'true');
144
+ }
145
+ });
146
+ }
147
+
148
+ getAutocompleteType() {
149
+ return this.getAttribute('autocomplete') || autocompleteType;
150
+ }
151
+
152
+ forwardInputValue(source, target) {
153
+ // set internal sync events
154
+ const valueDescriptor = Object.getOwnPropertyDescriptor(
155
+ this.inputElement.constructor.prototype,
156
+ 'value'
157
+ );
158
+
159
+ Object.defineProperty(source, 'value', {
160
+ ...valueDescriptor,
161
+
162
+ set(v) {
163
+ valueDescriptor.set.call(this, v);
164
+ // eslint-disable-next-line no-param-reassign
165
+ target.value = v;
166
+ },
167
+ configurable: true,
168
+ });
169
+ }
170
+ };
@@ -0,0 +1,13 @@
1
+ export const hoverableMixin = (superclass) =>
2
+ class HoverableMixinClass extends superclass {
3
+ init() {
4
+ super.init?.();
5
+
6
+ this.baseElement.addEventListener('mouseover', (e) => {
7
+ this.setAttribute('hover', 'true');
8
+ e.target.addEventListener('mouseleave', () => this.removeAttribute('hover'), {
9
+ once: true,
10
+ });
11
+ });
12
+ }
13
+ };
@@ -0,0 +1,14 @@
1
+ export { createStyleMixin } from './createStyleMixin';
2
+ export { draggableMixin } from './draggableMixin';
3
+ export { createProxy } from './createProxy';
4
+ export { proxyInputMixin } from './proxyInputMixin';
5
+ export { componentNameValidationMixin } from './componentNameValidationMixin';
6
+ export { hoverableMixin } from './hoverableMixin';
7
+ export { inputValidationMixin } from './inputValidationMixin';
8
+ export { portalMixin } from './portalMixin';
9
+ export { changeMixin } from './changeMixin';
10
+ export { normalizeBooleanAttributesMixin } from './normalizeBooleanAttributesMixin';
11
+ export { lifecycleEventsMixin } from './lifecycleEventsMixin';
12
+ export { inputEventsDispatchingMixin } from './inputEventsDispatchingMixin';
13
+ export { externalInputMixin } from './externalInputMixin';
14
+ export {componentsContextMixin} from './componentsContextMixin'