mn-angular-lib 1.0.140 → 1.0.142

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mn-angular-lib",
3
- "version": "1.0.140",
3
+ "version": "1.0.142",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.1.3",
6
6
  "@angular/core": "^21.1.3",
@@ -0,0 +1,76 @@
1
+ :host {
2
+ /* Native-feeling sheet curve (iOS-style decelerate, no out-of-bounds overshoot which
3
+ would expose a gap below the bottom-anchored sheet). Shared by the entrance keyframe,
4
+ the drag spring-back, and the swipe-dismiss glide so they read as one motion. */
5
+ --mn-sheet-ease: cubic-bezier(0.32, 0.72, 0, 1);
6
+
7
+ display: contents;
8
+ }
9
+
10
+ .mn-sheet-container {
11
+ /* Keep the last content clear of the iOS home indicator. The sheet background extends
12
+ into the inset so it still reads as one continuous surface. env() is 0 on the web,
13
+ so this is a no-op outside the native shell. */
14
+ padding-bottom: env(safe-area-inset-bottom);
15
+
16
+ /* Defined resting floor so the keyboard-grow (min-height -> max) animates from a set
17
+ value instead of jumping from `auto`. A consumer-supplied `minHeightPx` (inline
18
+ style) overrides this without disturbing the transition. */
19
+ min-height: 0;
20
+
21
+ /* Animate the spring-back / exit glide (follow the finger 1:1 while dragging), and the
22
+ keyboard-driven grow/shrink. */
23
+ transition: transform 0.35s var(--mn-sheet-ease), min-height 0.25s var(--mn-sheet-ease);
24
+
25
+ /* Entrance: rise from below the fold. */
26
+ animation: mn-sheet-in 0.35s var(--mn-sheet-ease);
27
+ }
28
+
29
+ /* While the host app marks the soft keyboard open, an opted-in sheet grows to its cap so
30
+ a short body still has scroll room to lift the focused field above the keyboard. Read
31
+ as a plain class/var, so the library keeps no dependency on the native shell. */
32
+ :host(.grow-with-keyboard):host-context(.mn-keyboard-open) .mn-sheet-container {
33
+ min-height: var(--mn-sheet-max, 92vh);
34
+ }
35
+
36
+ .mn-sheet-container.sheet-dragging {
37
+ transition: none;
38
+ }
39
+
40
+ .mn-sheet-backdrop {
41
+ animation: mn-sheet-backdrop-in 0.2s ease-out;
42
+ }
43
+
44
+ /* While dismissing, suppress the entrance keyframe (it would fight the exit transform)
45
+ and let the transform transition glide the sheet the rest of the way down. */
46
+ :host(.is-dismissing) .mn-sheet-container {
47
+ animation: none;
48
+ }
49
+
50
+ @keyframes mn-sheet-in {
51
+ from {
52
+ transform: translateY(100%);
53
+ }
54
+ to {
55
+ transform: translateY(0);
56
+ }
57
+ }
58
+
59
+ @keyframes mn-sheet-backdrop-in {
60
+ from {
61
+ opacity: 0;
62
+ }
63
+ to {
64
+ opacity: 1;
65
+ }
66
+ }
67
+
68
+ /* Collapse the entrance/exit to ~instant rather than removing them, so anything waiting
69
+ on transitionend (the exit teardown) still resolves promptly. */
70
+ @media (prefers-reduced-motion: reduce) {
71
+ .mn-sheet-container,
72
+ .mn-sheet-backdrop {
73
+ animation-duration: 0.01ms !important;
74
+ transition-duration: 0.01ms !important;
75
+ }
76
+ }
@@ -1,9 +1,4 @@
1
1
  :host {
2
- /* Native-feeling sheet curve (iOS-style decelerate, no out-of-bounds overshoot
3
- which would expose a gap below a bottom-anchored sheet). Shared by the
4
- slide keyframes, the drag spring-back, and the swipe-dismiss glide. */
5
- --mn-sheet-ease: cubic-bezier(0.32, 0.72, 0, 1);
6
-
7
2
  position: fixed;
8
3
  inset: 0;
9
4
  z-index: 1000;
@@ -13,6 +8,13 @@
13
8
  transition: transform 0.3s ease-in-out, filter 0.3s ease-in-out, opacity 0.3s ease-in-out;
14
9
  }
15
10
 
11
+ /* Anchor the mobile sheet to the bottom of the viewport. The sheet's own chrome
12
+ (rounded top, slide-up, swipe-to-dismiss, safe-area inset, keyboard-grow) is provided
13
+ by mn-bottom-sheet; the shell only supplies the bottom alignment and the backdrop. */
14
+ :host(.mobile-sheet) {
15
+ align-items: flex-end;
16
+ }
17
+
16
18
  :host(.is-stacked) {
17
19
  transform: scale(0.96) translateY(-1rem);
18
20
  filter: brightness(0.9) blur(1px);
@@ -20,26 +22,6 @@
20
22
  opacity: 0.8;
21
23
  }
