@descope/web-components-ui 1.0.289 → 1.0.291

Sign up to get free protection for your applications and to get access to all the features.
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;