@ionic/core 9.0.3-dev.11788449150.16022b1e → 9.0.3-dev.11790016799.1e269b7a
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-accordion.js +1 -1
- package/components/ion-alert.js +1 -1
- package/components/ion-back-button.js +1 -1
- package/components/ion-breadcrumb.js +1 -1
- package/components/ion-checkbox.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/ion-fab-button.js +1 -1
- package/components/ion-input-password-toggle.js +1 -1
- package/components/ion-input.js +1 -1
- package/components/ion-item.js +1 -1
- package/components/ion-menu-button.js +1 -1
- package/components/ion-refresher-content.js +1 -1
- package/components/ion-reorder.js +1 -1
- package/components/ion-searchbar.js +1 -1
- package/components/ion-select-modal.js +1 -1
- package/components/ion-select-popover.js +1 -1
- package/components/ion-select.js +1 -1
- package/components/ion-textarea.js +1 -1
- package/components/ion-toggle.js +1 -1
- package/components/{p-Cc3oC60a.js → p-0rXxxCTt.js} +1 -1
- package/components/p-B9ibhQu1.js +4 -0
- package/components/p-BzxHcuQH.js +4 -0
- package/components/p-C6wm_AQQ.js +4 -0
- package/components/p-CaxVJjmc.js +4 -0
- package/components/{p-Cm78Kk79.js → p-D2X-Hime.js} +1 -1
- package/css/ionic/bundle.ionic.css.map +1 -1
- package/css/ionic/core.ionic.css.map +1 -1
- package/css/ionic/global.bundle.ionic.css.map +1 -1
- package/css/ionic/ionic-swiper.ionic.css.map +1 -1
- package/css/ionic/link.ionic.css.map +1 -1
- package/css/ionic/typography.ionic.css.map +1 -1
- package/dist/cjs/ion-accordion_2.cjs.entry.js +9 -14
- package/dist/cjs/ion-alert.cjs.entry.js +4 -4
- package/dist/cjs/ion-back-button.cjs.entry.js +11 -13
- package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +16 -29
- package/dist/cjs/ion-checkbox.cjs.entry.js +23 -15
- package/dist/cjs/ion-datetime.cjs.entry.js +14 -50
- package/dist/cjs/ion-fab_3.cjs.entry.js +9 -14
- package/dist/cjs/ion-input-password-toggle.cjs.entry.js +17 -29
- package/dist/cjs/ion-input.cjs.entry.js +16 -32
- package/dist/cjs/ion-item_8.cjs.entry.js +10 -15
- package/dist/cjs/ion-menu_3.cjs.entry.js +9 -12
- package/dist/cjs/ion-refresher_2.cjs.entry.js +10 -5
- package/dist/cjs/ion-reorder_2.cjs.entry.js +5 -13
- package/dist/cjs/ion-searchbar.cjs.entry.js +8 -37
- package/dist/cjs/ion-select-modal.cjs.entry.js +11 -10
- package/dist/cjs/ion-select_3.cjs.entry.js +17 -41
- package/dist/cjs/ion-textarea.cjs.entry.js +14 -22
- package/dist/cjs/ion-toggle.cjs.entry.js +12 -28
- package/dist/collection/components/accordion/accordion.js +9 -14
- package/dist/collection/components/alert/alert.ionic.css +7 -9
- package/dist/collection/components/alert/alert.js +3 -3
- package/dist/collection/components/back-button/back-button.js +11 -13
- package/dist/collection/components/breadcrumb/breadcrumb.js +16 -28
- package/dist/collection/components/checkbox/checkbox.ionic.css +35 -42
- package/dist/collection/components/checkbox/checkbox.ios.css +33 -29
- package/dist/collection/components/checkbox/checkbox.js +23 -13
- package/dist/collection/components/checkbox/checkbox.md.css +33 -29
- package/dist/collection/components/datetime/datetime.ios.css +5 -10
- package/dist/collection/components/datetime/datetime.js +12 -48
- package/dist/collection/components/datetime/datetime.md.css +5 -10
- package/dist/collection/components/fab-button/fab-button.js +9 -14
- package/dist/collection/components/input/input.ionic.css +102 -79
- package/dist/collection/components/input/input.js +15 -31
- package/dist/collection/components/input-password-toggle/input-password-toggle.js +18 -28
- package/dist/collection/components/item/item.js +10 -15
- package/dist/collection/components/menu-button/menu-button.js +9 -12
- package/dist/collection/components/refresher-content/refresher-content.js +10 -4
- package/dist/collection/components/reorder/reorder.js +5 -13
- package/dist/collection/components/searchbar/searchbar.js +8 -35
- package/dist/collection/components/select/select.ionic.css +187 -76
- package/dist/collection/components/select/select.js +18 -43
- package/dist/collection/components/select-modal/select-modal.js +12 -10
- package/dist/collection/components/textarea/textarea.ionic.css +133 -85
- package/dist/collection/components/textarea/textarea.ios.css +0 -4
- package/dist/collection/components/textarea/textarea.js +14 -19
- package/dist/collection/components/textarea/textarea.md.css +0 -4
- package/dist/collection/components/toggle/toggle.js +12 -26
- package/dist/collection/utils/test/playwright/field-geometry.js +34 -0
- package/dist/collection/utils/test/playwright/index.js +1 -0
- package/dist/docs.json +60 -25
- package/dist/esm/{index-BqQ15K9a.js → index-BkJpfpXI.js} +1 -1
- package/dist/esm/ion-accordion_2.entry.js +10 -15
- package/dist/esm/ion-alert.entry.js +4 -4
- package/dist/esm/ion-back-button.entry.js +12 -14
- package/dist/esm/ion-breadcrumb_2.entry.js +17 -30
- package/dist/esm/ion-checkbox.entry.js +24 -16
- package/dist/esm/ion-datetime.entry.js +15 -51
- package/dist/esm/ion-fab_3.entry.js +10 -15
- package/dist/esm/ion-input-password-toggle.entry.js +19 -31
- package/dist/esm/ion-input.entry.js +17 -33
- package/dist/esm/ion-item_8.entry.js +11 -16
- package/dist/esm/ion-menu_3.entry.js +10 -13
- package/dist/esm/ion-refresher_2.entry.js +11 -6
- package/dist/esm/ion-reorder_2.entry.js +6 -14
- package/dist/esm/ion-searchbar.entry.js +9 -38
- package/dist/esm/ion-select-modal.entry.js +13 -12
- package/dist/esm/ion-select_3.entry.js +18 -42
- package/dist/esm/ion-textarea.entry.js +14 -22
- package/dist/esm/ion-toggle.entry.js +13 -29
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-016f2ee0.entry.js +4 -0
- package/dist/ionic/p-07b95001.entry.js +4 -0
- package/dist/ionic/p-14dfe86e.entry.js +4 -0
- package/dist/ionic/p-167af5d6.entry.js +4 -0
- package/dist/ionic/p-18285aab.entry.js +4 -0
- package/dist/ionic/{p-2e3acd77.entry.js → p-1e0f0eb9.entry.js} +1 -1
- package/dist/ionic/p-368935f5.entry.js +4 -0
- package/dist/ionic/p-38da0794.entry.js +4 -0
- package/dist/ionic/p-80f71456.entry.js +4 -0
- package/dist/ionic/p-83aa4043.entry.js +4 -0
- package/dist/ionic/p-944ce631.entry.js +4 -0
- package/dist/ionic/{p-BqQ15K9a.js → p-BkJpfpXI.js} +1 -1
- package/dist/ionic/p-aecef1d7.entry.js +4 -0
- package/dist/ionic/p-bb83b861.entry.js +4 -0
- package/dist/ionic/p-c1c90068.entry.js +4 -0
- package/dist/ionic/p-ccc7487b.entry.js +4 -0
- package/dist/ionic/p-cfd5dc50.entry.js +4 -0
- package/dist/ionic/p-d5c9bf12.entry.js +4 -0
- package/dist/ionic/p-f252ab8a.entry.js +4 -0
- package/dist/types/components/accordion/accordion.d.ts +7 -1
- package/dist/types/components/back-button/back-button.d.ts +8 -2
- package/dist/types/components/breadcrumb/breadcrumb.d.ts +12 -2
- package/dist/types/components/checkbox/checkbox.d.ts +12 -1
- package/dist/types/components/datetime/datetime.d.ts +4 -4
- package/dist/types/components/fab-button/fab-button.d.ts +7 -1
- package/dist/types/components/input/input.d.ts +7 -10
- package/dist/types/components/input-password-toggle/input-password-toggle.d.ts +14 -2
- package/dist/types/components/item/item.d.ts +7 -1
- package/dist/types/components/menu-button/menu-button.d.ts +6 -1
- package/dist/types/components/refresher-content/refresher-content.d.ts +6 -0
- package/dist/types/components/reorder/reorder.d.ts +1 -1
- package/dist/types/components/select/select.d.ts +7 -12
- package/dist/types/components/select-modal/select-modal.d.ts +6 -1
- package/dist/types/components/textarea/textarea.d.ts +8 -8
- package/dist/types/components/toggle/toggle.d.ts +5 -2
- package/dist/types/utils/config.d.ts +22 -2
- package/dist/types/utils/test/playwright/field-geometry.d.ts +13 -0
- package/dist/types/utils/test/playwright/index.d.ts +1 -0
- package/hydrate/index.js +222 -384
- package/hydrate/index.mjs +222 -384
- package/package.json +1 -2
- package/components/p-B1AK6oR-.js +0 -4
- package/components/p-BDqjX7Z_.js +0 -4
- package/components/p-BYSs-jZz.js +0 -4
- package/components/p-CPdOdJa7.js +0 -4
- package/components/p-D1t981Ih.js +0 -4
- package/components/p-Dhi5xtNS.js +0 -4
- package/components/p-DzaPYdjZ.js +0 -4
- package/components/p-e73ca-aN.js +0 -4
- package/components/p-fIOYmaqA.js +0 -4
- package/dist/cjs/caret-down-vtVgfXIs.js +0 -8
- package/dist/cjs/caret-left-CxZXLRv5.js +0 -8
- package/dist/cjs/caret-right-CRCgv98E.js +0 -8
- package/dist/cjs/list-a-7GSA6K.js +0 -8
- package/dist/cjs/x-BTF99yFH.js +0 -8
- package/dist/esm/caret-down-D1t981Ih.js +0 -6
- package/dist/esm/caret-left-fIOYmaqA.js +0 -6
- package/dist/esm/caret-right-BYSs-jZz.js +0 -6
- package/dist/esm/list-Dhi5xtNS.js +0 -6
- package/dist/esm/x-BDqjX7Z_.js +0 -6
- package/dist/ionic/p-04d96dad.entry.js +0 -4
- package/dist/ionic/p-0a924e6a.entry.js +0 -4
- package/dist/ionic/p-2da21af7.entry.js +0 -4
- package/dist/ionic/p-2fc1521f.entry.js +0 -4
- package/dist/ionic/p-32829ef8.entry.js +0 -4
- package/dist/ionic/p-4eec50dd.entry.js +0 -4
- package/dist/ionic/p-73309d35.entry.js +0 -4
- package/dist/ionic/p-74ab5f49.entry.js +0 -4
- package/dist/ionic/p-8dcd18cf.entry.js +0 -4
- package/dist/ionic/p-9ca59419.entry.js +0 -4
- package/dist/ionic/p-BDqjX7Z_.js +0 -4
- package/dist/ionic/p-BYSs-jZz.js +0 -4
- package/dist/ionic/p-D1t981Ih.js +0 -4
- package/dist/ionic/p-Dhi5xtNS.js +0 -4
- package/dist/ionic/p-b10dc124.entry.js +0 -4
- package/dist/ionic/p-b7ce4a50.entry.js +0 -4
- package/dist/ionic/p-c7035f3f.entry.js +0 -4
- package/dist/ionic/p-c91fc9d4.entry.js +0 -4
- package/dist/ionic/p-e53980b0.entry.js +0 -4
- package/dist/ionic/p-e9fdff49.entry.js +0 -4
- package/dist/ionic/p-f82b13a6.entry.js +0 -4
- package/dist/ionic/p-fIOYmaqA.js +0 -4
|
@@ -453,10 +453,6 @@
|
|
|
453
453
|
overflow: hidden;
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
-
.textarea-outline {
|
|
457
|
-
box-sizing: border-box;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
456
|
/**
|
|
461
457
|
* If no label text is placed into the slot
|
|
462
458
|
* then the element should be hidden otherwise
|
|
@@ -562,32 +558,6 @@
|
|
|
562
558
|
--border-color: var(--token-border-input-default, var(--token-primitives-neutral-600, #8c8c8c));
|
|
563
559
|
}
|
|
564
560
|
|
|
565
|
-
:host(.textarea-fill-outline) .textarea-wrapper {
|
|
566
|
-
background: initial;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
:host(.textarea-fill-outline) .textarea-wrapper-inner {
|
|
570
|
-
/**
|
|
571
|
-
* The border should be relative to the inner wrapper
|
|
572
|
-
* so that it does not include the label.
|
|
573
|
-
*/
|
|
574
|
-
position: relative;
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
:host(.textarea-fill-outline) .textarea-outline {
|
|
578
|
-
right: 0;
|
|
579
|
-
left: 0;
|
|
580
|
-
top: 0;
|
|
581
|
-
bottom: 0;
|
|
582
|
-
border-radius: var(--border-radius);
|
|
583
|
-
position: absolute;
|
|
584
|
-
width: 100%;
|
|
585
|
-
height: 100%;
|
|
586
|
-
pointer-events: none;
|
|
587
|
-
border: var(--border-width) var(--border-style) var(--border-color);
|
|
588
|
-
background: var(--background);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
561
|
/**
|
|
592
562
|
* The bottom content should never have
|
|
593
563
|
* a border with the outline style.
|
|
@@ -612,18 +582,6 @@
|
|
|
612
582
|
--background: var(--token-bg-input-bold-default, var(--token-primitives-neutral-200, #eae9e9));
|
|
613
583
|
}
|
|
614
584
|
|
|
615
|
-
:host(.textarea-fill-solid) .textarea-wrapper {
|
|
616
|
-
border-bottom: none;
|
|
617
|
-
background: none;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
:host(.textarea-fill-solid) .textarea-wrapper-inner {
|
|
621
|
-
border-radius: var(--border-radius);
|
|
622
|
-
position: relative;
|
|
623
|
-
border: var(--border-width) var(--border-style) var(--border-color);
|
|
624
|
-
background: var(--background);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
585
|
:host(.textarea-fill-solid) .textarea-bottom {
|
|
628
586
|
--border-width: var(--token-scale-0, 0px);
|
|
629
587
|
}
|
|
@@ -674,21 +632,31 @@
|
|
|
674
632
|
--highlight-color-focused: var(--ion-color-base);
|
|
675
633
|
}
|
|
676
634
|
|
|
677
|
-
|
|
635
|
+
/**
|
|
636
|
+
* The size padding is scoped to the field cells rather than to the wrapper, so
|
|
637
|
+
* the label, which sits outside the field box, does not inherit it.
|
|
638
|
+
*/
|
|
639
|
+
:host(.textarea-size-small) .textarea-start,
|
|
640
|
+
:host(.textarea-size-small) .native-wrapper,
|
|
641
|
+
:host(.textarea-size-small) .textarea-end {
|
|
678
642
|
--padding-top: var(--token-space-200, var(--token-scale-200, 8px));
|
|
679
643
|
--padding-end: var(--token-space-300, var(--token-scale-300, 12px));
|
|
680
644
|
--padding-bottom: var(--token-space-200, var(--token-scale-200, 8px));
|
|
681
645
|
--padding-start: var(--token-space-300, var(--token-scale-300, 12px));
|
|
682
646
|
}
|
|
683
647
|
|
|
684
|
-
:host(.textarea-size-medium) .textarea-
|
|
648
|
+
:host(.textarea-size-medium) .textarea-start,
|
|
649
|
+
:host(.textarea-size-medium) .native-wrapper,
|
|
650
|
+
:host(.textarea-size-medium) .textarea-end {
|
|
685
651
|
--padding-top: var(--token-space-300, var(--token-scale-300, 12px));
|
|
686
652
|
--padding-end: var(--token-space-400, var(--token-scale-400, 16px));
|
|
687
653
|
--padding-bottom: var(--token-space-300, var(--token-scale-300, 12px));
|
|
688
654
|
--padding-start: var(--token-space-400, var(--token-scale-400, 16px));
|
|
689
655
|
}
|
|
690
656
|
|
|
691
|
-
:host(.textarea-size-large) .textarea-
|
|
657
|
+
:host(.textarea-size-large) .textarea-start,
|
|
658
|
+
:host(.textarea-size-large) .native-wrapper,
|
|
659
|
+
:host(.textarea-size-large) .textarea-end {
|
|
692
660
|
--padding-top: var(--token-space-400, var(--token-scale-400, 16px));
|
|
693
661
|
--padding-end: var(--token-space-500, var(--token-scale-500, 20px));
|
|
694
662
|
--padding-bottom: var(--token-space-400, var(--token-scale-400, 16px));
|
|
@@ -714,63 +682,158 @@
|
|
|
714
682
|
--border-radius: var(--token-rectangular-xl, var(--token-border-radius-0, var(--token-scale-0, 0px)));
|
|
715
683
|
}
|
|
716
684
|
|
|
717
|
-
:host([auto-grow]) .textarea-wrapper-inner {
|
|
718
|
-
height: auto;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
685
|
:host([auto-grow]) .native-wrapper {
|
|
722
686
|
min-height: inherit;
|
|
723
687
|
max-height: inherit;
|
|
724
688
|
}
|
|
725
689
|
|
|
690
|
+
/**
|
|
691
|
+
* The label is nested in the control so that every theme renders the same
|
|
692
|
+
* tree. Laying the wrapper out as a grid and flattening the control lets the
|
|
693
|
+
* label sit outside the field box, which is drawn by `::before` over the cells
|
|
694
|
+
* the label does not occupy.
|
|
695
|
+
*/
|
|
726
696
|
.textarea-wrapper {
|
|
727
|
-
|
|
697
|
+
display: grid;
|
|
698
|
+
/**
|
|
699
|
+
* Auto rows stretch to fill any extra height by default, which would pad the
|
|
700
|
+
* label row and pull the field box away from it.
|
|
701
|
+
*/
|
|
702
|
+
align-content: start;
|
|
703
|
+
/**
|
|
704
|
+
* The wrapper spans the label too, so the background belongs on the field
|
|
705
|
+
* box rather than here.
|
|
706
|
+
*/
|
|
707
|
+
background: transparent;
|
|
728
708
|
}
|
|
729
709
|
|
|
730
|
-
|
|
731
|
-
|
|
710
|
+
.textarea-control {
|
|
711
|
+
display: contents;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.textarea-wrapper::before {
|
|
715
|
+
border-radius: var(--border-radius, 0);
|
|
716
|
+
align-self: stretch;
|
|
717
|
+
box-sizing: border-box;
|
|
718
|
+
content: "";
|
|
719
|
+
pointer-events: none;
|
|
720
|
+
/**
|
|
721
|
+
* The wrapper takes its min-height from the host and the pseudo-element
|
|
722
|
+
* inherits it, so a min-height on the host still reaches the box.
|
|
723
|
+
*/
|
|
724
|
+
min-height: inherit;
|
|
725
|
+
border: var(--border-width) var(--border-style) var(--border-color);
|
|
726
|
+
background: var(--background);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
:host(.textarea-label-placement-start) .textarea-wrapper,
|
|
730
|
+
:host(.textarea-label-placement-fixed) .textarea-wrapper {
|
|
731
|
+
grid-template-columns: [label] auto [field-start slot-start] auto [native] minmax(0, 1fr) [slot-end] auto [field-end];
|
|
732
|
+
grid-template-rows: [label field] auto;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
:host(.textarea-label-placement-start) .label-text-wrapper,
|
|
736
|
+
:host(.textarea-label-placement-fixed) .label-text-wrapper {
|
|
737
|
+
-webkit-margin-end: var(--token-space-100, var(--token-scale-100, 4px));
|
|
738
|
+
margin-inline-end: var(--token-space-100, var(--token-scale-100, 4px));
|
|
739
|
+
grid-column: label;
|
|
732
740
|
}
|
|
733
741
|
|
|
734
742
|
:host(.textarea-label-placement-end) .textarea-wrapper {
|
|
735
|
-
|
|
743
|
+
grid-template-columns: [field-start slot-start] auto [native] minmax(0, 1fr) [slot-end] auto [field-end label] auto;
|
|
744
|
+
grid-template-rows: [label field] auto;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
:host(.textarea-label-placement-end) .label-text-wrapper {
|
|
748
|
+
-webkit-margin-start: var(--token-space-100, var(--token-scale-100, 4px));
|
|
749
|
+
margin-inline-start: var(--token-space-100, var(--token-scale-100, 4px));
|
|
750
|
+
grid-column: label;
|
|
736
751
|
}
|
|
737
752
|
|
|
738
753
|
:host(.textarea-label-placement-stacked) .textarea-wrapper,
|
|
739
754
|
:host(.textarea-label-placement-floating) .textarea-wrapper {
|
|
740
|
-
|
|
741
|
-
|
|
755
|
+
grid-template-columns: [field-start slot-start] auto [native] minmax(0, 1fr) [slot-end] auto [field-end];
|
|
756
|
+
grid-template-rows: [label] auto [field] auto;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
:host(.textarea-label-placement-stacked) .label-text-wrapper,
|
|
760
|
+
:host(.textarea-label-placement-floating) .label-text-wrapper {
|
|
761
|
+
margin-bottom: var(--token-space-100, var(--token-scale-100, 4px));
|
|
762
|
+
grid-column: field-start/field-end;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* The templates above all name the same lines, so every placement shares these.
|
|
767
|
+
* A label with its own row lands on the label row. Otherwise that name resolves
|
|
768
|
+
* to the only row there is.
|
|
769
|
+
*/
|
|
770
|
+
.label-text-wrapper {
|
|
771
|
+
grid-row: label;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
.textarea-start {
|
|
775
|
+
grid-row: field;
|
|
776
|
+
grid-column: slot-start;
|
|
742
777
|
}
|
|
743
778
|
|
|
744
|
-
.
|
|
779
|
+
.native-wrapper {
|
|
780
|
+
grid-row: field;
|
|
781
|
+
grid-column: native;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
.textarea-end {
|
|
785
|
+
grid-row: field;
|
|
786
|
+
grid-column: slot-end;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
.textarea-wrapper::before {
|
|
790
|
+
grid-row: field;
|
|
791
|
+
grid-column: field-start/field-end;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* The padding sits on the cells that the field box covers, so the label is not
|
|
796
|
+
* indented by it.
|
|
797
|
+
*/
|
|
798
|
+
.textarea-start {
|
|
745
799
|
-webkit-padding-start: var(--padding-start);
|
|
746
800
|
padding-inline-start: var(--padding-start);
|
|
747
|
-
-webkit-padding-end: var(--padding-end);
|
|
748
|
-
padding-inline-end: var(--padding-end);
|
|
749
801
|
padding-top: var(--padding-top);
|
|
750
802
|
padding-bottom: var(--padding-bottom);
|
|
751
|
-
display: flex;
|
|
752
|
-
width: 100%;
|
|
753
|
-
min-height: inherit;
|
|
754
|
-
box-sizing: border-box;
|
|
755
803
|
}
|
|
756
804
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
805
|
+
/**
|
|
806
|
+
* The native wrapper's own content sizes the field row, and it stretches to
|
|
807
|
+
* fill it. The shared stylesheet sets `height: 100%`, which would resolve
|
|
808
|
+
* against the row this element is itself sizing, so reset it here.
|
|
809
|
+
*/
|
|
810
|
+
.native-wrapper {
|
|
811
|
+
padding-top: var(--padding-top);
|
|
812
|
+
padding-bottom: var(--padding-bottom);
|
|
813
|
+
align-self: stretch;
|
|
814
|
+
height: auto;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
.textarea-end {
|
|
760
818
|
-webkit-padding-end: var(--padding-end);
|
|
761
819
|
padding-inline-end: var(--padding-end);
|
|
820
|
+
padding-top: var(--padding-top);
|
|
821
|
+
padding-bottom: var(--padding-bottom);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
:host([rows]:not([auto-grow])) .native-wrapper {
|
|
762
825
|
padding-top: 0;
|
|
763
826
|
padding-bottom: 0;
|
|
764
827
|
}
|
|
765
828
|
|
|
766
829
|
/**
|
|
767
|
-
* Top and bottom padding are applied to ensure that text remains visible
|
|
768
|
-
* as it scrolls past the container boundaries. This provides a "sneak peek"
|
|
769
|
-
* of the content transitioning off-screen, mirroring native textarea behavior
|
|
770
|
-
* where text isn't immediately clipped or "glued" to the border at the
|
|
830
|
+
* Top and bottom padding are applied to ensure that text remains visible
|
|
831
|
+
* as it scrolls past the container boundaries. This provides a "sneak peek"
|
|
832
|
+
* of the content transitioning off-screen, mirroring native textarea behavior
|
|
833
|
+
* where text isn't immediately clipped or "glued" to the border at the
|
|
771
834
|
* scroll limits.
|
|
772
835
|
*/
|
|
773
|
-
:host([rows]:not([auto-grow])) .
|
|
836
|
+
:host([rows]:not([auto-grow])) .native-wrapper .native-textarea {
|
|
774
837
|
padding-top: var(--padding-top);
|
|
775
838
|
padding-bottom: var(--padding-bottom);
|
|
776
839
|
}
|
|
@@ -881,21 +944,6 @@ ion-icon {
|
|
|
881
944
|
margin-top: var(--token-space-050, var(--token-scale-050, 2px));
|
|
882
945
|
}
|
|
883
946
|
|
|
884
|
-
:host([rows]:not([auto-grow])) .textarea-start,
|
|
885
|
-
:host([rows]:not([auto-grow])) .textarea-end {
|
|
886
|
-
padding-left: 0;
|
|
887
|
-
padding-right: 0;
|
|
888
|
-
padding-top: var(--padding-top);
|
|
889
|
-
padding-bottom: var(--padding-bottom);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
.textarea-control {
|
|
893
|
-
padding-left: 0;
|
|
894
|
-
padding-right: 0;
|
|
895
|
-
padding-top: 0;
|
|
896
|
-
padding-bottom: 0;
|
|
897
|
-
}
|
|
898
|
-
|
|
899
947
|
:host(.has-focus) {
|
|
900
948
|
--border-color: var(--token-border-focus-default, var(--token-primitives-blue-400, #b5c0f7));
|
|
901
949
|
--border-width: var(--token-border-size-050, var(--token-scale-050, 2px));
|
|
@@ -25,6 +25,9 @@ import { getCounterText } from "../input/input.utils";
|
|
|
25
25
|
* @part error-text - Supporting text displayed beneath the textarea label when the textarea is invalid and touched.
|
|
26
26
|
* @part counter - The character counter displayed when the counter property is set.
|
|
27
27
|
* @part bottom - The container element for helper text, error text, and counter.
|
|
28
|
+
* @part start - The wrapper element for the content in the start slot.
|
|
29
|
+
* @part control - The wrapper element containing the label and the native textarea. The `"ionic"` theme flattens this wrapper, so it cannot be given a box of its own there.
|
|
30
|
+
* @part end - The wrapper element for the content in the end slot.
|
|
28
31
|
*/
|
|
29
32
|
export class Textarea {
|
|
30
33
|
constructor() {
|
|
@@ -519,7 +522,7 @@ export class Textarea {
|
|
|
519
522
|
* Renders the outline border with a notch for the label.
|
|
520
523
|
*/
|
|
521
524
|
renderOutlineContainer() {
|
|
522
|
-
return (h("div", { class: "textarea-outline-container" }, h("div", { class: "textarea-outline-start" }), h("div", { class: {
|
|
525
|
+
return (h("div", { key: "outline", class: "textarea-outline-container" }, h("div", { class: "textarea-outline-start" }), h("div", { class: {
|
|
523
526
|
'textarea-outline-notch': true,
|
|
524
527
|
'textarea-outline-notch-hidden': !this.hasLabel,
|
|
525
528
|
} }, h("div", { class: "notch-spacer", "aria-hidden": "true", ref: (el) => (this.notchSpacerEl = el) }, this.label)), h("div", { class: "textarea-outline-end" })));
|
|
@@ -528,32 +531,24 @@ export class Textarea {
|
|
|
528
531
|
const { inputId, disabled } = this;
|
|
529
532
|
return (h("textarea", { class: "native-textarea", part: "native", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.isInvalid ? 'true' : undefined, ...this.inheritedAttributes }, this.getValue()));
|
|
530
533
|
}
|
|
531
|
-
/**
|
|
532
|
-
* The ionic theme keeps the label above a field box that wraps the slots and
|
|
533
|
-
* the textarea, so the label can size independently of the slotted content.
|
|
534
|
-
*/
|
|
535
534
|
renderStartContainer() {
|
|
536
|
-
return (h("div", { class: "textarea-start", ref: (el) => (this.startContainerEl = el) }, h("slot", { name: "start" })));
|
|
535
|
+
return (h("div", { key: "start", class: "textarea-start", part: "start", ref: (el) => (this.startContainerEl = el) }, h("slot", { name: "start" })));
|
|
537
536
|
}
|
|
538
537
|
renderEndContainer() {
|
|
539
|
-
return (h("div", { class: "textarea-end" }, h("slot", { name: "end" })));
|
|
540
|
-
}
|
|
541
|
-
renderIonicField() {
|
|
542
|
-
return [
|
|
543
|
-
this.renderLabel(),
|
|
544
|
-
h("div", { class: "textarea-wrapper-inner" }, this.getFill() === 'outline' && h("div", { class: "textarea-outline" }), this.renderStartContainer(), h("div", { class: "textarea-control" }, h("div", { class: "native-wrapper", ref: (el) => (this.textareaWrapper = el), part: "container" }, this.renderNativeTextarea())), this.renderEndContainer()),
|
|
545
|
-
];
|
|
538
|
+
return (h("div", { key: "end", class: "textarea-end", part: "end" }, h("slot", { name: "end" })));
|
|
546
539
|
}
|
|
547
540
|
/**
|
|
548
|
-
*
|
|
549
|
-
*
|
|
541
|
+
* Every theme renders the same label and control structure, aside from the md
|
|
542
|
+
* outline container below. The label is nested alongside the textarea so the
|
|
543
|
+
* ios and md floating label can escape the control and clear the start and
|
|
544
|
+
* end slots. The ionic theme lifts it outside the field with grid instead.
|
|
550
545
|
*/
|
|
551
|
-
|
|
546
|
+
renderField() {
|
|
552
547
|
const hasOutlineFill = getIonTheme(this) === 'md' && this.getFill() === 'outline';
|
|
553
548
|
return [
|
|
554
549
|
hasOutlineFill && this.renderOutlineContainer(),
|
|
555
550
|
this.renderStartContainer(),
|
|
556
|
-
h("div", { class: "textarea-control" }, this.renderLabel(), h("div", { class: "native-wrapper", ref: (el) => (this.textareaWrapper = el), part: "container" }, this.renderNativeTextarea())),
|
|
551
|
+
h("div", { key: "control", class: "textarea-control", part: "control" }, this.renderLabel(), h("div", { class: "native-wrapper", ref: (el) => (this.textareaWrapper = el), part: "container" }, this.renderNativeTextarea())),
|
|
557
552
|
this.renderEndContainer(),
|
|
558
553
|
];
|
|
559
554
|
}
|
|
@@ -616,7 +611,7 @@ export class Textarea {
|
|
|
616
611
|
* the textarea has a value or is focused.
|
|
617
612
|
*/
|
|
618
613
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus));
|
|
619
|
-
return (h(Host, { key: '
|
|
614
|
+
return (h(Host, { key: '696d649f4d05739857823887be65ae9252ba77dc', class: createColorClasses(this.color, {
|
|
620
615
|
[theme]: true,
|
|
621
616
|
'has-value': hasValue,
|
|
622
617
|
'has-focus': hasFocus,
|
|
@@ -628,7 +623,7 @@ export class Textarea {
|
|
|
628
623
|
'in-item': inItem,
|
|
629
624
|
'textarea-disabled': disabled,
|
|
630
625
|
'textarea-readonly': readonly,
|
|
631
|
-
}) }, h("label", { key: '
|
|
626
|
+
}) }, h("label", { key: '61e64a211779e73def2b5d55a19dfc2f76463968', class: "textarea-wrapper", htmlFor: inputId, onMouseDown: this.onLabelPointerDown, onClick: this.onLabelClick, part: "wrapper" }, this.renderField(), shouldRenderHighlight && h("div", { key: '4ada5405635e1155e6b750ed797fd1ab82e6b314', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
632
627
|
}
|
|
633
628
|
static get is() { return "ion-textarea"; }
|
|
634
629
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import checkRegular from "@phosphor-icons/core/assets/regular/check.svg";
|
|
5
|
-
import minusRegular from "@phosphor-icons/core/assets/regular/minus.svg";
|
|
6
4
|
import { Build, Host, forceUpdate, h } from "@stencil/core";
|
|
7
5
|
import { checkInvalidState, createItemMultipleInputsObserver } from "../../utils/forms/index";
|
|
8
6
|
import { renderHiddenInput, inheritAriaAttributes } from "../../utils/helpers";
|
|
@@ -249,22 +247,17 @@ export class Toggle {
|
|
|
249
247
|
setFocus() {
|
|
250
248
|
this.el.focus();
|
|
251
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Get the default icon to use for the checked icon based on the theme.
|
|
252
|
+
*/
|
|
252
253
|
get toggleDefaultCheckedIcon() {
|
|
253
|
-
// Determine the theme and map to default
|
|
254
|
+
// Determine the theme and map to the default icon
|
|
254
255
|
const theme = getIonTheme(this);
|
|
255
|
-
|
|
256
|
-
ios: removeOutline,
|
|
257
|
-
ionic: checkRegular,
|
|
258
|
-
md: checkmarkOutline,
|
|
259
|
-
};
|
|
260
|
-
// Get the default icon based on the theme, falling back to 'md' icon if necessary
|
|
261
|
-
const defaultIcon = defaultIcons[theme] || defaultIcons.md;
|
|
262
|
-
// Return the default icon
|
|
263
|
-
return defaultIcon;
|
|
256
|
+
return theme === 'ios' ? removeOutline : checkmarkOutline;
|
|
264
257
|
}
|
|
265
258
|
/**
|
|
266
259
|
* Get the icon to use for the checked icon.
|
|
267
|
-
*
|
|
260
|
+
* Use the icon set in the config.
|
|
268
261
|
* If no icon is set in the config, use the default icon.
|
|
269
262
|
*/
|
|
270
263
|
get toggleCheckedIcon() {
|
|
@@ -272,20 +265,13 @@ export class Toggle {
|
|
|
272
265
|
}
|
|
273
266
|
/**
|
|
274
267
|
* Get the icon to use for the unchecked icon.
|
|
275
|
-
*
|
|
268
|
+
* Use the icon set in the config.
|
|
276
269
|
* If no icon is set in the config, use the default icon.
|
|
277
270
|
*/
|
|
278
271
|
get toggleUncheckedIcon() {
|
|
279
|
-
// Determine the theme and map to default
|
|
272
|
+
// Determine the theme and map to the default icon
|
|
280
273
|
const theme = getIonTheme(this);
|
|
281
|
-
const
|
|
282
|
-
ios: ellipseOutline,
|
|
283
|
-
ionic: minusRegular,
|
|
284
|
-
md: removeOutline,
|
|
285
|
-
};
|
|
286
|
-
// Get the default icon based on the theme, falling back to 'md' icon if necessary
|
|
287
|
-
const defaultIcon = defaultIcons[theme] || defaultIcons.md;
|
|
288
|
-
// Return the configured toggle unchecked icon or the default icon
|
|
274
|
+
const defaultIcon = theme === 'ios' ? ellipseOutline : removeOutline;
|
|
289
275
|
return config.get('toggleUncheckedIcon', defaultIcon);
|
|
290
276
|
}
|
|
291
277
|
renderOnOffSwitchLabels(checked) {
|
|
@@ -354,7 +340,7 @@ export class Toggle {
|
|
|
354
340
|
// The attributes are matched too because the class needs the item to render.
|
|
355
341
|
const inClickableItem = hostContext('ion-item.ion-activatable, ion-item[button], ion-item[href]', el);
|
|
356
342
|
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
|
357
|
-
return (h(Host, { key: '
|
|
343
|
+
return (h(Host, { key: '030fcdcc6074a283de193a04b4c52a9dda2a89b3', 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(color, {
|
|
358
344
|
[theme]: true,
|
|
359
345
|
'in-item': inItem,
|
|
360
346
|
// `ion-focusable` has to stay on because it is what makes the item focusable.
|
|
@@ -369,10 +355,10 @@ export class Toggle {
|
|
|
369
355
|
[`toggle-label-placement-${labelPlacement}`]: true,
|
|
370
356
|
[`toggle-${rtl}`]: true,
|
|
371
357
|
'ion-activatable': isIonicTheme,
|
|
372
|
-
}) }, h("label", { key: '
|
|
358
|
+
}) }, h("label", { key: '1d7d4f534661093ea5ea7c885ca7ba355983ff88', class: "toggle-wrapper", htmlFor: inputId }, h("input", { key: '43de25ac1c815db634915c302c934d0827b32b4c', type: "checkbox", role: "switch", "aria-checked": `${checked}`, checked: checked, disabled: disabled, id: inputId, required: required, ...inheritedAttributes }), h("div", { key: '9ed1fd6cd5b912b25628a2e2c29f0d758e0a7a24', class: {
|
|
373
359
|
'label-text-wrapper': true,
|
|
374
360
|
'label-text-wrapper-hidden': !hasLabel,
|
|
375
|
-
}, part: "label", id: inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '
|
|
361
|
+
}, part: "label", id: inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '0b7834f1e125d8a9c0acc7577f344812ccaf52fe' }), this.renderHintText()), h("div", { key: '16bebe3d305cccbfcf4d85eb16ac3fe94ae2c59c', class: "native-wrapper" }, this.renderToggleControl()))));
|
|
376
362
|
}
|
|
377
363
|
static get is() { return "ion-toggle"; }
|
|
378
364
|
static get encapsulation() { return "shadow"; }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
import { expect } from "@playwright/test";
|
|
5
|
+
/**
|
|
6
|
+
* These tracks are adjacent with no gap, so the edges are meant to be equal.
|
|
7
|
+
* Engines round fractional track origins differently, and a real ordering
|
|
8
|
+
* regression moves a cell by a whole track, so a pixel of slack is safe.
|
|
9
|
+
*/
|
|
10
|
+
const EDGE_TOLERANCE = 1;
|
|
11
|
+
/**
|
|
12
|
+
* Asserts that a form field's start slot, control and end slot occupy one row,
|
|
13
|
+
* in inline order.
|
|
14
|
+
*
|
|
15
|
+
* The ionic theme lays these out as grid columns. An invalid column template is
|
|
16
|
+
* dropped silently, and the cells then auto-place into a row each, so checking
|
|
17
|
+
* that they share a row is what catches it.
|
|
18
|
+
*
|
|
19
|
+
* @param host The form field element.
|
|
20
|
+
* @param prefix The component's cell-class prefix: `input`, `select` or `textarea`.
|
|
21
|
+
*/
|
|
22
|
+
export const expectFieldCellsShareARow = async (host, prefix) => {
|
|
23
|
+
const start = await host.locator(`.${prefix}-start`).boundingBox();
|
|
24
|
+
const native = await host.locator('.native-wrapper').boundingBox();
|
|
25
|
+
const end = await host.locator(`.${prefix}-end`).boundingBox();
|
|
26
|
+
expect(native).not.toBeNull();
|
|
27
|
+
for (const cell of [start, end]) {
|
|
28
|
+
expect(cell).not.toBeNull();
|
|
29
|
+
expect(cell.y).toBeLessThan(native.y + native.height);
|
|
30
|
+
expect(native.y).toBeLessThan(cell.y + cell.height);
|
|
31
|
+
}
|
|
32
|
+
expect(native.x).toBeGreaterThan(start.x + start.width - EDGE_TOLERANCE);
|
|
33
|
+
expect(end.x).toBeGreaterThan(native.x + native.width - EDGE_TOLERANCE);
|
|
34
|
+
};
|