22
24
 
23
- /* Swipe-to-dismiss: animate the spring-back, but follow the finger 1:1 while dragging.
24
- `min-height` is transitioned too so the mobile sheet grows/shrinks smoothly (not instantly)
25
- when the soft keyboard opens/closes — see the `.mn-keyboard-open` growth rule below. */
26
- .modal-container {
27
- transition: transform 0.35s var(--mn-sheet-ease), min-height 0.25s var(--mn-sheet-ease);
28
- }
29
-
30
- .modal-container.sheet-dragging {
31
- transition: none;
32
- }
33
-
34
- /* A swipe past the dismiss threshold glides the sheet off-screen via its transform
35
- transition. Suppress the slide-up keyframe (it would snap back to 0 first); the
36
- backdrop still fades out via its own .closing animation. */
37
- :host(.swipe-dismissing) .modal-container,
38
- :host(.swipe-dismissing).closing .modal-container {
39
- animation: none !important;
40
- transition: transform 0.3s var(--mn-sheet-ease);
41
- }
42
-
43
25
  @keyframes fadeIn {
44
26
  from { opacity: 0; }
45
27
  to { opacity: 1; }
@@ -70,19 +52,9 @@
70
52
  to { opacity: 0; transform: scale(0.95); }
71
53
  }
72
54
 
73
- @keyframes slideUpIn {
74
- from {
75
- opacity: 0;
76
- transform: translateY(100%);
77
- }
78
- to {
79
- opacity: 1;
80
- transform: translateY(0);
81
- }
82
- }
83
-
84
- /* Open animations — keyed by the same .anim-* host classes as the close animations
85
- below, so mobile bottom-sheet overrides can target both in one place. */
55
+ /* Open animations for the desktop centered dialog — keyed by the same .anim-* host
56
+ classes as the close animations below. The mobile sheet ignores these; its entrance
57
+ and exit are owned by mn-bottom-sheet. */
86
58
  :host(.anim-slide) .modal-container {
87
59
  animation: slideIn 0.2s ease-in-out;
88
60
  }
@@ -112,81 +84,9 @@
112
84
  }
113
85
 
114
86
  /* =========================
115
- Mobile bottom sheet (< 640px), gated by the .mobile-sheet host class.
116
- Anchors the modal to the bottom, makes it full-width with rounded top
117
- corners, and overrides every open/close animation with a slide-up.
118
- ========================= */
119
- @media (max-width: 639.98px) {
120
- :host(.mobile-sheet) {
121
- align-items: flex-end;
122
- }
123
-
124
- :host(.mobile-sheet) .modal-container {
125
- width: 100%;
126
- max-width: 100%;
127
- /* Explicit resting min-height so the keyboard-open growth (min-height: 92vh) can transition
128
- from a defined value (`auto` would jump instead of animate). */
129
- min-height: 0;
130
- /* Cap the sheet at 92vh. The soft keyboard OVERLAYS the lower part of the sheet rather
131
- than lifting it (on iOS the WKWebView does not resize — Capacitor `resize: none` — so
132
- there is nothing to lift into): the sheet stays anchored at the bottom and its inner
133
- scroll area scrolls the focused field up above the keyboard (see the `.mn-keyboard-open`
134
- growth rule below plus `scroll-padding-bottom` in the host app's styles.css). */
135
- max-height: 92vh;
136
- /* Keep the footer / last content clear of the iOS home indicator. The sheet
137
- background extends into the inset so it reads as one continuous surface.
138
- The container is border-box (Tailwind preflight), so this padding sits inside
139
- max-height — no need to subtract the inset from the cap. env() is 0 on the
140
- web, so this is a no-op outside the native shell. */
141
- padding-bottom: env(safe-area-inset-bottom);
142
- border-radius: 1rem 1rem 0 0;
143
- animation: slideUpIn 0.45s var(--mn-sheet-ease);
144
- }
145
-
146
- /* While the soft keyboard is open (the host app adds `.mn-keyboard-open` to <html> on iOS),
147
- grow the sheet to the full capped height. The keyboard overlays the lower part, so a
148
- SHORT form would otherwise sit entirely behind the keyboard with no room to scroll the
149
- focused field into view — pinning the height to 92vh guarantees content above the keyboard
150
- for the inner scroll (with its `--keyboard-height` scroll-padding) to reveal the field.
151
- Read as a plain class/var, so the library keeps no dependency on Capacitor.
152
- Uses `min-height` (not `height`) so it beats the inline `[style.height]` the shell binds for
153
- FULL-size / explicit `sizeHeight` sheets WITHOUT `!important` — a larger `min-height` wins over
154
- `height`, and `max-height: 92vh` caps a taller inline height back down — AND so the growth can
155
- be smoothly transitioned (see the `.modal-container` transition above). The app only adds
156
- `.mn-keyboard-open` when the focused field would actually be behind the keyboard, so a modal
157
- whose field is already visible never grows. */
158
- :host-context(.mn-keyboard-open).mobile-sheet .modal-container {
159
- min-height: 92vh;
160
- }
161
-
162
- /* Override whichever anim-* open animation was selected */
163
- :host(.mobile-sheet).anim-slide .modal-container,
164
- :host(.mobile-sheet).anim-fade .modal-container,
165
- :host(.mobile-sheet).anim-zoom .modal-container {
166
- animation: slideUpIn 0.45s var(--mn-sheet-ease);
167
- }
168
-
169
- /* Close via a transform TRANSITION, not a re-triggered keyframe. Replaying the
170
- slideUpOut KEYFRAME on a sheet whose open keyframe has already finished does
171
- not animate reliably on mobile browsers — the sheet just disappears. A
172
- transition animates dependably there (it's the same mechanism swipe-to-dismiss
173
- uses), and works whether or not change detection flushes the host class. */
174
- :host(.mobile-sheet).closing .modal-container,
175
- :host(.mobile-sheet).closing.anim-slide .modal-container,
176
- :host(.mobile-sheet).closing.anim-fade .modal-container,
177
- :host(.mobile-sheet).closing.anim-zoom .modal-container {
178
- animation: none !important;
179
- transform: translateY(100%);
180
- opacity: 0;
181
- transition: transform 0.45s var(--mn-sheet-ease), opacity 0.45s var(--mn-sheet-ease);
182
- }
183
- }
184
-
185
- /* =========================
186
- Reduced motion: collapse every open/close/drag animation to ~instant.
187
- Kept at 0.01ms (not `none`) so animationend still fires for the
188
- event-driven close teardown in the shell component. The shell also
189
- short-circuits its close wait when reduced motion is requested.
87
+ Reduced motion: collapse every open/close animation to ~instant. Kept at 0.01ms
88
+ (not `none`) so animationend still fires for the event-driven close teardown in the
89
+ shell component. The shell also short-circuits its close wait under reduced motion.
190
90
  ========================= */
