@descope/web-components-ui 1.0.289 → 1.0.291

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 (45) hide show
  1. package/dist/cjs/index.cjs.js +1301 -897
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.esm.js +1600 -1068
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/umd/1000.js +1 -1
  7. package/dist/umd/2106.js +1 -1
  8. package/dist/umd/7911.js +73 -0
  9. package/dist/umd/7911.js.LICENSE.txt +17 -0
  10. package/dist/umd/descope-avatar-index-js.js +1 -1
  11. package/dist/umd/descope-badge-index-js.js +1 -1
  12. package/dist/umd/descope-grid-index-js.js +1 -1
  13. package/dist/umd/descope-text-index-js.js +1 -1
  14. package/dist/umd/descope-user-attribute-index-js.js +1 -0
  15. package/dist/umd/index.js +1 -1
  16. package/dist/umd/mapping-fields-descope-mappings-field-descope-mapping-item-index-js.js +1 -1
  17. package/dist/umd/mapping-fields-descope-mappings-field-descope-mappings-field-internal-index-js.js +1 -1
  18. package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +2 -2
  19. package/dist/umd/mapping-fields-descope-saml-group-mappings-descope-saml-group-mappings-internal-index-js.js +1 -0
  20. package/dist/umd/mapping-fields-descope-saml-group-mappings-index-js.js +1 -0
  21. package/package.json +4 -2
  22. package/src/components/descope-avatar/AvatarClass.js +7 -5
  23. package/src/components/descope-badge/BadgeClass.js +3 -0
  24. package/src/components/descope-text/TextClass.js +1 -1
  25. package/src/components/descope-user-attribute/UserAttributeClass.js +228 -0
  26. package/src/components/descope-user-attribute/delete.svg +3 -0
  27. package/src/components/descope-user-attribute/edit.svg +3 -0
  28. package/src/components/descope-user-attribute/index.js +9 -0
  29. package/src/components/mapping-fields/descope-mappings-field/MappingsFieldClass.js +14 -1
  30. package/src/components/mapping-fields/descope-mappings-field/descope-mapping-item/MappingItem.js +1 -1
  31. package/src/components/mapping-fields/descope-mappings-field/descope-mappings-field-internal/MappingsFieldInternal.js +2 -2
  32. package/src/components/mapping-fields/descope-saml-group-mappings/SamlGroupMappingsClass.js +110 -0
  33. package/src/components/mapping-fields/descope-saml-group-mappings/descope-saml-group-mappings-internal/SamlGroupMappingsInternal.js +136 -0
  34. package/src/components/mapping-fields/descope-saml-group-mappings/descope-saml-group-mappings-internal/index.js +3 -0
  35. package/src/components/mapping-fields/descope-saml-group-mappings/index.js +10 -0
  36. package/src/helpers/themeHelpers/componentsThemeManager.js +4 -0
  37. package/src/index.cjs.js +2 -0
  38. package/src/index.d.ts +1 -0
  39. package/src/index.js +2 -0
  40. package/src/mixins/proxyInputMixin.js +7 -0
  41. package/src/theme/components/avatar.js +4 -0
  42. package/src/theme/components/index.js +4 -0
  43. package/src/theme/components/mappingsField.js +3 -1
  44. package/src/theme/components/samlGroupMappings.js +13 -0
  45. package/src/theme/components/userAttribute.js +20 -0
@@ -7,7 +7,7 @@ import {
7
7
  } from '../../../mixins';
8
8
  import { TextClass } from '../../descope-text/TextClass';
9
9
  import { compose } from '../../../helpers';
10
- import { forwardAttrs, getComponentName } from '../../../helpers/componentHelpers';
10
+ import { forwardAttrs, getComponentName, syncAttrs } from '../../../helpers/componentHelpers';
11
11
  import { componentName as descopeInternalComponentName } from './descope-mappings-field-internal/MappingsFieldInternal';
12
12
 
13
13
  export const componentName = getComponentName('mappings-field');
