@ionic/core 8.7.10-nightly.20251111 → 8.7.10-nightly.20251119
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/components/checkbox.js +63 -9
- package/components/ion-input.js +2 -1
- package/components/ion-select.js +7 -6
- package/components/ion-textarea.js +2 -1
- package/components/ion-toggle.js +62 -12
- package/components/notch-controller.js +153 -0
- package/components/radio-group.js +60 -7
- package/components/validity.js +1 -150
- package/dist/cjs/ion-checkbox.cjs.entry.js +60 -8
- package/dist/cjs/ion-input.cjs.entry.js +3 -2
- package/dist/cjs/ion-radio_2.cjs.entry.js +57 -6
- package/dist/cjs/ion-select_3.cjs.entry.js +7 -6
- package/dist/cjs/ion-textarea.cjs.entry.js +3 -2
- package/dist/cjs/ion-toggle.cjs.entry.js +58 -10
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{validity-C8QoAYT2.js → notch-controller-Bzqhjm4f.js} +0 -14
- package/dist/cjs/validity-BpS37YFM.js +19 -0
- package/dist/collection/components/checkbox/checkbox.js +67 -9
- package/dist/collection/components/radio-group/radio-group.js +64 -7
- package/dist/collection/components/select/select.js +5 -5
- package/dist/collection/components/toggle/toggle.js +62 -12
- package/dist/docs.json +1 -1
- package/dist/esm/ion-checkbox.entry.js +60 -8
- package/dist/esm/ion-input.entry.js +2 -1
- package/dist/esm/ion-radio_2.entry.js +57 -6
- package/dist/esm/ion-select_3.entry.js +6 -5
- package/dist/esm/ion-textarea.entry.js +2 -1
- package/dist/esm/ion-toggle.entry.js +58 -10
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{validity-B8oWougr.js → notch-controller-BwelN_JM.js} +1 -14
- package/dist/esm/validity-DJztqcrH.js +17 -0
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-40c261a3.entry.js +4 -0
- package/dist/ionic/p-4e41ea20.entry.js +4 -0
- package/dist/ionic/p-7380261c.entry.js +4 -0
- package/dist/ionic/{p-DieJyvMP.js → p-DCv9sLH2.js} +1 -1
- package/dist/ionic/p-DJztqcrH.js +4 -0
- package/dist/ionic/p-c19f63d0.entry.js +4 -0
- package/dist/ionic/p-d1f54e28.entry.js +4 -0
- package/dist/ionic/p-d3014190.entry.js +4 -0
- package/dist/types/components/checkbox/checkbox.d.ts +9 -1
- package/dist/types/components/radio-group/radio-group.d.ts +9 -1
- package/dist/types/components/select/select.d.ts +2 -2
- package/dist/types/components/toggle/toggle.d.ts +7 -1
- package/dist/types/utils/forms/validity.d.ts +1 -1
- package/hydrate/index.js +277 -225
- package/hydrate/index.mjs +277 -225
- package/package.json +2 -2
- package/dist/ionic/p-4cc26913.entry.js +0 -4
- package/dist/ionic/p-7bcfc421.entry.js +0 -4
- package/dist/ionic/p-8bdfc8f6.entry.js +0 -4
- package/dist/ionic/p-dc2e126d.entry.js +0 -4
- package/dist/ionic/p-f65f9308.entry.js +0 -4
- package/dist/ionic/p-fc278823.entry.js +0 -4
package/hydrate/index.mjs
CHANGED
|
@@ -9683,6 +9683,202 @@ class CardTitle {
|
|
|
9683
9683
|
}; }
|
|
9684
9684
|
}
|
|
9685
9685
|
|
|
9686
|
+
/**
|
|
9687
|
+
* A utility to calculate the size of an outline notch
|
|
9688
|
+
* width relative to the content passed. This is used in
|
|
9689
|
+
* components such as `ion-select` with `fill="outline"`
|
|
9690
|
+
* where we need to pass slotted HTML content. This is not
|
|
9691
|
+
* needed when rendering plaintext content because we can
|
|
9692
|
+
* render the plaintext again hidden with `opacity: 0` inside
|
|
9693
|
+
* of the notch. As a result we can rely on the intrinsic size
|
|
9694
|
+
* of the element to correctly compute the notch width. We
|
|
9695
|
+
* cannot do this with slotted content because we cannot project
|
|
9696
|
+
* it into 2 places at once.
|
|
9697
|
+
*
|
|
9698
|
+
* @internal
|
|
9699
|
+
* @param el: The host element
|
|
9700
|
+
* @param getNotchSpacerEl: A function that returns a reference to the notch spacer element inside of the component template.
|
|
9701
|
+
* @param getLabelSlot: A function that returns a reference to the slotted content.
|
|
9702
|
+
*/
|
|
9703
|
+
const createNotchController = (el, getNotchSpacerEl, getLabelSlot) => {
|
|
9704
|
+
let notchVisibilityIO;
|
|
9705
|
+
const needsExplicitNotchWidth = () => {
|
|
9706
|
+
const notchSpacerEl = getNotchSpacerEl();
|
|
9707
|
+
if (
|
|
9708
|
+
/**
|
|
9709
|
+
* If the notch is not being used
|
|
9710
|
+
* then we do not need to set the notch width.
|
|
9711
|
+
*/
|
|
9712
|
+
notchSpacerEl === undefined ||
|
|
9713
|
+
/**
|
|
9714
|
+
* If either the label property is being
|
|
9715
|
+
* used or the label slot is not defined,
|
|
9716
|
+
* then we do not need to estimate the notch width.
|
|
9717
|
+
*/
|
|
9718
|
+
el.label !== undefined ||
|
|
9719
|
+
getLabelSlot() === null) {
|
|
9720
|
+
return false;
|
|
9721
|
+
}
|
|
9722
|
+
return true;
|
|
9723
|
+
};
|
|
9724
|
+
const calculateNotchWidth = () => {
|
|
9725
|
+
if (needsExplicitNotchWidth()) {
|
|
9726
|
+
/**
|
|
9727
|
+
* Run this the frame after
|
|
9728
|
+
* the browser has re-painted the host element.
|
|
9729
|
+
* Otherwise, the label element may have a width
|
|
9730
|
+
* of 0 and the IntersectionObserver will be used.
|
|
9731
|
+
*/
|
|
9732
|
+
raf(() => {
|
|
9733
|
+
setNotchWidth();
|
|
9734
|
+
});
|
|
9735
|
+
}
|
|
9736
|
+
};
|
|
9737
|
+
/**
|
|
9738
|
+
* When using a label prop we can render
|
|
9739
|
+
* the label value inside of the notch and
|
|
9740
|
+
* let the browser calculate the size of the notch.
|
|
9741
|
+
* However, we cannot render the label slot in multiple
|
|
9742
|
+
* places so we need to manually calculate the notch dimension
|
|
9743
|
+
* based on the size of the slotted content.
|
|
9744
|
+
*
|
|
9745
|
+
* This function should only be used to set the notch width
|
|
9746
|
+
* on slotted label content. The notch width for label prop
|
|
9747
|
+
* content is automatically calculated based on the
|
|
9748
|
+
* intrinsic size of the label text.
|
|
9749
|
+
*/
|
|
9750
|
+
const setNotchWidth = () => {
|
|
9751
|
+
const notchSpacerEl = getNotchSpacerEl();
|
|
9752
|
+
if (notchSpacerEl === undefined) {
|
|
9753
|
+
return;
|
|
9754
|
+
}
|
|
9755
|
+
if (!needsExplicitNotchWidth()) {
|
|
9756
|
+
notchSpacerEl.style.removeProperty('width');
|
|
9757
|
+
return;
|
|
9758
|
+
}
|
|
9759
|
+
const width = getLabelSlot().scrollWidth;
|
|
9760
|
+
if (
|
|
9761
|
+
/**
|
|
9762
|
+
* If the computed width of the label is 0
|
|
9763
|
+
* and notchSpacerEl's offsetParent is null
|
|
9764
|
+
* then that means the element is hidden.
|
|
9765
|
+
* As a result, we need to wait for the element
|
|
9766
|
+
* to become visible before setting the notch width.
|
|
9767
|
+
*
|
|
9768
|
+
* We do not check el.offsetParent because
|
|
9769
|
+
* that can be null if the host element has
|
|
9770
|
+
* position: fixed applied to it.
|
|
9771
|
+
* notchSpacerEl does not have position: fixed.
|
|
9772
|
+
*/
|
|
9773
|
+
width === 0 &&
|
|
9774
|
+
notchSpacerEl.offsetParent === null &&
|
|
9775
|
+
win$1 !== undefined &&
|
|
9776
|
+
'IntersectionObserver' in win$1) {
|
|
9777
|
+
/**
|
|
9778
|
+
* If there is an IO already attached
|
|
9779
|
+
* then that will update the notch
|
|
9780
|
+
* once the element becomes visible.
|
|
9781
|
+
* As a result, there is no need to create
|
|
9782
|
+
* another one.
|
|
9783
|
+
*/
|
|
9784
|
+
if (notchVisibilityIO !== undefined) {
|
|
9785
|
+
return;
|
|
9786
|
+
}
|
|
9787
|
+
const io = (notchVisibilityIO = new IntersectionObserver((ev) => {
|
|
9788
|
+
/**
|
|
9789
|
+
* If the element is visible then we
|
|
9790
|
+
* can try setting the notch width again.
|
|
9791
|
+
*/
|
|
9792
|
+
if (ev[0].intersectionRatio === 1) {
|
|
9793
|
+
setNotchWidth();
|
|
9794
|
+
io.disconnect();
|
|
9795
|
+
notchVisibilityIO = undefined;
|
|
9796
|
+
}
|
|
9797
|
+
},
|
|
9798
|
+
/**
|
|
9799
|
+
* Set the root to be the host element
|
|
9800
|
+
* This causes the IO callback
|
|
9801
|
+
* to be fired in WebKit as soon as the element
|
|
9802
|
+
* is visible. If we used the default root value
|
|
9803
|
+
* then WebKit would only fire the IO callback
|
|
9804
|
+
* after any animations (such as a modal transition)
|
|
9805
|
+
* finished, and there would potentially be a flicker.
|
|
9806
|
+
*/
|
|
9807
|
+
{ threshold: 0.01, root: el }));
|
|
9808
|
+
io.observe(notchSpacerEl);
|
|
9809
|
+
return;
|
|
9810
|
+
}
|
|
9811
|
+
/**
|
|
9812
|
+
* If the element is visible then we can set the notch width.
|
|
9813
|
+
* The notch is only visible when the label is scaled,
|
|
9814
|
+
* which is why we multiply the width by 0.75 as this is
|
|
9815
|
+
* the same amount the label element is scaled by in the host CSS.
|
|
9816
|
+
* (See $form-control-label-stacked-scale in ionic.globals.scss).
|
|
9817
|
+
*/
|
|
9818
|
+
notchSpacerEl.style.setProperty('width', `${width * 0.75}px`);
|
|
9819
|
+
};
|
|
9820
|
+
const destroy = () => {
|
|
9821
|
+
if (notchVisibilityIO) {
|
|
9822
|
+
notchVisibilityIO.disconnect();
|
|
9823
|
+
notchVisibilityIO = undefined;
|
|
9824
|
+
}
|
|
9825
|
+
};
|
|
9826
|
+
return {
|
|
9827
|
+
calculateNotchWidth,
|
|
9828
|
+
destroy,
|
|
9829
|
+
};
|
|
9830
|
+
};
|
|
9831
|
+
|
|
9832
|
+
/**
|
|
9833
|
+
* Uses the compareWith param to compare two values to determine if they are equal.
|
|
9834
|
+
*
|
|
9835
|
+
* @param currentValue The current value of the control.
|
|
9836
|
+
* @param compareValue The value to compare against.
|
|
9837
|
+
* @param compareWith The function or property name to use to compare values.
|
|
9838
|
+
*/
|
|
9839
|
+
const compareOptions = (currentValue, compareValue, compareWith) => {
|
|
9840
|
+
if (typeof compareWith === 'function') {
|
|
9841
|
+
return compareWith(currentValue, compareValue);
|
|
9842
|
+
}
|
|
9843
|
+
else if (typeof compareWith === 'string') {
|
|
9844
|
+
return currentValue[compareWith] === compareValue[compareWith];
|
|
9845
|
+
}
|
|
9846
|
+
else {
|
|
9847
|
+
return Array.isArray(compareValue) ? compareValue.includes(currentValue) : currentValue === compareValue;
|
|
9848
|
+
}
|
|
9849
|
+
};
|
|
9850
|
+
/**
|
|
9851
|
+
* Compares a value against the current value(s) to determine if it is selected.
|
|
9852
|
+
*
|
|
9853
|
+
* @param currentValue The current value of the control.
|
|
9854
|
+
* @param compareValue The value to compare against.
|
|
9855
|
+
* @param compareWith The function or property name to use to compare values.
|
|
9856
|
+
*/
|
|
9857
|
+
const isOptionSelected = (currentValue, compareValue, compareWith) => {
|
|
9858
|
+
if (currentValue === undefined) {
|
|
9859
|
+
return false;
|
|
9860
|
+
}
|
|
9861
|
+
if (Array.isArray(currentValue)) {
|
|
9862
|
+
return currentValue.some((val) => compareOptions(val, compareValue, compareWith));
|
|
9863
|
+
}
|
|
9864
|
+
else {
|
|
9865
|
+
return compareOptions(currentValue, compareValue, compareWith);
|
|
9866
|
+
}
|
|
9867
|
+
};
|
|
9868
|
+
|
|
9869
|
+
/**
|
|
9870
|
+
* Checks if the form element is in an invalid state based on
|
|
9871
|
+
* Ionic validation classes.
|
|
9872
|
+
*
|
|
9873
|
+
* @param el The form element to check.
|
|
9874
|
+
* @returns `true` if the element is invalid, `false` otherwise.
|
|
9875
|
+
*/
|
|
9876
|
+
const checkInvalidState = (el) => {
|
|
9877
|
+
const hasIonTouched = el.classList.contains('ion-touched');
|
|
9878
|
+
const hasIonInvalid = el.classList.contains('ion-invalid');
|
|
9879
|
+
return hasIonTouched && hasIonInvalid;
|
|
9880
|
+
};
|
|
9881
|
+
|
|
9686
9882
|
const checkboxIosCss = ":host{--checkbox-background-checked:var(--ion-color-primary, #0054e9);--border-color-checked:var(--ion-color-primary, #0054e9);--checkmark-color:var(--ion-color-primary-contrast, #fff);--transition:none;display:inline-block;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-color){--checkbox-background-checked:var(--ion-color-base);--border-color-checked:var(--ion-color-base);--checkmark-color:var(--ion-color-contrast)}.checkbox-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper,:host(.in-item:not(.checkbox-label-placement-stacked):not([slot])) .native-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.checkbox-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.checkbox-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}input{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.checkbox-icon{border-radius:var(--border-radius);position:relative;width:var(--size);height:var(--size);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--checkbox-background);-webkit-box-sizing:border-box;box-sizing:border-box}.checkbox-icon path{fill:none;stroke:var(--checkmark-color);stroke-width:var(--checkmark-width);opacity:0}.checkbox-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.checkbox-label-placement-stacked) .checkbox-bottom{font-size:1rem}.checkbox-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.checkbox-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .checkbox-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .checkbox-bottom .helper-text{display:none}:host(.checkbox-label-placement-start) .checkbox-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.checkbox-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-end) .checkbox-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.checkbox-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.checkbox-label-placement-stacked) .checkbox-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.checkbox-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.checkbox-justify-space-between) .checkbox-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.checkbox-justify-start) .checkbox-wrapper{-ms-flex-pack:start;justify-content:start}:host(.checkbox-justify-end) .checkbox-wrapper{-ms-flex-pack:end;justify-content:end}:host(.checkbox-alignment-start) .checkbox-wrapper{-ms-flex-align:start;align-items:start}:host(.checkbox-alignment-center) .checkbox-wrapper{-ms-flex-align:center;align-items:center}:host(.checkbox-justify-space-between),:host(.checkbox-justify-start),:host(.checkbox-justify-end),:host(.checkbox-alignment-start),:host(.checkbox-alignment-center){display:block}:host(.checkbox-checked) .checkbox-icon,:host(.checkbox-indeterminate) .checkbox-icon{border-color:var(--border-color-checked);background:var(--checkbox-background-checked)}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{opacity:1}:host(.checkbox-disabled){pointer-events:none}:host{--border-radius:50%;--border-width:0.125rem;--border-style:solid;--border-color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.23);--checkbox-background:var(--ion-item-background, var(--ion-background-color, #fff));--size:min(1.375rem, 55.836px);--checkmark-width:1.5px}:host(.checkbox-disabled){opacity:0.3}";
|
|
9687
9883
|
|
|
9688
9884
|
const checkboxMdCss = ":host{--checkbox-background-checked:var(--ion-color-primary, #0054e9);--border-color-checked:var(--ion-color-primary, #0054e9);--checkmark-color:var(--ion-color-primary-contrast, #fff);--transition:none;display:inline-block;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-color){--checkbox-background-checked:var(--ion-color-base);--border-color-checked:var(--ion-color-base);--checkmark-color:var(--ion-color-contrast)}.checkbox-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper,:host(.in-item:not(.checkbox-label-placement-stacked):not([slot])) .native-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.checkbox-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.checkbox-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}input{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.checkbox-icon{border-radius:var(--border-radius);position:relative;width:var(--size);height:var(--size);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--checkbox-background);-webkit-box-sizing:border-box;box-sizing:border-box}.checkbox-icon path{fill:none;stroke:var(--checkmark-color);stroke-width:var(--checkmark-width);opacity:0}.checkbox-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.checkbox-label-placement-stacked) .checkbox-bottom{font-size:1rem}.checkbox-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.checkbox-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .checkbox-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .checkbox-bottom .helper-text{display:none}:host(.checkbox-label-placement-start) .checkbox-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.checkbox-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-end) .checkbox-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.checkbox-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.checkbox-label-placement-stacked) .checkbox-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.checkbox-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.checkbox-justify-space-between) .checkbox-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.checkbox-justify-start) .checkbox-wrapper{-ms-flex-pack:start;justify-content:start}:host(.checkbox-justify-end) .checkbox-wrapper{-ms-flex-pack:end;justify-content:end}:host(.checkbox-alignment-start) .checkbox-wrapper{-ms-flex-align:start;align-items:start}:host(.checkbox-alignment-center) .checkbox-wrapper{-ms-flex-align:center;align-items:center}:host(.checkbox-justify-space-between),:host(.checkbox-justify-start),:host(.checkbox-justify-end),:host(.checkbox-alignment-start),:host(.checkbox-alignment-center){display:block}:host(.checkbox-checked) .checkbox-icon,:host(.checkbox-indeterminate) .checkbox-icon{border-color:var(--border-color-checked);background:var(--checkbox-background-checked)}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{opacity:1}:host(.checkbox-disabled){pointer-events:none}:host{--border-radius:calc(var(--size) * .125);--border-width:2px;--border-style:solid;--border-color:rgb(var(--ion-text-color-rgb, 0, 0, 0), 0.6);--checkmark-width:3;--checkbox-background:var(--ion-item-background, var(--ion-background-color, #fff));--transition:background 180ms cubic-bezier(0.4, 0, 0.2, 1);--size:18px}.checkbox-icon path{stroke-dasharray:30;stroke-dashoffset:30}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{stroke-dashoffset:0;-webkit-transition:stroke-dashoffset 90ms linear 90ms;transition:stroke-dashoffset 90ms linear 90ms}:host(.checkbox-disabled) .label-text-wrapper{opacity:0.38}:host(.checkbox-disabled) .native-wrapper{opacity:0.63}";
|
|
@@ -9748,6 +9944,10 @@ class Checkbox {
|
|
|
9748
9944
|
* submitting if the value is invalid.
|
|
9749
9945
|
*/
|
|
9750
9946
|
this.required = false;
|
|
9947
|
+
/**
|
|
9948
|
+
* Track validation state for proper aria-live announcements.
|
|
9949
|
+
*/
|
|
9950
|
+
this.isInvalid = false;
|
|
9751
9951
|
/**
|
|
9752
9952
|
* Sets the checked property and emits
|
|
9753
9953
|
* the ionChange event. Use this to update the
|
|
@@ -9794,16 +9994,29 @@ class Checkbox {
|
|
|
9794
9994
|
ev.stopPropagation();
|
|
9795
9995
|
};
|
|
9796
9996
|
}
|
|
9997
|
+
connectedCallback() {
|
|
9998
|
+
const { el } = this;
|
|
9999
|
+
// Always set initial state
|
|
10000
|
+
this.isInvalid = checkInvalidState(el);
|
|
10001
|
+
}
|
|
9797
10002
|
componentWillLoad() {
|
|
9798
10003
|
this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
|
|
10004
|
+
this.hintTextId = this.getHintTextId();
|
|
10005
|
+
}
|
|
10006
|
+
disconnectedCallback() {
|
|
10007
|
+
// Clean up validation observer to prevent memory leaks.
|
|
10008
|
+
if (this.validationObserver) {
|
|
10009
|
+
this.validationObserver.disconnect();
|
|
10010
|
+
this.validationObserver = undefined;
|
|
10011
|
+
}
|
|
9799
10012
|
}
|
|
9800
10013
|
/** @internal */
|
|
9801
10014
|
async setFocus() {
|
|
9802
10015
|
this.el.focus();
|
|
9803
10016
|
}
|
|
9804
|
-
|
|
9805
|
-
const {
|
|
9806
|
-
if (
|
|
10017
|
+
getHintTextId() {
|
|
10018
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
10019
|
+
if (isInvalid && errorText) {
|
|
9807
10020
|
return errorTextId;
|
|
9808
10021
|
}
|
|
9809
10022
|
if (helperText) {
|
|
@@ -9816,7 +10029,7 @@ class Checkbox {
|
|
|
9816
10029
|
* This element should only be rendered if hint text is set.
|
|
9817
10030
|
*/
|
|
9818
10031
|
renderHintText() {
|
|
9819
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
10032
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
9820
10033
|
/**
|
|
9821
10034
|
* undefined and empty string values should
|
|
9822
10035
|
* be treated as not having helper/error text.
|
|
@@ -9825,7 +10038,7 @@ class Checkbox {
|
|
|
9825
10038
|
if (!hasHintText) {
|
|
9826
10039
|
return;
|
|
9827
10040
|
}
|
|
9828
|
-
return (hAsync("div", { class: "checkbox-bottom" }, hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText), hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText)));
|
|
10041
|
+
return (hAsync("div", { class: "checkbox-bottom" }, hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null), hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text", role: "alert" }, isInvalid ? errorText : null)));
|
|
9829
10042
|
}
|
|
9830
10043
|
render() {
|
|
9831
10044
|
const { color, checked, disabled, el, getSVGPath, indeterminate, inheritedAttributes, inputId, justify, labelPlacement, name, value, alignment, required, } = this;
|
|
@@ -9835,7 +10048,7 @@ class Checkbox {
|
|
|
9835
10048
|
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
|
9836
10049
|
// The host element must have a checkbox role to ensure proper VoiceOver
|
|
9837
10050
|
// support in Safari for accessibility.
|
|
9838
|
-
return (hAsync(Host, { key: '
|
|
10051
|
+
return (hAsync(Host, { key: 'ae0fbd4b21accbac132e6b85c513512ad9179394', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, "aria-required": required ? 'true' : undefined, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses$1(color, {
|
|
9839
10052
|
[mode]: true,
|
|
9840
10053
|
'in-item': hostContext('ion-item', el),
|
|
9841
10054
|
'checkbox-checked': checked,
|
|
@@ -9845,10 +10058,10 @@ class Checkbox {
|
|
|
9845
10058
|
[`checkbox-justify-${justify}`]: justify !== undefined,
|
|
9846
10059
|
[`checkbox-alignment-${alignment}`]: alignment !== undefined,
|
|
9847
10060
|
[`checkbox-label-placement-${labelPlacement}`]: true,
|
|
9848
|
-
}) }, hAsync("label", { key: '
|
|
10061
|
+
}) }, hAsync("label", { key: '7a3d7f3c27dde514f2dbf2e34f4629fad33ec3bf', class: "checkbox-wrapper", htmlFor: inputId }, hAsync("input", Object.assign({ key: '4130d77ddf034271fecccda14e101a5a809921b6', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), hAsync("div", { key: '5daa74f4e62b0947e37764762524001ee42609d9', class: {
|
|
9849
10062
|
'label-text-wrapper': true,
|
|
9850
10063
|
'label-text-wrapper-hidden': !hasLabelContent,
|
|
9851
|
-
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '
|
|
10064
|
+
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '23ff66138f8c3a2f56f39113fc842d54b2f7952a' }), this.renderHintText()), hAsync("div", { key: 'ab914d9623c19fc46821d5e62db92f1192ebbe7e', class: "native-wrapper" }, hAsync("svg", { key: '66e3f4f5dcaa9756fb0e9452299954f9ed3dcb7b', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
|
|
9852
10065
|
}
|
|
9853
10066
|
getSVGPath(mode, indeterminate) {
|
|
9854
10067
|
let path = indeterminate ? (hAsync("path", { d: "M6 12L18 12", part: "mark" })) : (hAsync("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
|
|
@@ -9878,6 +10091,8 @@ class Checkbox {
|
|
|
9878
10091
|
"justify": [1],
|
|
9879
10092
|
"alignment": [1],
|
|
9880
10093
|
"required": [4],
|
|
10094
|
+
"isInvalid": [32],
|
|
10095
|
+
"hintTextId": [32],
|
|
9881
10096
|
"setFocus": [64]
|
|
9882
10097
|
},
|
|
9883
10098
|
"$listeners$": undefined,
|
|
@@ -16312,202 +16527,6 @@ class InfiniteScrollContent {
|
|
|
16312
16527
|
}; }
|
|
16313
16528
|
}
|
|
16314
16529
|
|
|
16315
|
-
/**
|
|
16316
|
-
* A utility to calculate the size of an outline notch
|
|
16317
|
-
* width relative to the content passed. This is used in
|
|
16318
|
-
* components such as `ion-select` with `fill="outline"`
|
|
16319
|
-
* where we need to pass slotted HTML content. This is not
|
|
16320
|
-
* needed when rendering plaintext content because we can
|
|
16321
|
-
* render the plaintext again hidden with `opacity: 0` inside
|
|
16322
|
-
* of the notch. As a result we can rely on the intrinsic size
|
|
16323
|
-
* of the element to correctly compute the notch width. We
|
|
16324
|
-
* cannot do this with slotted content because we cannot project
|
|
16325
|
-
* it into 2 places at once.
|
|
16326
|
-
*
|
|
16327
|
-
* @internal
|
|
16328
|
-
* @param el: The host element
|
|
16329
|
-
* @param getNotchSpacerEl: A function that returns a reference to the notch spacer element inside of the component template.
|
|
16330
|
-
* @param getLabelSlot: A function that returns a reference to the slotted content.
|
|
16331
|
-
*/
|
|
16332
|
-
const createNotchController = (el, getNotchSpacerEl, getLabelSlot) => {
|
|
16333
|
-
let notchVisibilityIO;
|
|
16334
|
-
const needsExplicitNotchWidth = () => {
|
|
16335
|
-
const notchSpacerEl = getNotchSpacerEl();
|
|
16336
|
-
if (
|
|
16337
|
-
/**
|
|
16338
|
-
* If the notch is not being used
|
|
16339
|
-
* then we do not need to set the notch width.
|
|
16340
|
-
*/
|
|
16341
|
-
notchSpacerEl === undefined ||
|
|
16342
|
-
/**
|
|
16343
|
-
* If either the label property is being
|
|
16344
|
-
* used or the label slot is not defined,
|
|
16345
|
-
* then we do not need to estimate the notch width.
|
|
16346
|
-
*/
|
|
16347
|
-
el.label !== undefined ||
|
|
16348
|
-
getLabelSlot() === null) {
|
|
16349
|
-
return false;
|
|
16350
|
-
}
|
|
16351
|
-
return true;
|
|
16352
|
-
};
|
|
16353
|
-
const calculateNotchWidth = () => {
|
|
16354
|
-
if (needsExplicitNotchWidth()) {
|
|
16355
|
-
/**
|
|
16356
|
-
* Run this the frame after
|
|
16357
|
-
* the browser has re-painted the host element.
|
|
16358
|
-
* Otherwise, the label element may have a width
|
|
16359
|
-
* of 0 and the IntersectionObserver will be used.
|
|
16360
|
-
*/
|
|
16361
|
-
raf(() => {
|
|
16362
|
-
setNotchWidth();
|
|
16363
|
-
});
|
|
16364
|
-
}
|
|
16365
|
-
};
|
|
16366
|
-
/**
|
|
16367
|
-
* When using a label prop we can render
|
|
16368
|
-
* the label value inside of the notch and
|
|
16369
|
-
* let the browser calculate the size of the notch.
|
|
16370
|
-
* However, we cannot render the label slot in multiple
|
|
16371
|
-
* places so we need to manually calculate the notch dimension
|
|
16372
|
-
* based on the size of the slotted content.
|
|
16373
|
-
*
|
|
16374
|
-
* This function should only be used to set the notch width
|
|
16375
|
-
* on slotted label content. The notch width for label prop
|
|
16376
|
-
* content is automatically calculated based on the
|
|
16377
|
-
* intrinsic size of the label text.
|
|
16378
|
-
*/
|
|
16379
|
-
const setNotchWidth = () => {
|
|
16380
|
-
const notchSpacerEl = getNotchSpacerEl();
|
|
16381
|
-
if (notchSpacerEl === undefined) {
|
|
16382
|
-
return;
|
|
16383
|
-
}
|
|
16384
|
-
if (!needsExplicitNotchWidth()) {
|
|
16385
|
-
notchSpacerEl.style.removeProperty('width');
|
|
16386
|
-
return;
|
|
16387
|
-
}
|
|
16388
|
-
const width = getLabelSlot().scrollWidth;
|
|
16389
|
-
if (
|
|
16390
|
-
/**
|
|
16391
|
-
* If the computed width of the label is 0
|
|
16392
|
-
* and notchSpacerEl's offsetParent is null
|
|
16393
|
-
* then that means the element is hidden.
|
|
16394
|
-
* As a result, we need to wait for the element
|
|
16395
|
-
* to become visible before setting the notch width.
|
|
16396
|
-
*
|
|
16397
|
-
* We do not check el.offsetParent because
|
|
16398
|
-
* that can be null if the host element has
|
|
16399
|
-
* position: fixed applied to it.
|
|
16400
|
-
* notchSpacerEl does not have position: fixed.
|
|
16401
|
-
*/
|
|
16402
|
-
width === 0 &&
|
|
16403
|
-
notchSpacerEl.offsetParent === null &&
|
|
16404
|
-
win$1 !== undefined &&
|
|
16405
|
-
'IntersectionObserver' in win$1) {
|
|
16406
|
-
/**
|
|
16407
|
-
* If there is an IO already attached
|
|
16408
|
-
* then that will update the notch
|
|
16409
|
-
* once the element becomes visible.
|
|
16410
|
-
* As a result, there is no need to create
|
|
16411
|
-
* another one.
|
|
16412
|
-
*/
|
|
16413
|
-
if (notchVisibilityIO !== undefined) {
|
|
16414
|
-
return;
|
|
16415
|
-
}
|
|
16416
|
-
const io = (notchVisibilityIO = new IntersectionObserver((ev) => {
|
|
16417
|
-
/**
|
|
16418
|
-
* If the element is visible then we
|
|
16419
|
-
* can try setting the notch width again.
|
|
16420
|
-
*/
|
|
16421
|
-
if (ev[0].intersectionRatio === 1) {
|
|
16422
|
-
setNotchWidth();
|
|
16423
|
-
io.disconnect();
|
|
16424
|
-
notchVisibilityIO = undefined;
|
|
16425
|
-
}
|
|
16426
|
-
},
|
|
16427
|
-
/**
|
|
16428
|
-
* Set the root to be the host element
|
|
16429
|
-
* This causes the IO callback
|
|
16430
|
-
* to be fired in WebKit as soon as the element
|
|
16431
|
-
* is visible. If we used the default root value
|
|
16432
|
-
* then WebKit would only fire the IO callback
|
|
16433
|
-
* after any animations (such as a modal transition)
|
|
16434
|
-
* finished, and there would potentially be a flicker.
|
|
16435
|
-
*/
|
|
16436
|
-
{ threshold: 0.01, root: el }));
|
|
16437
|
-
io.observe(notchSpacerEl);
|
|
16438
|
-
return;
|
|
16439
|
-
}
|
|
16440
|
-
/**
|
|
16441
|
-
* If the element is visible then we can set the notch width.
|
|
16442
|
-
* The notch is only visible when the label is scaled,
|
|
16443
|
-
* which is why we multiply the width by 0.75 as this is
|
|
16444
|
-
* the same amount the label element is scaled by in the host CSS.
|
|
16445
|
-
* (See $form-control-label-stacked-scale in ionic.globals.scss).
|
|
16446
|
-
*/
|
|
16447
|
-
notchSpacerEl.style.setProperty('width', `${width * 0.75}px`);
|
|
16448
|
-
};
|
|
16449
|
-
const destroy = () => {
|
|
16450
|
-
if (notchVisibilityIO) {
|
|
16451
|
-
notchVisibilityIO.disconnect();
|
|
16452
|
-
notchVisibilityIO = undefined;
|
|
16453
|
-
}
|
|
16454
|
-
};
|
|
16455
|
-
return {
|
|
16456
|
-
calculateNotchWidth,
|
|
16457
|
-
destroy,
|
|
16458
|
-
};
|
|
16459
|
-
};
|
|
16460
|
-
|
|
16461
|
-
/**
|
|
16462
|
-
* Uses the compareWith param to compare two values to determine if they are equal.
|
|
16463
|
-
*
|
|
16464
|
-
* @param currentValue The current value of the control.
|
|
16465
|
-
* @param compareValue The value to compare against.
|
|
16466
|
-
* @param compareWith The function or property name to use to compare values.
|
|
16467
|
-
*/
|
|
16468
|
-
const compareOptions = (currentValue, compareValue, compareWith) => {
|
|
16469
|
-
if (typeof compareWith === 'function') {
|
|
16470
|
-
return compareWith(currentValue, compareValue);
|
|
16471
|
-
}
|
|
16472
|
-
else if (typeof compareWith === 'string') {
|
|
16473
|
-
return currentValue[compareWith] === compareValue[compareWith];
|
|
16474
|
-
}
|
|
16475
|
-
else {
|
|
16476
|
-
return Array.isArray(compareValue) ? compareValue.includes(currentValue) : currentValue === compareValue;
|
|
16477
|
-
}
|
|
16478
|
-
};
|
|
16479
|
-
/**
|
|
16480
|
-
* Compares a value against the current value(s) to determine if it is selected.
|
|
16481
|
-
*
|
|
16482
|
-
* @param currentValue The current value of the control.
|
|
16483
|
-
* @param compareValue The value to compare against.
|
|
16484
|
-
* @param compareWith The function or property name to use to compare values.
|
|
16485
|
-
*/
|
|
16486
|
-
const isOptionSelected = (currentValue, compareValue, compareWith) => {
|
|
16487
|
-
if (currentValue === undefined) {
|
|
16488
|
-
return false;
|
|
16489
|
-
}
|
|
16490
|
-
if (Array.isArray(currentValue)) {
|
|
16491
|
-
return currentValue.some((val) => compareOptions(val, compareValue, compareWith));
|
|
16492
|
-
}
|
|
16493
|
-
else {
|
|
16494
|
-
return compareOptions(currentValue, compareValue, compareWith);
|
|
16495
|
-
}
|
|
16496
|
-
};
|
|
16497
|
-
|
|
16498
|
-
/**
|
|
16499
|
-
* Checks if the form element is in an invalid state based on
|
|
16500
|
-
* Ionic validation classes.
|
|
16501
|
-
*
|
|
16502
|
-
* @param el The form element to check.
|
|
16503
|
-
* @returns `true` if the element is invalid, `false` otherwise.
|
|
16504
|
-
*/
|
|
16505
|
-
const checkInvalidState = (el) => {
|
|
16506
|
-
const hasIonTouched = el.classList.contains('ion-touched');
|
|
16507
|
-
const hasIonInvalid = el.classList.contains('ion-invalid');
|
|
16508
|
-
return hasIonTouched && hasIonInvalid;
|
|
16509
|
-
};
|
|
16510
|
-
|
|
16511
16530
|
/**
|
|
16512
16531
|
* Used to update a scoped component that uses emulated slots. This fires when
|
|
16513
16532
|
* content is passed into the slot or when the content inside of a slot changes.
|
|
@@ -28049,6 +28068,10 @@ class RadioGroup {
|
|
|
28049
28068
|
this.helperTextId = `${this.inputId}-helper-text`;
|
|
28050
28069
|
this.errorTextId = `${this.inputId}-error-text`;
|
|
28051
28070
|
this.labelId = `${this.inputId}-lbl`;
|
|
28071
|
+
/**
|
|
28072
|
+
* Track validation state for proper aria-live announcements.
|
|
28073
|
+
*/
|
|
28074
|
+
this.isInvalid = false;
|
|
28052
28075
|
/**
|
|
28053
28076
|
* If `true`, the radios can be deselected.
|
|
28054
28077
|
*/
|
|
@@ -28130,6 +28153,18 @@ class RadioGroup {
|
|
|
28130
28153
|
this.labelId = label.id = this.name + '-lbl';
|
|
28131
28154
|
}
|
|
28132
28155
|
}
|
|
28156
|
+
// Always set initial state
|
|
28157
|
+
this.isInvalid = checkInvalidState(this.el);
|
|
28158
|
+
}
|
|
28159
|
+
componentWillLoad() {
|
|
28160
|
+
this.hintTextId = this.getHintTextId();
|
|
28161
|
+
}
|
|
28162
|
+
disconnectedCallback() {
|
|
28163
|
+
// Clean up validation observer to prevent memory leaks.
|
|
28164
|
+
if (this.validationObserver) {
|
|
28165
|
+
this.validationObserver.disconnect();
|
|
28166
|
+
this.validationObserver = undefined;
|
|
28167
|
+
}
|
|
28133
28168
|
}
|
|
28134
28169
|
getRadios() {
|
|
28135
28170
|
return Array.from(this.el.querySelectorAll('ion-radio'));
|
|
@@ -28205,16 +28240,16 @@ class RadioGroup {
|
|
|
28205
28240
|
* Renders the helper text or error text values
|
|
28206
28241
|
*/
|
|
28207
28242
|
renderHintText() {
|
|
28208
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
28243
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
28209
28244
|
const hasHintText = !!helperText || !!errorText;
|
|
28210
28245
|
if (!hasHintText) {
|
|
28211
28246
|
return;
|
|
28212
28247
|
}
|
|
28213
|
-
return (hAsync("div", { class: "radio-group-top" }, hAsync("div", { id: helperTextId, class: "helper-text" }, helperText), hAsync("div", { id: errorTextId, class: "error-text" }, errorText)));
|
|
28248
|
+
return (hAsync("div", { class: "radio-group-top" }, hAsync("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null), hAsync("div", { id: errorTextId, class: "error-text", role: "alert" }, isInvalid ? errorText : null)));
|
|
28214
28249
|
}
|
|
28215
|
-
|
|
28216
|
-
const {
|
|
28217
|
-
if (
|
|
28250
|
+
getHintTextId() {
|
|
28251
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
28252
|
+
if (isInvalid && errorText) {
|
|
28218
28253
|
return errorTextId;
|
|
28219
28254
|
}
|
|
28220
28255
|
if (helperText) {
|
|
@@ -28226,7 +28261,7 @@ class RadioGroup {
|
|
|
28226
28261
|
const { label, labelId, el, name, value } = this;
|
|
28227
28262
|
const mode = getIonMode$1(this);
|
|
28228
28263
|
renderHiddenInput(true, el, name, value, false);
|
|
28229
|
-
return (hAsync(Host, { key: '
|
|
28264
|
+
return (hAsync(Host, { key: 'db593b3ed511e9395e3c7bfd91b787328692cd6d', role: "radiogroup", "aria-labelledby": label ? labelId : null, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, onClick: this.onClick, class: mode }, this.renderHintText(), hAsync("div", { key: '85045b45a0100a45f3b9a35d1c5a25ec63d525c4', class: "radio-group-wrapper" }, hAsync("slot", { key: '53dacb87ce62398e78771fb2efaf839ab922d946' }))));
|
|
28230
28265
|
}
|
|
28231
28266
|
get el() { return getElement(this); }
|
|
28232
28267
|
static get watchers() { return {
|
|
@@ -28246,6 +28281,8 @@ class RadioGroup {
|
|
|
28246
28281
|
"value": [1032],
|
|
28247
28282
|
"helperText": [1, "helper-text"],
|
|
28248
28283
|
"errorText": [1, "error-text"],
|
|
28284
|
+
"isInvalid": [32],
|
|
28285
|
+
"hintTextId": [32],
|
|
28249
28286
|
"setFocus": [64]
|
|
28250
28287
|
},
|
|
28251
28288
|
"$listeners$": [[4, "keydown", "onKeydown"]],
|
|
@@ -33373,7 +33410,7 @@ class Select {
|
|
|
33373
33410
|
}
|
|
33374
33411
|
componentWillLoad() {
|
|
33375
33412
|
this.inheritedAttributes = inheritAttributes$1(this.el, ['aria-label']);
|
|
33376
|
-
this.
|
|
33413
|
+
this.hintTextId = this.getHintTextId();
|
|
33377
33414
|
}
|
|
33378
33415
|
componentDidLoad() {
|
|
33379
33416
|
/**
|
|
@@ -33872,9 +33909,9 @@ class Select {
|
|
|
33872
33909
|
}
|
|
33873
33910
|
renderListbox() {
|
|
33874
33911
|
const { disabled, inputId, isExpanded, required } = this;
|
|
33875
|
-
return (hAsync("button", { disabled: disabled, id: inputId, "aria-label": this.ariaLabel, "aria-haspopup": "dialog", "aria-expanded": `${isExpanded}`, "aria-describedby": this.
|
|
33912
|
+
return (hAsync("button", { disabled: disabled, id: inputId, "aria-label": this.ariaLabel, "aria-haspopup": "dialog", "aria-expanded": `${isExpanded}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-required": `${required}`, onFocus: this.onFocus, onBlur: this.onBlur, ref: (focusEl) => (this.focusEl = focusEl) }));
|
|
33876
33913
|
}
|
|
33877
|
-
|
|
33914
|
+
getHintTextId() {
|
|
33878
33915
|
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
33879
33916
|
if (isInvalid && errorText) {
|
|
33880
33917
|
return errorTextId;
|
|
@@ -33999,7 +34036,7 @@ class Select {
|
|
|
33999
34036
|
"isExpanded": [32],
|
|
34000
34037
|
"hasFocus": [32],
|
|
34001
34038
|
"isInvalid": [32],
|
|
34002
|
-
"
|
|
34039
|
+
"hintTextId": [32],
|
|
34003
34040
|
"open": [64]
|
|
34004
34041
|
},
|
|
34005
34042
|
"$listeners$": undefined,
|
|
@@ -36470,6 +36507,10 @@ class Toggle {
|
|
|
36470
36507
|
this.inheritedAttributes = {};
|
|
36471
36508
|
this.didLoad = false;
|
|
36472
36509
|
this.activated = false;
|
|
36510
|
+
/**
|
|
36511
|
+
* Track validation state for proper aria-live announcements.
|
|
36512
|
+
*/
|
|
36513
|
+
this.isInvalid = false;
|
|
36473
36514
|
/**
|
|
36474
36515
|
* The name of the control, which is submitted with the form data.
|
|
36475
36516
|
*/
|
|
@@ -36583,15 +36624,18 @@ class Toggle {
|
|
|
36583
36624
|
});
|
|
36584
36625
|
}
|
|
36585
36626
|
async connectedCallback() {
|
|
36627
|
+
const { didLoad, el } = this;
|
|
36586
36628
|
/**
|
|
36587
36629
|
* If we have not yet rendered
|
|
36588
36630
|
* ion-toggle, then toggleTrack is not defined.
|
|
36589
36631
|
* But if we are moving ion-toggle via appendChild,
|
|
36590
36632
|
* then toggleTrack will be defined.
|
|
36591
36633
|
*/
|
|
36592
|
-
if (
|
|
36634
|
+
if (didLoad) {
|
|
36593
36635
|
this.setupGesture();
|
|
36594
36636
|
}
|
|
36637
|
+
// Always set initial state
|
|
36638
|
+
this.isInvalid = checkInvalidState(el);
|
|
36595
36639
|
}
|
|
36596
36640
|
componentDidLoad() {
|
|
36597
36641
|
this.setupGesture();
|
|
@@ -36602,9 +36646,15 @@ class Toggle {
|
|
|
36602
36646
|
this.gesture.destroy();
|
|
36603
36647
|
this.gesture = undefined;
|
|
36604
36648
|
}
|
|
36649
|
+
// Clean up validation observer to prevent memory leaks.
|
|
36650
|
+
if (this.validationObserver) {
|
|
36651
|
+
this.validationObserver.disconnect();
|
|
36652
|
+
this.validationObserver = undefined;
|
|
36653
|
+
}
|
|
36605
36654
|
}
|
|
36606
36655
|
componentWillLoad() {
|
|
36607
36656
|
this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
|
|
36657
|
+
this.hintTextId = this.getHintTextId();
|
|
36608
36658
|
}
|
|
36609
36659
|
onStart() {
|
|
36610
36660
|
this.activated = true;
|
|
@@ -36645,9 +36695,9 @@ class Toggle {
|
|
|
36645
36695
|
get hasLabel() {
|
|
36646
36696
|
return this.el.textContent !== '';
|
|
36647
36697
|
}
|
|
36648
|
-
|
|
36649
|
-
const {
|
|
36650
|
-
if (
|
|
36698
|
+
getHintTextId() {
|
|
36699
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
36700
|
+
if (isInvalid && errorText) {
|
|
36651
36701
|
return errorTextId;
|
|
36652
36702
|
}
|
|
36653
36703
|
if (helperText) {
|
|
@@ -36660,7 +36710,7 @@ class Toggle {
|
|
|
36660
36710
|
* This element should only be rendered if hint text is set.
|
|
36661
36711
|
*/
|
|
36662
36712
|
renderHintText() {
|
|
36663
|
-
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
36713
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
36664
36714
|
/**
|
|
36665
36715
|
* undefined and empty string values should
|
|
36666
36716
|
* be treated as not having helper/error text.
|
|
@@ -36669,15 +36719,15 @@ class Toggle {
|
|
|
36669
36719
|
if (!hasHintText) {
|
|
36670
36720
|
return;
|
|
36671
36721
|
}
|
|
36672
|
-
return (hAsync("div", { class: "toggle-bottom" }, hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText), hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText)));
|
|
36722
|
+
return (hAsync("div", { class: "toggle-bottom" }, hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null), hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text", role: "alert" }, isInvalid ? errorText : null)));
|
|
36673
36723
|
}
|
|
36674
36724
|
render() {
|
|
36675
|
-
const { activated, alignment, checked, color, disabled, el,
|
|
36725
|
+
const { activated, alignment, checked, color, disabled, el, hasLabel, inheritedAttributes, inputId, inputLabelId, justify, labelPlacement, name, required, } = this;
|
|
36676
36726
|
const mode = getIonMode$1(this);
|
|
36677
36727
|
const value = this.getValue();
|
|
36678
36728
|
const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
|
|
36679
36729
|
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
|
36680
|
-
return (hAsync(Host, { key: '
|
|
36730
|
+
return (hAsync(Host, { key: 'f569148edd89ee041a4719ffc4733c16b05229bd', role: "switch", "aria-checked": `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, onClick: this.onClick, "aria-labelledby": hasLabel ? inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, "aria-required": required ? 'true' : undefined, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, class: createColorClasses$1(color, {
|
|
36681
36731
|
[mode]: true,
|
|
36682
36732
|
'in-item': hostContext('ion-item', el),
|
|
36683
36733
|
'toggle-activated': activated,
|
|
@@ -36687,10 +36737,10 @@ class Toggle {
|
|
|
36687
36737
|
[`toggle-alignment-${alignment}`]: alignment !== undefined,
|
|
36688
36738
|
[`toggle-label-placement-${labelPlacement}`]: true,
|
|
36689
36739
|
[`toggle-${rtl}`]: true,
|
|
36690
|
-
}) }, hAsync("label", { key: '
|
|
36740
|
+
}) }, hAsync("label", { key: '3027f2ac4be6de422a14486d847fbee77f615db1', class: "toggle-wrapper", htmlFor: inputId }, hAsync("input", Object.assign({ key: '4b0304c9e879e432b80184b4e5de37d55c11b436', type: "checkbox", role: "switch", "aria-checked": `${checked}`, checked: checked, disabled: disabled, id: inputId, required: required }, inheritedAttributes)), hAsync("div", { key: '8ef265ec942e7f01ff31cbb202ed146c6bf94e02', class: {
|
|
36691
36741
|
'label-text-wrapper': true,
|
|
36692
36742
|
'label-text-wrapper-hidden': !hasLabel,
|
|
36693
|
-
}, part: "label", id: inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '
|
|
36743
|
+
}, part: "label", id: inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '7b162b7dd27199cca2a4c995276a18b9f8e44aaf' }), this.renderHintText()), hAsync("div", { key: 'd13c34bd42fca01cc73ddb4ea7e471b33a282a3e', class: "native-wrapper" }, this.renderToggleControl()))));
|
|
36694
36744
|
}
|
|
36695
36745
|
get el() { return getElement(this); }
|
|
36696
36746
|
static get watchers() { return {
|
|
@@ -36716,7 +36766,9 @@ class Toggle {
|
|
|
36716
36766
|
"justify": [1],
|
|
36717
36767
|
"alignment": [1],
|
|
36718
36768
|
"required": [4],
|
|
36719
|
-
"activated": [32]
|
|
36769
|
+
"activated": [32],
|
|
36770
|
+
"isInvalid": [32],
|
|
36771
|
+
"hintTextId": [32]
|
|
36720
36772
|
},
|
|
36721
36773
|
"$listeners$": undefined,
|
|
36722
36774
|
"$lazyBundleId$": "-",
|