@descope/web-components-ui 1.0.371 → 1.0.372
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/cjs/index.cjs.js +392 -9
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +395 -10
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/4392.js +1 -1
- package/dist/umd/4978.js +1 -1
- package/dist/umd/DescopeDev.js +1 -1
- package/dist/umd/descope-email-field-index-js.js +2 -2
- package/dist/umd/descope-new-password-descope-new-password-internal-index-js.js +1 -1
- package/dist/umd/descope-new-password-index-js.js +1 -1
- package/dist/umd/descope-number-field-index-js.js +1 -1
- package/dist/umd/descope-passcode-index-js.js +1 -1
- package/dist/umd/descope-password-index-js.js +1 -1
- package/dist/umd/descope-radio-group-index-js.js +1 -1
- package/dist/umd/descope-text-field-index-js.js +1 -1
- package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +1 -1
- package/package.json +1 -1
- package/src/components/descope-email-field/EmailFieldClass.js +12 -0
- package/src/components/descope-new-password/NewPasswordClass.js +35 -0
- package/src/components/descope-new-password/descope-new-password-internal/NewPasswordInternal.js +3 -1
- package/src/components/descope-password/PasswordClass.js +59 -1
- package/src/components/descope-text-field/textFieldMappings.js +37 -6
- package/src/mixins/externalInputHelpers.js +86 -0
- package/src/mixins/externalInputMixin.js +165 -0
- package/src/mixins/index.js +1 -0
- package/src/mixins/proxyInputMixin.js +5 -2
package/dist/index.esm.js
CHANGED
@@ -1008,7 +1008,7 @@ const proxyInputMixin =
|
|
1008
1008
|
({
|
1009
1009
|
proxyProps = [],
|
1010
1010
|
// useProxyTargets flag allows to forwardProps to other targets, other than
|
1011
|
-
// `this.inputElement`.
|
1011
|
+
// `this.inputElement`. It's to be used within `external-input` components,
|
1012
1012
|
// if needed
|
1013
1013
|
useProxyTargets = false,
|
1014
1014
|
// allows us to set the event that should trigger validation
|
@@ -1147,7 +1147,10 @@ const proxyInputMixin =
|
|
1147
1147
|
|
1148
1148
|
// sync properties
|
1149
1149
|
proxyProps.forEach((prop) => {
|
1150
|
-
const
|
1150
|
+
const externalInput = this.querySelector('input[slot="external-input"]') || null;
|
1151
|
+
const proxyTargets = useProxyTargets
|
1152
|
+
? [this.baseElement, externalInput].filter(Boolean)
|
1153
|
+
: [];
|
1151
1154
|
forwardProps(this, [this.inputElement, ...proxyTargets], prop);
|
1152
1155
|
});
|
1153
1156
|
|
@@ -1397,6 +1400,252 @@ const inputEventsDispatchingMixin = (superclass) =>
|
|
1397
1400
|
}
|
1398
1401
|
};
|
1399
1402
|
|
1403
|
+
// since on load we can only sample the color of the placeholder,
|
1404
|
+
// we need to temporarily populate the input in order to sample the value color
|
1405
|
+
const getValueColor = (ele, computedStyle) => {
|
1406
|
+
// eslint-disable-next-line no-param-reassign
|
1407
|
+
ele.value = '_';
|
1408
|
+
|
1409
|
+
const valueColor = computedStyle.getPropertyValue('color');
|
1410
|
+
|
1411
|
+
// eslint-disable-next-line no-param-reassign
|
1412
|
+
ele.value = '';
|
1413
|
+
|
1414
|
+
return valueColor;
|
1415
|
+
};
|
1416
|
+
|
1417
|
+
const createExternalInputSlot = (slotName, targetSlotName) => {
|
1418
|
+
const slotEle = document.createElement('slot');
|
1419
|
+
|
1420
|
+
slotEle.setAttribute('name', slotName);
|
1421
|
+
slotEle.setAttribute('slot', targetSlotName);
|
1422
|
+
|
1423
|
+
return slotEle;
|
1424
|
+
};
|
1425
|
+
|
1426
|
+
const createExternalInputEle = (targetSlotName, type, autocompleteType) => {
|
1427
|
+
const inputEle = document.createElement('input');
|
1428
|
+
|
1429
|
+
inputEle.setAttribute('slot', targetSlotName);
|
1430
|
+
inputEle.setAttribute('type', type);
|
1431
|
+
inputEle.setAttribute('data-hidden-input', 'true');
|
1432
|
+
inputEle.setAttribute('autocomplete', autocompleteType);
|
1433
|
+
|
1434
|
+
return inputEle;
|
1435
|
+
};
|
1436
|
+
|
1437
|
+
// We apply the original input's style to the external-input.
|
1438
|
+
// Eventually, the user should interact directly with the external input.
|
1439
|
+
// We keep the original input
|
1440
|
+
const applyExternalInputStyles = (sourceInputEle, targetInputEle, labelType) => {
|
1441
|
+
// We set a timeout here to avoid "Double Print" cases,
|
1442
|
+
// caused by sampling the computed style before it's ready.
|
1443
|
+
setTimeout(() => {
|
1444
|
+
const computedStyle = getComputedStyle(sourceInputEle);
|
1445
|
+
// Get minimal set of computed theme properties to set on external input
|
1446
|
+
const height = computedStyle.getPropertyValue('height');
|
1447
|
+
const paddingLeft = computedStyle.getPropertyValue('padding-left');
|
1448
|
+
const paddingRight = computedStyle.getPropertyValue('padding-right');
|
1449
|
+
const fontSize = computedStyle.getPropertyValue('font-size');
|
1450
|
+
const fontFamily = computedStyle.getPropertyValue('font-family');
|
1451
|
+
const letterSpacing = computedStyle.getPropertyValue('letter-spacing');
|
1452
|
+
const caretColor = computedStyle.getPropertyValue('caret-color');
|
1453
|
+
|
1454
|
+
const valueColor = getValueColor(sourceInputEle, computedStyle);
|
1455
|
+
|
1456
|
+
const commonThemeStyles = [
|
1457
|
+
['all', 'unset'],
|
1458
|
+
['position', 'absolute'],
|
1459
|
+
['background-color', 'transparent'],
|
1460
|
+
['height', height],
|
1461
|
+
['left', paddingLeft],
|
1462
|
+
['right', paddingRight],
|
1463
|
+
['font-size', fontSize],
|
1464
|
+
['font-family', fontFamily],
|
1465
|
+
['letter-spacing', letterSpacing],
|
1466
|
+
['caret-color', caretColor], // this is for seeing caret when focusing on external input
|
1467
|
+
['color', valueColor],
|
1468
|
+
];
|
1469
|
+
|
1470
|
+
commonThemeStyles.forEach(([key, val]) =>
|
1471
|
+
targetInputEle.style.setProperty(key, val, 'important')
|
1472
|
+
);
|
1473
|
+
|
1474
|
+
// Handle floating label theme properties
|
1475
|
+
if (labelType === 'floating') {
|
1476
|
+
const marginBottom = computedStyle.getPropertyValue('margin-bottom');
|
1477
|
+
targetInputEle.style.setProperty('margin-bottom', marginBottom, 'important');
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
// sample and apply width only after original input is ready and fully rendered
|
1481
|
+
const width = computedStyle.getPropertyValue('width');
|
1482
|
+
targetInputEle.style.setProperty(
|
1483
|
+
'width',
|
1484
|
+
`calc(${width} - ${paddingLeft} - ${paddingRight}`,
|
1485
|
+
'important'
|
1486
|
+
);
|
1487
|
+
}, 0);
|
1488
|
+
};
|
1489
|
+
|
1490
|
+
const externalInputMixin =
|
1491
|
+
({ inputType, autocompleteType, includeAttrs = [], noBlurDispatch = false }) =>
|
1492
|
+
(superclass) =>
|
1493
|
+
class ExternalInputMixinClass extends superclass {
|
1494
|
+
#timers = [];
|
1495
|
+
|
1496
|
+
get isExternalInput() {
|
1497
|
+
return this.getAttribute('external-input') === 'true';
|
1498
|
+
}
|
1499
|
+
|
1500
|
+
createExternalInput() {
|
1501
|
+
if (!this.isExternalInput) {
|
1502
|
+
return null;
|
1503
|
+
}
|
1504
|
+
|
1505
|
+
// use original input element as reference
|
1506
|
+
const origInput = this.baseElement.querySelector('input');
|
1507
|
+
|
1508
|
+
// to avoid focus loop between external-input and origInput
|
1509
|
+
// we set origInput's tabindex to -1
|
1510
|
+
// otherwise, shift-tab will never leave the component focus
|
1511
|
+
origInput.setAttribute('tabindex', '-1');
|
1512
|
+
|
1513
|
+
// create external slot
|
1514
|
+
const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
|
1515
|
+
|
1516
|
+
// append external slot to base element
|
1517
|
+
this.baseElement.appendChild(externalInputSlot);
|
1518
|
+
|
1519
|
+
this.externalInput = createExternalInputEle(
|
1520
|
+
'external-input',
|
1521
|
+
inputType,
|
1522
|
+
this.getAutocompleteType()
|
1523
|
+
);
|
1524
|
+
|
1525
|
+
// apply original input's styles to external input
|
1526
|
+
setTimeout(() => {
|
1527
|
+
applyExternalInputStyles(origInput, this.externalInput, this.getAttribute('label-type'));
|
1528
|
+
});
|
1529
|
+
|
1530
|
+
// 1Password catches the internal input, so we forward the value to the external input
|
1531
|
+
this.forwardInputValue(origInput, this.externalInput);
|
1532
|
+
|
1533
|
+
syncAttrs(origInput, this.externalInput, {
|
1534
|
+
includeAttrs,
|
1535
|
+
});
|
1536
|
+
|
1537
|
+
// We disable Vaadin's original `_setFocused` function, and use handleFocusEvents
|
1538
|
+
// and handleBlurEvents functions
|
1539
|
+
this.baseElement
|
1540
|
+
.querySelector('input')
|
1541
|
+
.addEventListener('focusout', (e) => e.stopImmediatePropagation(), true);
|
1542
|
+
|
1543
|
+
// In order to manage focus/blur events when moving between parts of the component
|
1544
|
+
// we're managing the event dispatching by ourselves, with the following strategy:
|
1545
|
+
// - If one of the component parts is focused - it means that the component is still focused - so we stop the blur events.
|
1546
|
+
// - When none of the component parts is focused, we dispatch blur event.
|
1547
|
+
this.handleFocusEvents();
|
1548
|
+
this.handleBlurEvents();
|
1549
|
+
|
1550
|
+
// sync input value
|
1551
|
+
this.handlelInputEvents(this.externalInput);
|
1552
|
+
|
1553
|
+
// append external input to component's DOM
|
1554
|
+
this.appendChild(this.externalInput);
|
1555
|
+
|
1556
|
+
return this.externalInput;
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
clearBlurTimers() {
|
1560
|
+
this.#timers.forEach((timer) => clearTimeout(timer));
|
1561
|
+
this.#timers.length = 0;
|
1562
|
+
}
|
1563
|
+
|
1564
|
+
dispatchBlur() {
|
1565
|
+
return setTimeout(() => {
|
1566
|
+
this.dispatchEvent(new Event('blur', { bubbles: true, composed: true }));
|
1567
|
+
this.removeAttribute('focused');
|
1568
|
+
});
|
1569
|
+
}
|
1570
|
+
|
1571
|
+
handleFocusEvents() {
|
1572
|
+
// on baseElement `focus` we forward the focus to the external input.
|
1573
|
+
// also, in order to avoid any blur within the component, we clear the blur timers.
|
1574
|
+
this.baseElement.addEventListener('focus', () => {
|
1575
|
+
this.externalInput.focus();
|
1576
|
+
this.clearBlurTimers();
|
1577
|
+
});
|
1578
|
+
|
1579
|
+
// on `focus` of the external input, we manually set the `focused` attribute
|
1580
|
+
this.externalInput.addEventListener('focus', () => {
|
1581
|
+
this.clearBlurTimers();
|
1582
|
+
setTimeout(() => this.baseElement.setAttribute('focused', 'true'));
|
1583
|
+
});
|
1584
|
+
}
|
1585
|
+
|
1586
|
+
handleBlurEvents() {
|
1587
|
+
this.baseElement.addEventListener(
|
1588
|
+
'blur',
|
1589
|
+
(e) => {
|
1590
|
+
e.stopImmediatePropagation();
|
1591
|
+
// some components do not require this synthetic blur dispatch (e.g. Password)
|
1592
|
+
// so we allow them to override this dispatch
|
1593
|
+
if (noBlurDispatch) return;
|
1594
|
+
this.#timers.push(this.dispatchBlur());
|
1595
|
+
},
|
1596
|
+
true
|
1597
|
+
);
|
1598
|
+
|
1599
|
+
this.externalInput.addEventListener(
|
1600
|
+
'blur',
|
1601
|
+
(e) => {
|
1602
|
+
e.stopImmediatePropagation();
|
1603
|
+
this.#timers.push(this.dispatchBlur());
|
1604
|
+
},
|
1605
|
+
true
|
1606
|
+
);
|
1607
|
+
}
|
1608
|
+
|
1609
|
+
handlelInputEvents(externalInput) {
|
1610
|
+
// sync value of insible input back to original input
|
1611
|
+
externalInput.addEventListener('input', (e) => {
|
1612
|
+
this.value = e.target.value;
|
1613
|
+
});
|
1614
|
+
|
1615
|
+
// handle has-value attr
|
1616
|
+
externalInput.addEventListener('input', (e) => {
|
1617
|
+
if (!e.target.value) {
|
1618
|
+
this.removeAttribute('has-value');
|
1619
|
+
} else {
|
1620
|
+
this.setAttribute('has-value', 'true');
|
1621
|
+
}
|
1622
|
+
});
|
1623
|
+
}
|
1624
|
+
|
1625
|
+
getAutocompleteType() {
|
1626
|
+
return this.getAttribute('autocomplete') || autocompleteType;
|
1627
|
+
}
|
1628
|
+
|
1629
|
+
forwardInputValue(source, target) {
|
1630
|
+
// set internal sync events
|
1631
|
+
const valueDescriptor = Object.getOwnPropertyDescriptor(
|
1632
|
+
this.inputElement.constructor.prototype,
|
1633
|
+
'value'
|
1634
|
+
);
|
1635
|
+
|
1636
|
+
Object.defineProperty(source, 'value', {
|
1637
|
+
...valueDescriptor,
|
1638
|
+
|
1639
|
+
set(v) {
|
1640
|
+
valueDescriptor.set.call(this, v);
|
1641
|
+
// eslint-disable-next-line no-param-reassign
|
1642
|
+
target.value = v;
|
1643
|
+
},
|
1644
|
+
configurable: true,
|
1645
|
+
});
|
1646
|
+
}
|
1647
|
+
};
|
1648
|
+
|
1400
1649
|
const getFileExtension = (path) => {
|
1401
1650
|
const match = path.match(/\.([0-9a-z]+)(?:[\\?#]|$)/i);
|
1402
1651
|
return match ? match[1] : null;
|
@@ -2601,6 +2850,10 @@ const {
|
|
2601
2850
|
disabledPlaceholder,
|
2602
2851
|
inputDisabled,
|
2603
2852
|
inputIcon,
|
2853
|
+
externalInput,
|
2854
|
+
externalInputDisabled,
|
2855
|
+
externalPlaceholder,
|
2856
|
+
externalDisabledPlaceholder,
|
2604
2857
|
} = {
|
2605
2858
|
host: { selector: () => ':host' },
|
2606
2859
|
label: { selector: '::part(label)' },
|
@@ -2617,6 +2870,10 @@ const {
|
|
2617
2870
|
helperText: { selector: '::part(helper-text)' },
|
2618
2871
|
errorMessage: { selector: '::part(error-message)' },
|
2619
2872
|
inputIcon: { selector: 'vaadin-icon' },
|
2873
|
+
externalInput: { selector: () => '::slotted(input)' },
|
2874
|
+
externalInputDisabled: { selector: () => '::slotted(input:disabled)' },
|
2875
|
+
externalPlaceholder: { selector: () => '::slotted(input:placeholder-shown)' },
|
2876
|
+
externalDisabledPlaceholder: { selector: () => '::slotted(input:disabled::placeholder)' },
|
2620
2877
|
};
|
2621
2878
|
|
2622
2879
|
var textFieldMappings = {
|
@@ -2649,8 +2906,12 @@ var textFieldMappings = {
|
|
2649
2906
|
inputValueTextColor: [
|
2650
2907
|
{ ...inputField$6, property: 'color' },
|
2651
2908
|
{ ...inputDisabled, property: '-webkit-text-fill-color' },
|
2909
|
+
{ ...externalInputDisabled, property: '-webkit-text-fill-color' },
|
2910
|
+
],
|
2911
|
+
inputCaretTextColor: [
|
2912
|
+
{ ...input, property: 'caret-color' },
|
2913
|
+
{ ...externalInput, property: 'caret-color' },
|
2652
2914
|
],
|
2653
|
-
inputCaretTextColor: [{ ...input, property: 'color' }],
|
2654
2915
|
|
2655
2916
|
labelRequiredIndicator: { ...requiredIndicator$9, property: 'content' },
|
2656
2917
|
|
@@ -2663,6 +2924,8 @@ var textFieldMappings = {
|
|
2663
2924
|
inputHorizontalPadding: [
|
2664
2925
|
{ ...input, property: 'padding-left' },
|
2665
2926
|
{ ...input, property: 'padding-right' },
|
2927
|
+
{ ...externalInput, property: 'padding-left' },
|
2928
|
+
{ ...externalInput, property: 'padding-right' },
|
2666
2929
|
],
|
2667
2930
|
|
2668
2931
|
inputOutlineColor: { ...inputField$6, property: 'outline-color' },
|
@@ -2670,12 +2933,17 @@ var textFieldMappings = {
|
|
2670
2933
|
inputOutlineWidth: { ...inputField$6, property: 'outline-width' },
|
2671
2934
|
inputOutlineOffset: { ...inputField$6, property: 'outline-offset' },
|
2672
2935
|
|
2673
|
-
inputTextAlign: [
|
2936
|
+
inputTextAlign: [
|
2937
|
+
{ ...input, property: 'text-align' },
|
2938
|
+
{ ...externalInput, property: 'text-align' },
|
2939
|
+
],
|
2674
2940
|
|
2675
2941
|
inputPlaceholderColor: [
|
2676
2942
|
{ selector: () => ':host input:placeholder-shown', property: 'color' },
|
2943
|
+
{ ...externalPlaceholder, property: 'color' },
|
2677
2944
|
{ ...placeholder$3, property: 'color' },
|
2678
2945
|
{ ...disabledPlaceholder, property: '-webkit-text-fill-color' },
|
2946
|
+
{ ...externalDisabledPlaceholder, property: '-webkit-text-fill-color' },
|
2679
2947
|
],
|
2680
2948
|
|
2681
2949
|
labelPosition: { ...label$9, property: 'position' },
|
@@ -2687,10 +2955,22 @@ var textFieldMappings = {
|
|
2687
2955
|
inputTransformY: { ...label$9, property: 'transform' },
|
2688
2956
|
inputTransition: { ...label$9, property: 'transition' },
|
2689
2957
|
marginInlineStart: { ...label$9, property: 'margin-inline-start' },
|
2690
|
-
placeholderOpacity: [
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2958
|
+
placeholderOpacity: [
|
2959
|
+
{ selector: '> input:placeholder-shown', property: 'opacity' },
|
2960
|
+
{ ...externalPlaceholder, property: 'opacity' },
|
2961
|
+
],
|
2962
|
+
inputVerticalAlignment: [
|
2963
|
+
{ ...inputField$6, property: 'align-items' },
|
2964
|
+
{ ...externalInput, property: 'align-items' },
|
2965
|
+
],
|
2966
|
+
valueInputHeight: [
|
2967
|
+
{ ...input, property: 'height' },
|
2968
|
+
{ ...externalInput, property: 'height' },
|
2969
|
+
],
|
2970
|
+
valueInputMarginBottom: [
|
2971
|
+
{ ...input, property: 'margin-bottom' },
|
2972
|
+
{ ...externalInput, property: 'margin-bottom' },
|
2973
|
+
],
|
2694
2974
|
|
2695
2975
|
inputIconOffset: [
|
2696
2976
|
{ ...inputIcon, property: 'margin-right' },
|
@@ -2716,6 +2996,8 @@ const customMixin$c = (superclass) =>
|
|
2716
2996
|
if (!this.getAttribute('autocomplete')) {
|
2717
2997
|
this.setAttribute('autocomplete', defaultAutocomplete);
|
2718
2998
|
}
|
2999
|
+
|
3000
|
+
this.createExternalInput();
|
2719
3001
|
}
|
2720
3002
|
};
|
2721
3003
|
|
@@ -2724,6 +3006,11 @@ const EmailFieldClass = compose(
|
|
2724
3006
|
mappings: textFieldMappings,
|
2725
3007
|
}),
|
2726
3008
|
draggableMixin,
|
3009
|
+
externalInputMixin({
|
3010
|
+
inputType: 'text',
|
3011
|
+
autocompleteType: 'username',
|
3012
|
+
includeAttrs: ['disabled', 'readonly', 'pattern'],
|
3013
|
+
}),
|
2727
3014
|
composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
|
2728
3015
|
componentNameValidationMixin,
|
2729
3016
|
customMixin$c
|
@@ -2755,6 +3042,10 @@ const EmailFieldClass = compose(
|
|
2755
3042
|
:host ::slotted(*) {
|
2756
3043
|
-webkit-mask-image: none;
|
2757
3044
|
}
|
3045
|
+
|
3046
|
+
vaadin-email-field[external-input="true"] > input:not(:placeholder-shown) {
|
3047
|
+
opacity: 0;
|
3048
|
+
}
|
2758
3049
|
`,
|
2759
3050
|
excludeAttrsSync: ['tabindex'],
|
2760
3051
|
componentName: componentName$Q,
|
@@ -3593,6 +3884,15 @@ const customMixin$9 = (superclass) =>
|
|
3593
3884
|
this.origSetPasswordVisible = this.baseElement._setPasswordVisible;
|
3594
3885
|
this.origSetFocused = this.baseElement._setFocused;
|
3595
3886
|
this.baseElement._setFocused = this.setFocus.bind(this);
|
3887
|
+
|
3888
|
+
this.initExternalInput();
|
3889
|
+
}
|
3890
|
+
|
3891
|
+
initExternalInput() {
|
3892
|
+
const externalInput = this.createExternalInput();
|
3893
|
+
if (externalInput) {
|
3894
|
+
this.handlePasswordVisibility(externalInput);
|
3895
|
+
}
|
3596
3896
|
}
|
3597
3897
|
|
3598
3898
|
get caretPosition() {
|
@@ -3607,6 +3907,7 @@ const customMixin$9 = (superclass) =>
|
|
3607
3907
|
setTimeout(() => {
|
3608
3908
|
origTogglePasswordVisibility();
|
3609
3909
|
this.inputElement.setSelectionRange(this.caretPosition, this.caretPosition);
|
3910
|
+
return false;
|
3610
3911
|
});
|
3611
3912
|
};
|
3612
3913
|
}
|
@@ -3633,6 +3934,44 @@ const customMixin$9 = (superclass) =>
|
|
3633
3934
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
3634
3935
|
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
3635
3936
|
}
|
3937
|
+
|
3938
|
+
// override vaadin's password visibility toggle.
|
3939
|
+
// we need this override in order to to resolve the external input `focus` race condition,
|
3940
|
+
// which is caused due to the focus sync between the two inputs.
|
3941
|
+
handlePasswordVisibility(externalInput) {
|
3942
|
+
// disable vaadin's `__boundRevealButtonMouseDown` mouse-down event lisetener
|
3943
|
+
const origBoundRevealButtonMouseDown = this.baseElement.__boundRevealButtonMouseDown;
|
3944
|
+
this.baseElement
|
3945
|
+
.querySelector('vaadin-password-field-button')
|
3946
|
+
.removeEventListener('mousedown', origBoundRevealButtonMouseDown);
|
3947
|
+
|
3948
|
+
// disable vaadin's `_passwordVisibleChanged` observer
|
3949
|
+
this.baseElement._passwordVisibleChanged = () => {};
|
3950
|
+
|
3951
|
+
// override vaadin's `_togglePasswordVisibility`
|
3952
|
+
this.baseElement._togglePasswordVisibility = () => {
|
3953
|
+
const currVisibility = externalInput.getAttribute('type');
|
3954
|
+
if (currVisibility === 'password') {
|
3955
|
+
this.showPasswordVisibility(externalInput);
|
3956
|
+
} else {
|
3957
|
+
this.hidePasswordVisibility(externalInput);
|
3958
|
+
}
|
3959
|
+
};
|
3960
|
+
}
|
3961
|
+
|
3962
|
+
showPasswordVisibility(input) {
|
3963
|
+
// handle input element's type
|
3964
|
+
input.setAttribute('type', 'text');
|
3965
|
+
// handle vaadin's `password-visible` attribute
|
3966
|
+
this.setAttribute('password-visible', 'true');
|
3967
|
+
}
|
3968
|
+
|
3969
|
+
hidePasswordVisibility(input) {
|
3970
|
+
// handle input element's type
|
3971
|
+
input.setAttribute('type', 'password');
|
3972
|
+
// handle vaadin's `password-visible` attribute
|
3973
|
+
this.setAttribute('password-visible', 'false');
|
3974
|
+
}
|
3636
3975
|
};
|
3637
3976
|
|
3638
3977
|
const {
|
@@ -3727,7 +4066,12 @@ const PasswordClass = compose(
|
|
3727
4066
|
},
|
3728
4067
|
}),
|
3729
4068
|
draggableMixin,
|
3730
|
-
|
4069
|
+
externalInputMixin({
|
4070
|
+
inputType: 'password',
|
4071
|
+
includeAttrs: ['disabled', 'readonly', 'pattern', 'type', 'autocomplete'],
|
4072
|
+
noBlurDispatch: true,
|
4073
|
+
}),
|
4074
|
+
composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
|
3731
4075
|
componentNameValidationMixin,
|
3732
4076
|
passwordDraggableMixin,
|
3733
4077
|
customMixin$9
|
@@ -3791,6 +4135,10 @@ const PasswordClass = compose(
|
|
3791
4135
|
::part(reveal-button) {
|
3792
4136
|
align-self: center;
|
3793
4137
|
}
|
4138
|
+
|
4139
|
+
vaadin-password-field[external-input="true"] > input:not(:placeholder-shown) {
|
4140
|
+
opacity: 0;
|
4141
|
+
}
|
3794
4142
|
`,
|
3795
4143
|
excludeAttrsSync: ['tabindex'],
|
3796
4144
|
componentName: componentName$H,
|
@@ -6918,11 +7266,14 @@ const customMixin$6 = (superclass) =>
|
|
6918
7266
|
|
6919
7267
|
const template = document.createElement('template');
|
6920
7268
|
|
7269
|
+
const externalInputAttr = this.getAttribute('external-input');
|
7270
|
+
|
6921
7271
|
template.innerHTML = `
|
6922
7272
|
<${componentName$y}
|
6923
7273
|
name="new-password"
|
6924
7274
|
tabindex="-1"
|
6925
7275
|
slot="input"
|
7276
|
+
external-input="${externalInputAttr}"
|
6926
7277
|
>
|
6927
7278
|
</${componentName$y}>
|
6928
7279
|
`;
|
@@ -6931,6 +7282,10 @@ const customMixin$6 = (superclass) =>
|
|
6931
7282
|
|
6932
7283
|
this.inputElement = this.shadowRoot.querySelector(componentName$y);
|
6933
7284
|
|
7285
|
+
if (this.getAttribute('external-input') === 'true') {
|
7286
|
+
this.initExternalInput();
|
7287
|
+
}
|
7288
|
+
|
6934
7289
|
forwardAttrs(this, this.inputElement, {
|
6935
7290
|
includeAttrs: [
|
6936
7291
|
'password-label',
|
@@ -6955,6 +7310,34 @@ const customMixin$6 = (superclass) =>
|
|
6955
7310
|
],
|
6956
7311
|
});
|
6957
7312
|
}
|
7313
|
+
|
7314
|
+
createSlottedExternalInput(node, slotName) {
|
7315
|
+
const externalInput = node.querySelector('input');
|
7316
|
+
const slotEle = document.createElement('slot');
|
7317
|
+
|
7318
|
+
const targetSlot = externalInput.getAttribute('slot');
|
7319
|
+
|
7320
|
+
slotEle.setAttribute('name', slotName);
|
7321
|
+
slotEle.setAttribute('slot', targetSlot);
|
7322
|
+
|
7323
|
+
node.appendChild(slotEle);
|
7324
|
+
|
7325
|
+
// move external input
|
7326
|
+
externalInput.setAttribute('slot', slotName);
|
7327
|
+
externalInput.setAttribute('data-hidden-input', 'true');
|
7328
|
+
|
7329
|
+
this.appendChild(externalInput);
|
7330
|
+
}
|
7331
|
+
|
7332
|
+
initExternalInput() {
|
7333
|
+
// get descope input components
|
7334
|
+
this.passwordInput = this.inputElement.querySelector('[data-id="password"]');
|
7335
|
+
this.confirmInput = this.inputElement.querySelector('[data-id="confirm"]');
|
7336
|
+
|
7337
|
+
// create slots for external password input
|
7338
|
+
this.createSlottedExternalInput(this.passwordInput, 'external-password-input');
|
7339
|
+
this.createSlottedExternalInput(this.confirmInput, 'external-confirm-input');
|
7340
|
+
}
|
6958
7341
|
};
|
6959
7342
|
|
6960
7343
|
const {
|
@@ -7181,24 +7564,26 @@ class NewPasswordInternal extends BaseInputClass$4 {
|
|
7181
7564
|
this.passwordInput.focus();
|
7182
7565
|
}
|
7183
7566
|
});
|
7184
|
-
|
7185
7567
|
super.init?.();
|
7186
7568
|
this.renderInputs(this.hasConfirm, this.hasValidation);
|
7187
7569
|
}
|
7188
7570
|
|
7189
7571
|
renderInputs() {
|
7572
|
+
const hasExternalInput = this.getAttribute('external-input') === 'true';
|
7190
7573
|
const template = `
|
7191
7574
|
<div>
|
7192
7575
|
<descope-password
|
7193
7576
|
autocomplete="new-password"
|
7194
7577
|
manual-visibility-toggle="true"
|
7195
7578
|
data-id="password"
|
7579
|
+
external-input="${hasExternalInput}"
|
7196
7580
|
></descope-password>
|
7197
7581
|
<descope-policy-validation></descope-policy-validation>
|
7198
7582
|
</div>
|
7199
7583
|
<descope-password
|
7200
7584
|
autocomplete="new-password"
|
7201
7585
|
manual-visibility-toggle="true"
|
7586
|
+
external-input="${hasExternalInput}"
|
7202
7587
|
data-id="confirm"
|
7203
7588
|
></descope-password>
|
7204
7589
|
`;
|