191
91
  @media (prefers-reduced-motion: reduce) {
192
92
  :host,
@@ -1,56 +1,6 @@
1
1
  /*
2
- Mobile bottom-sheet chrome for the dropdown panel.
3
-
4
- These rules are keyed off plain classes rather than `:host` because both the panel
5
- and its backdrop are portalled out to `document.body` while open. Angular's emulated
6
- encapsulation attribute is stamped on the elements themselves and travels with them
7
- when they are relocated, so the scoping still holds — but `:host` would no longer
8
- match, since neither element is the host any more.
9
-
10
- Layout (position, size, colour) lives in the template's Tailwind classes; only the
11
- things Tailwind cannot express — keyframes and the safe-area inset — are here.
2
+ The mobile bottom-sheet chrome (anchoring, slide animation, backdrop, safe-area inset)
3
+ now lives in the shared mn-bottom-sheet component, which this multi-select projects its
4
+ panel content into. No component-local styles remain layout is expressed through the
5
+ template's Tailwind classes.
12
6
  */
13
-
14
- .mn-ms-sheet {
15
- /* Same iOS-style decelerate curve the modal sheet uses, so the two read as one
16
- motion language when a multi-select opens from inside a modal. */
17
- --mn-sheet-ease: cubic-bezier(0.32, 0.72, 0, 1);
18
-
19
- /* Keeps the last option clear of the iOS home indicator. The sheet background
20
- extends into the inset so it still reads as one continuous surface. env() is 0
21
- on the web, so this is a no-op outside the native shell. */
22
- padding-bottom: env(safe-area-inset-bottom);
23
-
24
- animation: mn-ms-sheet-in 0.3s var(--mn-sheet-ease);
25
- }
26
-
27
- .mn-ms-sheet-backdrop {
28
- animation: mn-ms-backdrop-in 0.2s ease-out;
29
- }
30
-
31
- @keyframes mn-ms-sheet-in {
32
- from {
33
- transform: translateY(100%);
34
- }
35
- to {
36
- transform: translateY(0);
37
- }
38
- }
39
-
40
- @keyframes mn-ms-backdrop-in {
41
- from {
42
- opacity: 0;
43
- }
44
- to {
45
- opacity: 1;
46
- }
47
- }
48
-
49
- /* Collapse the entrance animations to ~instant rather than removing them, matching
50
- the modal shell's approach so anything listening for animationend still fires. */
51
- @media (prefers-reduced-motion: reduce) {
52
- .mn-ms-sheet,
53
- .mn-ms-sheet-backdrop {
54
- animation-duration: 0.01ms !important;
55
- }
56
- }