ngwr 12.1.0 → 12.2.0

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.
@@ -18,7 +18,17 @@ $alert-colors: (
18
18
 
19
19
  // Defaults — overridden per variant below.
20
20
  --wr-alert-bg: var(--wr-color-info-soft);
21
- --wr-alert-border: var(--wr-color-info-soft-border);
21
+ // `transparent`, not a `-soft-border` hairline: the tint alone carries the
22
+ // block, and the ring around it was a second edge saying the same thing.
23
+ //
24
+ // The hook itself stays, and is still what the border reads — it is public
25
+ // API, an app that wants a bordered alert sets `--wr-alert-border` and gets
26
+ // one back, per variant if it likes. Nor does the declaration go: a
27
+ // transparent 1px border still occupies its 1px, so a consumer switching the
28
+ // hook on does not reflow the block by a pixel on each side, and no variant's
29
+ // padding has to be re-derived. NO variant overrides this any more — an alert
30
+ // has one border value, and it is the one a consumer can reach.
31
+ --wr-alert-border: transparent;
22
32
  // `-ink`, never the bare intent: this is the intent used AS TEXT on its own
23
33
  // soft tint, and a bare `--wr-color-warning` there is 1.71:1 in the light
24
34
  // theme. See the token note in AGENTS.md — `-contrast` is the other
@@ -103,7 +113,6 @@ $alert-colors: (
103
113
  @each $variant, $color in $alert-colors {
104
114
  &--#{$variant} {
105
115
  --wr-alert-bg: var(--wr-color-#{$color}-soft);
106
- --wr-alert-border: var(--wr-color-#{$color}-soft-border);
107
116
  --wr-alert-title: var(--wr-color-#{$color}-ink);
108
117
  --wr-alert-close: var(--wr-color-#{$color}-ink);
109
118
  }
@@ -112,7 +121,6 @@ $alert-colors: (
112
121
  // Neutral — muted gray chip, reusing the `medium` soft tokens.
113
122
  &--neutral {
114
123
  --wr-alert-bg: var(--wr-color-medium-soft);
115
- --wr-alert-border: var(--wr-color-medium-soft-border);
116
124
  --wr-alert-title: var(--wr-color-on-surface);
117
125
  --wr-alert-message: var(--wr-color-on-surface-muted);
118
126
  --wr-alert-close: var(--wr-color-on-surface-muted);
@@ -126,7 +134,6 @@ $alert-colors: (
126
134
  // light text in light theme; light bg + dark text in dark theme.
127
135
  &--offline {
128
136
  --wr-alert-bg: var(--wr-color-on-surface);
129
- --wr-alert-border: var(--wr-color-on-surface);
130
137
  --wr-alert-title: var(--wr-color-surface);
131
138
  --wr-alert-message: var(--wr-color-surface);
132
139
  --wr-alert-close: var(--wr-color-surface);
@@ -81,6 +81,31 @@
81
81
 
82
82
  // Outlined — transparent fill, colored border + text. The inset ring
83
83
  // replaces the solid background, so padding stays identical.
84
+ //
85
+ // The ring is deliberately NOT `currentcolor` once an intent is on the host.
86
+ // The label sits on `-ink`, which is calibrated to 5.0:1 and must not move —
87
+ // so a ring drawn in the text colour is a hairline at full label strength
88
+ // wrapped around text of exactly that strength, and the two cannot be
89
+ // separated while they share one value. `-soft-border` is the same intent at
90
+ // 0.3 alpha: the theme's canonical hairline, already per intent and already
91
+ // theme-correct through the `-rgb` channels. `wr-tag--outlined` draws the same
92
+ // ring from the same token; the tag keeps its 6% fill, because a tag is a
93
+ // chip you can click and a badge is a label you cannot.
94
+ //
95
+ // The soft trio covers the seven CHROMATIC intents, so `light` and `dark` have
96
+ // no `-soft-border` and the `var()` carries the token's own recipe as its
97
+ // fallback. That fallback is load-bearing twice over: an undefined custom
98
+ // property with no fallback invalidates the whole declaration, which would
99
+ // leave those two badges with no ring at all rather than a soft one — and
100
+ // 0.3 alpha is what keeps `dark` in the same family as the other eight
101
+ // instead of the only ring still drawn at full label strength, which is the
102
+ // weight this rule exists to stop drawing.
103
+ //
104
+ // `light` is the one intent the recipe cannot serve: it is a surface tone by
105
+ // definition, a hair off the page in either theme, so 30% of it over the page
106
+ // is nothing. At FULL strength it is `--wr-color-outline` — the hairline every
107
+ // bordered surface in the library already draws — so it is reached by that
108
+ // name, after the loop, rather than by an alpha that happens to land there.
84
109
  &--outlined {
85
110
  background-color: transparent;
86
111
  box-shadow: inset 0 0 0 1px currentcolor;
@@ -88,7 +113,12 @@
88
113
  @each $name in theme.$colors {
89
114
  &.wr-badge--#{$name} {
90
115
  color: var(--wr-color-#{$name}-ink);
116
+ box-shadow: inset 0 0 0 1px var(--wr-color-#{$name}-soft-border, rgba(var(--wr-color-#{$name}-rgb), 0.3));
91
117
  }
92
118
  }
119
+
120
+ &.wr-badge--light {
121
+ box-shadow: inset 0 0 0 1px var(--wr-color-outline);
122
+ }
93
123
  }
94
124
  }
@@ -74,10 +74,17 @@
74
74
  --wr-tag-bg: var(--wr-color-#{$name});
75
75
  --wr-tag-border: var(--wr-color-#{$name});
76
76
 
77
+ // The ring reads from `-soft-border` rather than a hand-rolled alpha, so
78
+ // it is the same hairline `wr-badge--outlined` draws — one alpha in one
79
+ // place, which is the reason the soft trio exists. 0.25 -> 0.30 is the
80
+ // whole visual change here. The 6% fill stays, and that is the one place
81
+ // the two deliberately differ: a tag is a chip you can click, hover and
82
+ // dismiss, so it keeps a body the badge has none of. `light` and `dark`
83
+ // fall back exactly as the badge does — see the note there.
77
84
  &.wr-tag--outlined {
78
85
  --wr-tag-color: var(--wr-color-#{$name}-ink);
79
86
  --wr-tag-bg: rgba(var(--wr-color-#{$name}-rgb), 0.06);
80
- --wr-tag-border: rgba(var(--wr-color-#{$name}-rgb), 0.25);
87
+ --wr-tag-border: var(--wr-color-#{$name}-soft-border, rgba(var(--wr-color-#{$name}-rgb), 0.3));
81
88
  }
82
89
 
83
90
  &.wr-tag--transparent {
@@ -87,4 +94,11 @@
87
94
  }
88
95
  }
89
96
  }
97
+
98
+ // `light` outlined, after the loop for the same reason the badge carries the
99
+ // same rule: 30% of a surface tone is not a line. At full strength it IS
100
+ // `--wr-color-outline`, which is already this component's default border.
101
+ &--light.wr-tag--outlined {
102
+ --wr-tag-border: var(--wr-color-outline);
103
+ }
90
104
  }
@@ -80,10 +80,14 @@
80
80
 
81
81
  &--bordered &__row {
82
82
  padding: 0.625rem 0.875rem;
83
+ }
83
84
 
84
- & + & {
85
- border-top: 1px solid var(--wr-color-outline);
86
- }
85
+ // Nesting this as `& + &` expands BOTH sides in full —
86
+ // `… .wr-descriptions__row + .wr-descriptions--bordered .wr-descriptions__row` —
87
+ // which asks for a `--bordered` HOST as a row's sibling and can never match, so
88
+ // the stacked bordered card shipped with no dividers at all. Name the sibling.
89
+ &--bordered &__row + &__row {
90
+ border-top: 1px solid var(--wr-color-outline);
87
91
  }
88
92
 
89
93
  &--bordered#{&}--inline &__list {
@@ -122,6 +126,12 @@
122
126
  display: flex;
123
127
  flex-direction: column;
124
128
  gap: 0.5rem;
129
+ // The grid layout above aligns its two columns on `baseline`, which is
130
+ // correct there and wrong here: once the list is a COLUMN flex container
131
+ // the cross axis is the width, so `baseline` sizes each row to its own
132
+ // content. Rows must stretch, or a bordered row's divider paints only as
133
+ // wide as its longest line instead of spanning the card.
134
+ align-items: stretch;
125
135
  }
126
136
 
127
137
  .wr-descriptions--inline .wr-descriptions__row {
@@ -49,7 +49,12 @@
49
49
  // `elementFromPoint` still answered "close button" over the first 10px of the
50
50
  // content: the boxes had stopped intersecting and the control was still covered.
51
51
  // 52px clears the target with two pixels to spare.
52
- .wr-drawer__panel--untitled > *:not(.wr-drawer__close) {
52
+ // `:not(.wr-drawer__handle)` for the same reason as `:not(.wr-drawer__close)` —
53
+ // the grab handle is chrome, not the content column. It clears the × on its own
54
+ // (the button is corner-anchored, the bottom-sheet handle is centred), and on
55
+ // `left` / `right` it is out of the flow entirely, where a block-start padding
56
+ // would shove the rail off its own centre line.
57
+ .wr-drawer__panel--untitled > *:not(.wr-drawer__close):not(.wr-drawer__handle) {
53
58
  padding-block-start: 3.25rem;
54
59
  }
55
60
 
@@ -144,6 +149,23 @@
144
149
  border-bottom-left-radius: var(--wr-border-radius-lg);
145
150
  }
146
151
 
152
+ // Room for the vertical grab rail, which is out of the flow (see
153
+ // `&__panel--left &__handle`). Only the two horizontal positions need it: the
154
+ // `top` / `bottom` handle is a flow row and reserves its own height.
155
+ //
156
+ // On the PANEL rather than per slot, because an absolutely positioned child
157
+ // is placed against the padding box — so `right: 0` lands the rail in exactly
158
+ // the gutter this opens, and the title's and footer's rules stay untouched.
159
+ // Same 1.25rem the handle measures across.
160
+ &--handle.wr-drawer__panel--left {
161
+ // rtl-ok: mirrors the physically placed rail — inner edge of a left-anchored panel
162
+ padding-right: 1.25rem;
163
+ }
164
+ &--handle.wr-drawer__panel--right {
165
+ // rtl-ok: mirrors the physically placed rail — inner edge of a right-anchored panel
166
+ padding-left: 1.25rem;
167
+ }
168
+
147
169
  // Safe-area padding on the trailing edge. `env(safe-area-inset-*)` is defined
148
170
  // per physical screen edge — the notch does not move when the text does — so
149
171
  // the padding that clears it stays physical as well.
@@ -165,6 +187,10 @@
165
187
 
166
188
  .wr-drawer {
167
189
  // Grab handle (visual swipe-to-dismiss affordance)
190
+ //
191
+ // The base rule is the BOTTOM sheet: a horizontal bar in the flow at the top
192
+ // of the column. `--top`, `--left` and `--right` re-place it below — see the
193
+ // block after this one, which is where the whole point of the handle lives.
168
194
  &__handle {
169
195
  display: flex;
170
196
  align-items: center;
@@ -174,6 +200,8 @@
174
200
  cursor: grab;
175
201
  user-select: none;
176
202
  // Own the gesture — stop the browser turning the drag into a scroll/pan.
203
+ // Every placement below inherits this: without it the browser claims the
204
+ // drag as a pan and the panel never follows the finger.
177
205
  touch-action: none;
178
206
  }
179
207
 
@@ -185,6 +213,72 @@
185
213
  background: rgba(var(--wr-color-on-surface-rgb), 0.18);
186
214
  }
187
215
 
216
+ // The handle follows `position`, because the gesture does.
217
+ //
218
+ // `showHandle` has always documented itself as a handle "at the leading edge"
219
+ // — the edge facing the viewport interior, the one the panel is dragged away
220
+ // from — and `closeAxis()` in drawer.ts already resolves all four: down for
221
+ // `bottom`, up for `top`, left for `left`, right for `right`. The CSS
222
+ // implemented one of them. The other three drew the same horizontal bar at
223
+ // the top of the panel, so a right-side drawer showed a stray pill above its
224
+ // title pointing along an axis the drag does not travel.
225
+ //
226
+ // Keep these two in step: a bar the finger finds on the wrong axis is worse
227
+ // than no bar, because it invites the gesture that does nothing.
228
+
229
+ // `top` — same horizontal bar, block-END edge. `order` rather than a template
230
+ // change: the handle is `aria-hidden` chrome, so nothing depends on its DOM
231
+ // position, and `margin-block-start: auto` puts it against the bottom even
232
+ // when the projected content does not grow (a bare `<nav>` is `flex: 0 1 auto`,
233
+ // so without it the handle would float directly under the content).
234
+ &__panel--top &__handle {
235
+ order: 1;
236
+ margin-block-start: auto;
237
+ }
238
+
239
+ // `left` / `right` — a VERTICAL bar on the inner vertical edge.
240
+ //
241
+ // Out of the flow, because the panel is a column and a rail on its inline
242
+ // edge is not a row of it; putting it back in the flow would mean wrapping
243
+ // the projected title / content / footer in a new element, and those sit
244
+ // directly under `.wr-drawer__panel` in markup consumers already style.
245
+ // The panel reserves the gutter it floats over (`&--handle`, up in the
246
+ // `.wr-drawer__panel` block), so nothing is covered — the lesson `--untitled`
247
+ // learned about the × button.
248
+ &__panel--left &__handle,
249
+ &__panel--right &__handle {
250
+ position: absolute;
251
+ inset-block-start: 50%;
252
+ // Not the panel's own transform: `onSwipeMove` writes `translateX(…)` onto
253
+ // the PANEL while dragging, and this element is its child.
254
+ transform: translateY(-50%);
255
+ // 0.5rem each side of a 0.25rem bar — the same 1.25rem thickness the
256
+ // horizontal handle has, turned ninety degrees, so the gutter reserved for
257
+ // it is the one the panel's slots already pad by. The 1.5rem block padding
258
+ // is grab target rather than decoration: it takes the 2.5rem bar to a 5.5rem
259
+ // reachable strip, which a finger can find without aiming at a 4px pill.
260
+ padding: 1.5rem 0.5rem;
261
+ z-index: 1;
262
+ }
263
+
264
+ &__panel--left &__handle {
265
+ // rtl-ok: `position` is physical (`left` names a viewport edge, and the CDK
266
+ // strategy calls `.left()`), so the inner edge of a left-anchored panel is
267
+ // the physical right one in either direction
268
+ right: 0;
269
+ }
270
+
271
+ &__panel--right &__handle {
272
+ // rtl-ok: physical `position` — inner edge of a right-anchored panel
273
+ left: 0;
274
+ }
275
+
276
+ &__panel--left &__grabber,
277
+ &__panel--right &__grabber {
278
+ width: 0.25rem;
279
+ height: 2.5rem;
280
+ }
281
+
188
282
  &__title {
189
283
  margin: 0;
190
284
  padding: 1rem 1.25rem;
@@ -145,6 +145,12 @@ class WrDrawer {
145
145
  parts.push('wr-drawer__panel--safe-area');
146
146
  if (this.closable())
147
147
  parts.push('wr-drawer__panel--closable');
148
+ // The handle sits on the LEADING edge, which for `left` / `right` is a
149
+ // vertical rail rather than a row in the column — so it leaves the flow and
150
+ // the panel has to reserve the gutter it floats over. Only the panel can do
151
+ // that, and only if it knows the handle is there.
152
+ if (this.showHandle())
153
+ parts.push('wr-drawer__panel--handle');
148
154
  // Only when there is something to collide with: a closable drawer with a
149
155
  // title already clears the button, and an unclosable one has no button.
150
156
  if (this.closable() && !this.projectedTitle())
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-drawer.mjs","sources":["../../../projects/lib/drawer/directives/drawer-title.ts","../../../projects/lib/drawer/drawer.ts","../../../projects/lib/drawer/drawer.html","../../../projects/lib/drawer/drawer-ref.ts","../../../projects/lib/drawer/tokens/drawer-data.token.ts","../../../projects/lib/drawer/tokens/drawer-ref.token.ts","../../../projects/lib/drawer/drawer-manager.ts","../../../projects/lib/drawer/directives/drawer-content.ts","../../../projects/lib/drawer/directives/drawer-footer.ts","../../../projects/lib/drawer/directives/drawer-close.ts","../../../projects/lib/drawer/ngwr-drawer.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Marks an element as the drawer's title row. Applies the `wr-drawer__title`\n * class so the drawer's stylesheet can lay it out alongside content and\n * footer slots. Auto-assigns an `id` so the drawer panel references it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"open\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>…</div>\n * </wr-drawer>\n * ```\n */\n@Directive({\n selector: '[wrDrawerTitle]',\n host: { class: 'wr-drawer__title', '[attr.id]': 'id' },\n})\nexport class WrDrawerTitle {\n /** Generated id used by the drawer panel for `aria-labelledby`. */\n readonly id = `wr-drawer-title-${++uid}`;\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n PLATFORM_ID,\n TemplateRef,\n ViewContainerRef,\n ViewEncapsulation,\n afterEveryRender,\n contentChild,\n effect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\nimport { WrDrawerTitle } from './directives/drawer-title';\nimport type { WrDrawerPosition } from './interfaces';\n\n/**\n * Side panel that slides in from an edge of the viewport. Two-way binds\n * `open` and renders into a CDK overlay so it sits above page content.\n *\n * Compose the body with `<wrDrawerTitle>`, `<wrDrawerContent>`, and\n * `<wrDrawerFooter>` directives.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"settingsOpen\" position=\"right\" width=\"24rem\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>...</div>\n * <div wrDrawerFooter>\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * </div>\n * </wr-drawer>\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Component({\n selector: 'wr-drawer',\n templateUrl: './drawer.html',\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrDrawer {\n /** Two-way bindable open state. */\n readonly open = model<boolean>(false);\n\n /** Side the drawer slides in from. @default 'right' */\n readonly position = input<WrDrawerPosition>('right');\n\n /** Width when position is left/right. Any CSS length. @default '20rem' */\n readonly width = input<string>('20rem');\n\n /** Height when position is top/bottom. Any CSS length. @default '16rem' */\n readonly height = input<string>('16rem');\n\n /**\n * Upper cap on height (top/bottom positions). Useful for bottom sheets\n * that should grow with content up to a viewport-relative max.\n * Any CSS length. @default null (no cap)\n */\n readonly maxHeight = input<string | null>(null);\n\n /**\n * Round the leading corners — the edge facing the viewport interior.\n * Common bottom-sheet styling. @default false\n */\n readonly rounded = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Render a grab handle at the leading edge and enable swipe-to-dismiss:\n * drag the handle toward the drawer's edge (down for `bottom`, left for\n * `left`, …) and release past ~30% of the panel to close. @default false\n */\n readonly showHandle = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Pad the trailing edge with `env(safe-area-inset-*)` so content\n * doesn't sit under the iOS home indicator. @default false\n */\n readonly safeArea = input(false, { transform: coerceBooleanProperty });\n\n /** Show the dimming backdrop. @default true */\n readonly hasBackdrop = input(true, { transform: coerceBooleanProperty });\n\n /** Close when the backdrop is clicked. @default true */\n readonly closeOnBackdropClick = input(true, { transform: coerceBooleanProperty });\n\n /** Close on Escape. @default true */\n readonly closeOnEscape = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Show a dismiss (×) button in the panel's top-right corner. Set `false` when\n * the projected content supplies its own close affordance. @default true\n */\n readonly closable = input(true, { transform: coerceBooleanProperty });\n\n /** Accessible name for the dismiss button. Falls back to `drawer.close`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'drawer.close', 'Close drawer');\n\n protected readonly panelTpl = viewChild.required(TemplateRef);\n\n /**\n * A projected `[wrDrawerTitle]`, if the consumer gave one.\n *\n * The dismiss button is corner chrome positioned at a fixed\n * `inset-block-start` chosen to centre it on the TITLE's first line. With no\n * title the content starts at the top of the panel and runs underneath it: on\n * a bare `<wr-drawer><nav /></wr-drawer>` the button covered the first menu\n * row by 24×16 px, and `elementFromPoint` at the button's centre returned the\n * button, so that corner of the first item was unclickable. The panel has to\n * know, because only the panel can reserve the space.\n */\n private readonly projectedTitle = contentChild(WrDrawerTitle);\n\n protected panelClass(): string {\n const parts = ['wr-drawer__panel', `wr-drawer__panel--${this.position()}`];\n if (this.rounded()) parts.push('wr-drawer__panel--rounded');\n if (this.safeArea()) parts.push('wr-drawer__panel--safe-area');\n if (this.closable()) parts.push('wr-drawer__panel--closable');\n // Only when there is something to collide with: a closable drawer with a\n // title already clears the button, and an unclosable one has no button.\n if (this.closable() && !this.projectedTitle()) parts.push('wr-drawer__panel--untitled');\n return parts.join(' ');\n }\n\n // Swipe-to-dismiss — gated to the grab handle, so it never fights the\n // panel's own scrolling. The panel follows the finger toward the closing\n // edge and closes past ~30% of its size, otherwise snaps back.\n\n private swipeStartX = 0;\n private swipeStartY = 0;\n private swiping = false;\n\n // Pointer, not Touch. The handle has always advertised itself to a mouse with\n // `cursor: grab`, but the gesture was bound to touch events only, so on a\n // desktop it could not be dragged at all. Pointer Events cover touch, mouse and\n // pen through one path — the same idiom `wr-splitter` already uses.\n\n protected onSwipeStart(event: PointerEvent): void {\n // Ignore secondary contacts of a multi-touch gesture.\n if (!event.isPrimary) return;\n this.swipeStartX = event.clientX;\n this.swipeStartY = event.clientY;\n this.swiping = true;\n // Capture, so the drag keeps reporting once the cursor leaves the 2.5rem\n // grabber — without it a mouse drag dies the moment it slips off the handle.\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n }\n\n protected onSwipeMove(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n // Only follow the pointer when dragging toward the closing edge.\n if (delta * sign <= 0) {\n panel.style.transform = '';\n return;\n }\n panel.style.transition = 'none';\n panel.style.transform = axis === 'y' ? `translateY(${delta}px)` : `translateX(${delta}px)`;\n }\n\n /**\n * A cancelled pointer is an ABANDONED swipe, not a completed one — the system\n * took the gesture away (a call, a system gesture, an orientation change) and\n * no `pointerup` ever arrives. Routing it through `onSwipeEnd` dismissed the\n * drawer on an interruption the user did not ask for and, because the overlay\n * is disposed with the dragged offset applied, could not take back. Same rule\n * `wr-pull-to-refresh` states for `touchcancel`.\n */\n protected onSwipeCancel(panel: HTMLElement): void {\n if (!this.swiping) return;\n this.swiping = false;\n panel.style.transition = '';\n panel.style.transform = '';\n }\n\n protected onSwipeEnd(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n this.swiping = false;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n const panelSize = axis === 'y' ? panel.offsetHeight : panel.offsetWidth;\n if (delta * sign > panelSize * 0.3) {\n this.open.set(false); // keep the dragged offset as the overlay disposes\n } else {\n panel.style.transition = '';\n panel.style.transform = '';\n }\n }\n\n /** Axis + sign of the closing direction for the current position. */\n private closeAxis(): { axis: 'x' | 'y'; sign: number } {\n switch (this.position()) {\n case 'bottom':\n return { axis: 'y', sign: 1 };\n case 'top':\n return { axis: 'y', sign: -1 };\n case 'left':\n return { axis: 'x', sign: -1 };\n case 'right':\n default:\n return { axis: 'x', sign: 1 };\n }\n }\n\n private readonly overlay = inject(WR_OVERLAY);\n private readonly vcr = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private overlayRef: OverlayRef | null = null;\n private focusTrap: ConfigurableFocusTrap | null = null;\n private previouslyFocused: HTMLElement | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n afterEveryRender(() => this.syncLabel());\n this.destroyRef.onDestroy(() => this.closeOverlay());\n }\n\n /**\n * Point the panel's `aria-labelledby` at the CURRENT `[wrDrawerTitle]`.\n *\n * Re-resolved after every render rather than once when the drawer opens,\n * because the title element is projected content and can come and go while\n * the drawer stays open — an `@if` around it, or a heading that only exists\n * once the data arrives. A one-shot lookup leaves the attribute naming an\n * element that has been removed or replaced, and a dangling reference is not\n * a name: the dialog is announced as unnamed, with nothing on screen to say\n * so. A missing title clears the attribute for the same reason.\n */\n private syncLabel(): void {\n const host = this.overlayRef?.overlayElement;\n if (!host) return;\n\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n }\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n const pos = this.position();\n const isHorizontal = pos === 'left' || pos === 'right';\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [pos === 'left' ? 'left' : pos === 'right' ? 'right' : 'centerHorizontally']();\n\n if (pos === 'top') positionStrategy.top();\n else if (pos === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = this.maxHeight();\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n hasBackdrop: this.hasBackdrop(),\n backdropClass: 'wr-drawer-backdrop',\n panelClass: ['wr-drawer-overlay', `wr-drawer-overlay--${pos}`],\n scrollStrategy: this.overlay.scrollStrategies.block(),\n width: isHorizontal ? this.width() : '100vw',\n height: isHorizontal ? undefined : this.height(),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n this.previouslyFocused = active instanceof HTMLElement ? active : null;\n const host = this.overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n this.focusTrap = this.focusTrapFactory.create(host);\n void this.focusTrap.focusInitialElementWhenReady();\n }\n\n if (this.closeOnBackdropClick()) {\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.open.set(false));\n }\n\n if (this.closeOnEscape()) {\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n }\n });\n }\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n}\n","<ng-template>\n <div #panel [class]=\"panelClass()\">\n @if (showHandle()) {\n <div\n class=\"wr-drawer__handle\"\n aria-hidden=\"true\"\n (pointerdown)=\"onSwipeStart($event)\"\n (pointermove)=\"onSwipeMove($event, panel)\"\n (pointerup)=\"onSwipeEnd($event, panel)\"\n (pointercancel)=\"onSwipeCancel(panel)\"\n >\n <span class=\"wr-drawer__grabber\"></span>\n </div>\n }\n @if (closable()) {\n <button type=\"button\" class=\"wr-drawer__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"open.set(false)\">\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n <ng-content />\n </div>\n</ng-template>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDrawerManager.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the drawer's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDrawerClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = drawers.open<ChatComponent, boolean>(ChatComponent, { position: 'right' });\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the drawer closes itself.\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject(WrDrawerRef);\n *\n * send(): void {\n * this.store.send(this.draft());\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDrawerRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated drawer component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDrawerRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the drawer, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the drawer is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDrawerManager.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * readonly data = inject<ChatData>(WR_DRAWER_DATA);\n * }\n * ```\n */\nexport const WR_DRAWER_DATA = new InjectionToken<unknown>('WR_DRAWER_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDrawerRef } from '../drawer-ref';\n\n/**\n * Token exposing the open drawer's `WrDrawerRef` to components and\n * directives rendered inside it (e.g. `[wrDrawerClose]`).\n *\n * **Prefer `inject(WrDrawerRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDrawerRef, { optional: true })`\n * works for content that also renders outside a drawer, and\n * `inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef)` types the generics\n * without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDrawerClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef);\n *\n * dismiss(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DRAWER_REF = new InjectionToken<WrDrawerRef<unknown, unknown>>('WR_DRAWER_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { Location, isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Injector, PLATFORM_ID, Service, afterEveryRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, wrAppendOverlayClose } from 'ngwr/overlay';\n\nimport { WrDrawerRef } from './drawer-ref';\nimport type { WrDrawerOptions, WrDrawerPosition } from './interfaces';\nimport { WR_DRAWER_DATA, WR_DRAWER_REF } from './tokens';\n\nconst DEFAULT_POSITION: WrDrawerPosition = 'right';\nconst DEFAULT_WIDTH = '20rem';\nconst DEFAULT_HEIGHT = '16rem';\nconst BACKDROP_CLASS = 'wr-drawer-backdrop';\n\n/**\n * Opens drawer components in an isolated NGWR overlay — the programmatic\n * counterpart to `<wr-drawer [(open)]=\"…\">`.\n *\n * Use the component when the drawer is part of a template and its open state\n * is a signal you already own; use this service when the caller doesn't own\n * the markup (opening a chat panel from a toolbar action, from an effect, from\n * a route guard) or when you need the close result.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — drawers render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * `showHandle` / swipe-to-dismiss is component-only: it needs the drawer's own\n * wrapper markup, which the service path replaces with your component.\n *\n * @example\n * ```ts\n * const drawers = inject(WrDrawerManager);\n *\n * const ref = drawers.open(ChatComponent, {\n * data: { threadId },\n * position: 'right',\n * width: '28rem',\n * });\n *\n * await ref.awaitClose();\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Service()\nexport class WrDrawerManager {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly i18n = inject(WrI18n);\n private readonly location = inject(Location);\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDrawerOptions<D> = {}): WrDrawerRef<C, R> {\n const position = options.position ?? DEFAULT_POSITION;\n const isHorizontal = position === 'left' || position === 'right';\n\n // The content component is attached straight into the overlay pane, so the\n // panel styles land on the pane rather than on an inner wrapper.\n const panelClasses = [\n 'wr-drawer-overlay',\n `wr-drawer-overlay--${position}`,\n 'wr-drawer__panel',\n `wr-drawer__panel--${position}`,\n ];\n if (options.rounded) panelClasses.push('wr-drawer__panel--rounded');\n if (options.safeArea) panelClasses.push('wr-drawer__panel--safe-area');\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [position === 'left' ? 'left' : position === 'right' ? 'right' : 'centerHorizontally']();\n\n if (position === 'top') positionStrategy.top();\n else if (position === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = options.maxHeight ?? null;\n\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: options.hasBackdrop !== false,\n backdropClass: BACKDROP_CLASS,\n panelClass: panelClasses,\n width: isHorizontal ? (options.width ?? DEFAULT_WIDTH) : '100vw',\n height: isHorizontal ? undefined : (options.height ?? DEFAULT_HEIGHT),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const drawerRef = new WrDrawerRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n drawerRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DRAWER_DATA, useValue: options.data },\n { provide: WR_DRAWER_REF, useValue: drawerRef },\n // Provided as its own token as well, so drawer content can reach for\n // the familiar `inject(WrDrawerRef)` and close itself.\n { provide: WrDrawerRef, useValue: drawerRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n drawerRef.componentRef = overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss, same contract as WrDialog's `closable`.\n if (options.closable !== false) {\n host.classList.add('wr-drawer__panel--closable');\n const label = options.closeLabel ?? this.closeLabel();\n wrAppendOverlayClose(host, 'wr-drawer__close', label, () => drawerRef.close());\n }\n // Wire aria-labelledby to wrDrawerTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n //\n // And after EVERY render, not just the next one: the title belongs to the\n // caller's component, so an `@if` or a late-arriving heading can replace\n // or remove the element the attribute names. A reference to a node that is\n // no longer there is not a name — the dialog announces as unnamed — so a\n // missing title clears the attribute rather than leaving it dangling.\n const labelSync = afterEveryRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n },\n { injector: this.parentInjector }\n );\n // The hook is bound to the root injector, so it outlives the drawer unless\n // it is torn down with it. `detachments()` fires on dispose, which is the\n // one path every dismissal goes through.\n overlayRef.detachments().subscribe(() => labelSync.destroy());\n // Trap focus inside the drawer and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n drawerRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n // Overlay subscriptions complete when the overlay is disposed, so no\n // explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => drawerRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n drawerRef.close();\n }\n });\n }\n if (options.closeOnNavigation !== false) {\n this.watchNavigation(overlayRef, drawerRef);\n }\n\n return drawerRef;\n }\n\n /**\n * Tie the drawer's lifetime to the URL it was opened on — the same treatment\n * `WrDialog` gets, and for the same reason.\n *\n * Nothing else does. The overlay belongs to a root service and is dismissed\n * only by the backdrop, Escape, the appended × or an explicit `close()`, so\n * navigating away left the panel, its backdrop, its focus trap and the\n * page-wide scroll block sitting over a page the user never opened them on.\n *\n * `onUrlChange`, not `Location.subscribe()` — which is what CDK's own\n * `disposeOnNavigation` uses: `subscribe` fires on popstate alone, so an in-app\n * `router.navigate()` left the drawer standing. And `drawerRef.close()` rather\n * than disposing the overlay behind the ref's back, which would never emit\n * `closed`, never destroy the focus trap, and leave `awaitClose()` pending.\n */\n private watchNavigation<C, R>(overlayRef: OverlayRef, drawerRef: WrDrawerRef<C, R>): void {\n const stopWatching = this.location.onUrlChange(() => drawerRef.close());\n // Unhooked a microtask late, because `Location` notifies its listeners with\n // a `forEach` and unregistering splices the array it is iterating: removing\n // ours synchronously from inside the notification would shift the next entry\n // into the slot forEach has already passed, and a SECOND stacked drawer\n // would be skipped and left behind.\n overlayRef.detachments().subscribe(() => queueMicrotask(stopWatching));\n }\n\n /**\n * The dismiss button's accessible name.\n *\n * Resolved per open, not stored as a plain string at injection: this is a root\n * service, so a one-shot read — which is what `WrDialog` used to have, and moved\n * off for this reason — would run before an async catalog had loaded and then\n * freeze that answer for the life of the app. (`readI18nText` hands back a signal\n * now, so it would no longer freeze; the name still has to be pushed onto the\n * button per open either way.) `WrDialog.closeLabel()` is the matching precedent,\n * not the counter-example.\n *\n * The miss check is the point. `t()` hands back the KEY when the catalog has\n * no entry, and `WrI18n` is root-provided with an empty catalog by default —\n * so an app that never configured i18n got a button announced as\n * \"drawer.close, button\". A name WAS present, which is exactly why the axe\n * gate could not see it.\n */\n private closeLabel(): string {\n const resolved = this.i18n.t('drawer.close');\n return resolved === 'drawer.close' ? 'Close drawer' : resolved;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\n/**\n * Marks the scrollable body of the drawer. Applies the `wr-drawer__content`\n * class so the panel's flex layout can stretch it between the title and the\n * footer.\n */\n@Directive({\n selector: '[wrDrawerContent]',\n host: { class: 'wr-drawer__content' },\n})\nexport class WrDrawerContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Marks the action row pinned to the bottom of the drawer. Adds the\n * `wr-drawer__footer` class plus an alignment modifier so action buttons\n * can sit at the start, center, or end of the row.\n *\n * @example\n * ```html\n * <div wrDrawerFooter align=\"end\">\n * <wr-btn wrDrawerClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" (click)=\"save()\">Save</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDrawerFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDrawerFooter {\n /** Horizontal alignment of footer content. @default 'end' */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-drawer__footer wr-drawer__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport { WrDrawer } from '../drawer';\nimport type { WrDrawerRef } from '../drawer-ref';\nimport { WR_DRAWER_REF } from '../tokens';\n\n/**\n * Closes the parent drawer on click. Attach to any clickable element.\n *\n * Works for both drawer flavours: inside `<wr-drawer>` it clears the\n * component's `open` model, and inside a `WrDrawerManager.open()` drawer it\n * closes the ref — optionally passing a `[wrDrawerClose]` value as the close\n * result (the component flavour has no result to carry, so the value is\n * ignored there).\n *\n * @example\n * ```html\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * <wr-btn color=\"primary\" [wrDrawerClose]=\"true\">Save</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDrawerClose]',\n host: { '(click)': 'close()' },\n})\nexport class WrDrawerClose<R = unknown> {\n /**\n * Value to pass to `close()` for service-opened drawers. When unset — or\n * used as a bare attribute — the drawer closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDrawerClose',\n // A bare `wrDrawerClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly drawer = inject(WrDrawer, { optional: true });\n private readonly ref = inject<WrDrawerRef<unknown, R>>(WR_DRAWER_REF, { optional: true });\n\n protected close(): void {\n // Element injectors win, so a surrounding `<wr-drawer>` is the nearer\n // owner even when a service-opened drawer sits further up the tree.\n if (this.drawer) {\n this.drawer.open.set(false);\n return;\n }\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-drawer.mjs","sources":["../../../projects/lib/drawer/directives/drawer-title.ts","../../../projects/lib/drawer/drawer.ts","../../../projects/lib/drawer/drawer.html","../../../projects/lib/drawer/drawer-ref.ts","../../../projects/lib/drawer/tokens/drawer-data.token.ts","../../../projects/lib/drawer/tokens/drawer-ref.token.ts","../../../projects/lib/drawer/drawer-manager.ts","../../../projects/lib/drawer/directives/drawer-content.ts","../../../projects/lib/drawer/directives/drawer-footer.ts","../../../projects/lib/drawer/directives/drawer-close.ts","../../../projects/lib/drawer/ngwr-drawer.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Marks an element as the drawer's title row. Applies the `wr-drawer__title`\n * class so the drawer's stylesheet can lay it out alongside content and\n * footer slots. Auto-assigns an `id` so the drawer panel references it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"open\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>…</div>\n * </wr-drawer>\n * ```\n */\n@Directive({\n selector: '[wrDrawerTitle]',\n host: { class: 'wr-drawer__title', '[attr.id]': 'id' },\n})\nexport class WrDrawerTitle {\n /** Generated id used by the drawer panel for `aria-labelledby`. */\n readonly id = `wr-drawer-title-${++uid}`;\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n PLATFORM_ID,\n TemplateRef,\n ViewContainerRef,\n ViewEncapsulation,\n afterEveryRender,\n contentChild,\n effect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\nimport { WrDrawerTitle } from './directives/drawer-title';\nimport type { WrDrawerPosition } from './interfaces';\n\n/**\n * Side panel that slides in from an edge of the viewport. Two-way binds\n * `open` and renders into a CDK overlay so it sits above page content.\n *\n * Compose the body with `<wrDrawerTitle>`, `<wrDrawerContent>`, and\n * `<wrDrawerFooter>` directives.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"settingsOpen\" position=\"right\" width=\"24rem\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>...</div>\n * <div wrDrawerFooter>\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * </div>\n * </wr-drawer>\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Component({\n selector: 'wr-drawer',\n templateUrl: './drawer.html',\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrDrawer {\n /** Two-way bindable open state. */\n readonly open = model<boolean>(false);\n\n /** Side the drawer slides in from. @default 'right' */\n readonly position = input<WrDrawerPosition>('right');\n\n /** Width when position is left/right. Any CSS length. @default '20rem' */\n readonly width = input<string>('20rem');\n\n /** Height when position is top/bottom. Any CSS length. @default '16rem' */\n readonly height = input<string>('16rem');\n\n /**\n * Upper cap on height (top/bottom positions). Useful for bottom sheets\n * that should grow with content up to a viewport-relative max.\n * Any CSS length. @default null (no cap)\n */\n readonly maxHeight = input<string | null>(null);\n\n /**\n * Round the leading corners — the edge facing the viewport interior.\n * Common bottom-sheet styling. @default false\n */\n readonly rounded = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Render a grab handle at the leading edge and enable swipe-to-dismiss:\n * drag the handle toward the drawer's edge (down for `bottom`, left for\n * `left`, …) and release past ~30% of the panel to close. @default false\n */\n readonly showHandle = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Pad the trailing edge with `env(safe-area-inset-*)` so content\n * doesn't sit under the iOS home indicator. @default false\n */\n readonly safeArea = input(false, { transform: coerceBooleanProperty });\n\n /** Show the dimming backdrop. @default true */\n readonly hasBackdrop = input(true, { transform: coerceBooleanProperty });\n\n /** Close when the backdrop is clicked. @default true */\n readonly closeOnBackdropClick = input(true, { transform: coerceBooleanProperty });\n\n /** Close on Escape. @default true */\n readonly closeOnEscape = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Show a dismiss (×) button in the panel's top-right corner. Set `false` when\n * the projected content supplies its own close affordance. @default true\n */\n readonly closable = input(true, { transform: coerceBooleanProperty });\n\n /** Accessible name for the dismiss button. Falls back to `drawer.close`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'drawer.close', 'Close drawer');\n\n protected readonly panelTpl = viewChild.required(TemplateRef);\n\n /**\n * A projected `[wrDrawerTitle]`, if the consumer gave one.\n *\n * The dismiss button is corner chrome positioned at a fixed\n * `inset-block-start` chosen to centre it on the TITLE's first line. With no\n * title the content starts at the top of the panel and runs underneath it: on\n * a bare `<wr-drawer><nav /></wr-drawer>` the button covered the first menu\n * row by 24×16 px, and `elementFromPoint` at the button's centre returned the\n * button, so that corner of the first item was unclickable. The panel has to\n * know, because only the panel can reserve the space.\n */\n private readonly projectedTitle = contentChild(WrDrawerTitle);\n\n protected panelClass(): string {\n const parts = ['wr-drawer__panel', `wr-drawer__panel--${this.position()}`];\n if (this.rounded()) parts.push('wr-drawer__panel--rounded');\n if (this.safeArea()) parts.push('wr-drawer__panel--safe-area');\n if (this.closable()) parts.push('wr-drawer__panel--closable');\n // The handle sits on the LEADING edge, which for `left` / `right` is a\n // vertical rail rather than a row in the column — so it leaves the flow and\n // the panel has to reserve the gutter it floats over. Only the panel can do\n // that, and only if it knows the handle is there.\n if (this.showHandle()) parts.push('wr-drawer__panel--handle');\n // Only when there is something to collide with: a closable drawer with a\n // title already clears the button, and an unclosable one has no button.\n if (this.closable() && !this.projectedTitle()) parts.push('wr-drawer__panel--untitled');\n return parts.join(' ');\n }\n\n // Swipe-to-dismiss — gated to the grab handle, so it never fights the\n // panel's own scrolling. The panel follows the finger toward the closing\n // edge and closes past ~30% of its size, otherwise snaps back.\n\n private swipeStartX = 0;\n private swipeStartY = 0;\n private swiping = false;\n\n // Pointer, not Touch. The handle has always advertised itself to a mouse with\n // `cursor: grab`, but the gesture was bound to touch events only, so on a\n // desktop it could not be dragged at all. Pointer Events cover touch, mouse and\n // pen through one path — the same idiom `wr-splitter` already uses.\n\n protected onSwipeStart(event: PointerEvent): void {\n // Ignore secondary contacts of a multi-touch gesture.\n if (!event.isPrimary) return;\n this.swipeStartX = event.clientX;\n this.swipeStartY = event.clientY;\n this.swiping = true;\n // Capture, so the drag keeps reporting once the cursor leaves the 2.5rem\n // grabber — without it a mouse drag dies the moment it slips off the handle.\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n }\n\n protected onSwipeMove(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n // Only follow the pointer when dragging toward the closing edge.\n if (delta * sign <= 0) {\n panel.style.transform = '';\n return;\n }\n panel.style.transition = 'none';\n panel.style.transform = axis === 'y' ? `translateY(${delta}px)` : `translateX(${delta}px)`;\n }\n\n /**\n * A cancelled pointer is an ABANDONED swipe, not a completed one — the system\n * took the gesture away (a call, a system gesture, an orientation change) and\n * no `pointerup` ever arrives. Routing it through `onSwipeEnd` dismissed the\n * drawer on an interruption the user did not ask for and, because the overlay\n * is disposed with the dragged offset applied, could not take back. Same rule\n * `wr-pull-to-refresh` states for `touchcancel`.\n */\n protected onSwipeCancel(panel: HTMLElement): void {\n if (!this.swiping) return;\n this.swiping = false;\n panel.style.transition = '';\n panel.style.transform = '';\n }\n\n protected onSwipeEnd(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n this.swiping = false;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n const panelSize = axis === 'y' ? panel.offsetHeight : panel.offsetWidth;\n if (delta * sign > panelSize * 0.3) {\n this.open.set(false); // keep the dragged offset as the overlay disposes\n } else {\n panel.style.transition = '';\n panel.style.transform = '';\n }\n }\n\n /** Axis + sign of the closing direction for the current position. */\n private closeAxis(): { axis: 'x' | 'y'; sign: number } {\n switch (this.position()) {\n case 'bottom':\n return { axis: 'y', sign: 1 };\n case 'top':\n return { axis: 'y', sign: -1 };\n case 'left':\n return { axis: 'x', sign: -1 };\n case 'right':\n default:\n return { axis: 'x', sign: 1 };\n }\n }\n\n private readonly overlay = inject(WR_OVERLAY);\n private readonly vcr = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private overlayRef: OverlayRef | null = null;\n private focusTrap: ConfigurableFocusTrap | null = null;\n private previouslyFocused: HTMLElement | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n afterEveryRender(() => this.syncLabel());\n this.destroyRef.onDestroy(() => this.closeOverlay());\n }\n\n /**\n * Point the panel's `aria-labelledby` at the CURRENT `[wrDrawerTitle]`.\n *\n * Re-resolved after every render rather than once when the drawer opens,\n * because the title element is projected content and can come and go while\n * the drawer stays open — an `@if` around it, or a heading that only exists\n * once the data arrives. A one-shot lookup leaves the attribute naming an\n * element that has been removed or replaced, and a dangling reference is not\n * a name: the dialog is announced as unnamed, with nothing on screen to say\n * so. A missing title clears the attribute for the same reason.\n */\n private syncLabel(): void {\n const host = this.overlayRef?.overlayElement;\n if (!host) return;\n\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n }\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n const pos = this.position();\n const isHorizontal = pos === 'left' || pos === 'right';\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [pos === 'left' ? 'left' : pos === 'right' ? 'right' : 'centerHorizontally']();\n\n if (pos === 'top') positionStrategy.top();\n else if (pos === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = this.maxHeight();\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n hasBackdrop: this.hasBackdrop(),\n backdropClass: 'wr-drawer-backdrop',\n panelClass: ['wr-drawer-overlay', `wr-drawer-overlay--${pos}`],\n scrollStrategy: this.overlay.scrollStrategies.block(),\n width: isHorizontal ? this.width() : '100vw',\n height: isHorizontal ? undefined : this.height(),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n this.previouslyFocused = active instanceof HTMLElement ? active : null;\n const host = this.overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n this.focusTrap = this.focusTrapFactory.create(host);\n void this.focusTrap.focusInitialElementWhenReady();\n }\n\n if (this.closeOnBackdropClick()) {\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.open.set(false));\n }\n\n if (this.closeOnEscape()) {\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n }\n });\n }\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n}\n","<ng-template>\n <div #panel [class]=\"panelClass()\">\n @if (showHandle()) {\n <div\n class=\"wr-drawer__handle\"\n aria-hidden=\"true\"\n (pointerdown)=\"onSwipeStart($event)\"\n (pointermove)=\"onSwipeMove($event, panel)\"\n (pointerup)=\"onSwipeEnd($event, panel)\"\n (pointercancel)=\"onSwipeCancel(panel)\"\n >\n <span class=\"wr-drawer__grabber\"></span>\n </div>\n }\n @if (closable()) {\n <button type=\"button\" class=\"wr-drawer__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"open.set(false)\">\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n <ng-content />\n </div>\n</ng-template>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDrawerManager.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the drawer's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDrawerClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = drawers.open<ChatComponent, boolean>(ChatComponent, { position: 'right' });\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the drawer closes itself.\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject(WrDrawerRef);\n *\n * send(): void {\n * this.store.send(this.draft());\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDrawerRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated drawer component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDrawerRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the drawer, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the drawer is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDrawerManager.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * readonly data = inject<ChatData>(WR_DRAWER_DATA);\n * }\n * ```\n */\nexport const WR_DRAWER_DATA = new InjectionToken<unknown>('WR_DRAWER_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDrawerRef } from '../drawer-ref';\n\n/**\n * Token exposing the open drawer's `WrDrawerRef` to components and\n * directives rendered inside it (e.g. `[wrDrawerClose]`).\n *\n * **Prefer `inject(WrDrawerRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDrawerRef, { optional: true })`\n * works for content that also renders outside a drawer, and\n * `inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef)` types the generics\n * without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDrawerClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef);\n *\n * dismiss(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DRAWER_REF = new InjectionToken<WrDrawerRef<unknown, unknown>>('WR_DRAWER_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { Location, isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Injector, PLATFORM_ID, Service, afterEveryRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, wrAppendOverlayClose } from 'ngwr/overlay';\n\nimport { WrDrawerRef } from './drawer-ref';\nimport type { WrDrawerOptions, WrDrawerPosition } from './interfaces';\nimport { WR_DRAWER_DATA, WR_DRAWER_REF } from './tokens';\n\nconst DEFAULT_POSITION: WrDrawerPosition = 'right';\nconst DEFAULT_WIDTH = '20rem';\nconst DEFAULT_HEIGHT = '16rem';\nconst BACKDROP_CLASS = 'wr-drawer-backdrop';\n\n/**\n * Opens drawer components in an isolated NGWR overlay — the programmatic\n * counterpart to `<wr-drawer [(open)]=\"…\">`.\n *\n * Use the component when the drawer is part of a template and its open state\n * is a signal you already own; use this service when the caller doesn't own\n * the markup (opening a chat panel from a toolbar action, from an effect, from\n * a route guard) or when you need the close result.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — drawers render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * `showHandle` / swipe-to-dismiss is component-only: it needs the drawer's own\n * wrapper markup, which the service path replaces with your component.\n *\n * @example\n * ```ts\n * const drawers = inject(WrDrawerManager);\n *\n * const ref = drawers.open(ChatComponent, {\n * data: { threadId },\n * position: 'right',\n * width: '28rem',\n * });\n *\n * await ref.awaitClose();\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Service()\nexport class WrDrawerManager {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly i18n = inject(WrI18n);\n private readonly location = inject(Location);\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDrawerOptions<D> = {}): WrDrawerRef<C, R> {\n const position = options.position ?? DEFAULT_POSITION;\n const isHorizontal = position === 'left' || position === 'right';\n\n // The content component is attached straight into the overlay pane, so the\n // panel styles land on the pane rather than on an inner wrapper.\n const panelClasses = [\n 'wr-drawer-overlay',\n `wr-drawer-overlay--${position}`,\n 'wr-drawer__panel',\n `wr-drawer__panel--${position}`,\n ];\n if (options.rounded) panelClasses.push('wr-drawer__panel--rounded');\n if (options.safeArea) panelClasses.push('wr-drawer__panel--safe-area');\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [position === 'left' ? 'left' : position === 'right' ? 'right' : 'centerHorizontally']();\n\n if (position === 'top') positionStrategy.top();\n else if (position === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = options.maxHeight ?? null;\n\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: options.hasBackdrop !== false,\n backdropClass: BACKDROP_CLASS,\n panelClass: panelClasses,\n width: isHorizontal ? (options.width ?? DEFAULT_WIDTH) : '100vw',\n height: isHorizontal ? undefined : (options.height ?? DEFAULT_HEIGHT),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const drawerRef = new WrDrawerRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n drawerRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DRAWER_DATA, useValue: options.data },\n { provide: WR_DRAWER_REF, useValue: drawerRef },\n // Provided as its own token as well, so drawer content can reach for\n // the familiar `inject(WrDrawerRef)` and close itself.\n { provide: WrDrawerRef, useValue: drawerRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n drawerRef.componentRef = overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss, same contract as WrDialog's `closable`.\n if (options.closable !== false) {\n host.classList.add('wr-drawer__panel--closable');\n const label = options.closeLabel ?? this.closeLabel();\n wrAppendOverlayClose(host, 'wr-drawer__close', label, () => drawerRef.close());\n }\n // Wire aria-labelledby to wrDrawerTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n //\n // And after EVERY render, not just the next one: the title belongs to the\n // caller's component, so an `@if` or a late-arriving heading can replace\n // or remove the element the attribute names. A reference to a node that is\n // no longer there is not a name — the dialog announces as unnamed — so a\n // missing title clears the attribute rather than leaving it dangling.\n const labelSync = afterEveryRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n },\n { injector: this.parentInjector }\n );\n // The hook is bound to the root injector, so it outlives the drawer unless\n // it is torn down with it. `detachments()` fires on dispose, which is the\n // one path every dismissal goes through.\n overlayRef.detachments().subscribe(() => labelSync.destroy());\n // Trap focus inside the drawer and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n drawerRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n // Overlay subscriptions complete when the overlay is disposed, so no\n // explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => drawerRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n drawerRef.close();\n }\n });\n }\n if (options.closeOnNavigation !== false) {\n this.watchNavigation(overlayRef, drawerRef);\n }\n\n return drawerRef;\n }\n\n /**\n * Tie the drawer's lifetime to the URL it was opened on — the same treatment\n * `WrDialog` gets, and for the same reason.\n *\n * Nothing else does. The overlay belongs to a root service and is dismissed\n * only by the backdrop, Escape, the appended × or an explicit `close()`, so\n * navigating away left the panel, its backdrop, its focus trap and the\n * page-wide scroll block sitting over a page the user never opened them on.\n *\n * `onUrlChange`, not `Location.subscribe()` — which is what CDK's own\n * `disposeOnNavigation` uses: `subscribe` fires on popstate alone, so an in-app\n * `router.navigate()` left the drawer standing. And `drawerRef.close()` rather\n * than disposing the overlay behind the ref's back, which would never emit\n * `closed`, never destroy the focus trap, and leave `awaitClose()` pending.\n */\n private watchNavigation<C, R>(overlayRef: OverlayRef, drawerRef: WrDrawerRef<C, R>): void {\n const stopWatching = this.location.onUrlChange(() => drawerRef.close());\n // Unhooked a microtask late, because `Location` notifies its listeners with\n // a `forEach` and unregistering splices the array it is iterating: removing\n // ours synchronously from inside the notification would shift the next entry\n // into the slot forEach has already passed, and a SECOND stacked drawer\n // would be skipped and left behind.\n overlayRef.detachments().subscribe(() => queueMicrotask(stopWatching));\n }\n\n /**\n * The dismiss button's accessible name.\n *\n * Resolved per open, not stored as a plain string at injection: this is a root\n * service, so a one-shot read — which is what `WrDialog` used to have, and moved\n * off for this reason — would run before an async catalog had loaded and then\n * freeze that answer for the life of the app. (`readI18nText` hands back a signal\n * now, so it would no longer freeze; the name still has to be pushed onto the\n * button per open either way.) `WrDialog.closeLabel()` is the matching precedent,\n * not the counter-example.\n *\n * The miss check is the point. `t()` hands back the KEY when the catalog has\n * no entry, and `WrI18n` is root-provided with an empty catalog by default —\n * so an app that never configured i18n got a button announced as\n * \"drawer.close, button\". A name WAS present, which is exactly why the axe\n * gate could not see it.\n */\n private closeLabel(): string {\n const resolved = this.i18n.t('drawer.close');\n return resolved === 'drawer.close' ? 'Close drawer' : resolved;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\n/**\n * Marks the scrollable body of the drawer. Applies the `wr-drawer__content`\n * class so the panel's flex layout can stretch it between the title and the\n * footer.\n */\n@Directive({\n selector: '[wrDrawerContent]',\n host: { class: 'wr-drawer__content' },\n})\nexport class WrDrawerContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Marks the action row pinned to the bottom of the drawer. Adds the\n * `wr-drawer__footer` class plus an alignment modifier so action buttons\n * can sit at the start, center, or end of the row.\n *\n * @example\n * ```html\n * <div wrDrawerFooter align=\"end\">\n * <wr-btn wrDrawerClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" (click)=\"save()\">Save</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDrawerFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDrawerFooter {\n /** Horizontal alignment of footer content. @default 'end' */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-drawer__footer wr-drawer__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport { WrDrawer } from '../drawer';\nimport type { WrDrawerRef } from '../drawer-ref';\nimport { WR_DRAWER_REF } from '../tokens';\n\n/**\n * Closes the parent drawer on click. Attach to any clickable element.\n *\n * Works for both drawer flavours: inside `<wr-drawer>` it clears the\n * component's `open` model, and inside a `WrDrawerManager.open()` drawer it\n * closes the ref — optionally passing a `[wrDrawerClose]` value as the close\n * result (the component flavour has no result to carry, so the value is\n * ignored there).\n *\n * @example\n * ```html\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * <wr-btn color=\"primary\" [wrDrawerClose]=\"true\">Save</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDrawerClose]',\n host: { '(click)': 'close()' },\n})\nexport class WrDrawerClose<R = unknown> {\n /**\n * Value to pass to `close()` for service-opened drawers. When unset — or\n * used as a bare attribute — the drawer closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDrawerClose',\n // A bare `wrDrawerClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly drawer = inject(WrDrawer, { optional: true });\n private readonly ref = inject<WrDrawerRef<unknown, R>>(WR_DRAWER_REF, { optional: true });\n\n protected close(): void {\n // Element injectors win, so a surrounding `<wr-drawer>` is the nearer\n // owner even when a service-opened drawer sits further up the tree.\n if (this.drawer) {\n this.drawer.open.set(false);\n return;\n }\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -518,10 +518,20 @@ class WrSelect {
518
518
  draft = signal('', /* @ts-ignore */
519
519
  ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
520
520
  /**
521
- * Show a clear-all (×) button at the end of the chip row when at
522
- * least one option is selected (multi mode only). @default true
521
+ * Show a clear (×) button once at least one option is selected.
522
+ *
523
+ * NOT multi-only, which this said for a long time and which the template
524
+ * refutes: only the button trigger gates on `isMulti()`, so the chips trigger
525
+ * AND a single `mode="search"` / `[searchable]` select carry it too. The
526
+ * wording mattered little while the default was `true`; it decides what a
527
+ * reader expects to lose now that it is not.
528
+ *
529
+ * The default changed from `true` to `false`: the affordance is opt-in, so a
530
+ * trigger that grew an × on its own no longer does — pass `clearable` to keep
531
+ * it. In `search` mode this also gates Backspace-to-clear on an empty field,
532
+ * since that key is the keyboard twin of this button. @default false
523
533
  */
524
- clearable = input(true, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
534
+ clearable = input(false, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
525
535
  /**
526
536
  * Cap on selected items (multi mode). `0` = unlimited. Once reached,
527
537
  * additional clicks on unselected options are ignored. @default 0