@descope/web-components-ui 3.20.4 → 3.21.1
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.
- package/dist/cjs/index.cjs.js +358 -25
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +358 -25
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/1411.js +339 -0
- package/dist/umd/1411.js.map +1 -0
- package/dist/umd/189.js +171 -0
- package/dist/umd/189.js.map +1 -0
- package/dist/umd/2894.js +339 -0
- package/dist/umd/2894.js.map +1 -0
- package/dist/umd/3792.js +339 -0
- package/dist/umd/3792.js.map +1 -0
- package/dist/umd/{9117.js → 384.js} +121 -9
- package/dist/umd/{descope-tooltip.js.LICENSE.txt → 384.js.LICENSE.txt} +2 -2
- package/dist/umd/384.js.map +1 -0
- package/dist/umd/4268.js +339 -0
- package/dist/umd/4268.js.LICENSE.txt +11 -0
- package/dist/umd/4268.js.map +1 -0
- package/dist/umd/513.js +339 -0
- package/dist/umd/513.js.LICENSE.txt +11 -0
- package/dist/umd/513.js.map +1 -0
- package/dist/umd/6227.js +320 -0
- package/dist/umd/6227.js.map +1 -0
- package/dist/umd/6535.js +115 -0
- package/dist/umd/{9275.js.LICENSE.txt → 6535.js.LICENSE.txt} +0 -6
- package/dist/umd/6535.js.map +1 -0
- package/dist/umd/6649.js +339 -0
- package/dist/umd/6649.js.LICENSE.txt +11 -0
- package/dist/umd/6649.js.map +1 -0
- package/dist/umd/7125.js +339 -0
- package/dist/umd/7125.js.LICENSE.txt +11 -0
- package/dist/umd/7125.js.map +1 -0
- package/dist/umd/{5263.js → 8264.js} +5 -5
- package/dist/umd/8264.js.map +1 -0
- package/dist/umd/8983.js +7 -324
- package/dist/umd/8983.js.map +1 -1
- package/dist/umd/9030.js +339 -0
- package/dist/umd/9030.js.LICENSE.txt +11 -0
- package/dist/umd/9030.js.map +1 -0
- package/dist/umd/9380.js +130 -0
- package/dist/umd/9380.js.map +1 -0
- package/dist/umd/9506.js +339 -0
- package/dist/umd/9506.js.LICENSE.txt +11 -0
- package/dist/umd/9506.js.map +1 -0
- package/dist/umd/DescopeDev.js +1 -1
- package/dist/umd/DescopeDev.js.map +1 -1
- package/dist/umd/button-selection-group-fields-descope-button-multi-selection-group-index-js.js +1 -1
- package/dist/umd/button-selection-group-fields-descope-button-multi-selection-group-index-js.js.map +1 -1
- package/dist/umd/button-selection-group-fields-descope-button-selection-group-index-js.js +1 -1
- package/dist/umd/button-selection-group-fields-descope-button-selection-group-index-js.js.map +1 -1
- package/dist/umd/button-selection-group-fields-descope-button-selection-group-item-index-js.js +1 -338
- package/dist/umd/button-selection-group-fields-descope-button-selection-group-item-index-js.js.map +1 -1
- package/dist/umd/descope-apps-list.js +161 -1
- package/dist/umd/descope-apps-list.js.LICENSE.txt +17 -0
- package/dist/umd/descope-apps-list.js.map +1 -1
- package/dist/umd/descope-avatar.js +5 -20
- package/dist/umd/descope-avatar.js.LICENSE.txt +0 -12
- package/dist/umd/descope-avatar.js.map +1 -1
- package/dist/umd/descope-button.js +3 -3
- package/dist/umd/descope-button.js.LICENSE.txt +6 -0
- package/dist/umd/descope-button.js.map +1 -1
- package/dist/umd/descope-date-field-descope-calendar-index-js.js +1 -1
- package/dist/umd/descope-date-field-descope-calendar-index-js.js.map +1 -1
- package/dist/umd/descope-grid-descope-grid-custom-column-index-js.js +4 -321
- package/dist/umd/descope-grid-descope-grid-custom-column-index-js.js.LICENSE.txt +0 -6
- package/dist/umd/descope-grid-descope-grid-custom-column-index-js.js.map +1 -1
- package/dist/umd/descope-grid-descope-grid-item-details-column-index-js.js +5 -322
- package/dist/umd/descope-grid-descope-grid-item-details-column-index-js.js.map +1 -1
- package/dist/umd/descope-grid-descope-grid-text-column-index-js.js +4 -321
- package/dist/umd/descope-grid-descope-grid-text-column-index-js.js.LICENSE.txt +0 -6
- package/dist/umd/descope-grid-descope-grid-text-column-index-js.js.map +1 -1
- package/dist/umd/descope-multi-line-mappings.js +1 -1
- package/dist/umd/descope-multi-line-mappings.js.map +1 -1
- package/dist/umd/descope-multi-sso.js +1 -338
- package/dist/umd/descope-multi-sso.js.map +1 -1
- package/dist/umd/descope-outbound-app-button.js +1 -338
- package/dist/umd/descope-outbound-app-button.js.map +1 -1
- package/dist/umd/descope-recovery-codes.js +1 -1
- package/dist/umd/descope-recovery-codes.js.map +1 -1
- package/dist/umd/descope-timer-button.js +1 -338
- package/dist/umd/descope-timer-button.js.map +1 -1
- package/dist/umd/descope-tooltip.js +1 -2
- package/dist/umd/descope-tooltip.js.map +1 -1
- package/dist/umd/descope-upload-file-index-js.js +1 -338
- package/dist/umd/descope-upload-file-index-js.js.map +1 -1
- package/dist/umd/descope-user-attribute-index-js.js +1 -338
- package/dist/umd/descope-user-attribute-index-js.js.map +1 -1
- package/dist/umd/descope-user-auth-method-index-js.js +1 -338
- package/dist/umd/descope-user-auth-method-index-js.js.map +1 -1
- package/dist/umd/descope-user-passkeys.js +1 -338
- package/dist/umd/descope-user-passkeys.js.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +42 -42
- package/dist/umd/1453.js +0 -177
- package/dist/umd/1453.js.LICENSE.txt +0 -29
- package/dist/umd/1453.js.map +0 -1
- package/dist/umd/5263.js.map +0 -1
- package/dist/umd/6063.js +0 -18
- package/dist/umd/6063.js.map +0 -1
- package/dist/umd/6818.js +0 -3
- package/dist/umd/6818.js.map +0 -1
- package/dist/umd/8248.js +0 -171
- package/dist/umd/8248.js.map +0 -1
- package/dist/umd/8968.js +0 -432
- package/dist/umd/8968.js.map +0 -1
- package/dist/umd/9117.js.map +0 -1
- package/dist/umd/9275.js +0 -18
- package/dist/umd/9275.js.map +0 -1
- package/dist/umd/button-selection-group-fields-descope-button-selection-group-item-index-js.js.LICENSE.txt +0 -5
- package/dist/umd/descope-multi-sso.js.LICENSE.txt +0 -5
- package/dist/umd/descope-outbound-app-button.js.LICENSE.txt +0 -5
- package/dist/umd/descope-timer-button.js.LICENSE.txt +0 -5
- package/dist/umd/descope-upload-file-index-js.js.LICENSE.txt +0 -5
- package/dist/umd/descope-user-attribute-index-js.js.LICENSE.txt +0 -5
- package/dist/umd/descope-user-passkeys.js.LICENSE.txt +0 -5
- /package/dist/umd/{8968.js.LICENSE.txt → 1411.js.LICENSE.txt} +0 -0
- /package/dist/umd/{6063.js.LICENSE.txt → 189.js.LICENSE.txt} +0 -0
- /package/dist/umd/{9117.js.LICENSE.txt → 2894.js.LICENSE.txt} +0 -0
- /package/dist/umd/{descope-user-auth-method-index-js.js.LICENSE.txt → 3792.js.LICENSE.txt} +0 -0
- /package/dist/umd/{6818.js.LICENSE.txt → 6227.js.LICENSE.txt} +0 -0
- /package/dist/umd/{5263.js.LICENSE.txt → 8264.js.LICENSE.txt} +0 -0
- /package/dist/umd/{8248.js.LICENSE.txt → 9380.js.LICENSE.txt} +0 -0
package/dist/index.esm.js
CHANGED
|
@@ -24920,6 +24920,37 @@ var collapsibleContainer$1 = /*#__PURE__*/Object.freeze({
|
|
|
24920
24920
|
|
|
24921
24921
|
const componentName$h = getComponentName$1('recovery-codes');
|
|
24922
24922
|
|
|
24923
|
+
const NO_ACTION = 'none';
|
|
24924
|
+
const DEFAULT_ERROR_MESSAGE =
|
|
24925
|
+
'Copy or download your recovery codes to continue.';
|
|
24926
|
+
|
|
24927
|
+
// default button label per action (buttons variant). the icons variant uses the vaadin
|
|
24928
|
+
// glyphs hardcoded in the shadow-DOM template below; the buttons variant uses image srcs.
|
|
24929
|
+
const ACTIONS = {
|
|
24930
|
+
copy: { defaultText: 'Copy' },
|
|
24931
|
+
download: { defaultText: 'Download' },
|
|
24932
|
+
};
|
|
24933
|
+
|
|
24934
|
+
// per-button config suffixes; the full attribute is `${action}-${suffix}`.
|
|
24935
|
+
// `icon`/`icon-dark` are image srcs (the seeded glyph or a custom upload), matching
|
|
24936
|
+
// the standard button's start-icon (light/dark), not a boolean.
|
|
24937
|
+
const BUTTON_SUFFIXES = [
|
|
24938
|
+
'text',
|
|
24939
|
+
'variant',
|
|
24940
|
+
'color',
|
|
24941
|
+
'size',
|
|
24942
|
+
'icon',
|
|
24943
|
+
'icon-dark',
|
|
24944
|
+
];
|
|
24945
|
+
|
|
24946
|
+
// changing any of these rebuilds the buttons (so the editor preview stays live)
|
|
24947
|
+
const BUTTON_ATTRS = [
|
|
24948
|
+
'show-download',
|
|
24949
|
+
...Object.keys(ACTIONS).flatMap((action) =>
|
|
24950
|
+
BUTTON_SUFFIXES.map((suffix) => `${action}-${suffix}`),
|
|
24951
|
+
),
|
|
24952
|
+
];
|
|
24953
|
+
|
|
24923
24954
|
const itemRenderer$4 = ({ value }, _, ref) => {
|
|
24924
24955
|
return `
|
|
24925
24956
|
<descope-text variant="${ref.variant}" mode="${ref.mode}">
|
|
@@ -24933,24 +24964,44 @@ class RawRecoveryCodes extends createBaseClass$1({
|
|
|
24933
24964
|
baseSelector: ':host > div',
|
|
24934
24965
|
}) {
|
|
24935
24966
|
static get observedAttributes() {
|
|
24936
|
-
return ['readonly'];
|
|
24967
|
+
return ['readonly', 'required', ...BUTTON_ATTRS];
|
|
24937
24968
|
}
|
|
24938
24969
|
|
|
24970
|
+
// 'none' | 'copied' | 'downloaded' - the last action the user took on the codes
|
|
24971
|
+
#action = NO_ACTION;
|
|
24972
|
+
|
|
24973
|
+
// the error is shown only after a submit attempt (reportValidity), like inputs
|
|
24974
|
+
#showError = false;
|
|
24975
|
+
|
|
24976
|
+
// init() builds the buttons once with all seeded attrs; guards against rebuilding
|
|
24977
|
+
// on every per-attribute change fired during element upgrade (before init runs)
|
|
24978
|
+
#initialized = false;
|
|
24979
|
+
|
|
24939
24980
|
constructor() {
|
|
24940
24981
|
super();
|
|
24941
24982
|
|
|
24942
24983
|
this.attachShadow({ mode: 'open' }).innerHTML = `
|
|
24943
24984
|
<div class="wrapper">
|
|
24944
|
-
<div class="
|
|
24945
|
-
|
|
24946
|
-
<
|
|
24947
|
-
|
|
24985
|
+
<div class="codes-box">
|
|
24986
|
+
<div class="list"></div>
|
|
24987
|
+
<descope-text class="icon-wrapper">
|
|
24988
|
+
<div class="icons">
|
|
24989
|
+
<vaadin-icon class="icon copy-icon" icon="vaadin:copy-o" title="Copy"></vaadin-icon>
|
|
24990
|
+
<vaadin-icon class="icon download-icon" icon="vaadin:download-alt" title="Download"></vaadin-icon>
|
|
24991
|
+
</div>
|
|
24992
|
+
</descope-text>
|
|
24993
|
+
</div>
|
|
24994
|
+
<div class="error-message"></div>
|
|
24995
|
+
<div class="buttons-row"></div>
|
|
24948
24996
|
</div>
|
|
24949
24997
|
`;
|
|
24950
24998
|
|
|
24951
24999
|
this.list = this.shadowRoot.querySelector('.list');
|
|
24952
|
-
this.
|
|
25000
|
+
this.copyIcon = this.shadowRoot.querySelector('.copy-icon');
|
|
25001
|
+
this.downloadIcon = this.shadowRoot.querySelector('.download-icon');
|
|
24953
25002
|
this.iconWrapper = this.shadowRoot.querySelector('.icon-wrapper');
|
|
25003
|
+
this.errorMessageEle = this.shadowRoot.querySelector('.error-message');
|
|
25004
|
+
this.buttonsRow = this.shadowRoot.querySelector('.buttons-row');
|
|
24954
25005
|
|
|
24955
25006
|
injectStyle(
|
|
24956
25007
|
`
|
|
@@ -24959,8 +25010,14 @@ class RawRecoveryCodes extends createBaseClass$1({
|
|
|
24959
25010
|
position: relative;
|
|
24960
25011
|
}
|
|
24961
25012
|
.wrapper {
|
|
25013
|
+
display: flex;
|
|
25014
|
+
flex-direction: column;
|
|
25015
|
+
}
|
|
25016
|
+
.codes-box {
|
|
24962
25017
|
display: flex;
|
|
24963
25018
|
justify-content: space-between;
|
|
25019
|
+
box-sizing: border-box;
|
|
25020
|
+
/* border shows the error ring inside the box; style/width/color/radius come from theme */
|
|
24964
25021
|
}
|
|
24965
25022
|
.list {
|
|
24966
25023
|
display: flex;
|
|
@@ -24979,15 +25036,57 @@ class RawRecoveryCodes extends createBaseClass$1({
|
|
|
24979
25036
|
.icon-wrapper {
|
|
24980
25037
|
align-self: flex-start;
|
|
24981
25038
|
}
|
|
25039
|
+
.icons {
|
|
25040
|
+
display: flex;
|
|
25041
|
+
flex-direction: column;
|
|
25042
|
+
}
|
|
24982
25043
|
.icon {
|
|
24983
25044
|
cursor: pointer;
|
|
24984
25045
|
}
|
|
24985
25046
|
.icon.copied {
|
|
24986
25047
|
cursor: initial;
|
|
25048
|
+
/* block re-clicks while the checkmark shows, so rapid clicks cannot repeat the action */
|
|
25049
|
+
pointer-events: none;
|
|
24987
25050
|
}
|
|
24988
|
-
|
|
25051
|
+
/* readonly is a host attribute, so disable pointer events from one place */
|
|
25052
|
+
:host([readonly="true"]) .icon,
|
|
25053
|
+
:host([readonly="true"]) .buttons-row {
|
|
24989
25054
|
pointer-events: none;
|
|
24990
25055
|
}
|
|
25056
|
+
.download-icon {
|
|
25057
|
+
display: none;
|
|
25058
|
+
}
|
|
25059
|
+
:host([show-download="true"]) .download-icon {
|
|
25060
|
+
display: inline-flex;
|
|
25061
|
+
}
|
|
25062
|
+
.error-message {
|
|
25063
|
+
display: none;
|
|
25064
|
+
/* width:0 + min-width:100% lets the message wrap to the component width without
|
|
25065
|
+
its text expanding the (shrink-to-fit) component; full-width still fills the parent */
|
|
25066
|
+
width: 0;
|
|
25067
|
+
min-width: 100%;
|
|
25068
|
+
box-sizing: border-box;
|
|
25069
|
+
line-height: 1.2;
|
|
25070
|
+
overflow-wrap: break-word;
|
|
25071
|
+
}
|
|
25072
|
+
:host([invalid]) .error-message {
|
|
25073
|
+
display: block;
|
|
25074
|
+
}
|
|
25075
|
+
.buttons-row {
|
|
25076
|
+
display: none;
|
|
25077
|
+
}
|
|
25078
|
+
:host([display-variant="buttons"]) .icon-wrapper {
|
|
25079
|
+
display: none;
|
|
25080
|
+
}
|
|
25081
|
+
:host([display-variant="buttons"]) .buttons-row {
|
|
25082
|
+
display: flex;
|
|
25083
|
+
flex-wrap: wrap;
|
|
25084
|
+
}
|
|
25085
|
+
/* grow to fill equally; don't shrink below content, so they wrap to a new line
|
|
25086
|
+
when they don't fit (like a container with auto-fit items) */
|
|
25087
|
+
.buttons-row > descope-button {
|
|
25088
|
+
flex: 1 0 auto;
|
|
25089
|
+
}
|
|
24991
25090
|
`,
|
|
24992
25091
|
this,
|
|
24993
25092
|
);
|
|
@@ -25001,41 +25100,190 @@ class RawRecoveryCodes extends createBaseClass$1({
|
|
|
25001
25100
|
return this.getAttribute('mode');
|
|
25002
25101
|
}
|
|
25003
25102
|
|
|
25103
|
+
// the form value read by the flow SDK (#getFormData reads `.value`)
|
|
25104
|
+
get value() {
|
|
25105
|
+
return this.#action;
|
|
25106
|
+
}
|
|
25107
|
+
|
|
25108
|
+
// a boolean attribute is "on" when present and not explicitly "false"
|
|
25109
|
+
#boolAttr(name) {
|
|
25110
|
+
return this.hasAttribute(name) && this.getAttribute(name) !== 'false';
|
|
25111
|
+
}
|
|
25112
|
+
|
|
25113
|
+
get isRequired() {
|
|
25114
|
+
return this.#boolAttr('required');
|
|
25115
|
+
}
|
|
25116
|
+
|
|
25117
|
+
get isReadOnly() {
|
|
25118
|
+
return this.#boolAttr('readonly');
|
|
25119
|
+
}
|
|
25120
|
+
|
|
25121
|
+
get errorMessage() {
|
|
25122
|
+
return (
|
|
25123
|
+
this.getAttribute('data-errormessage-value-missing') ||
|
|
25124
|
+
DEFAULT_ERROR_MESSAGE
|
|
25125
|
+
);
|
|
25126
|
+
}
|
|
25127
|
+
|
|
25128
|
+
get codesText() {
|
|
25129
|
+
return String((this.data || []).map((rc) => rc.value).join('\n'));
|
|
25130
|
+
}
|
|
25131
|
+
|
|
25004
25132
|
init() {
|
|
25005
25133
|
super.init();
|
|
25006
25134
|
|
|
25007
|
-
this.
|
|
25135
|
+
this.copyIcon.addEventListener('click', this.onCopy.bind(this));
|
|
25136
|
+
this.downloadIcon.addEventListener('click', this.onDownload.bind(this));
|
|
25008
25137
|
|
|
25009
25138
|
forwardAttrs$1(this, this.iconWrapper, { includeAttrs: ['variant', 'mode'] });
|
|
25139
|
+
|
|
25140
|
+
this.renderButtons();
|
|
25141
|
+
this.#initialized = true;
|
|
25010
25142
|
}
|
|
25011
25143
|
|
|
25012
|
-
|
|
25013
|
-
|
|
25014
|
-
|
|
25144
|
+
get isDownloadEnabled() {
|
|
25145
|
+
return this.getAttribute('show-download') === 'true';
|
|
25146
|
+
}
|
|
25147
|
+
|
|
25148
|
+
// buttons variant: copy (+ download when enabled) as descope-buttons, each independently
|
|
25149
|
+
// configurable. rendered even in the icons variant (CSS hides the row) so a variant switch is instant.
|
|
25150
|
+
renderButtons() {
|
|
25151
|
+
if (!this.buttonsRow) return;
|
|
25152
|
+
|
|
25153
|
+
const buttons = [this.buildButton('copy')];
|
|
25154
|
+
if (this.isDownloadEnabled) {
|
|
25155
|
+
buttons.push(this.buildButton('download'));
|
|
25156
|
+
}
|
|
25157
|
+
this.buttonsRow.replaceChildren(...buttons);
|
|
25158
|
+
}
|
|
25159
|
+
|
|
25160
|
+
buildButton(action) {
|
|
25161
|
+
const { defaultText } = ACTIONS[action];
|
|
25162
|
+
const attr = (name, fallback) =>
|
|
25163
|
+
this.getAttribute(`${action}-${name}`) || fallback;
|
|
25164
|
+
|
|
25165
|
+
const button = document.createElement('descope-button');
|
|
25166
|
+
button.setAttribute('data-action', action);
|
|
25167
|
+
button.setAttribute('variant', attr('variant', 'outline'));
|
|
25168
|
+
button.setAttribute('mode', attr('color', 'primary'));
|
|
25169
|
+
button.setAttribute('size', attr('size', 'md'));
|
|
25170
|
+
|
|
25171
|
+
// icon is an image src - the seeded glyph or a custom upload (light/dark),
|
|
25172
|
+
// same as the standard button's start icon. rendered via descope-icon in the
|
|
25173
|
+
// default slot (not slot="prefix") so it centers with the label when the
|
|
25174
|
+
// button grows. descope-icon inlines SVGs, so the glyph (authored with
|
|
25175
|
+
// fill="currentColor") tracks the button text color while an uploaded image
|
|
25176
|
+
// keeps its own colors.
|
|
25177
|
+
const iconSrc = this.getAttribute(`${action}-icon`);
|
|
25178
|
+
if (iconSrc) {
|
|
25179
|
+
const icon = document.createElement('descope-icon');
|
|
25180
|
+
icon.setAttribute('src', iconSrc);
|
|
25181
|
+
const iconDark = this.getAttribute(`${action}-icon-dark`);
|
|
25182
|
+
if (iconDark) icon.setAttribute('src-dark', iconDark);
|
|
25183
|
+
button.appendChild(icon);
|
|
25184
|
+
}
|
|
25185
|
+
|
|
25186
|
+
button.appendChild(document.createTextNode(attr('text', defaultText)));
|
|
25187
|
+
button.addEventListener('click', () =>
|
|
25188
|
+
action === 'copy' ? this.onCopy() : this.onDownload(),
|
|
25015
25189
|
);
|
|
25190
|
+
return button;
|
|
25191
|
+
}
|
|
25016
25192
|
|
|
25017
|
-
|
|
25018
|
-
this.
|
|
25019
|
-
|
|
25193
|
+
onCopy() {
|
|
25194
|
+
if (this.isReadOnly) return;
|
|
25195
|
+
navigator.clipboard.writeText(this.codesText);
|
|
25196
|
+
this.showActionFeedback(this.copyIcon, 'Copied');
|
|
25197
|
+
this.recordAction('copied');
|
|
25198
|
+
}
|
|
25020
25199
|
|
|
25021
|
-
|
|
25022
|
-
|
|
25023
|
-
|
|
25024
|
-
|
|
25200
|
+
onDownload() {
|
|
25201
|
+
if (this.isReadOnly) return;
|
|
25202
|
+
const blob = new Blob([this.codesText], { type: 'text/plain' });
|
|
25203
|
+
const url = URL.createObjectURL(blob);
|
|
25204
|
+
const anchor = document.createElement('a');
|
|
25205
|
+
anchor.href = url;
|
|
25206
|
+
anchor.download = 'recovery-codes.txt';
|
|
25207
|
+
anchor.click();
|
|
25208
|
+
URL.revokeObjectURL(url);
|
|
25209
|
+
|
|
25210
|
+
this.showActionFeedback(this.downloadIcon, 'Downloaded');
|
|
25211
|
+
this.recordAction('downloaded');
|
|
25212
|
+
}
|
|
25213
|
+
|
|
25214
|
+
// copy/download share this - only the visual feedback differs by variant
|
|
25215
|
+
recordAction(action) {
|
|
25216
|
+
this.#action = action;
|
|
25217
|
+
// let the flow re-evaluate real-time conditions and pick up the new value
|
|
25218
|
+
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
25219
|
+
// acting clears the mandatory error
|
|
25220
|
+
if (this.checkValidity()) {
|
|
25221
|
+
this.#showError = false;
|
|
25222
|
+
}
|
|
25223
|
+
this.syncValidityUI();
|
|
25224
|
+
}
|
|
25225
|
+
|
|
25226
|
+
// icons variant: swap the icon to a checkmark for 5s (buttons variant is static)
|
|
25227
|
+
showActionFeedback(iconEle, doneTitle) {
|
|
25228
|
+
// on a rapid re-click the checkmark is already showing, so cancel the pending restore
|
|
25229
|
+
// and keep the glyph/title we saved the first time (never capture the checkmark itself)
|
|
25230
|
+
if (iconEle.feedbackTimer) {
|
|
25231
|
+
clearTimeout(iconEle.feedbackTimer);
|
|
25232
|
+
} else {
|
|
25233
|
+
iconEle.originalIcon = iconEle.getAttribute('icon');
|
|
25234
|
+
iconEle.originalTitle = iconEle.getAttribute('title');
|
|
25235
|
+
}
|
|
25236
|
+
|
|
25237
|
+
iconEle.setAttribute('icon', 'vaadin:check-circle-o');
|
|
25238
|
+
iconEle.setAttribute('title', doneTitle);
|
|
25239
|
+
iconEle.classList.add('copied');
|
|
25240
|
+
|
|
25241
|
+
iconEle.feedbackTimer = setTimeout(() => {
|
|
25242
|
+
iconEle.setAttribute('icon', iconEle.originalIcon);
|
|
25243
|
+
iconEle.setAttribute('title', iconEle.originalTitle);
|
|
25244
|
+
iconEle.classList.remove('copied');
|
|
25245
|
+
iconEle.feedbackTimer = null;
|
|
25025
25246
|
}, 5000);
|
|
25026
25247
|
}
|
|
25027
25248
|
|
|
25028
|
-
|
|
25029
|
-
|
|
25249
|
+
// the flow SDK's #validateInputs calls checkValidity/reportValidity on every *[name]
|
|
25250
|
+
checkValidity() {
|
|
25251
|
+
return this.isReadOnly || !this.isRequired || this.value !== NO_ACTION;
|
|
25252
|
+
}
|
|
25253
|
+
|
|
25254
|
+
reportValidity() {
|
|
25255
|
+
const valid = this.checkValidity();
|
|
25256
|
+
this.#showError = !valid;
|
|
25257
|
+
this.syncValidityUI();
|
|
25258
|
+
return valid;
|
|
25259
|
+
}
|
|
25260
|
+
|
|
25261
|
+
// single source of truth for the error UI - reflects `invalid` (theme `_invalid`
|
|
25262
|
+
// draws the outline) and fills the message. never toggled anywhere else.
|
|
25263
|
+
syncValidityUI() {
|
|
25264
|
+
this.toggleAttribute('invalid', this.#showError);
|
|
25265
|
+
if (this.errorMessageEle) {
|
|
25266
|
+
this.errorMessageEle.textContent = this.#showError
|
|
25267
|
+
? this.errorMessage
|
|
25268
|
+
: '';
|
|
25269
|
+
}
|
|
25030
25270
|
}
|
|
25031
25271
|
|
|
25032
25272
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
|
25033
25273
|
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
|
25034
25274
|
|
|
25035
|
-
if (newValue
|
|
25036
|
-
|
|
25037
|
-
|
|
25038
|
-
|
|
25275
|
+
if (newValue === oldValue) return;
|
|
25276
|
+
|
|
25277
|
+
// if it stops being required, drop any error already shown
|
|
25278
|
+
if (attrName === 'required' && !this.isRequired) {
|
|
25279
|
+
this.#showError = false;
|
|
25280
|
+
this.syncValidityUI();
|
|
25281
|
+
}
|
|
25282
|
+
|
|
25283
|
+
// only rebuild for live edits after init (init already built once with all attrs);
|
|
25284
|
+
// avoids rebuilding once per attribute during the initial element upgrade
|
|
25285
|
+
if (this.#initialized && BUTTON_ATTRS.includes(attrName)) {
|
|
25286
|
+
this.renderButtons();
|
|
25039
25287
|
}
|
|
25040
25288
|
}
|
|
25041
25289
|
}
|
|
@@ -25055,10 +25303,66 @@ const RecoveryCodesClass = compose$1(
|
|
|
25055
25303
|
textAlign: { selector: () => '.list', property: 'align-items' },
|
|
25056
25304
|
iconColor: { selector: () => 'vaadin-icon', property: 'color' },
|
|
25057
25305
|
iconSize: { selector: () => 'vaadin-icon', property: 'font-size' },
|
|
25058
|
-
iconGap: { selector: () => '.
|
|
25306
|
+
iconGap: { selector: () => '.codes-box', property: 'gap' },
|
|
25307
|
+
iconStackGap: { selector: () => '.icons', property: 'gap' },
|
|
25308
|
+
buttonsGap: { selector: () => '.buttons-row', property: 'gap' },
|
|
25309
|
+
sectionsGap: { selector: () => '.wrapper', property: 'gap' },
|
|
25059
25310
|
bulletGap: { selector: () => 'descope-text span', property: 'gap' },
|
|
25311
|
+
// top + bottom padding sit inside the border (below the codes) in both variants; in the
|
|
25312
|
+
// buttons variant the bottom padding also repeats below the buttons (the buttons-row entry
|
|
25313
|
+
// is inert in the icons variant, where the row is display:none).
|
|
25314
|
+
verticalPadding: [
|
|
25315
|
+
{ selector: () => '.codes-box', property: 'padding-top' },
|
|
25316
|
+
{ selector: () => '.codes-box', property: 'padding-bottom' },
|
|
25317
|
+
{ selector: () => '.buttons-row', property: 'padding-bottom' },
|
|
25318
|
+
],
|
|
25319
|
+
// horizontal padding insets the codes (inside the border) and the buttons, but NOT the
|
|
25320
|
+
// error message, which stays aligned to the component edge (like the input error).
|
|
25321
|
+
horizontalPadding: [
|
|
25322
|
+
{ selector: () => '.codes-box', property: 'padding-left' },
|
|
25323
|
+
{ selector: () => '.codes-box', property: 'padding-right' },
|
|
25324
|
+
{ selector: () => '.buttons-row', property: 'padding-left' },
|
|
25325
|
+
{ selector: () => '.buttons-row', property: 'padding-right' },
|
|
25326
|
+
],
|
|
25327
|
+
errorBorderColor: {
|
|
25328
|
+
selector: () => '.codes-box',
|
|
25329
|
+
property: 'border-color',
|
|
25330
|
+
},
|
|
25331
|
+
errorMessageColor: {
|
|
25332
|
+
selector: () => '.error-message',
|
|
25333
|
+
property: 'color',
|
|
25334
|
+
},
|
|
25335
|
+
errorMessageFontSize: {
|
|
25336
|
+
selector: () => '.error-message',
|
|
25337
|
+
property: 'font-size',
|
|
25338
|
+
},
|
|
25339
|
+
errorMessageFontWeight: {
|
|
25340
|
+
selector: () => '.error-message',
|
|
25341
|
+
property: 'font-weight',
|
|
25342
|
+
},
|
|
25343
|
+
errorMessageFontFamily: {
|
|
25344
|
+
selector: () => '.error-message',
|
|
25345
|
+
property: 'font-family',
|
|
25346
|
+
},
|
|
25347
|
+
boxBorderRadius: {
|
|
25348
|
+
selector: () => '.codes-box',
|
|
25349
|
+
property: 'border-radius',
|
|
25350
|
+
},
|
|
25351
|
+
errorBorderWidth: {
|
|
25352
|
+
selector: () => '.codes-box',
|
|
25353
|
+
property: 'border-width',
|
|
25354
|
+
},
|
|
25355
|
+
boxBorderStyle: {
|
|
25356
|
+
selector: () => '.codes-box',
|
|
25357
|
+
property: 'border-style',
|
|
25358
|
+
},
|
|
25060
25359
|
},
|
|
25061
25360
|
}),
|
|
25361
|
+
// also inject the shared input-wrapper theme onto our host (like the input components do),
|
|
25362
|
+
// so the error message + border track the console "customize inputs" tokens
|
|
25363
|
+
createStyleMixin$1({
|
|
25364
|
+
componentNameOverride: getComponentName$1('input-wrapper'),
|
|
25365
|
+
}),
|
|
25062
25366
|
createDynamicDataMixin$1({
|
|
25063
25367
|
itemRenderer: itemRenderer$4,
|
|
25064
25368
|
rerenderAttrsList: ['variant', 'mode'],
|
|
@@ -25077,9 +25381,33 @@ const recoveryCodes = {
|
|
|
25077
25381
|
[vars$T.hostDirection]: globalRefs$t.direction,
|
|
25078
25382
|
[vars$T.iconColor]: useVar$1(textVars$1.textColor),
|
|
25079
25383
|
[vars$T.iconSize]: useVar$1(textVars$1.fontSize),
|
|
25384
|
+
// gap between the codes and the icon column
|
|
25080
25385
|
[vars$T.iconGap]: '8px',
|
|
25386
|
+
// gap between the stacked copy and download icons
|
|
25387
|
+
[vars$T.iconStackGap]: '16px',
|
|
25388
|
+
// gap between the copy and download buttons (buttons variant)
|
|
25389
|
+
[vars$T.buttonsGap]: '8px',
|
|
25390
|
+
// gap between the codes, the error message and the buttons
|
|
25391
|
+
[vars$T.sectionsGap]: '8px',
|
|
25081
25392
|
[vars$T.bulletGap]: '0.35em',
|
|
25082
25393
|
|
|
25394
|
+
// no padding by default so the current look is unchanged; the editor overrides per instance
|
|
25395
|
+
[vars$T.verticalPadding]: '0',
|
|
25396
|
+
[vars$T.horizontalPadding]: '0',
|
|
25397
|
+
|
|
25398
|
+
// error ring is transparent until the component is marked invalid (see _invalid below).
|
|
25399
|
+
// message color/font + border come from the shared input-wrapper tokens, so customizing
|
|
25400
|
+
// inputs in the console updates the recovery-codes error styling from the same place.
|
|
25401
|
+
[vars$T.errorBorderColor]: 'transparent',
|
|
25402
|
+
[vars$T.errorBorderWidth]: refs$1.borderWidth,
|
|
25403
|
+
[vars$T.boxBorderRadius]: refs$1.borderRadius,
|
|
25404
|
+
// local default; can later map to the input-wrapper border style if it exposes one
|
|
25405
|
+
[vars$T.boxBorderStyle]: 'solid',
|
|
25406
|
+
[vars$T.errorMessageColor]: refs$1.errorMessageTextColor,
|
|
25407
|
+
[vars$T.errorMessageFontSize]: refs$1.errorMessageFontSize,
|
|
25408
|
+
[vars$T.errorMessageFontWeight]: refs$1.errorMessageFontWeight,
|
|
25409
|
+
[vars$T.errorMessageFontFamily]: refs$1.fontFamily,
|
|
25410
|
+
|
|
25083
25411
|
textAlign: {
|
|
25084
25412
|
right: { [vars$T.textAlign]: 'flex-end' },
|
|
25085
25413
|
left: { [vars$T.textAlign]: 'flex-start' },
|
|
@@ -25089,6 +25417,11 @@ const recoveryCodes = {
|
|
|
25089
25417
|
_fullWidth: {
|
|
25090
25418
|
[vars$T.hostWidth]: '100%',
|
|
25091
25419
|
},
|
|
25420
|
+
|
|
25421
|
+
// reflected `invalid` attribute (set by the component on a failed submit)
|
|
25422
|
+
_invalid: {
|
|
25423
|
+
[vars$T.errorBorderColor]: refs$1.errorMessageTextColor,
|
|
25424
|
+
},
|
|
25092
25425
|
};
|
|
25093
25426
|
|
|
25094
25427
|
var recoveryCodes$1 = /*#__PURE__*/Object.freeze({
|