@propbinder/mobile-design 0.2.31 → 0.2.33
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/index.d.ts
CHANGED
|
@@ -616,7 +616,7 @@ declare class DsMobileProfileActionsSheetComponent implements OnInit, OnChanges
|
|
|
616
616
|
/**
|
|
617
617
|
* Current view state
|
|
618
618
|
*/
|
|
619
|
-
currentView: _angular_core.WritableSignal<"
|
|
619
|
+
currentView: _angular_core.WritableSignal<"language" | "main">;
|
|
620
620
|
/**
|
|
621
621
|
* Reference to the view container for height calculations
|
|
622
622
|
*/
|
|
@@ -1158,7 +1158,7 @@ declare class DsMobileContentComponent {
|
|
|
1158
1158
|
*/
|
|
1159
1159
|
declare class SectionHeaderComponent {
|
|
1160
1160
|
/** Width of the header placeholder */
|
|
1161
|
-
width: _angular_core.InputSignal<"
|
|
1161
|
+
width: _angular_core.InputSignal<"full" | "half" | "third">;
|
|
1162
1162
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SectionHeaderComponent, never>;
|
|
1163
1163
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SectionHeaderComponent, "section-header", never, { "width": { "alias": "width"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1164
1164
|
}
|
package/package.json
CHANGED
package/styles/ionic.css
CHANGED
|
@@ -22,54 +22,46 @@
|
|
|
22
22
|
:root {
|
|
23
23
|
/* Mobile-specific brand color for headers/backgrounds */
|
|
24
24
|
--color-brand-secondary: #221a4c;
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
/* Ionic Keyboard Appearance - force light theme */
|
|
27
27
|
--ion-keyboard-color: #ffffff;
|
|
28
28
|
--ion-keyboard-background: #ffffff;
|
|
29
29
|
--ion-keyboard-text-color: #000000;
|
|
30
30
|
color-scheme: light;
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
/* Layout - Mobile Navigation */
|
|
33
33
|
--mobile-tab-bar-height: 64px;
|
|
34
34
|
--mobile-content-spacing: 20px;
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
/* Tab Bar Height - Used for FAB positioning and other layout calculations */
|
|
37
37
|
/* This is set by ds-mobile-tab-bar and consumed by ds-mobile-fab */
|
|
38
38
|
--ds-tab-bar-height: 64px;
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
/* ============================================
|
|
41
41
|
SPRING ANIMATIONS
|
|
42
42
|
Physics-based easing curves with natural bounce
|
|
43
43
|
============================================ */
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
/* Spring Curves */
|
|
46
|
-
--spring-curve-bouncy: linear(
|
|
47
|
-
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
--spring-curve-
|
|
51
|
-
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
--spring-curve-snappy: linear(
|
|
55
|
-
0, 0.3, 0.7, 1.05, 0.98, 1
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
--spring-curve-smooth: linear(
|
|
59
|
-
0, 0.215, 0.61, 0.855, 1
|
|
60
|
-
);
|
|
61
|
-
|
|
46
|
+
--spring-curve-bouncy: linear(0, 0.0209, 0.0772, 0.1598, 0.2602, 0.3709, 0.4854, 0.5984, 0.7056, 0.8038, 0.8908, 0.9653, 1.0267, 1.075, 1.111, 1.1354, 1.1497, 1.1551, 1.1532, 1.1455, 1.1335, 1.1184, 1.1014, 1.0837, 1.066, 1.0492, 1.0336, 1.0197, 1.0077, 0.9977, 0.9898, 0.9838, 0.9796, 0.9771, 0.976, 0.9761, 0.9771, 0.9788, 0.9811, 0.9837, 0.9864, 0.9892, 0.9918, 0.9943, 0.9965, 0.9984, 1.0001, 1.0013, 1.0023, 1.003, 1.0035, 1);
|
|
47
|
+
|
|
48
|
+
--spring-curve-gentle: linear(0, 0.2, 0.5, 0.8, 1.02, 1.01, 1);
|
|
49
|
+
|
|
50
|
+
--spring-curve-snappy: linear(0, 0.3, 0.7, 1.05, 0.98, 1);
|
|
51
|
+
|
|
52
|
+
--spring-curve-smooth: linear(0, 0.215, 0.61, 0.855, 1);
|
|
53
|
+
|
|
62
54
|
/* Spring Durations */
|
|
63
55
|
--spring-duration-fast: 400ms;
|
|
64
56
|
--spring-duration-medium: 700ms;
|
|
65
57
|
--spring-duration-slow: 1000ms;
|
|
66
|
-
|
|
58
|
+
|
|
67
59
|
/* Spring Presets (curve + duration) */
|
|
68
60
|
--spring-bouncy: var(--spring-duration-medium) var(--spring-curve-bouncy);
|
|
69
61
|
--spring-gentle: var(--spring-duration-fast) var(--spring-curve-gentle);
|
|
70
62
|
--spring-snappy: var(--spring-duration-fast) var(--spring-curve-snappy);
|
|
71
63
|
--spring-smooth: var(--spring-duration-medium) var(--spring-curve-smooth);
|
|
72
|
-
|
|
64
|
+
|
|
73
65
|
/* ============================================
|
|
74
66
|
SAFE AREA / STATUS BAR CONFIGURATION
|
|
75
67
|
|
|
@@ -83,12 +75,12 @@
|
|
|
83
75
|
1. app.ts: StatusBar.setOverlaysWebView({ overlay: true/false })
|
|
84
76
|
2. These CSS variables below
|
|
85
77
|
============================================ */
|
|
86
|
-
|
|
78
|
+
|
|
87
79
|
/* Sheet/modal top offset - positions content below status bar area */
|
|
88
80
|
/* Uses max() to ensure at least 32px offset even on devices without notch */
|
|
89
81
|
/* +12px adds breathing room below the status bar */
|
|
90
82
|
--app-sheet-top-offset: calc(max(32px, env(safe-area-inset-top, 32px)) + 12px);
|
|
91
|
-
|
|
83
|
+
|
|
92
84
|
/* Header top offset - used to fine-tune header position on iOS with overlay: true */
|
|
93
85
|
/* On web (no safe area), this should be 0px. On iOS, it compensates for status bar overlap */
|
|
94
86
|
--app-header-top-offset: max(0px, calc(env(safe-area-inset-top, 0px) - 16px));
|
|
@@ -109,13 +101,13 @@ body {
|
|
|
109
101
|
background-color: var(--color-header-surface);
|
|
110
102
|
color: var(--text-color-default-primary);
|
|
111
103
|
font-family: 'Brockmann', system-ui, -apple-system, sans-serif;
|
|
112
|
-
|
|
104
|
+
|
|
113
105
|
/* Ensure full height for iOS PWA */
|
|
114
106
|
height: 100%;
|
|
115
107
|
width: 100%;
|
|
116
108
|
margin: 0;
|
|
117
109
|
padding: 0;
|
|
118
|
-
|
|
110
|
+
|
|
119
111
|
/* Don't add padding to html/body - let Ionic components handle safe areas */
|
|
120
112
|
}
|
|
121
113
|
|
|
@@ -127,6 +119,11 @@ body {
|
|
|
127
119
|
|
|
128
120
|
.plt-ios ion-app {
|
|
129
121
|
background-color: var(--color-header-surface) !important;
|
|
122
|
+
height: 100dvh;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
ion-app {
|
|
126
|
+
height: 100dvh;
|
|
130
127
|
}
|
|
131
128
|
|
|
132
129
|
/* When modal opens, ensure purple background is maintained */
|
|
@@ -144,7 +141,7 @@ body.backdrop-no-scroll {
|
|
|
144
141
|
--ion-color-primary-contrast: var(--color-on-accent);
|
|
145
142
|
--ion-color-primary-shade: var(--color-accent-hover);
|
|
146
143
|
--ion-color-primary-tint: var(--color-accent);
|
|
147
|
-
|
|
144
|
+
|
|
148
145
|
/* Ionic component defaults */
|
|
149
146
|
--ion-background-color: var(--color-header-surface);
|
|
150
147
|
--ion-text-color: var(--text-color-default-primary);
|
|
@@ -183,8 +180,10 @@ ion-content::part(scroll) {
|
|
|
183
180
|
overscroll-behavior-y: none;
|
|
184
181
|
-webkit-overflow-scrolling: touch;
|
|
185
182
|
/* Hide scrollbar while maintaining scroll functionality */
|
|
186
|
-
scrollbar-width: none;
|
|
187
|
-
|
|
183
|
+
scrollbar-width: none;
|
|
184
|
+
/* Firefox */
|
|
185
|
+
-ms-overflow-style: none;
|
|
186
|
+
/* IE/Edge */
|
|
188
187
|
}
|
|
189
188
|
|
|
190
189
|
/* Hide scrollbar for WebKit browsers (Chrome, Safari, iOS) */
|
|
@@ -329,7 +328,7 @@ ion-toast {
|
|
|
329
328
|
--box-shadow: 0px -2px 24px rgba(0, 0, 0, 0.12);
|
|
330
329
|
--backdrop-opacity: 0.4;
|
|
331
330
|
transition: --backdrop-opacity 0.3s ease;
|
|
332
|
-
|
|
331
|
+
|
|
333
332
|
/* Position the modal container to fill screen */
|
|
334
333
|
top: 0 !important;
|
|
335
334
|
height: 100% !important;
|
|
@@ -416,7 +415,8 @@ ion-toast {
|
|
|
416
415
|
|
|
417
416
|
/* Ensure action list scrolls if needed */
|
|
418
417
|
.ds-bottom-sheet .actions-list {
|
|
419
|
-
max-height: calc(85dvh - 80px);
|
|
418
|
+
max-height: calc(85dvh - 80px);
|
|
419
|
+
/* Account for handle, padding, and safe area */
|
|
420
420
|
overflow-y: auto;
|
|
421
421
|
-webkit-overflow-scrolling: touch;
|
|
422
422
|
}
|
|
@@ -544,6 +544,7 @@ ion-toast {
|
|
|
544
544
|
from {
|
|
545
545
|
transform: translateY(100%);
|
|
546
546
|
}
|
|
547
|
+
|
|
547
548
|
to {
|
|
548
549
|
transform: translateY(0);
|
|
549
550
|
}
|
|
@@ -553,6 +554,7 @@ ion-toast {
|
|
|
553
554
|
from {
|
|
554
555
|
transform: translateY(0);
|
|
555
556
|
}
|
|
557
|
+
|
|
556
558
|
to {
|
|
557
559
|
transform: translateY(100%);
|
|
558
560
|
}
|
|
@@ -562,6 +564,7 @@ ion-toast {
|
|
|
562
564
|
from {
|
|
563
565
|
opacity: 0;
|
|
564
566
|
}
|
|
567
|
+
|
|
565
568
|
to {
|
|
566
569
|
opacity: 1;
|
|
567
570
|
}
|
|
@@ -571,6 +574,7 @@ ion-toast {
|
|
|
571
574
|
from {
|
|
572
575
|
opacity: 1;
|
|
573
576
|
}
|
|
577
|
+
|
|
574
578
|
to {
|
|
575
579
|
opacity: 0;
|
|
576
580
|
}
|
|
@@ -588,6 +592,7 @@ ion-toast {
|
|
|
588
592
|
|
|
589
593
|
/* Accessibility: Reduced motion */
|
|
590
594
|
@media (prefers-reduced-motion: reduce) {
|
|
595
|
+
|
|
591
596
|
.ds-mobile-modal.modal-card-enter-active,
|
|
592
597
|
.ds-mobile-modal.modal-card-leave-active,
|
|
593
598
|
.ds-mobile-modal.modal-sheet-enter-active,
|
|
@@ -616,11 +621,11 @@ ion-modal.ds-modal-base {
|
|
|
616
621
|
--width: 100%;
|
|
617
622
|
--max-width: 640px;
|
|
618
623
|
/* Subtract top offset from total height to avoid bottom clipping */
|
|
619
|
-
|
|
620
|
-
|
|
624
|
+
--height: calc(100dvh - var(--app-sheet-top-offset, 24px)) !important;
|
|
625
|
+
--max-height: calc(100dvh - var(--app-sheet-top-offset, 24px)) !important;
|
|
621
626
|
--border-radius: 16px 16px 0 0;
|
|
622
627
|
display: flex !important;
|
|
623
|
-
|
|
628
|
+
align-items: flex-end !important;
|
|
624
629
|
}
|
|
625
630
|
|
|
626
631
|
ion-modal.ds-modal-base::part(content) {
|
|
@@ -630,10 +635,10 @@ ion-modal.ds-modal-base::part(content) {
|
|
|
630
635
|
max-width: 640px;
|
|
631
636
|
margin: 0 auto;
|
|
632
637
|
/* Reset Ionic's default top offset and stick to bottom */
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
638
|
+
top: auto !important;
|
|
639
|
+
bottom: 0 !important;
|
|
640
|
+
height: 100% !important;
|
|
641
|
+
position: relative !important;
|
|
637
642
|
}
|
|
638
643
|
|
|
639
644
|
/* Auto-height support for base modals */
|
|
@@ -649,13 +654,14 @@ ion-modal.ds-modal-base::part(content) {
|
|
|
649
654
|
position: relative !important;
|
|
650
655
|
top: auto !important;
|
|
651
656
|
max-height: calc(100dvh - var(--app-sheet-top-offset, 24px)) !important;
|
|
652
|
-
|
|
657
|
+
bottom: 0 !important;
|
|
653
658
|
}
|
|
654
659
|
|
|
655
660
|
.ds-modal-base.auto-height ion-content {
|
|
656
661
|
height: auto !important;
|
|
657
662
|
--height: auto;
|
|
658
663
|
}
|
|
664
|
+
|
|
659
665
|
.ds-modal-base::part(backdrop) {
|
|
660
666
|
background: rgba(0, 0, 0, 0.4);
|
|
661
667
|
backdrop-filter: blur(4px);
|
|
@@ -673,7 +679,8 @@ ion-modal.ds-modal-base::part(content) {
|
|
|
673
679
|
--background: var(--color-background-neutral-primary, #ffffff);
|
|
674
680
|
--width: 100%;
|
|
675
681
|
--max-width: 640px;
|
|
676
|
-
--height: 100dvh;
|
|
682
|
+
--height: 100dvh;
|
|
683
|
+
/* Full viewport height - content top offset creates gap */
|
|
677
684
|
--border-radius: 16px 16px 0 0;
|
|
678
685
|
}
|
|
679
686
|
|
|
@@ -766,7 +773,8 @@ ion-app ion-router-outlet.ion-page-hidden {
|
|
|
766
773
|
--background: var(--color-background-neutral-primary, #ffffff);
|
|
767
774
|
--width: 100%;
|
|
768
775
|
--max-width: 640px;
|
|
769
|
-
--height: 100dvh;
|
|
776
|
+
--height: 100dvh;
|
|
777
|
+
/* Full viewport height - content top offset creates gap */
|
|
770
778
|
--border-radius: 16px 16px 0 0;
|
|
771
779
|
}
|
|
772
780
|
|
|
@@ -801,7 +809,8 @@ ion-app ion-router-outlet.ion-page-hidden {
|
|
|
801
809
|
--background: var(--color-background-neutral-primary, #ffffff);
|
|
802
810
|
--width: 100%;
|
|
803
811
|
--max-width: 640px;
|
|
804
|
-
--height: 100dvh;
|
|
812
|
+
--height: 100dvh;
|
|
813
|
+
/* Use dynamic viewport height instead of 100% */
|
|
805
814
|
--border-radius: 16px 16px 0 0;
|
|
806
815
|
margin-top: var(--app-sheet-top-offset);
|
|
807
816
|
}
|
|
@@ -830,15 +839,15 @@ ion-app ion-router-outlet.ion-page-hidden {
|
|
|
830
839
|
.ds-handbook-detail-modal {
|
|
831
840
|
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
832
841
|
}
|
|
833
|
-
|
|
842
|
+
|
|
834
843
|
.ds-handbook-detail-modal::part(content) {
|
|
835
844
|
background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
836
845
|
}
|
|
837
|
-
|
|
846
|
+
|
|
838
847
|
.ds-handbook-detail-modal::part(backdrop) {
|
|
839
848
|
background: rgba(0, 0, 0, 0.6);
|
|
840
849
|
}
|
|
841
|
-
|
|
850
|
+
|
|
842
851
|
.ds-handbook-detail-modal ion-content {
|
|
843
852
|
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
844
853
|
}
|
|
@@ -852,7 +861,8 @@ ion-app ion-router-outlet.ion-page-hidden {
|
|
|
852
861
|
--background: var(--color-background-neutral-primary, #ffffff);
|
|
853
862
|
--width: 100%;
|
|
854
863
|
--max-width: 640px;
|
|
855
|
-
--height: 100dvh;
|
|
864
|
+
--height: 100dvh;
|
|
865
|
+
/* Full viewport height - content top offset creates gap */
|
|
856
866
|
--border-radius: 16px 16px 0 0;
|
|
857
867
|
}
|
|
858
868
|
|
|
@@ -897,5 +907,4 @@ ds-button .btn:active:not(:disabled) {
|
|
|
897
907
|
/* FORCE hover background color directly - only for primary variant */
|
|
898
908
|
ds-button[variant="primary"]:hover .btn {
|
|
899
909
|
background-color: var(--color-accent-hover) !important;
|
|
900
|
-
}
|
|
901
|
-
|
|
910
|
+
}
|