@propbinder/mobile-design 0.2.4 → 0.2.5
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/fesm2022/propbinder-mobile-design.mjs +5510 -3000
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -1
- package/index.d.ts +1084 -280
- package/package.json +1 -1
- package/styles/ionic.css +84 -73
- package/styles/mobile-common.css +41 -0
- package/styles/mobile-page-base.css +9 -7
package/package.json
CHANGED
package/styles/ionic.css
CHANGED
|
@@ -69,7 +69,7 @@ html {
|
|
|
69
69
|
html,
|
|
70
70
|
body {
|
|
71
71
|
/* Background color must match theme-color for iOS PWA status bar */
|
|
72
|
-
background-color:
|
|
72
|
+
background-color: var(--color-brand-secondary);
|
|
73
73
|
color: var(--text-color-default-primary);
|
|
74
74
|
font-family: 'Brockmann', system-ui, -apple-system, sans-serif;
|
|
75
75
|
|
|
@@ -110,7 +110,7 @@ body.backdrop-no-scroll {
|
|
|
110
110
|
--ion-color-primary-tint: var(--color-brand-base);
|
|
111
111
|
|
|
112
112
|
/* Ionic component defaults */
|
|
113
|
-
--ion-background-color: var(--color-
|
|
113
|
+
--ion-background-color: var(--color-brand-secondary);
|
|
114
114
|
--ion-text-color: var(--text-color-default-primary);
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -127,6 +127,21 @@ ion-content {
|
|
|
127
127
|
--background: var(--color-background-neutral-primary);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
/* iOS: Set base ion-content background to brand secondary for pages */
|
|
131
|
+
.plt-ios ion-content {
|
|
132
|
+
background: var(--color-brand-secondary) !important;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* iOS: Also target any inner background parts */
|
|
136
|
+
.plt-ios ion-content::part(background) {
|
|
137
|
+
background: var(--color-brand-secondary) !important;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* iOS: Target the inner container if it exists */
|
|
141
|
+
.plt-ios ion-content .inner-scroll {
|
|
142
|
+
background: var(--color-brand-secondary) !important;
|
|
143
|
+
}
|
|
144
|
+
|
|
130
145
|
/* Default: Block browser overscroll on all platforms */
|
|
131
146
|
ion-content::part(scroll) {
|
|
132
147
|
overscroll-behavior-y: none;
|
|
@@ -148,10 +163,37 @@ ion-content::part(scroll)::-webkit-scrollbar {
|
|
|
148
163
|
/* iOS-specific: Enable native scroll overshoot/bounce effect */
|
|
149
164
|
.plt-ios ion-content::part(scroll) {
|
|
150
165
|
overscroll-behavior-y: contain;
|
|
166
|
+
/* iOS: Set scroll container background to match brand secondary */
|
|
167
|
+
/* This prevents white background from showing when header fades on scroll */
|
|
168
|
+
background: var(--color-brand-secondary) !important;
|
|
151
169
|
}
|
|
152
170
|
|
|
153
171
|
.plt-ios .ion-page {
|
|
154
172
|
overscroll-behavior-y: contain;
|
|
173
|
+
/* Set page background to brand secondary to match header on iOS */
|
|
174
|
+
background: var(--color-brand-secondary) !important;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* iOS-specific: Override ion-content background for pages (not modals) */
|
|
178
|
+
.plt-ios .ion-page > ion-content {
|
|
179
|
+
--background: var(--color-brand-secondary);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* iOS: Ensure modal content stays with neutral background */
|
|
183
|
+
.plt-ios ion-modal ion-content::part(scroll) {
|
|
184
|
+
background: var(--color-background-neutral-primary) !important;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.plt-ios ion-modal ion-content {
|
|
188
|
+
background: var(--color-background-neutral-primary) !important;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.plt-ios ion-modal ion-content::part(background) {
|
|
192
|
+
background: var(--color-background-neutral-primary) !important;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.plt-ios ion-modal ion-content .inner-scroll {
|
|
196
|
+
background: var(--color-background-neutral-primary) !important;
|
|
155
197
|
}
|
|
156
198
|
|
|
157
199
|
ion-footer {
|
|
@@ -159,7 +201,8 @@ ion-footer {
|
|
|
159
201
|
}
|
|
160
202
|
|
|
161
203
|
ion-router-outlet {
|
|
162
|
-
--background: var(--color-
|
|
204
|
+
--background: var(--color-brand-secondary);
|
|
205
|
+
background: var(--color-brand-secondary);
|
|
163
206
|
}
|
|
164
207
|
|
|
165
208
|
ion-refresher {
|
|
@@ -186,7 +229,7 @@ ion-modal {
|
|
|
186
229
|
max-height: 100vh !important;
|
|
187
230
|
}
|
|
188
231
|
|
|
189
|
-
|
|
232
|
+
/* Prevent modal container from resizing when keyboard appears */
|
|
190
233
|
ion-modal::part(content) {
|
|
191
234
|
position: fixed !important;
|
|
192
235
|
height: 100% !important;
|
|
@@ -484,16 +527,7 @@ ion-toast {
|
|
|
484
527
|
}
|
|
485
528
|
}
|
|
486
529
|
|
|
487
|
-
/* Dark mode support
|
|
488
|
-
@media (prefers-color-scheme: dark) {
|
|
489
|
-
.ds-mobile-modal {
|
|
490
|
-
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
.ds-mobile-modal::part(backdrop) {
|
|
494
|
-
background: rgba(0, 0, 0, 0.6);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
530
|
+
/* Dark mode support removed - modals should not change based on system dark mode */
|
|
497
531
|
|
|
498
532
|
/* Accessibility: Reduced motion */
|
|
499
533
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -516,6 +550,39 @@ ion-tab-button::part(native) {
|
|
|
516
550
|
gap: 2px;
|
|
517
551
|
}
|
|
518
552
|
|
|
553
|
+
/* ============================================
|
|
554
|
+
Base Modal Styles (Shared across all modals)
|
|
555
|
+
============================================ */
|
|
556
|
+
|
|
557
|
+
.ds-modal-base {
|
|
558
|
+
--background: var(--color-background-neutral-primary, #ffffff);
|
|
559
|
+
--width: 100%;
|
|
560
|
+
--max-width: 640px;
|
|
561
|
+
--height: 100dvh; /* Full viewport height - content top offset creates gap */
|
|
562
|
+
--border-radius: 16px 16px 0 0;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
.ds-modal-base::part(content) {
|
|
566
|
+
border-radius: 16px 16px 0 0;
|
|
567
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
|
|
568
|
+
background: var(--color-background-neutral-primary, #ffffff);
|
|
569
|
+
max-width: 640px;
|
|
570
|
+
margin: 0 auto;
|
|
571
|
+
/* Use top positioning instead of margin-top to work with fixed positioning */
|
|
572
|
+
top: var(--app-sheet-top-offset) !important;
|
|
573
|
+
height: calc(100% - var(--app-sheet-top-offset)) !important;
|
|
574
|
+
max-height: calc(100vh - var(--app-sheet-top-offset)) !important;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
.ds-modal-base::part(backdrop) {
|
|
578
|
+
background: rgba(0, 0, 0, 0.4);
|
|
579
|
+
backdrop-filter: blur(4px);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.ds-modal-base ion-content {
|
|
583
|
+
--background: var(--color-background-neutral-primary, #ffffff);
|
|
584
|
+
}
|
|
585
|
+
|
|
519
586
|
/* ============================================
|
|
520
587
|
Post Detail Modal Styles
|
|
521
588
|
============================================ */
|
|
@@ -556,11 +623,6 @@ ion-router-outlet.ion-page-hidden,
|
|
|
556
623
|
overflow: hidden;
|
|
557
624
|
}
|
|
558
625
|
|
|
559
|
-
/* Set background to brand secondary */
|
|
560
|
-
ion-router-outlet {
|
|
561
|
-
background: var(--color-brand-secondary) !important;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
626
|
/* Override Ionic's default 10px border-radius */
|
|
565
627
|
body.backdrop-no-scroll ion-router-outlet {
|
|
566
628
|
border-radius: 16px 16px 0 0 !important;
|
|
@@ -612,24 +674,7 @@ ion-app ion-router-outlet.ion-page-hidden {
|
|
|
612
674
|
|
|
613
675
|
/* Safe area handling - NOT needed here since modal positioning (--app-sheet-top-offset) handles it */
|
|
614
676
|
|
|
615
|
-
/* Dark mode support */
|
|
616
|
-
@media (prefers-color-scheme: dark) {
|
|
617
|
-
.ds-post-detail-modal {
|
|
618
|
-
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
.ds-post-detail-modal::part(content) {
|
|
622
|
-
background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
.ds-post-detail-modal::part(backdrop) {
|
|
626
|
-
background: rgba(0, 0, 0, 0.6);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
.ds-post-detail-modal ion-content {
|
|
630
|
-
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
677
|
+
/* Dark mode support removed - modals should not change based on system dark mode */
|
|
633
678
|
|
|
634
679
|
/* ============================================
|
|
635
680
|
Chat Modal Styles
|
|
@@ -664,24 +709,7 @@ ion-app ion-router-outlet.ion-page-hidden {
|
|
|
664
709
|
--background: var(--color-background-neutral-primary, #ffffff);
|
|
665
710
|
}
|
|
666
711
|
|
|
667
|
-
/* Dark mode support */
|
|
668
|
-
@media (prefers-color-scheme: dark) {
|
|
669
|
-
.ds-chat-modal {
|
|
670
|
-
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
.ds-chat-modal::part(content) {
|
|
674
|
-
background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
.ds-chat-modal::part(backdrop) {
|
|
678
|
-
background: rgba(0, 0, 0, 0.6);
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
.ds-chat-modal ion-content {
|
|
682
|
-
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
683
|
-
}
|
|
684
|
-
}
|
|
712
|
+
/* Dark mode support removed - modals should not change based on system dark mode */
|
|
685
713
|
|
|
686
714
|
/* ============================================
|
|
687
715
|
Handbook Detail Modal Styles
|
|
@@ -767,22 +795,5 @@ ion-app ion-router-outlet.ion-page-hidden {
|
|
|
767
795
|
--background: #ffffff;
|
|
768
796
|
}
|
|
769
797
|
|
|
770
|
-
/* Dark mode support */
|
|
771
|
-
@media (prefers-color-scheme: dark) {
|
|
772
|
-
.ds-whitelabel-demo-modal {
|
|
773
|
-
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
.ds-whitelabel-demo-modal::part(content) {
|
|
777
|
-
background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
.ds-whitelabel-demo-modal::part(backdrop) {
|
|
781
|
-
background: rgba(0, 0, 0, 0.6);
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
.ds-whitelabel-demo-modal ion-content {
|
|
785
|
-
--background: var(--color-background-neutral-primary-dark, #1a1a1a);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
798
|
+
/* Dark mode support removed - modals should not change based on system dark mode */
|
|
788
799
|
|
package/styles/mobile-common.css
CHANGED
|
@@ -107,3 +107,44 @@
|
|
|
107
107
|
margin: 0;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
/* ============================================
|
|
111
|
+
FORM UTILITIES
|
|
112
|
+
============================================ */
|
|
113
|
+
|
|
114
|
+
/* Ghost Input/Textarea - No focus/hover outlines */
|
|
115
|
+
.ghost-input-clean ::ng-deep .ds-input,
|
|
116
|
+
.ghost-input-clean ::ng-deep .ds-textarea,
|
|
117
|
+
.ghost-input-clean ::ng-deep .textarea-container {
|
|
118
|
+
outline: none !important;
|
|
119
|
+
border: none !important;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.ghost-input-clean ::ng-deep .ds-input:hover,
|
|
123
|
+
.ghost-input-clean ::ng-deep .ds-textarea:hover,
|
|
124
|
+
.ghost-input-clean ::ng-deep .textarea-container:hover,
|
|
125
|
+
.ghost-input-clean ::ng-deep .ds-input:focus,
|
|
126
|
+
.ghost-input-clean ::ng-deep .ds-textarea:focus,
|
|
127
|
+
.ghost-input-clean ::ng-deep .textarea-container:focus,
|
|
128
|
+
.ghost-input-clean ::ng-deep .ds-input:focus-within,
|
|
129
|
+
.ghost-input-clean ::ng-deep .ds-textarea:focus-within,
|
|
130
|
+
.ghost-input-clean ::ng-deep .textarea-container:focus-within {
|
|
131
|
+
outline: none !important;
|
|
132
|
+
border: none !important;
|
|
133
|
+
box-shadow: none !important;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Target the actual textarea element inside ds-textarea */
|
|
137
|
+
.ghost-input-clean ::ng-deep textarea {
|
|
138
|
+
outline: none !important;
|
|
139
|
+
border: none !important;
|
|
140
|
+
box-shadow: none !important;
|
|
141
|
+
resize: none !important;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.ghost-input-clean ::ng-deep textarea:hover,
|
|
145
|
+
.ghost-input-clean ::ng-deep textarea:focus {
|
|
146
|
+
outline: none !important;
|
|
147
|
+
border: none !important;
|
|
148
|
+
box-shadow: none !important;
|
|
149
|
+
}
|
|
150
|
+
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
flex-direction: column;
|
|
14
14
|
align-items: center;
|
|
15
15
|
height: 100%;
|
|
16
|
+
/* Solid background to cover overlay from page underneath during transitions */
|
|
17
|
+
background: var(--color-secondary-surface);
|
|
18
|
+
width: 100%;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
/* ============================================
|
|
@@ -211,6 +214,12 @@
|
|
|
211
214
|
background: var(--color-background-neutral-primary);
|
|
212
215
|
border-radius: 24px 24px 0 0;
|
|
213
216
|
|
|
217
|
+
/* Visual styling for iOS overshoot - extend background below using box-shadow */
|
|
218
|
+
transform: translateZ(0);
|
|
219
|
+
will-change: transform;
|
|
220
|
+
isolation: isolate;
|
|
221
|
+
box-shadow: 0 200vh 0 0 var(--color-background-neutral-primary);
|
|
222
|
+
|
|
214
223
|
/* Fixed 20px horizontal padding globally */
|
|
215
224
|
padding: 20px;
|
|
216
225
|
/* Add bottom padding on mobile to account for fixed tab bar */
|
|
@@ -218,13 +227,6 @@
|
|
|
218
227
|
}
|
|
219
228
|
|
|
220
229
|
:host .content-inner {
|
|
221
|
-
/* Visual styling - background, border-radius, and shadow extend */
|
|
222
|
-
transform: translateZ(0);
|
|
223
|
-
will-change: transform;
|
|
224
|
-
isolation: isolate;
|
|
225
|
-
/* Extend white background below for iOS overshoot using box-shadow */
|
|
226
|
-
box-shadow: 0 200vh 0 0 var(--color-background-neutral-primary);
|
|
227
|
-
|
|
228
230
|
/* Grow to fill parent flex container */
|
|
229
231
|
flex: 1;
|
|
230
232
|
|