@ionic/core 8.8.19-dev.11786730389.1a1927bf → 8.8.19-dev.11786832241.150538c7
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/ion-action-sheet.js +1 -1
- package/components/ion-alert.js +1 -1
- package/components/ion-back-button.js +1 -1
- package/components/ion-button.js +1 -1
- package/components/ion-card.js +1 -1
- package/components/ion-chip.js +1 -1
- package/components/ion-datetime-button.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/ion-fab-button.js +1 -1
- package/components/ion-infinite-scroll-content.js +1 -1
- package/components/ion-input-otp.js +1 -1
- package/components/ion-input-password-toggle.js +1 -1
- package/components/ion-input.js +1 -1
- package/components/ion-item-divider.js +1 -1
- package/components/ion-item-group.js +1 -1
- package/components/ion-item-option.js +1 -1
- package/components/ion-item-options.js +1 -1
- package/components/ion-item-sliding.js +1 -1
- package/components/ion-item.js +1 -1
- package/components/ion-label.js +1 -1
- package/components/ion-list-header.js +1 -1
- package/components/ion-list.js +1 -1
- package/components/ion-loading.js +1 -1
- package/components/ion-menu-button.js +1 -1
- package/components/ion-menu-toggle.js +1 -1
- package/components/ion-menu.js +1 -1
- package/components/ion-modal.js +1 -1
- package/components/ion-nav-link.js +1 -1
- package/components/ion-nav.js +1 -1
- package/components/ion-note.js +1 -1
- package/components/ion-picker-column-option.js +1 -1
- package/components/ion-popover.js +1 -1
- package/components/ion-progress-bar.js +1 -1
- package/components/ion-radio-group.js +1 -1
- package/components/ion-radio.js +1 -1
- package/components/ion-range.js +1 -1
- package/components/ion-refresher-content.js +1 -1
- package/components/ion-refresher.js +1 -1
- package/components/ion-reorder-group.js +1 -1
- package/components/ion-reorder.js +1 -1
- package/components/ion-ripple-effect.js +1 -1
- package/components/ion-router-link.js +1 -1
- package/components/ion-router-outlet.js +1 -1
- package/components/ion-row.js +1 -1
- package/components/ion-searchbar.js +1 -1
- package/components/ion-segment-button.js +1 -1
- package/components/ion-segment-content.js +1 -1
- package/components/ion-segment-view.js +1 -1
- package/components/ion-segment.js +1 -1
- package/components/ion-select-modal.js +1 -1
- package/components/ion-select-option.js +1 -1
- package/components/ion-select-popover.js +1 -1
- package/components/ion-select.js +1 -1
- package/components/ion-skeleton-text.js +1 -1
- package/components/ion-spinner.js +1 -1
- package/components/ion-split-pane.js +1 -1
- package/components/ion-tab-bar.js +1 -1
- package/components/ion-tab-button.js +1 -1
- package/components/ion-tab.js +1 -1
- package/components/ion-tabs.js +1 -1
- package/components/ion-text.js +1 -1
- package/components/ion-textarea.js +1 -1
- package/components/ion-thumbnail.js +1 -1
- package/components/ion-title.js +1 -1
- package/components/ion-toast.js +1 -1
- package/components/ion-toggle.js +1 -1
- package/components/ion-toolbar.js +1 -1
- package/components/{p-C1O9GEug.js → p--m5cCjbK.js} +1 -1
- package/components/{p-CfnGxjv-.js → p-B4uHHhPK.js} +1 -1
- package/components/{p-BxUIQcD9.js → p-BOvLNVKq.js} +1 -1
- package/components/{p-D_XD0pVT.js → p-BWBigMsI.js} +1 -1
- package/components/{p-xOjr4bwc.js → p-BZ4-QTes.js} +1 -1
- package/components/{p-tYCT3JGl.js → p-BjluhQMI.js} +1 -1
- package/components/{p-ClFYbgND.js → p-BlsIikdZ.js} +1 -1
- package/components/{p-Obm7si-x.js → p-Blug1Vxu.js} +1 -1
- package/components/{p-DTY4otpr.js → p-C91npEel.js} +1 -1
- package/components/{p-CVnwvOBD.js → p-CVb3x_r3.js} +1 -1
- package/components/{p-B6dUPQXq.js → p-CWLrHG8Y.js} +1 -1
- package/components/{p-0Pyit076.js → p-CfnNZz_d.js} +1 -1
- package/components/{p-DyePCNGr.js → p-DKrhJJV0.js} +1 -1
- package/components/p-DSzSbVP2.js +4 -0
- package/components/{p-BsVxQGUT.js → p-DgZOZQjJ.js} +1 -1
- package/components/{p-BO4sUqUv.js → p-Dmd2xqCe.js} +1 -1
- package/components/{p-83oP9gzn.js → p-GG5GhznE.js} +1 -1
- package/components/{p-Bc4wROfM.js → p-UQSiXX2Z.js} +1 -1
- package/components/{p-Dm7h4Nyv.js → p-qT1szVjw.js} +1 -1
- package/components/p-ypuYdSDB.js +4 -0
- package/dist/cjs/input.utils-BZdMWVrt.js +35 -0
- package/dist/cjs/ion-app_8.cjs.entry.js +5 -5
- package/dist/cjs/ion-avatar_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-col_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-input-otp.cjs.entry.js +3 -3
- package/dist/cjs/ion-input-password-toggle.cjs.entry.js +3 -3
- package/dist/cjs/ion-input.cjs.entry.js +42 -56
- package/dist/cjs/ion-item-option_3.cjs.entry.js +4 -4
- package/dist/cjs/ion-item_8.cjs.entry.js +12 -12
- package/dist/cjs/ion-loading.cjs.entry.js +2 -2
- package/dist/cjs/ion-menu_3.cjs.entry.js +6 -6
- package/dist/cjs/ion-modal.cjs.entry.js +4 -4
- package/dist/cjs/ion-nav_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-picker-column-option.cjs.entry.js +2 -2
- package/dist/cjs/ion-popover.cjs.entry.js +2 -2
- package/dist/cjs/ion-progress-bar.cjs.entry.js +1 -1
- package/dist/cjs/ion-radio_2.cjs.entry.js +4 -4
- package/dist/cjs/ion-range.cjs.entry.js +3 -3
- package/dist/cjs/ion-refresher_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-reorder_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-ripple-effect.cjs.entry.js +1 -1
- package/dist/cjs/ion-route_4.cjs.entry.js +2 -2
- package/dist/cjs/ion-searchbar.cjs.entry.js +4 -4
- package/dist/cjs/ion-segment-content.cjs.entry.js +1 -1
- package/dist/cjs/ion-segment-view.cjs.entry.js +2 -2
- package/dist/cjs/ion-segment_2.cjs.entry.js +4 -4
- package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
- package/dist/cjs/ion-select_3.cjs.entry.js +41 -59
- package/dist/cjs/ion-spinner.cjs.entry.js +1 -1
- package/dist/cjs/ion-split-pane.cjs.entry.js +2 -2
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +4 -4
- package/dist/cjs/ion-tab_2.cjs.entry.js +3 -3
- package/dist/cjs/ion-text.cjs.entry.js +2 -2
- package/dist/cjs/ion-textarea.cjs.entry.js +44 -55
- package/dist/cjs/ion-toast.cjs.entry.js +2 -2
- package/dist/cjs/ion-toggle.cjs.entry.js +4 -4
- package/dist/cjs/slot-mutation-controller-CgTGFqlW.js +397 -0
- package/dist/collection/components/input/input.ios.css +56 -24
- package/dist/collection/components/input/input.js +36 -51
- package/dist/collection/components/input/input.md.css +78 -41
- package/dist/collection/components/input-otp/input-otp.js +3 -3
- package/dist/collection/components/input-password-toggle/input-password-toggle.js +3 -3
- package/dist/collection/components/item-divider/item-divider.js +2 -2
- package/dist/collection/components/item-group/item-group.js +1 -1
- package/dist/collection/components/item-option/item-option.js +2 -2
- package/dist/collection/components/item-options/item-options.js +1 -1
- package/dist/collection/components/item-sliding/item-sliding.js +1 -1
- package/dist/collection/components/label/label.js +2 -2
- package/dist/collection/components/list/list.js +1 -1
- package/dist/collection/components/list-header/list-header.js +2 -2
- package/dist/collection/components/loading/loading.js +2 -2
- package/dist/collection/components/menu/menu.js +2 -2
- package/dist/collection/components/menu-button/menu-button.js +2 -2
- package/dist/collection/components/menu-toggle/menu-toggle.js +2 -2
- package/dist/collection/components/modal/modal.js +4 -4
- package/dist/collection/components/nav/nav.js +1 -1
- package/dist/collection/components/nav-link/nav-link.js +1 -1
- package/dist/collection/components/note/note.js +2 -2
- package/dist/collection/components/picker-column-option/picker-column-option.js +2 -2
- package/dist/collection/components/popover/popover.js +2 -2
- package/dist/collection/components/progress-bar/progress-bar.js +1 -1
- package/dist/collection/components/radio/radio.js +3 -3
- package/dist/collection/components/radio-group/radio-group.js +1 -1
- package/dist/collection/components/range/range.js +3 -3
- package/dist/collection/components/refresher/refresher.js +1 -1
- package/dist/collection/components/refresher-content/refresher-content.js +1 -1
- package/dist/collection/components/reorder/reorder.js +1 -1
- package/dist/collection/components/reorder-group/reorder-group.js +1 -1
- package/dist/collection/components/ripple-effect/ripple-effect.js +1 -1
- package/dist/collection/components/router-link/router-link.js +2 -2
- package/dist/collection/components/router-outlet/router-outlet.js +1 -1
- package/dist/collection/components/row/row.js +1 -1
- package/dist/collection/components/searchbar/searchbar.js +4 -4
- package/dist/collection/components/segment/segment.js +2 -2
- package/dist/collection/components/segment-button/segment-button.js +2 -2
- package/dist/collection/components/segment-content/segment-content.js +1 -1
- package/dist/collection/components/segment-view/segment-view.js +2 -2
- package/dist/collection/components/select/select.ios.css +63 -69
- package/dist/collection/components/select/select.js +40 -55
- package/dist/collection/components/select/select.md.css +85 -85
- package/dist/collection/components/select-modal/select-modal.js +1 -1
- package/dist/collection/components/select-option/select-option.js +1 -1
- package/dist/collection/components/select-popover/select-popover.js +1 -1
- package/dist/collection/components/skeleton-text/skeleton-text.js +2 -2
- package/dist/collection/components/spinner/spinner.js +1 -1
- package/dist/collection/components/split-pane/split-pane.js +2 -2
- package/dist/collection/components/tab/tab.js +2 -2
- package/dist/collection/components/tab-bar/tab-bar.js +2 -2
- package/dist/collection/components/tab-button/tab-button.js +2 -2
- package/dist/collection/components/tabs/tabs.js +1 -1
- package/dist/collection/components/text/text.js +2 -2
- package/dist/collection/components/textarea/textarea.ios.css +94 -62
- package/dist/collection/components/textarea/textarea.js +39 -51
- package/dist/collection/components/textarea/textarea.md.css +103 -77
- package/dist/collection/components/thumbnail/thumbnail.js +1 -1
- package/dist/collection/components/title/title.js +2 -2
- package/dist/collection/components/toast/toast.js +2 -2
- package/dist/collection/components/toggle/toggle.js +3 -3
- package/dist/collection/components/toolbar/toolbar.js +2 -2
- package/dist/collection/utils/forms/index.js +1 -0
- package/dist/collection/utils/forms/start-container-controller.js +132 -0
- package/dist/docs.json +22 -6
- package/dist/esm/input.utils-B1ValN_N.js +33 -0
- package/dist/esm/ion-app_8.entry.js +5 -5
- package/dist/esm/ion-avatar_3.entry.js +1 -1
- package/dist/esm/ion-col_3.entry.js +1 -1
- package/dist/esm/ion-input-otp.entry.js +3 -3
- package/dist/esm/ion-input-password-toggle.entry.js +3 -3
- package/dist/esm/ion-input.entry.js +40 -54
- package/dist/esm/ion-item-option_3.entry.js +4 -4
- package/dist/esm/ion-item_8.entry.js +12 -12
- package/dist/esm/ion-loading.entry.js +2 -2
- package/dist/esm/ion-menu_3.entry.js +6 -6
- package/dist/esm/ion-modal.entry.js +4 -4
- package/dist/esm/ion-nav_2.entry.js +2 -2
- package/dist/esm/ion-picker-column-option.entry.js +2 -2
- package/dist/esm/ion-popover.entry.js +2 -2
- package/dist/esm/ion-progress-bar.entry.js +1 -1
- package/dist/esm/ion-radio_2.entry.js +4 -4
- package/dist/esm/ion-range.entry.js +3 -3
- package/dist/esm/ion-refresher_2.entry.js +2 -2
- package/dist/esm/ion-reorder_2.entry.js +2 -2
- package/dist/esm/ion-ripple-effect.entry.js +1 -1
- package/dist/esm/ion-route_4.entry.js +2 -2
- package/dist/esm/ion-searchbar.entry.js +4 -4
- package/dist/esm/ion-segment-content.entry.js +1 -1
- package/dist/esm/ion-segment-view.entry.js +2 -2
- package/dist/esm/ion-segment_2.entry.js +4 -4
- package/dist/esm/ion-select-modal.entry.js +1 -1
- package/dist/esm/ion-select_3.entry.js +40 -58
- package/dist/esm/ion-spinner.entry.js +1 -1
- package/dist/esm/ion-split-pane.entry.js +2 -2
- package/dist/esm/ion-tab-bar_2.entry.js +4 -4
- package/dist/esm/ion-tab_2.entry.js +3 -3
- package/dist/esm/ion-text.entry.js +2 -2
- package/dist/esm/ion-textarea.entry.js +43 -54
- package/dist/esm/ion-toast.entry.js +2 -2
- package/dist/esm/ion-toggle.entry.js +4 -4
- package/dist/esm/slot-mutation-controller-u741eD3Z.js +393 -0
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-dbfd2d52.entry.js → p-06533d51.entry.js} +1 -1
- package/dist/ionic/{p-a641d428.entry.js → p-141f5b47.entry.js} +1 -1
- package/dist/ionic/p-14a5e8f5.entry.js +4 -0
- package/dist/ionic/{p-12589d59.entry.js → p-19269e04.entry.js} +1 -1
- package/dist/ionic/{p-efef6788.entry.js → p-19abbc33.entry.js} +1 -1
- package/dist/ionic/{p-5394e1d4.entry.js → p-4204184c.entry.js} +1 -1
- package/dist/ionic/p-4bc3ecdb.entry.js +4 -0
- package/dist/ionic/{p-21a7fb2a.entry.js → p-4eed9ca1.entry.js} +1 -1
- package/dist/ionic/p-5521dc1f.entry.js +4 -0
- package/dist/ionic/p-5c3626de.entry.js +4 -0
- package/dist/ionic/{p-374b10cb.entry.js → p-5d3b411c.entry.js} +1 -1
- package/dist/ionic/p-60576951.entry.js +4 -0
- package/dist/ionic/{p-1d2e53e8.entry.js → p-711a8319.entry.js} +1 -1
- package/dist/ionic/{p-48b6835f.entry.js → p-71419a55.entry.js} +1 -1
- package/dist/ionic/{p-ba8a598f.entry.js → p-79325ffe.entry.js} +1 -1
- package/dist/ionic/p-84a38904.entry.js +4 -0
- package/dist/ionic/{p-bf7c1f05.entry.js → p-8f204f1e.entry.js} +1 -1
- package/dist/ionic/p-9055e897.entry.js +4 -0
- package/dist/ionic/{p-6277efba.entry.js → p-9658e083.entry.js} +1 -1
- package/dist/ionic/{p-74f30659.entry.js → p-988baee1.entry.js} +1 -1
- package/dist/ionic/p-DAztxQR0.js +4 -0
- package/dist/ionic/p-DkUB-ROc.js +4 -0
- package/dist/ionic/{p-3835a020.entry.js → p-a71232d6.entry.js} +1 -1
- package/dist/ionic/{p-08f1ed1c.entry.js → p-a73d8742.entry.js} +1 -1
- package/dist/ionic/{p-8a21bdbd.entry.js → p-a8421d18.entry.js} +1 -1
- package/dist/ionic/{p-2ce59395.entry.js → p-a8c2c343.entry.js} +1 -1
- package/dist/ionic/{p-c3f65965.entry.js → p-bc2bad5f.entry.js} +1 -1
- package/dist/ionic/{p-f622796d.entry.js → p-be08d500.entry.js} +1 -1
- package/dist/ionic/p-be9a4f51.entry.js +4 -0
- package/dist/ionic/{p-33829e94.entry.js → p-ccc5044d.entry.js} +1 -1
- package/dist/ionic/{p-3c5fdd27.entry.js → p-ce32912b.entry.js} +1 -1
- package/dist/ionic/p-ded69ceb.entry.js +4 -0
- package/dist/ionic/{p-cec87704.entry.js → p-e0c6e31e.entry.js} +1 -1
- package/dist/ionic/{p-09b47b7d.entry.js → p-e8c3e08a.entry.js} +1 -1
- package/dist/ionic/{p-8f3a1995.entry.js → p-ed5d540d.entry.js} +1 -1
- package/dist/ionic/{p-6b286c5c.entry.js → p-f2802440.entry.js} +1 -1
- package/dist/ionic/{p-62e71297.entry.js → p-fe1bfbcf.entry.js} +1 -1
- package/dist/types/components/input/input.d.ts +11 -5
- package/dist/types/components/select/select.d.ts +12 -6
- package/dist/types/components/textarea/textarea.d.ts +12 -5
- package/dist/types/utils/forms/index.d.ts +1 -0
- package/dist/types/utils/forms/start-container-controller.d.ts +34 -0
- package/hydrate/index.js +350 -267
- package/hydrate/index.mjs +350 -267
- package/package.json +4 -4
- package/components/p-DIgGHN7D.js +0 -4
- package/components/p-MCJ7HjWe.js +0 -4
- package/dist/cjs/input.utils-CP4fzrqk.js +0 -149
- package/dist/cjs/notch-controller-BEUpEgb5.js +0 -155
- package/dist/esm/input.utils-J6HWocLA.js +0 -146
- package/dist/esm/notch-controller-CrUGyHYz.js +0 -153
- package/dist/ionic/p-0266b7e1.entry.js +0 -4
- package/dist/ionic/p-214e000a.entry.js +0 -4
- package/dist/ionic/p-91c6faf1.entry.js +0 -4
- package/dist/ionic/p-9b865fe6.entry.js +0 -4
- package/dist/ionic/p-BnMQxWON.js +0 -4
- package/dist/ionic/p-ac6ef997.entry.js +0 -4
- package/dist/ionic/p-b24dc0a1.entry.js +0 -4
- package/dist/ionic/p-c8fbe544.entry.js +0 -4
- package/dist/ionic/p-cb12f6c3.entry.js +0 -4
- package/dist/ionic/p-ede019ef.entry.js +0 -4
- package/dist/ionic/p-kJA95YWg.js +0 -4
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
var index = require('./index-DkNv4J_i.js');
|
|
7
|
+
var helpers = require('./helpers-CaLhEmTE.js');
|
|
8
|
+
var dir = require('./dir-Brx7VkvP.js');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A utility to calculate the size of an outline notch
|
|
12
|
+
* width relative to the content passed. This is used in
|
|
13
|
+
* components such as `ion-select` with `fill="outline"`
|
|
14
|
+
* where we need to pass slotted HTML content. This is not
|
|
15
|
+
* needed when rendering plaintext content because we can
|
|
16
|
+
* render the plaintext again hidden with `opacity: 0` inside
|
|
17
|
+
* of the notch. As a result we can rely on the intrinsic size
|
|
18
|
+
* of the element to correctly compute the notch width. We
|
|
19
|
+
* cannot do this with slotted content because we cannot project
|
|
20
|
+
* it into 2 places at once.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
* @param el: The host element
|
|
24
|
+
* @param getNotchSpacerEl: A function that returns a reference to the notch spacer element inside of the component template.
|
|
25
|
+
* @param getLabelSlot: A function that returns a reference to the slotted content.
|
|
26
|
+
*/
|
|
27
|
+
const createNotchController = (el, getNotchSpacerEl, getLabelSlot) => {
|
|
28
|
+
let notchVisibilityIO;
|
|
29
|
+
const needsExplicitNotchWidth = () => {
|
|
30
|
+
const notchSpacerEl = getNotchSpacerEl();
|
|
31
|
+
if (
|
|
32
|
+
/**
|
|
33
|
+
* If the notch is not being used
|
|
34
|
+
* then we do not need to set the notch width.
|
|
35
|
+
*/
|
|
36
|
+
notchSpacerEl === undefined ||
|
|
37
|
+
/**
|
|
38
|
+
* If either the label property is being
|
|
39
|
+
* used or the label slot is not defined,
|
|
40
|
+
* then we do not need to estimate the notch width.
|
|
41
|
+
*/
|
|
42
|
+
el.label !== undefined ||
|
|
43
|
+
getLabelSlot() === null) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
};
|
|
48
|
+
const calculateNotchWidth = () => {
|
|
49
|
+
if (needsExplicitNotchWidth()) {
|
|
50
|
+
/**
|
|
51
|
+
* Run this the frame after
|
|
52
|
+
* the browser has re-painted the host element.
|
|
53
|
+
* Otherwise, the label element may have a width
|
|
54
|
+
* of 0 and the IntersectionObserver will be used.
|
|
55
|
+
*/
|
|
56
|
+
helpers.raf(() => {
|
|
57
|
+
setNotchWidth();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* When using a label prop we can render
|
|
63
|
+
* the label value inside of the notch and
|
|
64
|
+
* let the browser calculate the size of the notch.
|
|
65
|
+
* However, we cannot render the label slot in multiple
|
|
66
|
+
* places so we need to manually calculate the notch dimension
|
|
67
|
+
* based on the size of the slotted content.
|
|
68
|
+
*
|
|
69
|
+
* This function should only be used to set the notch width
|
|
70
|
+
* on slotted label content. The notch width for label prop
|
|
71
|
+
* content is automatically calculated based on the
|
|
72
|
+
* intrinsic size of the label text.
|
|
73
|
+
*/
|
|
74
|
+
const setNotchWidth = () => {
|
|
75
|
+
const notchSpacerEl = getNotchSpacerEl();
|
|
76
|
+
if (notchSpacerEl === undefined) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!needsExplicitNotchWidth()) {
|
|
80
|
+
notchSpacerEl.style.removeProperty('width');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const width = getLabelSlot().scrollWidth;
|
|
84
|
+
if (
|
|
85
|
+
/**
|
|
86
|
+
* If the computed width of the label is 0
|
|
87
|
+
* and notchSpacerEl's offsetParent is null
|
|
88
|
+
* then that means the element is hidden.
|
|
89
|
+
* As a result, we need to wait for the element
|
|
90
|
+
* to become visible before setting the notch width.
|
|
91
|
+
*
|
|
92
|
+
* We do not check el.offsetParent because
|
|
93
|
+
* that can be null if the host element has
|
|
94
|
+
* position: fixed applied to it.
|
|
95
|
+
* notchSpacerEl does not have position: fixed.
|
|
96
|
+
*/
|
|
97
|
+
width === 0 &&
|
|
98
|
+
notchSpacerEl.offsetParent === null &&
|
|
99
|
+
index.win !== undefined &&
|
|
100
|
+
'IntersectionObserver' in index.win) {
|
|
101
|
+
/**
|
|
102
|
+
* If there is an IO already attached
|
|
103
|
+
* then that will update the notch
|
|
104
|
+
* once the element becomes visible.
|
|
105
|
+
* As a result, there is no need to create
|
|
106
|
+
* another one.
|
|
107
|
+
*/
|
|
108
|
+
if (notchVisibilityIO !== undefined) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const io = (notchVisibilityIO = new IntersectionObserver((ev) => {
|
|
112
|
+
/**
|
|
113
|
+
* If the element is visible then we
|
|
114
|
+
* can try setting the notch width again.
|
|
115
|
+
*/
|
|
116
|
+
if (ev[0].intersectionRatio === 1) {
|
|
117
|
+
setNotchWidth();
|
|
118
|
+
io.disconnect();
|
|
119
|
+
notchVisibilityIO = undefined;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
/**
|
|
123
|
+
* Set the root to be the host element
|
|
124
|
+
* This causes the IO callback
|
|
125
|
+
* to be fired in WebKit as soon as the element
|
|
126
|
+
* is visible. If we used the default root value
|
|
127
|
+
* then WebKit would only fire the IO callback
|
|
128
|
+
* after any animations (such as a modal transition)
|
|
129
|
+
* finished, and there would potentially be a flicker.
|
|
130
|
+
*/
|
|
131
|
+
{ threshold: 0.01, root: el }));
|
|
132
|
+
io.observe(notchSpacerEl);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* If the element is visible then we can set the notch width.
|
|
137
|
+
* The notch is only visible when the label is scaled,
|
|
138
|
+
* which is why we multiply the width by 0.75 as this is
|
|
139
|
+
* the same amount the label element is scaled by in the host CSS.
|
|
140
|
+
* (See $form-control-label-stacked-scale in ionic.globals.scss).
|
|
141
|
+
*/
|
|
142
|
+
notchSpacerEl.style.setProperty('width', `${width * 0.75}px`);
|
|
143
|
+
};
|
|
144
|
+
const destroy = () => {
|
|
145
|
+
if (notchVisibilityIO) {
|
|
146
|
+
notchVisibilityIO.disconnect();
|
|
147
|
+
notchVisibilityIO = undefined;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
return {
|
|
151
|
+
calculateNotchWidth,
|
|
152
|
+
destroy,
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Applied to the host while the label is being repositioned. The
|
|
158
|
+
* component stylesheets style this class, so it must stay in sync with
|
|
159
|
+
* the `skip-label-transition` selector in those files. Renaming it here
|
|
160
|
+
* requires renaming it there too.
|
|
161
|
+
*/
|
|
162
|
+
const SKIP_LABEL_TRANSITION_CLASS = 'skip-label-transition';
|
|
163
|
+
/**
|
|
164
|
+
* Set on the host as an inline style. The component stylesheets declare
|
|
165
|
+
* this property and read it with `var()`, so it must stay in sync with
|
|
166
|
+
* the `--internal-start-container-adjustment` references in those files.
|
|
167
|
+
* Renaming it here requires renaming it there too.
|
|
168
|
+
*/
|
|
169
|
+
const START_CONTAINER_ADJUSTMENT_VAR = '--internal-start-container-adjustment';
|
|
170
|
+
/**
|
|
171
|
+
* A utility to measure and update the start container width adjustment
|
|
172
|
+
* for form components (input, textarea, select) with `fill="outline"`.
|
|
173
|
+
* This adjustment compensates for the start container width when
|
|
174
|
+
* positioning floating/stacked labels within the outline border.
|
|
175
|
+
*
|
|
176
|
+
* Measurement is deferred with raf() to avoid forcing layout during
|
|
177
|
+
* component updates, and a ResizeObserver watches for dynamic width
|
|
178
|
+
* changes (e.g., when web fonts load or async content changes).
|
|
179
|
+
*
|
|
180
|
+
* @internal
|
|
181
|
+
* @param el - The host element (ion-input, ion-textarea, or ion-select).
|
|
182
|
+
* @param getStartContainer - A callback that returns the start container element.
|
|
183
|
+
* @param shouldApplyAdjustment - A callback that determines whether the adjustment should be applied.
|
|
184
|
+
*/
|
|
185
|
+
const createStartContainerController = (el, getStartContainer, shouldApplyAdjustment) => {
|
|
186
|
+
let resizeObserver;
|
|
187
|
+
let observedContainer;
|
|
188
|
+
let measurementRaf;
|
|
189
|
+
let transitionRaf;
|
|
190
|
+
let appliedAdjustment;
|
|
191
|
+
const calculateAdjustment = () => {
|
|
192
|
+
const startSlot = getStartContainer();
|
|
193
|
+
if (!startSlot || !shouldApplyAdjustment()) {
|
|
194
|
+
return '';
|
|
195
|
+
}
|
|
196
|
+
/*
|
|
197
|
+
* Round to one decimal place so fractional widths produce a stable
|
|
198
|
+
* label offset when the start container is added, removed, or resized.
|
|
199
|
+
*/
|
|
200
|
+
const startContainerWidth = startSlot.getBoundingClientRect().width;
|
|
201
|
+
const roundedWidth = Math.round(startContainerWidth * 10) / 10;
|
|
202
|
+
const sign = dir.isRTL(el) ? '' : '-';
|
|
203
|
+
return roundedWidth ? `${sign}${roundedWidth}px` : '0px';
|
|
204
|
+
};
|
|
205
|
+
const scheduleAdjustmentUpdate = () => {
|
|
206
|
+
// Return if there is already a measurement queued to avoid a flicker
|
|
207
|
+
if (measurementRaf !== undefined) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
/*
|
|
211
|
+
* Defer the measurement until the next animation frame so layout
|
|
212
|
+
* is measured after the current update has been applied.
|
|
213
|
+
*/
|
|
214
|
+
measurementRaf = helpers.raf(() => {
|
|
215
|
+
measurementRaf = undefined;
|
|
216
|
+
const adjustment = calculateAdjustment();
|
|
217
|
+
// Only suppress the label transition when the label has to move
|
|
218
|
+
if (adjustment !== appliedAdjustment) {
|
|
219
|
+
// Discard a removal queued by an earlier change
|
|
220
|
+
if (transitionRaf !== undefined) {
|
|
221
|
+
cancelAnimationFrame(transitionRaf);
|
|
222
|
+
}
|
|
223
|
+
el.classList.add(SKIP_LABEL_TRANSITION_CLASS);
|
|
224
|
+
el.style.setProperty(START_CONTAINER_ADJUSTMENT_VAR, adjustment);
|
|
225
|
+
appliedAdjustment = adjustment;
|
|
226
|
+
// Re-enable the transition once the new offset has been painted
|
|
227
|
+
transitionRaf = helpers.raf(() => {
|
|
228
|
+
transitionRaf = undefined;
|
|
229
|
+
el.classList.remove(SKIP_LABEL_TRANSITION_CLASS);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
setupResizeObserver();
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
const disconnectResizeObserver = () => {
|
|
236
|
+
if (resizeObserver) {
|
|
237
|
+
resizeObserver.disconnect();
|
|
238
|
+
resizeObserver = undefined;
|
|
239
|
+
observedContainer = undefined;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
const setupResizeObserver = () => {
|
|
243
|
+
const startSlot = getStartContainer();
|
|
244
|
+
// Stop watching once the adjustment no longer applies
|
|
245
|
+
if (!startSlot || !shouldApplyAdjustment()) {
|
|
246
|
+
disconnectResizeObserver();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// Return when prerendering or already watching this container
|
|
250
|
+
if (typeof ResizeObserver !== 'function' || (resizeObserver && observedContainer === startSlot)) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
disconnectResizeObserver();
|
|
254
|
+
resizeObserver = new ResizeObserver(() => {
|
|
255
|
+
scheduleAdjustmentUpdate();
|
|
256
|
+
});
|
|
257
|
+
observedContainer = startSlot;
|
|
258
|
+
resizeObserver.observe(startSlot);
|
|
259
|
+
};
|
|
260
|
+
const calculateStartContainerWidth = () => {
|
|
261
|
+
scheduleAdjustmentUpdate();
|
|
262
|
+
};
|
|
263
|
+
const destroy = () => {
|
|
264
|
+
disconnectResizeObserver();
|
|
265
|
+
if (measurementRaf !== undefined) {
|
|
266
|
+
cancelAnimationFrame(measurementRaf);
|
|
267
|
+
measurementRaf = undefined;
|
|
268
|
+
}
|
|
269
|
+
// Tearing down mid-toggle would leave the transition disabled
|
|
270
|
+
if (transitionRaf !== undefined) {
|
|
271
|
+
cancelAnimationFrame(transitionRaf);
|
|
272
|
+
transitionRaf = undefined;
|
|
273
|
+
el.classList.remove(SKIP_LABEL_TRANSITION_CLASS);
|
|
274
|
+
}
|
|
275
|
+
// Re-apply from scratch if the element is connected again
|
|
276
|
+
appliedAdjustment = undefined;
|
|
277
|
+
};
|
|
278
|
+
return {
|
|
279
|
+
calculateStartContainerWidth,
|
|
280
|
+
destroy,
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Used to update a scoped component that uses emulated slots. This fires when
|
|
286
|
+
* content is passed into the slot or when the content inside of a slot changes.
|
|
287
|
+
* This is not needed for components using native slots in the Shadow DOM.
|
|
288
|
+
* @internal
|
|
289
|
+
* @param el The host element to observe
|
|
290
|
+
* @param slotName mutationCallback will fire when nodes on these slot(s) change
|
|
291
|
+
* @param mutationCallback The callback to fire whenever the slotted content changes
|
|
292
|
+
*/
|
|
293
|
+
const createSlotMutationController = (el, slotName, mutationCallback) => {
|
|
294
|
+
let hostMutationObserver;
|
|
295
|
+
let slottedContentMutationObserver;
|
|
296
|
+
if (index.win !== undefined && 'MutationObserver' in index.win) {
|
|
297
|
+
const slots = Array.isArray(slotName) ? slotName : [slotName];
|
|
298
|
+
hostMutationObserver = new MutationObserver((entries) => {
|
|
299
|
+
for (const entry of entries) {
|
|
300
|
+
for (const node of entry.addedNodes) {
|
|
301
|
+
/**
|
|
302
|
+
* Check to see if the added node
|
|
303
|
+
* is our slotted content.
|
|
304
|
+
*/
|
|
305
|
+
if (node.nodeType === Node.ELEMENT_NODE && slots.includes(node.slot)) {
|
|
306
|
+
/**
|
|
307
|
+
* If so, we want to watch the slotted
|
|
308
|
+
* content itself for changes. This lets us
|
|
309
|
+
* detect when content inside of the slot changes.
|
|
310
|
+
*/
|
|
311
|
+
mutationCallback();
|
|
312
|
+
/**
|
|
313
|
+
* Adding the listener in an raf
|
|
314
|
+
* waits until Stencil moves the slotted element
|
|
315
|
+
* into the correct place in the event that
|
|
316
|
+
* slotted content is being added.
|
|
317
|
+
*/
|
|
318
|
+
helpers.raf(() => watchForSlotChange(node));
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
hostMutationObserver.observe(el, {
|
|
325
|
+
childList: true,
|
|
326
|
+
/**
|
|
327
|
+
* This fixes an issue with the `ion-input` and
|
|
328
|
+
* `ion-textarea` not re-rendering in some cases
|
|
329
|
+
* when using the label slot functionality.
|
|
330
|
+
*
|
|
331
|
+
* HTML element patches in Stencil that are enabled
|
|
332
|
+
* by the `experimentalSlotFixes` flag in Stencil v4
|
|
333
|
+
* result in DOM manipulations that won't trigger
|
|
334
|
+
* the current mutation observer configuration and
|
|
335
|
+
* callback.
|
|
336
|
+
*/
|
|
337
|
+
subtree: true,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Listen for changes inside of the slotted content.
|
|
342
|
+
* We can listen for subtree changes here to be
|
|
343
|
+
* informed of text within the slotted content
|
|
344
|
+
* changing. Doing this on the host is possible
|
|
345
|
+
* but it is much more expensive to do because
|
|
346
|
+
* it also listens for changes to the internals
|
|
347
|
+
* of the component.
|
|
348
|
+
*/
|
|
349
|
+
const watchForSlotChange = (slottedEl) => {
|
|
350
|
+
if (slottedContentMutationObserver) {
|
|
351
|
+
slottedContentMutationObserver.disconnect();
|
|
352
|
+
slottedContentMutationObserver = undefined;
|
|
353
|
+
}
|
|
354
|
+
slottedContentMutationObserver = new MutationObserver((entries) => {
|
|
355
|
+
mutationCallback();
|
|
356
|
+
for (const entry of entries) {
|
|
357
|
+
for (const node of entry.removedNodes) {
|
|
358
|
+
/**
|
|
359
|
+
* If the element was removed then we
|
|
360
|
+
* need to destroy the MutationObserver
|
|
361
|
+
* so the element can be garbage collected.
|
|
362
|
+
*/
|
|
363
|
+
if (node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) {
|
|
364
|
+
destroySlottedContentObserver();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
/**
|
|
370
|
+
* Listen for changes inside of the element
|
|
371
|
+
* as well as anything deep in the tree.
|
|
372
|
+
* We listen on the parentElement so that we can
|
|
373
|
+
* detect when slotted element itself is removed.
|
|
374
|
+
*/
|
|
375
|
+
slottedContentMutationObserver.observe(slottedEl.parentElement ?? slottedEl, { subtree: true, childList: true });
|
|
376
|
+
};
|
|
377
|
+
const destroy = () => {
|
|
378
|
+
if (hostMutationObserver) {
|
|
379
|
+
hostMutationObserver.disconnect();
|
|
380
|
+
hostMutationObserver = undefined;
|
|
381
|
+
}
|
|
382
|
+
destroySlottedContentObserver();
|
|
383
|
+
};
|
|
384
|
+
const destroySlottedContentObserver = () => {
|
|
385
|
+
if (slottedContentMutationObserver) {
|
|
386
|
+
slottedContentMutationObserver.disconnect();
|
|
387
|
+
slottedContentMutationObserver = undefined;
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
return {
|
|
391
|
+
destroy,
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
exports.createNotchController = createNotchController;
|
|
396
|
+
exports.createSlotMutationController = createSlotMutationController;
|
|
397
|
+
exports.createStartContainerController = createStartContainerController;
|
|
@@ -206,12 +206,6 @@
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
.input-clear-icon {
|
|
209
|
-
-webkit-margin-start: auto;
|
|
210
|
-
margin-inline-start: auto;
|
|
211
|
-
-webkit-margin-end: auto;
|
|
212
|
-
margin-inline-end: auto;
|
|
213
|
-
margin-top: auto;
|
|
214
|
-
margin-bottom: auto;
|
|
215
209
|
padding-left: 0;
|
|
216
210
|
padding-right: 0;
|
|
217
211
|
padding-top: 0;
|
|
@@ -269,14 +263,47 @@
|
|
|
269
263
|
line-height: normal;
|
|
270
264
|
}
|
|
271
265
|
|
|
266
|
+
.input-control {
|
|
267
|
+
display: flex;
|
|
268
|
+
flex-grow: 1;
|
|
269
|
+
width: 100%;
|
|
270
|
+
/**
|
|
271
|
+
* Allows the control to shrink below the label and input's intrinsic
|
|
272
|
+
* width, preventing the start and end slots from being pushed outside
|
|
273
|
+
* the wrapper. The label and input truncate independently, so it can
|
|
274
|
+
* use whatever space remains after accounting for the slots.
|
|
275
|
+
*/
|
|
276
|
+
min-width: 0;
|
|
277
|
+
}
|
|
278
|
+
|
|
272
279
|
.native-wrapper {
|
|
273
280
|
display: flex;
|
|
274
281
|
position: relative;
|
|
275
282
|
flex-grow: 1;
|
|
276
|
-
align-items: center;
|
|
277
283
|
width: 100%;
|
|
278
284
|
}
|
|
279
285
|
|
|
286
|
+
/**
|
|
287
|
+
* When the label sits beside the input, the label should size to its content
|
|
288
|
+
* and the input should take the remaining space. A zero flex basis prevents
|
|
289
|
+
* the input from requesting its full width and forcing the label to shrink.
|
|
290
|
+
* Stacked and floating placements use a column layout, so their flex basis
|
|
291
|
+
* controls height instead and does not need to be overridden.
|
|
292
|
+
*/
|
|
293
|
+
:host(.input-label-placement-start) .native-wrapper,
|
|
294
|
+
:host(.input-label-placement-end) .native-wrapper,
|
|
295
|
+
:host(.input-label-placement-fixed) .native-wrapper {
|
|
296
|
+
flex: 1 1 0;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.input-start,
|
|
300
|
+
.input-end {
|
|
301
|
+
display: flex;
|
|
302
|
+
position: relative;
|
|
303
|
+
flex-shrink: 0;
|
|
304
|
+
align-items: center;
|
|
305
|
+
}
|
|
306
|
+
|
|
280
307
|
:host(.ion-touched.ion-invalid) {
|
|
281
308
|
--highlight-color: var(--highlight-color-invalid);
|
|
282
309
|
}
|
|
@@ -377,6 +404,12 @@
|
|
|
377
404
|
*/
|
|
378
405
|
display: flex;
|
|
379
406
|
align-items: center;
|
|
407
|
+
/**
|
|
408
|
+
* Allows the label to shrink below its intrinsic content width.
|
|
409
|
+
* Without this the label keeps its full width and can push the
|
|
410
|
+
* input and end slot outside the wrapper.
|
|
411
|
+
*/
|
|
412
|
+
min-width: 0;
|
|
380
413
|
/**
|
|
381
414
|
* Label text should not extend
|
|
382
415
|
* beyond the bounds of the input.
|
|
@@ -395,6 +428,18 @@
|
|
|
395
428
|
pointer-events: none;
|
|
396
429
|
}
|
|
397
430
|
|
|
431
|
+
/**
|
|
432
|
+
* When start/end slots are added or removed, we temporarily
|
|
433
|
+
* disable the label transition to prevent the floating label
|
|
434
|
+
* from animating as its position is adjusted.
|
|
435
|
+
*
|
|
436
|
+
* This class is applied by the start container controller, so
|
|
437
|
+
* renaming it here requires renaming it there too.
|
|
438
|
+
*/
|
|
439
|
+
:host(.skip-label-transition) .label-text-wrapper {
|
|
440
|
+
transition: none;
|
|
441
|
+
}
|
|
442
|
+
|
|
398
443
|
/**
|
|
399
444
|
* We need to use two elements instead of
|
|
400
445
|
* one. The .label-text-wrapper is responsible
|
|
@@ -438,7 +483,7 @@
|
|
|
438
483
|
* Label is on the left of the input in LTR and
|
|
439
484
|
* on the right in RTL.
|
|
440
485
|
*/
|
|
441
|
-
:host(.input-label-placement-start) .input-
|
|
486
|
+
:host(.input-label-placement-start) .input-control {
|
|
442
487
|
flex-direction: row;
|
|
443
488
|
}
|
|
444
489
|
|
|
@@ -460,7 +505,7 @@
|
|
|
460
505
|
* Label is on the right of the input in LTR and
|
|
461
506
|
* on the left in RTL.
|
|
462
507
|
*/
|
|
463
|
-
:host(.input-label-placement-end) .input-
|
|
508
|
+
:host(.input-label-placement-end) .input-control {
|
|
464
509
|
flex-direction: row-reverse;
|
|
465
510
|
}
|
|
466
511
|
|
|
@@ -508,10 +553,9 @@
|
|
|
508
553
|
* Floating: Label sits over the input when the input has no
|
|
509
554
|
* value and is blurred. Label sits above the input and is scaled
|
|
510
555
|
* down when the input is focused or has a value.
|
|
511
|
-
*
|
|
512
556
|
*/
|
|
513
|
-
:host(.input-label-placement-stacked) .input-
|
|
514
|
-
:host(.input-label-placement-floating) .input-
|
|
557
|
+
:host(.input-label-placement-stacked) .input-control,
|
|
558
|
+
:host(.input-label-placement-floating) .input-control {
|
|
515
559
|
flex-direction: column;
|
|
516
560
|
align-items: start;
|
|
517
561
|
}
|
|
@@ -542,18 +586,6 @@
|
|
|
542
586
|
}
|
|
543
587
|
}
|
|
544
588
|
|
|
545
|
-
/**
|
|
546
|
-
* Ensures the input does not
|
|
547
|
-
* overlap the label.
|
|
548
|
-
*/
|
|
549
|
-
:host(.input-label-placement-stacked) input,
|
|
550
|
-
:host(.input-label-placement-floating) input {
|
|
551
|
-
margin-left: 0;
|
|
552
|
-
margin-right: 0;
|
|
553
|
-
margin-top: 1px;
|
|
554
|
-
margin-bottom: 0;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
589
|
/**
|
|
558
590
|
* This makes the label sit over the input
|
|
559
591
|
* when the input is blurred and has no value.
|