@@ -64,6 +64,10 @@ const customMixin = (superclass) =>
64
64
  ],
65
65
  });
66
66
 
67
+ // This is required since when we remove the invalid attribute from the internal mappings field,
68
+ // we want to reflect the change in the parent component
69
+ syncAttrs(this, this.inputElement, { includeAttrs: ['invalid'] });
70
+
67
71
  this.setDefaultValues();
68
72
  }
69
73
  };
@@ -74,6 +78,7 @@ const {
74
78
  errorMessage,
75
79
  mappingItem,
76
80
  labels,
81
+ labelsText,
77
82
  valueLabel,
78
83
  attrLabel,
79
84
  separator,
@@ -84,6 +89,9 @@ const {
84
89
  errorMessage: { selector: '::part(error-message)' },
85
90
  mappingItem: { selector: 'descope-mapping-item::part(wrapper)' },
86
91
  labels: { selector: 'descope-mappings-field-internal [part="labels"] descope-text' },
92
+ labelsText: {
93
+ selector: 'descope-mappings-field-internal [part="labels"] descope-text::part(text-wrapper)',
94
+ },
87
95
  valueLabel: { selector: 'descope-mappings-field-internal [part="labels"] [part="value-label"]' },
88
96
  attrLabel: { selector: 'descope-mappings-field-internal [part="labels"] [part="attr-label"]' },
89
97
  separator: { selector: 'descope-mapping-item::part(separator)' },
@@ -99,6 +107,11 @@ export const MappingsFieldClass = compose(
99
107
  fontSize: [{}, host, { ...separator, property: 'margin-top' }],
100
108
  fontFamily: [helperText, errorMessage, labels],
101
109
  separatorFontSize: { ...separator, property: 'font-size' },
110
+ labelsFontSize: { ...labelsText, property: 'font-size' },
111
+ labelsLineHeight: [
112
+ { ...labelsText, property: 'line-height' },
113
+ { ...labels, property: 'line-height' },
114
+ ],
102
115
  labelTextColor: { ...labels, property: TextClass.cssVarList.textColor },
103
116
  itemMarginBottom: { ...mappingItem, property: 'margin-bottom' },
104
117
  valueLabelMinWidth: { ...valueLabel, property: 'min-width' },
@@ -92,7 +92,7 @@ class MappingItem extends BaseInputClass {
92
92
 
93
93
  initRemoveButton() {
94
94
  this.removeButton.addEventListener('click', () =>
95
- this.dispatchEvent(new CustomEvent('mapping-item-removed'))
95
+ this.dispatchEvent(new CustomEvent('mapping-item-removed', { bubbles: true, composed: true }))
96
96
  );
97
97
  }
98
98
 
@@ -66,7 +66,7 @@ class MappingsFieldInternal extends BaseInputClass {
66
66
  // before the new item is added and thus returns a wrong result
67
67
  setTimeout(() => {
68
68
  this.setCustomValidity('');
69
- newMappingItem.addEventListener('mapping-item-removed', (e) => {
69
+ newMappingItem.addEventListener('mapping-item-removed', () => {
70
70
  // If the removed item was the one that was invalid, we need to reset the invalid indication for the internal
71
71
  if (newMappingItem === this.#errorItem) {
72
72
  this.resetInvalidIndication();
@@ -74,8 +74,8 @@ class MappingsFieldInternal extends BaseInputClass {
74
74
  }
75
75
  newMappingItem.remove();
76
76
  this.setCustomValidity('');
77
- e.stopPropagation();
78
77
  });
78
+ this.dispatchEvent(new CustomEvent('mapping-item-added', { bubbles: true, composed: true }));
79
79
  if (focusNewItem) {
80
80
  newMappingItem.focus();
81
81
  }
@@ -0,0 +1,110 @@
1
+ import {
2
+ createStyleMixin,
3
+ draggableMixin,
4
+ createProxy,
5
+ proxyInputMixin,
6
+ componentNameValidationMixin,
7
+ } from '../../../mixins';
8
+ import { compose } from '../../../helpers';
9
+ import { forwardAttrs, getComponentName, syncAttrs } from '../../../helpers/componentHelpers';
10
+ import { componentName as descopeInternalComponentName } from './descope-saml-group-mappings-internal/SamlGroupMappingsInternal';
11
+
12
+ export const componentName = getComponentName('saml-group-mappings');
13
+
14
+ const customMixin = (superclass) =>
15
+ class SamlGroupMappingsMixinClass extends superclass {
16
+ init() {
17
+ super.init?.();
18
+
19
+ const template = document.createElement('template');
20
+
21
+ template.innerHTML = `
22
+ <${descopeInternalComponentName}
23
+ tabindex="-1"
24
+ ></${descopeInternalComponentName}>
25
+ `;
26
+
27
+ this.baseElement.appendChild(template.content.cloneNode(true));
28
+
29
+ this.inputElement = this.shadowRoot.querySelector(descopeInternalComponentName);
30
+
31
+ forwardAttrs(this, this.inputElement, {
32
+ includeAttrs: [
33
+ 'size',
34
+ 'full-width',
35
+ 'label-group',
36
+ 'label-value',
37
+ 'label-attr',
38
+ 'button-label',
39
+ 'separator',
40
+ 'options',
41
+ 'readonly',
42
+ 'disabled',
43
+ ],
44
+ });
45
+
46
+ syncAttrs(this, this.inputElement, { includeAttrs: ['invalid'] });
47
+ }
48
+ };
49
+
50
+ const { host, groupInput } = {
51
+ host: { selector: () => ':host' },
52
+ groupInput: { selector: 'descope-text-field' },
53
+ };
54
+
55
+ export const SamlGroupMappingsClass = compose(
56
+ createStyleMixin({
57
+ mappings: {
58
+ hostWidth: { ...host, property: 'width' },
59
+ hostDirection: { ...host, property: 'direction' },
60
+ groupNameInputMarginBottom: { ...groupInput, property: 'margin-bottom' },
61
+ },
62
+ }),
63
+ draggableMixin,
64
+ proxyInputMixin({
65
+ proxyProps: ['value', 'selectionStart'],
66
+ inputEvent: 'input',
67
+ triggerValidationEvents: ['mapping-item-added', 'mapping-item-removed'],
68
+ proxyParentValidation: true,
69
+ }),
70
+ componentNameValidationMixin,
71
+ customMixin
72
+ )(
73
+ createProxy({
74
+ slots: [],
75
+ wrappedEleName: 'vaadin-custom-field',
76
+ style: () => `
77
+ :host {
78
+ display: inline-flex;
79
+ max-width: 100%;
80
+ direction: ltr;
81
+ }
82
+
83
+ vaadin-custom-field {
84
+ line-height: unset;
85
+ width: 100%;
86
+ }
87
+
88
+ descope-text-field {
89
+ width: auto;
90
+ }
91
+
92
+ descope-mappings-field {
93
+ display: block;
94
+ }
95
+ `,
96
+ excludeAttrsSync: [
97
+ 'tabindex',
98
+ 'label-group',
99
+ 'label-value',
100
+ 'label-attr',
101
+ 'button-label',
102
+ 'separator',
103
+ 'options',
104
+ 'error-message',
105
+ ],
106
+ componentName,
107
+ })
108
+ );
109
+
110
+ export default SamlGroupMappingsClass;
@@ -0,0 +1,136 @@
1
+ import { createBaseInputClass } from '../../../../baseClasses/createBaseInputClass';
2
+ import {
3
+ getComponentName,
4
+ forwardAttrs,
5
+ observeAttributes,
6
+ } from '../../../../helpers/componentHelpers';
7
+
8
+ export const componentName = getComponentName('saml-group-mappings-internal');
9
+
10
+ const BaseInputClass = createBaseInputClass({ componentName, baseSelector: '' });
11
+
12
+ class SamlGroupMappingsInternal extends BaseInputClass {
13
+ static get observedAttributes() {
14
+ return ['invalid'].concat(BaseInputClass.observedAttributes || []);
15
+ }
16
+
17
+ constructor() {
18
+ super();
19
+
20
+ this.innerHTML = `
21
+ <descope-text-field variant="body2" bordered="true"></descope-text-field>
22
+ <descope-mappings-field></descope-mappings-field>
23
+ `;
24
+
25
+ this.groupInputElement = this.querySelector('descope-text-field');
26
+ this.mappingsElement = this.querySelector('descope-mappings-field');
27
+ }
28
+
29
+ resetInvalidIndication() {
30
+ this.removeAttribute('invalid');
31
+ }
32
+
33
+ handleMappingsInvalidChange(changedAttributes) {
34
+ if (changedAttributes.includes('invalid')) {
35
+ if (!this.mappingsElement.hasAttribute('invalid')) {
36
+ this.resetInvalidIndication();
37
+ }
38
+ }
39
+ }
40
+
41
+ initFocusHandler() {
42
+ // This event listener needs to be placed before the super.init() call
43
+ this.addEventListener('focus', (e) => {
44
+ // we want to ignore focus events we are dispatching
45
+ if (e.isTrusted) {
46
+ const focusedElement = this.mappingsElement.checkValidity()
47
+ ? this.groupInputElement
48
+ : this.mappingsElement;
49
+ focusedElement.focus();
50
+ }
51
+ });
52
+ }
53
+
54
+ init() {
55
+ // This needs to be placed before the super.init() call to work
56
+ this.initFocusHandler();
57
+
58
+ super.init?.();
59
+
60
+ forwardAttrs(this, this.groupInputElement, {
61
+ mapAttrs: { 'label-group': 'label' },
62
+ includeAttrs: ['size', 'label-group', 'readonly', 'disabled'],
63
+ });
64
+
65
+ forwardAttrs(this, this.mappingsElement, {
66
+ includeAttrs: [
67
+ 'size',
68
+ 'full-width',
69
+ 'label-value',
70
+ 'label-attr',
71
+ 'button-label',
72
+ 'separator',
73
+ 'options',
74
+ 'readonly',
75
+ 'disabled',
76
+ 'data-errormessage-pattern-mismatch',
77
+ ],
78
+ });
79
+
80
+ // Observing the invalid attribute of the mappings field to reset the invalid state for this component.
81
+ // When an invalid item turns valid, the mappings field will remove the invalid attribute, and at this component
82
+ // level, we need to remove the invalid attribute as well to be able to mark the component as invalid the next time
83
+ observeAttributes(this.mappingsElement, this.handleMappingsInvalidChange.bind(this), {
84
+ includeAttrs: ['invalid'],
85
+ });
86
+ }
87
+
88
+ get value() {
89
+ return {
90
+ group: this.groupInputElement.value,
91
+ mappings: this.mappingsElement.value,
92
+ };
93
+ }
94
+
95
+ set value(value) {
96
+ if (value?.group && typeof value.group === 'string') {
97
+ this.groupInputElement.value = value.group;
98
+ }
99
+ if (Array.isArray(value?.mappings)) {
100
+ this.mappingsElement.value = value.mappings;
101
+ }
102
+ }
103
+
104
+ getValidity() {
105
+ if (!this.groupInputElement.checkValidity()) {
106
+ return this.groupInputElement.validity;
107
+ }
108
+ if (!this.mappingsElement.checkValidity()) {
109
+ return this.mappingsElement.validity;
110
+ }
111
+
112
+ return {};
113
+ }
114
+
115
+ #handleInvalidState(isInvalid) {
116
+ if (isInvalid) {
117
+ if (!this.groupInputElement.checkValidity()) {
118
+ this.groupInputElement.setAttribute('invalid', 'true');
119
+ return;
120
+ }
121
+
122
+ if (!this.mappingsElement.checkValidity()) {
123
+ this.mappingsElement.setAttribute('invalid', 'true');
124
+ }
125
+ }
126
+ }
127
+
128
+ attributeChangedCallback(attrName, oldValue, newValue) {
129
+ super.attributeChangedCallback?.(attrName, oldValue, newValue);
130
+ if (attrName === 'invalid') {
131
+ this.#handleInvalidState(newValue === 'true');
132
+ }
133
+ }
134
+ }
135
+
136
+ export default SamlGroupMappingsInternal;
@@ -0,0 +1,3 @@
1
+ import SamlGroupMappingsInternal, { componentName } from './SamlGroupMappingsInternal';
2
+
3
+ customElements.define(componentName, SamlGroupMappingsInternal);
@@ -0,0 +1,10 @@
1
+ import '@vaadin/custom-field';
2
+
3
+ import { componentName, SamlGroupMappingsClass } from './SamlGroupMappingsClass';
4
+ import '../../descope-text-field';
5
+ import '../descope-mappings-field';
6
+ import './descope-saml-group-mappings-internal';
7
+
8
+ customElements.define(componentName, SamlGroupMappingsClass);
9
+
10
+ export { SamlGroupMappingsClass };
@@ -36,6 +36,10 @@ class ComponentsThemeManager {
36
36
  this.#themes = themes;
37
37
  this.#notify();
38
38
  }
39
+
40
+ get hasThemes() {
41
+ return !!Object.keys(this.#themes).length;
42
+ }
39
43
  }
40
44
 
41
45
  export const componentsThemeManager = new ComponentsThemeManager();
package/src/index.cjs.js CHANGED
@@ -38,4 +38,6 @@ export { GridClass } from './components/descope-grid/GridClass';
38
38
  export { BadgeClass } from './components/descope-badge/BadgeClass';
39
39
  export { MultiSelectComboBoxClass } from './components/descope-multi-select-combo-box/MultiSelectComboBoxClass';
40
40
  export { AvatarClass } from './components/descope-avatar/AvatarClass';
41
+ export { UserAttributeClass } from './components/descope-user-attribute/UserAttributeClass';
41
42
  export { MappingsFieldClass } from './components/mapping-fields/descope-mappings-field/MappingsFieldClass';
43
+ export { SamlGroupMappingsClass } from './components/mapping-fields/descope-saml-group-mappings/SamlGroupMappingsClass';
package/src/index.d.ts CHANGED
@@ -43,6 +43,7 @@ export { NotificationClass } from './components/descope-notification/';
43
43
  export { BadgeClass } from './components/descope-badge/';
44
44
  export { MultiSelectComboBoxClass } from './components/descope-multi-select-combo-box/';
45
45
  export { MappingsFieldClass } from './components/mapping-fields/descope-mappings-field/';
46
+ export { SamlGroupMappingsClass } from './components/mapping-fields/descope-saml-group-mappings/';
46
47
 
47
48
  export type Theme = {
48
49
  globals: {
package/src/index.js CHANGED
@@ -33,6 +33,8 @@ export * from './components/descope-modal';
33
33
  export * from './components/descope-notification';
34
34
  export * from './components/descope-avatar';
35
35
  export * from './components/mapping-fields/descope-mappings-field';
36
+ export * from './components/descope-user-attribute';
37
+ export * from './components/mapping-fields/descope-saml-group-mappings';
36
38
 
37
39
  export {
38
40
  globalsThemeToStyle,
@@ -40,6 +40,7 @@ const proxyInputMixin =
40
40
  // allows us to set the event that should trigger validation
41
41
  // it can be either a string or an array of strings (for multiple events)
42
42
  inputEvent = 'input',
43
+ triggerValidationEvents = [],
43
44
  // Proxies all validations from the parent component to the input element
44
45
  proxyParentValidation = false,
45
46
  }) =>
@@ -128,6 +129,12 @@ const proxyInputMixin =
128
129
  }
129
130
  };
130
131
 
132
+ triggerValidationEvents.forEach((e) => {
133
+ this.baseElement?.addEventListener(e, () => {
134
+ this.inputElement?.setCustomValidity('');
135
+ });
136
+ });
137
+
131
138
  // on some cases the base element is not ready so the inputElement is empty
132
139
  // we are deferring this section to make sure the base element is ready
133
140
  setTimeout(() => {
@@ -13,6 +13,10 @@ const avatar = {
13
13
  [compVars.avatarTextColor]: globalRefs.colors.surface.main,
14
14
  [compVars.avatarBackgroundColor]: globalRefs.colors.surface.dark,
15
15
 
16
+ _editable: {
17
+ [compVars.cursor]: 'pointer',
18
+ },
19
+
16
20
  size: {
17
21
  xs: {
18
22
  [compVars.hostWidth]: '30px',
@@ -32,6 +32,8 @@ import * as multiSelectComboBox from './multiSelectComboBox';
32
32
  import * as badge from './badge';
33
33
  import * as avatar from './avatar';
34
34
  import * as mappingsField from './mappingsField';
35
+ import * as userAttribute from './userAttribute';
36
+ import * as samlGroupMappings from './samlGroupMappings';
35
37
 
36
38
  const components = {
37
39
  button,
@@ -69,6 +71,8 @@ const components = {
69
71
  badge,
70
72
  avatar,
71
73
  mappingsField,
74
+ userAttribute,
75
+ samlGroupMappings,
72
76
  };
73
77
 
74
78
  const theme = Object.keys(components).reduce(
@@ -13,13 +13,15 @@ export const mappingsField = {
13
13
  [vars.fontSize]: refs.fontSize,
14
14
  [vars.fontFamily]: refs.fontFamily,
15
15
  [vars.separatorFontSize]: '14px',
16
+ [vars.labelsFontSize]: '14px',
17
+ [vars.labelsLineHeight]: '1',
18
+ [vars.labelsMarginBottom]: '6px',
16
19
  [vars.labelTextColor]: refs.labelTextColor,
17
20
  [vars.itemMarginBottom]: '1em',
18
21
  // To be positioned correctly, the min width has to match the text field min width
19
22
  [vars.valueLabelMinWidth]: refs.minWidth,
20
23
  // To be positioned correctly, the min width has to match the combo box field min width
21
24
  [vars.attrLabelMinWidth]: `calc(12em + 2 * ${globalRefs.border.xs})`,
22
- [vars.labelsMarginBottom]: `calc(${globalRefs.typography.body2.size} / 2)`,
23
25
  [vars.separatorWidth]: '70px',
24
26
  [vars.removeButtonWidth]: '60px',
25
27
  };
@@ -0,0 +1,13 @@
1
+ import { SamlGroupMappingsClass } from '../../components/mapping-fields/descope-saml-group-mappings/SamlGroupMappingsClass';
2
+ import { refs } from './inputWrapper';
3
+
4
+ const vars = SamlGroupMappingsClass.cssVarList;
5
+
6
+ export const samlGroupMappings = {
7
+ [vars.hostWidth]: refs.width,
8
+ [vars.hostDirection]: refs.direction,
9
+ [vars.groupNameInputMarginBottom]: '1em',
10
+ };
11
+
12
+ export default samlGroupMappings;
13
+ export { vars };
@@ -0,0 +1,20 @@
1
+ import globals from '../globals';
2
+ import { UserAttributeClass } from '../../components/descope-user-attribute/UserAttributeClass';
3
+ import { getThemeRefs } from '../../helpers/themeHelpers';
4
+
5
+ const globalRefs = getThemeRefs(globals);
6
+ export const vars = UserAttributeClass.cssVarList;
7
+
8
+ const userAttribute = {
9
+ [vars.hostDirection]: globalRefs.direction,
10
+ [vars.labelTextWidth]: '150px',
11
+ [vars.valueTextWidth]: '200px',
12
+ [vars.badgeMaxWidth]: '85px',
13
+ [vars.itemsGap]: '16px',
14
+ [vars.hostMinWidth]: '530px',
15
+ _fullWidth: {
16
+ [vars.hostWidth]: '100%',
17
+ },
18
+ };
19
+
20
+ export default userAttribute;