ngwr 7.2.0 → 7.3.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.
- package/README.md +3 -3
- package/carousel/styles/_index.scss +2 -0
- package/color-picker/styles/_index.scss +7 -0
- package/density/styles/_index.scss +10 -0
- package/drawer/styles/_index.scss +2 -0
- package/fesm2022/ngwr-carousel.mjs +45 -4
- package/fesm2022/ngwr-carousel.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +77 -5
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-density.mjs +3 -3
- package/fesm2022/ngwr-density.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +13 -3
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +66 -5
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +45 -2
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +11 -3
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text.mjs +15 -4
- package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +9 -3
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +38 -6
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +54 -2
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +11 -4
- package/fesm2022/ngwr-toolbar.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/lightbox/styles/_index.scss +2 -0
- package/llms-full.txt +673 -0
- package/llms.txt +106 -0
- package/package.json +1 -1
- package/pagination/styles/_index.scss +34 -0
- package/slider/styles/_index.scss +3 -0
- package/splitter/styles/_index.scss +3 -0
- package/table/styles/_index.scss +61 -0
- package/tabs/styles/_index.scss +24 -0
- package/toast/styles/_index.scss +2 -0
- package/toolbar/styles/_index.scss +29 -0
- package/types/ngwr-carousel.d.ts +8 -1
- package/types/ngwr-context-menu.d.ts +25 -3
- package/types/ngwr-density.d.ts +2 -2
- package/types/ngwr-drag-drop.d.ts +13 -1
- package/types/ngwr-drawer.d.ts +11 -3
- package/types/ngwr-lightbox.d.ts +5 -0
- package/types/ngwr-pagination.d.ts +7 -1
- package/types/ngwr-rotating-text.d.ts +1 -0
- package/types/ngwr-table.d.ts +7 -1
- package/types/ngwr-tabs.d.ts +6 -0
- package/types/ngwr-toolbar.d.ts +7 -1
- package/types/ngwr-version.d.ts +1 -1
package/fesm2022/ngwr-tabs.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NgTemplateOutlet } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { InjectionToken, input, viewChild, TemplateRef, inject, DestroyRef, computed, ViewEncapsulation, Component, model, contentChildren, forwardRef } from '@angular/core';
|
|
3
|
+
import { InjectionToken, input, viewChild, TemplateRef, inject, DestroyRef, computed, ViewEncapsulation, Component, model, contentChildren, signal, afterNextRender, forwardRef } from '@angular/core';
|
|
4
4
|
import { RouterLink, RouterLinkActive } from '@angular/router';
|
|
5
5
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
6
6
|
import { randomId } from 'ngwr/utils';
|
|
@@ -143,6 +143,34 @@ class WrTabs {
|
|
|
143
143
|
// Template handlers
|
|
144
144
|
stripRef = viewChild('strip', /* @ts-ignore */
|
|
145
145
|
...(ngDevMode ? [{ debugName: "stripRef" }] : /* istanbul ignore next */ []));
|
|
146
|
+
/** Whether the strip is scrolled away from its start / end — drives the edge fades. */
|
|
147
|
+
canScrollStart = signal(false, /* @ts-ignore */
|
|
148
|
+
...(ngDevMode ? [{ debugName: "canScrollStart" }] : /* istanbul ignore next */ []));
|
|
149
|
+
canScrollEnd = signal(false, /* @ts-ignore */
|
|
150
|
+
...(ngDevMode ? [{ debugName: "canScrollEnd" }] : /* istanbul ignore next */ []));
|
|
151
|
+
constructor() {
|
|
152
|
+
const destroyRef = inject(DestroyRef);
|
|
153
|
+
afterNextRender(() => {
|
|
154
|
+
this.updateFades();
|
|
155
|
+
const el = this.stripRef()?.nativeElement;
|
|
156
|
+
if (!el || typeof ResizeObserver === 'undefined')
|
|
157
|
+
return;
|
|
158
|
+
// Re-evaluate when the strip's width changes (e.g. the container narrows
|
|
159
|
+
// and the tabs start overflowing).
|
|
160
|
+
const ro = new ResizeObserver(() => this.updateFades());
|
|
161
|
+
ro.observe(el);
|
|
162
|
+
destroyRef.onDestroy(() => ro.disconnect());
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/** Recompute which edges can scroll, from the strip's scroll metrics. @internal */
|
|
166
|
+
updateFades() {
|
|
167
|
+
const el = this.stripRef()?.nativeElement;
|
|
168
|
+
if (!el)
|
|
169
|
+
return;
|
|
170
|
+
const max = el.scrollWidth - el.clientWidth;
|
|
171
|
+
this.canScrollStart.set(el.scrollLeft > 1);
|
|
172
|
+
this.canScrollEnd.set(max > 1 && el.scrollLeft < max - 1);
|
|
173
|
+
}
|
|
146
174
|
onTabClick(tab) {
|
|
147
175
|
if (tab.disabled())
|
|
148
176
|
return;
|
|
@@ -190,24 +218,28 @@ class WrTabs {
|
|
|
190
218
|
headerEl?.focus();
|
|
191
219
|
}
|
|
192
220
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrTabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
193
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WrTabs, isStandalone: true, selector: "wr-tabs", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { active: "activeChange" }, host: { classAttribute: "wr-tabs" }, providers: [
|
|
221
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WrTabs, isStandalone: true, selector: "wr-tabs", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { active: "activeChange" }, host: { properties: { "class.wr-tabs--fade-start": "canScrollStart()", "class.wr-tabs--fade-end": "canScrollEnd()" }, classAttribute: "wr-tabs" }, providers: [
|
|
194
222
|
{
|
|
195
223
|
provide: WR_TABS,
|
|
196
224
|
// eslint-disable-next-line @angular-eslint/no-forward-ref
|
|
197
225
|
useExisting: forwardRef(() => WrTabs),
|
|
198
226
|
},
|
|
199
|
-
], queries: [{ propertyName: "tabs", predicate: WrTab, isSignal: true }], viewQueries: [{ propertyName: "stripRef", first: true, predicate: ["strip"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div
|
|
227
|
+
], queries: [{ propertyName: "tabs", predicate: WrTab, isSignal: true }], viewQueries: [{ propertyName: "stripRef", first: true, predicate: ["strip"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div\n #strip\n class=\"wr-tabs__strip\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n (keydown)=\"onStripKeydown($event)\"\n (scroll)=\"updateFades()\"\n>\n @for (tab of tabs(); track tab.key()) {\n @if (tab.routerLink(); as link) {\n <a\n class=\"wr-tabs__tab\"\n role=\"tab\"\n routerLinkActive=\"wr-tabs__tab--active\"\n [attr.id]=\"headerId(tab.key())\"\n [routerLink]=\"link\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-disabled]=\"tab.disabled() ? true : null\"\n [attr.tabindex]=\"tab.disabled() ? -1 : 0\"\n >\n {{ tab.title() }}\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"wr-tabs__tab\"\n role=\"tab\"\n [attr.id]=\"headerId(tab.key())\"\n [attr.aria-controls]=\"panelId(tab.key())\"\n [attr.tabindex]=\"tab === activeTab() ? 0 : -1\"\n [class.wr-tabs__tab--active]=\"tab === activeTab()\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-selected]=\"tab === activeTab()\"\n [disabled]=\"tab.disabled()\"\n (click)=\"onTabClick(tab)\"\n >\n {{ tab.title() }}\n </button>\n }\n }\n</div>\n\n@if (!isRouter() && activeTab(); as tab) {\n <div\n class=\"wr-tabs__panel\"\n role=\"tabpanel\"\n tabindex=\"0\"\n [attr.id]=\"panelId(tab.key())\"\n [attr.aria-labelledby]=\"headerId(tab.key())\"\n >\n <ng-container [ngTemplateOutlet]=\"tab.contentTpl()\" />\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
200
228
|
}
|
|
201
229
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrTabs, decorators: [{
|
|
202
230
|
type: Component,
|
|
203
|
-
args: [{ selector: 'wr-tabs', encapsulation: ViewEncapsulation.None, host: {
|
|
231
|
+
args: [{ selector: 'wr-tabs', encapsulation: ViewEncapsulation.None, host: {
|
|
232
|
+
class: 'wr-tabs',
|
|
233
|
+
'[class.wr-tabs--fade-start]': 'canScrollStart()',
|
|
234
|
+
'[class.wr-tabs--fade-end]': 'canScrollEnd()',
|
|
235
|
+
}, imports: [NgTemplateOutlet, RouterLink, RouterLinkActive], providers: [
|
|
204
236
|
{
|
|
205
237
|
provide: WR_TABS,
|
|
206
238
|
// eslint-disable-next-line @angular-eslint/no-forward-ref
|
|
207
239
|
useExisting: forwardRef(() => WrTabs),
|
|
208
240
|
},
|
|
209
|
-
], template: "<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div
|
|
210
|
-
}], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }, { type: i0.Output, args: ["activeChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => WrTab), { isSignal: true }] }], stripRef: [{ type: i0.ViewChild, args: ['strip', { isSignal: true }] }] } });
|
|
241
|
+
], template: "<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div\n #strip\n class=\"wr-tabs__strip\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n (keydown)=\"onStripKeydown($event)\"\n (scroll)=\"updateFades()\"\n>\n @for (tab of tabs(); track tab.key()) {\n @if (tab.routerLink(); as link) {\n <a\n class=\"wr-tabs__tab\"\n role=\"tab\"\n routerLinkActive=\"wr-tabs__tab--active\"\n [attr.id]=\"headerId(tab.key())\"\n [routerLink]=\"link\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-disabled]=\"tab.disabled() ? true : null\"\n [attr.tabindex]=\"tab.disabled() ? -1 : 0\"\n >\n {{ tab.title() }}\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"wr-tabs__tab\"\n role=\"tab\"\n [attr.id]=\"headerId(tab.key())\"\n [attr.aria-controls]=\"panelId(tab.key())\"\n [attr.tabindex]=\"tab === activeTab() ? 0 : -1\"\n [class.wr-tabs__tab--active]=\"tab === activeTab()\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-selected]=\"tab === activeTab()\"\n [disabled]=\"tab.disabled()\"\n (click)=\"onTabClick(tab)\"\n >\n {{ tab.title() }}\n </button>\n }\n }\n</div>\n\n@if (!isRouter() && activeTab(); as tab) {\n <div\n class=\"wr-tabs__panel\"\n role=\"tabpanel\"\n tabindex=\"0\"\n [attr.id]=\"panelId(tab.key())\"\n [attr.aria-labelledby]=\"headerId(tab.key())\"\n >\n <ng-container [ngTemplateOutlet]=\"tab.contentTpl()\" />\n </div>\n}\n" }]
|
|
242
|
+
}], ctorParameters: () => [], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }, { type: i0.Output, args: ["activeChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => WrTab), { isSignal: true }] }], stripRef: [{ type: i0.ViewChild, args: ['strip', { isSignal: true }] }] } });
|
|
211
243
|
|
|
212
244
|
/**
|
|
213
245
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-tabs.mjs","sources":["../../../projects/lib/tabs/tokens/tabs.token.ts","../../../projects/lib/tabs/tab.ts","../../../projects/lib/tabs/tabs.ts","../../../projects/lib/tabs/tabs.html","../../../projects/lib/tabs/ngwr-tabs.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 { InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Contract a `<wr-tab>` uses to talk to its parent `<wr-tabs>`.\n *\n * @internal\n */\nexport interface WrTabsContext {\n /** Currently active tab key (component-managed only). */\n readonly active: Signal<string | null>;\n /** Activate a tab by key (component-managed only). */\n activate(key: string): void;\n /** Register a child tab so the parent can pick a default. */\n register(tab: { key: string; routerLink: unknown }): void;\n /** Unregister on destroy. */\n unregister(key: string): void;\n}\n\n/**\n * Token a `<wr-tab>` injects to register itself with — and read the active\n * key from — its parent `<wr-tabs>` host.\n *\n * @internal\n */\nexport const WR_TABS = new InjectionToken<WrTabsContext>('WR_TABS');\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 { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n DestroyRef,\n TemplateRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n viewChild,\n} from '@angular/core';\n\nimport { randomId } from 'ngwr/utils';\n\nimport { WR_TABS } from './tokens';\n\n/**\n * Single tab. Two modes, decided by inputs:\n *\n * - **Content tab** — projected children render in the parent's content\n * panel when this tab is active.\n * - **Router tab** — set `routerLink` and the tab becomes a link; the\n * parent skips its content panel and the consumer drops a\n * `<router-outlet>` below the tab strip.\n */\n@Component({\n selector: 'wr-tab',\n template: `<ng-template><ng-content /></ng-template>`,\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrTab {\n /** Visible label on the tab strip. */\n readonly title = input.required<string>();\n\n /**\n * Stable identifier used by the parent to track the active tab.\n * Auto-generated if omitted.\n */\n readonly key = input<string>(randomId('wr-tab'));\n\n /** Router target — when set, the tab becomes a `[routerLink]` link. */\n readonly routerLink = input<string | readonly string[] | null>(null);\n\n /** Disable the tab. */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Tab content template; portaled into the parent's panel area. @internal */\n readonly contentTpl = viewChild.required(TemplateRef);\n\n private readonly parent = inject(WR_TABS, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly isRouter = computed(() => this.routerLink() !== null);\n\n constructor() {\n if (this.parent) {\n this.parent.register({ key: this.key(), routerLink: this.routerLink() });\n this.destroyRef.onDestroy(() => this.parent?.unregister(this.key()));\n }\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 { NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n type ElementRef,\n ViewEncapsulation,\n computed,\n contentChildren,\n forwardRef,\n input,\n model,\n viewChild,\n} from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { WrTab } from './tab';\nimport { WR_TABS, type WrTabsContext } from './tokens';\n\n/**\n * Tabbed container. Two modes depending on the child `<wr-tab>`\n * definitions:\n *\n * - **Content** — children project body content; the parent renders an\n * active-tab panel automatically.\n * - **Router** — any child with `routerLink` switches the whole strip\n * into router mode; the parent skips its panel so the consumer can\n * drop a `<router-outlet>` after it.\n *\n * @example\n * ```html\n * <!-- content tabs -->\n * <wr-tabs [(active)]=\"key\">\n * <wr-tab key=\"one\" title=\"One\">First panel</wr-tab>\n * <wr-tab key=\"two\" title=\"Two\">Second panel</wr-tab>\n * </wr-tabs>\n *\n * <!-- router tabs -->\n * <wr-tabs>\n * <wr-tab title=\"Overview\" routerLink=\"overview\" />\n * <wr-tab title=\"Details\" routerLink=\"details\" />\n * </wr-tabs>\n * <router-outlet />\n * ```\n *\n * @see https://ngwr.dev/components/tabs\n */\n@Component({\n selector: 'wr-tabs',\n templateUrl: './tabs.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-tabs' },\n imports: [NgTemplateOutlet, RouterLink, RouterLinkActive],\n providers: [\n {\n provide: WR_TABS,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => WrTabs),\n },\n ],\n})\nexport class WrTabs implements WrTabsContext {\n /** Two-way bindable active tab key (content mode). */\n readonly active = model<string | null>(null);\n\n /** Visual size variant. */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n\n protected readonly tabs = contentChildren(WrTab);\n\n /** When any child has a routerLink, the whole strip switches to router mode. */\n protected readonly isRouter = computed(() => this.tabs().some(t => t.routerLink() !== null));\n\n /** Content-mode: the tab whose key matches `active()` (or the first tab if none yet). */\n protected readonly activeTab = computed(() => {\n const key = this.active();\n const tabs = this.tabs();\n if (tabs.length === 0) return null;\n return tabs.find(t => t.key() === key) ?? tabs[0];\n });\n\n // WrTabsContext\n\n activate(key: string): void {\n this.active.set(key);\n }\n\n register({ key }: { key: string; routerLink: unknown }): void {\n if (this.active() === null) this.active.set(key);\n }\n\n unregister(): void {\n // No-op: contentChildren handles removal.\n }\n\n // Template handlers\n\n protected readonly stripRef = viewChild<ElementRef<HTMLElement>>('strip');\n\n protected onTabClick(tab: WrTab): void {\n if (tab.disabled()) return;\n if (!this.isRouter()) this.activate(tab.key());\n }\n\n /** Header id for `aria-labelledby` on the panel. @internal */\n headerId(key: string): string {\n return `wr-tab-${key}-header`;\n }\n\n /** Panel id for `aria-controls` on the tab header. @internal */\n panelId(key: string): string {\n return `wr-tab-${key}-panel`;\n }\n\n /** ArrowLeft/Right/Home/End keyboard navigation on the tab strip. */\n protected onStripKeydown(event: KeyboardEvent): void {\n const tabs = this.tabs().filter(t => !t.disabled());\n if (tabs.length === 0) return;\n const active = this.activeTab();\n const idx = active ? tabs.indexOf(active) : -1;\n let nextIdx: number;\n\n switch (event.key) {\n case 'ArrowRight':\n nextIdx = idx < tabs.length - 1 ? idx + 1 : 0;\n break;\n case 'ArrowLeft':\n nextIdx = idx > 0 ? idx - 1 : tabs.length - 1;\n break;\n case 'Home':\n nextIdx = 0;\n break;\n case 'End':\n nextIdx = tabs.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const next = tabs[nextIdx];\n if (!this.isRouter()) this.activate(next.key());\n // Move focus to the corresponding header element.\n const headerEl = this.stripRef()?.nativeElement.querySelector<HTMLElement>(\n `#${CSS.escape(this.headerId(next.key()))}`\n );\n headerEl?.focus();\n }\n}\n","<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div #strip class=\"wr-tabs__strip\" role=\"tablist\" aria-orientation=\"horizontal\" (keydown)=\"onStripKeydown($event)\">\n @for (tab of tabs(); track tab.key()) {\n @if (tab.routerLink(); as link) {\n <a\n class=\"wr-tabs__tab\"\n role=\"tab\"\n routerLinkActive=\"wr-tabs__tab--active\"\n [attr.id]=\"headerId(tab.key())\"\n [routerLink]=\"link\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-disabled]=\"tab.disabled() ? true : null\"\n [attr.tabindex]=\"tab.disabled() ? -1 : 0\"\n >\n {{ tab.title() }}\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"wr-tabs__tab\"\n role=\"tab\"\n [attr.id]=\"headerId(tab.key())\"\n [attr.aria-controls]=\"panelId(tab.key())\"\n [attr.tabindex]=\"tab === activeTab() ? 0 : -1\"\n [class.wr-tabs__tab--active]=\"tab === activeTab()\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-selected]=\"tab === activeTab()\"\n [disabled]=\"tab.disabled()\"\n (click)=\"onTabClick(tab)\"\n >\n {{ tab.title() }}\n </button>\n }\n }\n</div>\n\n@if (!isRouter() && activeTab(); as tab) {\n <div\n class=\"wr-tabs__panel\"\n role=\"tabpanel\"\n tabindex=\"0\"\n [attr.id]=\"panelId(tab.key())\"\n [attr.aria-labelledby]=\"headerId(tab.key())\"\n >\n <ng-container [ngTemplateOutlet]=\"tab.contentTpl()\" />\n </div>\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-tabs.mjs","sources":["../../../projects/lib/tabs/tokens/tabs.token.ts","../../../projects/lib/tabs/tab.ts","../../../projects/lib/tabs/tabs.ts","../../../projects/lib/tabs/tabs.html","../../../projects/lib/tabs/ngwr-tabs.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 { InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Contract a `<wr-tab>` uses to talk to its parent `<wr-tabs>`.\n *\n * @internal\n */\nexport interface WrTabsContext {\n /** Currently active tab key (component-managed only). */\n readonly active: Signal<string | null>;\n /** Activate a tab by key (component-managed only). */\n activate(key: string): void;\n /** Register a child tab so the parent can pick a default. */\n register(tab: { key: string; routerLink: unknown }): void;\n /** Unregister on destroy. */\n unregister(key: string): void;\n}\n\n/**\n * Token a `<wr-tab>` injects to register itself with — and read the active\n * key from — its parent `<wr-tabs>` host.\n *\n * @internal\n */\nexport const WR_TABS = new InjectionToken<WrTabsContext>('WR_TABS');\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 { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n DestroyRef,\n TemplateRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n viewChild,\n} from '@angular/core';\n\nimport { randomId } from 'ngwr/utils';\n\nimport { WR_TABS } from './tokens';\n\n/**\n * Single tab. Two modes, decided by inputs:\n *\n * - **Content tab** — projected children render in the parent's content\n * panel when this tab is active.\n * - **Router tab** — set `routerLink` and the tab becomes a link; the\n * parent skips its content panel and the consumer drops a\n * `<router-outlet>` below the tab strip.\n */\n@Component({\n selector: 'wr-tab',\n template: `<ng-template><ng-content /></ng-template>`,\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrTab {\n /** Visible label on the tab strip. */\n readonly title = input.required<string>();\n\n /**\n * Stable identifier used by the parent to track the active tab.\n * Auto-generated if omitted.\n */\n readonly key = input<string>(randomId('wr-tab'));\n\n /** Router target — when set, the tab becomes a `[routerLink]` link. */\n readonly routerLink = input<string | readonly string[] | null>(null);\n\n /** Disable the tab. */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Tab content template; portaled into the parent's panel area. @internal */\n readonly contentTpl = viewChild.required(TemplateRef);\n\n private readonly parent = inject(WR_TABS, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly isRouter = computed(() => this.routerLink() !== null);\n\n constructor() {\n if (this.parent) {\n this.parent.register({ key: this.key(), routerLink: this.routerLink() });\n this.destroyRef.onDestroy(() => this.parent?.unregister(this.key()));\n }\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 { NgTemplateOutlet } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n type ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n contentChildren,\n forwardRef,\n inject,\n input,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { WrTab } from './tab';\nimport { WR_TABS, type WrTabsContext } from './tokens';\n\n/**\n * Tabbed container. Two modes depending on the child `<wr-tab>`\n * definitions:\n *\n * - **Content** — children project body content; the parent renders an\n * active-tab panel automatically.\n * - **Router** — any child with `routerLink` switches the whole strip\n * into router mode; the parent skips its panel so the consumer can\n * drop a `<router-outlet>` after it.\n *\n * @example\n * ```html\n * <!-- content tabs -->\n * <wr-tabs [(active)]=\"key\">\n * <wr-tab key=\"one\" title=\"One\">First panel</wr-tab>\n * <wr-tab key=\"two\" title=\"Two\">Second panel</wr-tab>\n * </wr-tabs>\n *\n * <!-- router tabs -->\n * <wr-tabs>\n * <wr-tab title=\"Overview\" routerLink=\"overview\" />\n * <wr-tab title=\"Details\" routerLink=\"details\" />\n * </wr-tabs>\n * <router-outlet />\n * ```\n *\n * @see https://ngwr.dev/components/tabs\n */\n@Component({\n selector: 'wr-tabs',\n templateUrl: './tabs.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-tabs',\n '[class.wr-tabs--fade-start]': 'canScrollStart()',\n '[class.wr-tabs--fade-end]': 'canScrollEnd()',\n },\n imports: [NgTemplateOutlet, RouterLink, RouterLinkActive],\n providers: [\n {\n provide: WR_TABS,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => WrTabs),\n },\n ],\n})\nexport class WrTabs implements WrTabsContext {\n /** Two-way bindable active tab key (content mode). */\n readonly active = model<string | null>(null);\n\n /** Visual size variant. */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n\n protected readonly tabs = contentChildren(WrTab);\n\n /** When any child has a routerLink, the whole strip switches to router mode. */\n protected readonly isRouter = computed(() => this.tabs().some(t => t.routerLink() !== null));\n\n /** Content-mode: the tab whose key matches `active()` (or the first tab if none yet). */\n protected readonly activeTab = computed(() => {\n const key = this.active();\n const tabs = this.tabs();\n if (tabs.length === 0) return null;\n return tabs.find(t => t.key() === key) ?? tabs[0];\n });\n\n // WrTabsContext\n\n activate(key: string): void {\n this.active.set(key);\n }\n\n register({ key }: { key: string; routerLink: unknown }): void {\n if (this.active() === null) this.active.set(key);\n }\n\n unregister(): void {\n // No-op: contentChildren handles removal.\n }\n\n // Template handlers\n\n protected readonly stripRef = viewChild<ElementRef<HTMLElement>>('strip');\n\n /** Whether the strip is scrolled away from its start / end — drives the edge fades. */\n protected readonly canScrollStart = signal(false);\n protected readonly canScrollEnd = signal(false);\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n afterNextRender(() => {\n this.updateFades();\n const el = this.stripRef()?.nativeElement;\n if (!el || typeof ResizeObserver === 'undefined') return;\n // Re-evaluate when the strip's width changes (e.g. the container narrows\n // and the tabs start overflowing).\n const ro = new ResizeObserver(() => this.updateFades());\n ro.observe(el);\n destroyRef.onDestroy(() => ro.disconnect());\n });\n }\n\n /** Recompute which edges can scroll, from the strip's scroll metrics. @internal */\n protected updateFades(): void {\n const el = this.stripRef()?.nativeElement;\n if (!el) return;\n const max = el.scrollWidth - el.clientWidth;\n this.canScrollStart.set(el.scrollLeft > 1);\n this.canScrollEnd.set(max > 1 && el.scrollLeft < max - 1);\n }\n\n protected onTabClick(tab: WrTab): void {\n if (tab.disabled()) return;\n if (!this.isRouter()) this.activate(tab.key());\n }\n\n /** Header id for `aria-labelledby` on the panel. @internal */\n headerId(key: string): string {\n return `wr-tab-${key}-header`;\n }\n\n /** Panel id for `aria-controls` on the tab header. @internal */\n panelId(key: string): string {\n return `wr-tab-${key}-panel`;\n }\n\n /** ArrowLeft/Right/Home/End keyboard navigation on the tab strip. */\n protected onStripKeydown(event: KeyboardEvent): void {\n const tabs = this.tabs().filter(t => !t.disabled());\n if (tabs.length === 0) return;\n const active = this.activeTab();\n const idx = active ? tabs.indexOf(active) : -1;\n let nextIdx: number;\n\n switch (event.key) {\n case 'ArrowRight':\n nextIdx = idx < tabs.length - 1 ? idx + 1 : 0;\n break;\n case 'ArrowLeft':\n nextIdx = idx > 0 ? idx - 1 : tabs.length - 1;\n break;\n case 'Home':\n nextIdx = 0;\n break;\n case 'End':\n nextIdx = tabs.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const next = tabs[nextIdx];\n if (!this.isRouter()) this.activate(next.key());\n // Move focus to the corresponding header element.\n const headerEl = this.stripRef()?.nativeElement.querySelector<HTMLElement>(\n `#${CSS.escape(this.headerId(next.key()))}`\n );\n headerEl?.focus();\n }\n}\n","<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div\n #strip\n class=\"wr-tabs__strip\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n (keydown)=\"onStripKeydown($event)\"\n (scroll)=\"updateFades()\"\n>\n @for (tab of tabs(); track tab.key()) {\n @if (tab.routerLink(); as link) {\n <a\n class=\"wr-tabs__tab\"\n role=\"tab\"\n routerLinkActive=\"wr-tabs__tab--active\"\n [attr.id]=\"headerId(tab.key())\"\n [routerLink]=\"link\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-disabled]=\"tab.disabled() ? true : null\"\n [attr.tabindex]=\"tab.disabled() ? -1 : 0\"\n >\n {{ tab.title() }}\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"wr-tabs__tab\"\n role=\"tab\"\n [attr.id]=\"headerId(tab.key())\"\n [attr.aria-controls]=\"panelId(tab.key())\"\n [attr.tabindex]=\"tab === activeTab() ? 0 : -1\"\n [class.wr-tabs__tab--active]=\"tab === activeTab()\"\n [class.wr-tabs__tab--disabled]=\"tab.disabled()\"\n [attr.aria-selected]=\"tab === activeTab()\"\n [disabled]=\"tab.disabled()\"\n (click)=\"onTabClick(tab)\"\n >\n {{ tab.title() }}\n </button>\n }\n }\n</div>\n\n@if (!isRouter() && activeTab(); as tab) {\n <div\n class=\"wr-tabs__panel\"\n role=\"tabpanel\"\n tabindex=\"0\"\n [attr.id]=\"panelId(tab.key())\"\n [attr.aria-labelledby]=\"headerId(tab.key())\"\n >\n <ng-container [ngTemplateOutlet]=\"tab.contentTpl()\" />\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/fesm2022/ngwr-toast.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComponentPortal } from '@angular/cdk/portal';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, output, signal, computed, ViewEncapsulation, Component,
|
|
3
|
+
import { input, output, signal, computed, inject, ElementRef, ViewEncapsulation, Component, DestroyRef, InjectionToken, Service, makeEnvironmentProviders } from '@angular/core';
|
|
4
4
|
import { WR_OVERLAY } from 'ngwr/overlay';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -64,18 +64,70 @@ class WrToastItem {
|
|
|
64
64
|
// Clipboard unavailable (insecure context / permission denied) — silent.
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
// Swipe-sideways-to-dismiss. The toast follows the finger and fades; releasing
|
|
68
|
+
// past 40% of its width emits `dismissed`, otherwise it snaps back.
|
|
69
|
+
elRef = inject(ElementRef);
|
|
70
|
+
swipeStartX = 0;
|
|
71
|
+
swipeWidth = 0;
|
|
72
|
+
swipeX = signal(0, /* @ts-ignore */
|
|
73
|
+
...(ngDevMode ? [{ debugName: "swipeX" }] : /* istanbul ignore next */ []));
|
|
74
|
+
swiping = signal(false, /* @ts-ignore */
|
|
75
|
+
...(ngDevMode ? [{ debugName: "swiping" }] : /* istanbul ignore next */ []));
|
|
76
|
+
swipeTransform = computed(() => (this.swipeX() === 0 ? null : `translateX(${this.swipeX()}px)`), /* @ts-ignore */
|
|
77
|
+
...(ngDevMode ? [{ debugName: "swipeTransform" }] : /* istanbul ignore next */ []));
|
|
78
|
+
swipeOpacity = computed(() => {
|
|
79
|
+
const dist = Math.abs(this.swipeX());
|
|
80
|
+
return dist === 0 ? null : Math.max(0, 1 - dist / (this.swipeWidth || 1));
|
|
81
|
+
}, /* @ts-ignore */
|
|
82
|
+
...(ngDevMode ? [{ debugName: "swipeOpacity" }] : /* istanbul ignore next */ []));
|
|
83
|
+
onSwipeStart(event) {
|
|
84
|
+
if (!this.dismissible())
|
|
85
|
+
return;
|
|
86
|
+
const touch = event.touches[0];
|
|
87
|
+
if (!touch)
|
|
88
|
+
return;
|
|
89
|
+
this.swipeStartX = touch.clientX;
|
|
90
|
+
this.swipeWidth = this.elRef.nativeElement.offsetWidth;
|
|
91
|
+
this.swiping.set(true);
|
|
92
|
+
}
|
|
93
|
+
onSwipeMove(event) {
|
|
94
|
+
if (!this.swiping())
|
|
95
|
+
return;
|
|
96
|
+
const touch = event.touches[0];
|
|
97
|
+
if (!touch)
|
|
98
|
+
return;
|
|
99
|
+
this.swipeX.set(touch.clientX - this.swipeStartX);
|
|
100
|
+
}
|
|
101
|
+
onSwipeEnd() {
|
|
102
|
+
if (!this.swiping())
|
|
103
|
+
return;
|
|
104
|
+
this.swiping.set(false);
|
|
105
|
+
if (Math.abs(this.swipeX()) > (this.swipeWidth || 0) * 0.4) {
|
|
106
|
+
this.dismissed.emit();
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.swipeX.set(0);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
67
112
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrToastItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
68
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WrToastItem, isStandalone: true, selector: "wr-toast", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, showProgress: { classPropertyName: "showProgress", publicName: "showProgress", isSignal: true, isRequired: false, transformFunction: null }, showCopy: { classPropertyName: "showCopy", publicName: "showCopy", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dismissed: "dismissed", pauseRequested: "pauseRequested", resumeRequested: "resumeRequested" }, host: { listeners: { "mouseenter": "pauseRequested.emit()", "mouseleave": "resumeRequested.emit()" }, properties: { "class": "classes()", "style.--wr-toast-duration": "durationMs()", "attr.role": "liveRole()", "attr.aria-live": "liveLevel()" } }, ngImport: i0, template: "<div class=\"wr-toast__body\">\n @if (title(); as text) {\n <p class=\"wr-toast__title\">{{ text }}</p>\n }\n <p class=\"wr-toast__message\">{{ message() }}</p>\n</div>\n\n<div class=\"wr-toast__actions\">\n @if (showCopy()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"justCopied() ? labels().copied : labels().copy\"\n [title]=\"justCopied() ? labels().copied : labels().copy\"\n (click)=\"onCopy()\"\n >\n @if (justCopied()) {\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=\"M20 6 9 17l-5-5\" />\n </svg>\n } @else {\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 <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n }\n </button>\n }\n\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"labels().close\"\n [title]=\"labels().close\"\n (click)=\"dismissed.emit()\"\n >\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</div>\n\n@if (progressVisible()) {\n <span class=\"wr-toast__progress\" aria-hidden=\"true\"></span>\n}\n", encapsulation: i0.ViewEncapsulation.None });
|
|
113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WrToastItem, isStandalone: true, selector: "wr-toast", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, showProgress: { classPropertyName: "showProgress", publicName: "showProgress", isSignal: true, isRequired: false, transformFunction: null }, showCopy: { classPropertyName: "showCopy", publicName: "showCopy", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dismissed: "dismissed", pauseRequested: "pauseRequested", resumeRequested: "resumeRequested" }, host: { listeners: { "mouseenter": "pauseRequested.emit()", "mouseleave": "resumeRequested.emit()", "touchstart": "onSwipeStart($event)", "touchmove": "onSwipeMove($event)", "touchend": "onSwipeEnd()", "touchcancel": "onSwipeEnd()" }, properties: { "class": "classes()", "style.--wr-toast-duration": "durationMs()", "style.transform": "swipeTransform()", "style.opacity": "swipeOpacity()", "style.transition": "swiping() ? \"none\" : null", "attr.role": "liveRole()", "attr.aria-live": "liveLevel()" } }, ngImport: i0, template: "<div class=\"wr-toast__body\">\n @if (title(); as text) {\n <p class=\"wr-toast__title\">{{ text }}</p>\n }\n <p class=\"wr-toast__message\">{{ message() }}</p>\n</div>\n\n<div class=\"wr-toast__actions\">\n @if (showCopy()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"justCopied() ? labels().copied : labels().copy\"\n [title]=\"justCopied() ? labels().copied : labels().copy\"\n (click)=\"onCopy()\"\n >\n @if (justCopied()) {\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=\"M20 6 9 17l-5-5\" />\n </svg>\n } @else {\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 <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n }\n </button>\n }\n\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"labels().close\"\n [title]=\"labels().close\"\n (click)=\"dismissed.emit()\"\n >\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</div>\n\n@if (progressVisible()) {\n <span class=\"wr-toast__progress\" aria-hidden=\"true\"></span>\n}\n", encapsulation: i0.ViewEncapsulation.None });
|
|
69
114
|
}
|
|
70
115
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrToastItem, decorators: [{
|
|
71
116
|
type: Component,
|
|
72
117
|
args: [{ selector: 'wr-toast', encapsulation: ViewEncapsulation.None, host: {
|
|
73
118
|
'[class]': 'classes()',
|
|
74
119
|
'[style.--wr-toast-duration]': 'durationMs()',
|
|
120
|
+
'[style.transform]': 'swipeTransform()',
|
|
121
|
+
'[style.opacity]': 'swipeOpacity()',
|
|
122
|
+
'[style.transition]': 'swiping() ? "none" : null',
|
|
75
123
|
'[attr.role]': 'liveRole()',
|
|
76
124
|
'[attr.aria-live]': 'liveLevel()',
|
|
77
125
|
'(mouseenter)': 'pauseRequested.emit()',
|
|
78
126
|
'(mouseleave)': 'resumeRequested.emit()',
|
|
127
|
+
'(touchstart)': 'onSwipeStart($event)',
|
|
128
|
+
'(touchmove)': 'onSwipeMove($event)',
|
|
129
|
+
'(touchend)': 'onSwipeEnd()',
|
|
130
|
+
'(touchcancel)': 'onSwipeEnd()',
|
|
79
131
|
}, template: "<div class=\"wr-toast__body\">\n @if (title(); as text) {\n <p class=\"wr-toast__title\">{{ text }}</p>\n }\n <p class=\"wr-toast__message\">{{ message() }}</p>\n</div>\n\n<div class=\"wr-toast__actions\">\n @if (showCopy()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"justCopied() ? labels().copied : labels().copy\"\n [title]=\"justCopied() ? labels().copied : labels().copy\"\n (click)=\"onCopy()\"\n >\n @if (justCopied()) {\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=\"M20 6 9 17l-5-5\" />\n </svg>\n } @else {\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 <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n }\n </button>\n }\n\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"labels().close\"\n [title]=\"labels().close\"\n (click)=\"dismissed.emit()\"\n >\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</div>\n\n@if (progressVisible()) {\n <span class=\"wr-toast__progress\" aria-hidden=\"true\"></span>\n}\n" }]
|
|
80
132
|
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], showProgress: [{ type: i0.Input, args: [{ isSignal: true, alias: "showProgress", required: false }] }], showCopy: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCopy", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: true }] }], dismissed: [{ type: i0.Output, args: ["dismissed"] }], pauseRequested: [{ type: i0.Output, args: ["pauseRequested"] }], resumeRequested: [{ type: i0.Output, args: ["resumeRequested"] }] } });
|
|
81
133
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-toast.mjs","sources":["../../../projects/lib/toast/toast-item.ts","../../../projects/lib/toast/toast-item.html","../../../projects/lib/toast/toast-host.ts","../../../projects/lib/toast/toast-host.html","../../../projects/lib/toast/toast-ref.ts","../../../projects/lib/toast/default-toast-config.ts","../../../projects/lib/toast/tokens/toast-config.token.ts","../../../projects/lib/toast/services/toast.ts","../../../projects/lib/toast/provide-wr-toast-config.ts","../../../projects/lib/toast/ngwr-toast.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 { Component, ViewEncapsulation, computed, input, output, signal } from '@angular/core';\n\nimport type { WrToastConfig, WrToastType } from './interfaces';\n\n/**\n * One toast row inside the toast host. Not used directly — see\n * `WrToast.show()`.\n *\n * @internal\n */\n@Component({\n selector: 'wr-toast',\n templateUrl: './toast-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style.--wr-toast-duration]': 'durationMs()',\n '[attr.role]': 'liveRole()',\n '[attr.aria-live]': 'liveLevel()',\n '(mouseenter)': 'pauseRequested.emit()',\n '(mouseleave)': 'resumeRequested.emit()',\n },\n})\nexport class WrToastItem {\n readonly type = input<WrToastType>('info');\n readonly title = input<string | null>(null);\n readonly message = input.required<string>();\n readonly dismissible = input<boolean>(true);\n readonly showProgress = input<boolean>(false);\n readonly showCopy = input<boolean>(false);\n /** Auto-dismiss duration in ms — used to scale the progress bar. `0` hides it. */\n readonly duration = input<number>(0);\n readonly labels = input.required<WrToastConfig['labels']>();\n\n readonly dismissed = output<void>();\n readonly pauseRequested = output<void>();\n readonly resumeRequested = output<void>();\n\n /** True for ~1.5s after a successful copy; flips the icon to a check. */\n protected readonly justCopied = signal(false);\n private copyResetTimer: ReturnType<typeof setTimeout> | null = null;\n\n protected readonly classes = computed(() => `wr-toast wr-toast--${this.type()}`);\n\n /** Escalate to `alert`/`assertive` for danger/warning toasts. */\n protected readonly liveRole = computed(() => (this.type() === 'danger' ? 'alert' : 'status'));\n protected readonly liveLevel = computed(() =>\n this.type() === 'danger' || this.type() === 'warning' ? 'assertive' : 'polite'\n );\n\n /** Inline CSS value for `--wr-toast-duration`. */\n protected readonly durationMs = computed(() => `${this.duration()}ms`);\n\n protected readonly progressVisible = computed(() => this.showProgress() && this.duration() > 0);\n\n protected async onCopy(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.message());\n this.justCopied.set(true);\n if (this.copyResetTimer) clearTimeout(this.copyResetTimer);\n this.copyResetTimer = setTimeout(() => this.justCopied.set(false), 1500);\n } catch {\n // Clipboard unavailable (insecure context / permission denied) — silent.\n }\n }\n}\n","<div class=\"wr-toast__body\">\n @if (title(); as text) {\n <p class=\"wr-toast__title\">{{ text }}</p>\n }\n <p class=\"wr-toast__message\">{{ message() }}</p>\n</div>\n\n<div class=\"wr-toast__actions\">\n @if (showCopy()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"justCopied() ? labels().copied : labels().copy\"\n [title]=\"justCopied() ? labels().copied : labels().copy\"\n (click)=\"onCopy()\"\n >\n @if (justCopied()) {\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=\"M20 6 9 17l-5-5\" />\n </svg>\n } @else {\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 <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n }\n </button>\n }\n\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"labels().close\"\n [title]=\"labels().close\"\n (click)=\"dismissed.emit()\"\n >\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</div>\n\n@if (progressVisible()) {\n <span class=\"wr-toast__progress\" aria-hidden=\"true\"></span>\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 { Component, DestroyRef, ViewEncapsulation, computed, inject, input, output, signal } from '@angular/core';\n\nimport type { WrToastConfig, WrToastMode, WrToastOptions, WrToastPosition } from './interfaces';\nimport { WrToastItem } from './toast-item';\n\n/** ms before a mouseleave actually collapses the stack. Buffers the cursor\n * briefly leaving the host as toasts reflow underneath it. */\nconst COLLAPSE_DELAY_MS = 120;\n\n/** Active entry pushed by the service — adds the bookkeeping fields the host renders. */\ntype ActiveToast = WrToastOptions & {\n readonly id: number;\n readonly resolvedDuration: number;\n};\n\n/**\n * Internal host that lives inside the toast overlay and renders the\n * active stack. Owned by `WrToast`.\n *\n * @internal\n */\n@Component({\n selector: 'wr-toast-host',\n templateUrl: './toast-host.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n role: 'region',\n 'aria-label': 'Notifications',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave()',\n },\n imports: [WrToastItem],\n})\nexport class WrToastHost {\n readonly position = input<WrToastPosition>('top-end');\n readonly config = input.required<WrToastConfig>();\n /** Layout mode. @default 'stack' (Sonner-style; hover to fan out) */\n readonly mode = input<WrToastMode>('stack');\n\n /** @internal — hover toggles this in stack mode. */\n protected readonly expanded = signal(false);\n\n private readonly destroyRef = inject(DestroyRef);\n private collapseTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n this.destroyRef.onDestroy(() => this.clearCollapseTimer());\n }\n\n /** @internal */\n protected onMouseEnter(): void {\n this.clearCollapseTimer();\n this.expanded.set(true);\n }\n\n /** @internal — delay the collapse so cursor briefly slipping off the host\n * during a layout reflow doesn't cause a flicker. */\n protected onMouseLeave(): void {\n this.clearCollapseTimer();\n this.collapseTimer = setTimeout(() => {\n this.expanded.set(false);\n this.collapseTimer = null;\n }, COLLAPSE_DELAY_MS);\n }\n\n private clearCollapseTimer(): void {\n if (this.collapseTimer !== null) {\n clearTimeout(this.collapseTimer);\n this.collapseTimer = null;\n }\n }\n\n /** @internal — pushed by the service. */\n readonly toasts = signal<readonly ActiveToast[]>([]);\n\n /** @internal — service listens to update its internal state. */\n readonly dismissed = output<number>();\n readonly pauseRequested = output<number>();\n readonly resumeRequested = output<number>();\n readonly dismissAllRequested = output<void>();\n\n protected readonly classes = computed(() => {\n const parts = ['wr-toast-host', `wr-toast-host--${this.position()}`, `wr-toast-host--${this.mode()}`];\n if (this.mode() === 'stack' && this.expanded()) parts.push('wr-toast-host--expanded');\n return parts.join(' ');\n });\n\n /** Distance from the front of the stack (0 = newest / fully visible). */\n protected stackIndex(i: number): number {\n return this.toasts().length - 1 - i;\n }\n\n protected readonly closeAllVisible = computed(() => {\n const cfg = this.config();\n // In stack mode the toasts cascade absolutely while collapsed, which\n // makes the close-all button jump between layout positions on hover\n // (button moves → cursor leaves → host collapses → cycle = blink).\n // Only show it once the stack is expanded, or always in list mode.\n if (this.mode() === 'stack' && !this.expanded()) return false;\n return cfg.showCloseAll && this.toasts().length >= cfg.closeAllThreshold;\n });\n\n protected showProgressFor(t: WrToastOptions): boolean {\n return t.showProgress ?? this.config().showProgress;\n }\n\n protected showCopyFor(t: WrToastOptions): boolean {\n return t.showCopy ?? this.config().showCopy;\n }\n}\n","@if (closeAllVisible()) {\n <button type=\"button\" class=\"wr-toast-host__close-all\" (click)=\"dismissAllRequested.emit()\">\n {{ config().labels.closeAll }} ({{ toasts().length }})\n </button>\n}\n\n@for (toast of toasts(); track toast.id) {\n <wr-toast\n [style.--wr-toast-stack-index]=\"stackIndex($index)\"\n [type]=\"toast.type ?? 'info'\"\n [title]=\"toast.title ?? null\"\n [message]=\"toast.message\"\n [dismissible]=\"toast.dismissible ?? true\"\n [showProgress]=\"showProgressFor(toast)\"\n [showCopy]=\"showCopyFor(toast)\"\n [duration]=\"toast.resolvedDuration\"\n [labels]=\"config().labels\"\n (dismissed)=\"dismissed.emit(toast.id)\"\n (pauseRequested)=\"pauseRequested.emit(toast.id)\"\n (resumeRequested)=\"resumeRequested.emit(toast.id)\"\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 type { WrToastOptions } from './interfaces';\n\n/**\n * Handle returned by `WrToast.show()`. Call `dismiss()` to remove\n * the toast early. Inspect `options` to see what the caller requested.\n */\nexport class WrToastRef {\n constructor(\n public readonly id: number,\n public readonly options: WrToastOptions,\n private readonly onDismiss: (id: number) => void\n ) {}\n\n /** Remove this toast from the stack. */\n dismiss(): void {\n this.onDismiss(this.id);\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 type { WrToastConfig } from './interfaces';\n\n/**\n * Library defaults applied when no {@link provideWrToastConfig} call is\n * registered. Merged shallowly with the consumer's overrides (the `labels`\n * sub-object is merged separately so callers can override one string at a\n * time).\n */\nexport const DEFAULT_TOAST_CONFIG: WrToastConfig = {\n position: 'top-end',\n mode: 'stack',\n duration: 4000,\n showProgress: true,\n showCopy: false,\n showCloseAll: true,\n closeAllThreshold: 2,\n maxStack: 5,\n labels: {\n close: 'Close',\n copy: 'Copy',\n copied: 'Copied',\n closeAll: 'Close all',\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\nimport { DEFAULT_TOAST_CONFIG } from '../default-toast-config';\nimport type { WrToastConfig } from '../interfaces';\n\n/**\n * Holds the global {@link WrToastConfig} used by {@link WrToast}.\n * The default factory returns {@link DEFAULT_TOAST_CONFIG} so the service\n * works out of the box; override via {@link provideWrToastConfig}.\n */\nexport const WR_TOAST_CONFIG = new InjectionToken<WrToastConfig>('WR_TOAST_CONFIG', {\n providedIn: 'root',\n factory: () => DEFAULT_TOAST_CONFIG,\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 OverlayRef } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { type ComponentRef, Service, inject } from '@angular/core';\n\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\nimport type { WrToastOptions, WrToastPosition } from '../interfaces';\nimport { WrToastHost } from '../toast-host';\nimport { WrToastRef } from '../toast-ref';\nimport { WR_TOAST_CONFIG } from '../tokens';\n\ntype ActiveEntry = WrToastOptions & {\n readonly id: number;\n /** Resolved auto-dismiss duration in ms after merging with global config. */\n readonly resolvedDuration: number;\n /** Resolved corner for this stack. */\n readonly resolvedPosition: WrToastPosition;\n /** Pending timeout handle. */\n timer?: ReturnType<typeof setTimeout>;\n /** Timestamp of the last timer (re)start, used to compute remaining on pause. */\n startedAt?: number;\n /** Milliseconds left when paused. */\n remaining: number;\n};\n\n/**\n * Opens toast notifications in a single shared overlay.\n *\n * Global defaults come from {@link WR_TOAST_CONFIG}; register\n * {@link provideWrToastConfig} once at bootstrap to customise. Each\n * `show()` call accepts per-toast overrides via {@link WrToastOptions}.\n *\n * @example\n * ```ts\n * const toast = inject(WrToast);\n *\n * toast.show({ type: 'success', title: 'Saved', message: 'Profile updated.' });\n * toast.show({ type: 'danger', message: 'Network error', duration: 0 });\n * toast.show({ message: 'Permalink copied', position: 'bottom', showCopy: true });\n * ```\n *\n * @see https://ngwr.dev/components/toast\n */\n@Service()\nexport class WrToast {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly config = inject(WR_TOAST_CONFIG);\n\n private overlayRef: OverlayRef | null = null;\n private hostRef: ComponentRef<WrToastHost> | null = null;\n private currentPosition: WrToastPosition = this.config.position;\n private currentMode: 'stack' | 'list' = this.config.mode;\n private nextId = 1;\n private active: ActiveEntry[] = [];\n\n /** Open a toast. Returns a handle you can `dismiss()` early. */\n show(options: WrToastOptions): WrToastRef {\n const resolvedPosition = options.position ?? this.config.position;\n const resolvedDuration = options.duration ?? this.config.duration;\n\n this.ensureHost(resolvedPosition);\n\n const entry: ActiveEntry = {\n ...options,\n id: this.nextId++,\n resolvedDuration,\n resolvedPosition,\n remaining: resolvedDuration,\n };\n\n this.active = [...this.active, entry];\n this.enforceMaxStack();\n this.pushToHost();\n this.startTimer(entry);\n\n return new WrToastRef(entry.id, options, id => this.dismiss(id));\n }\n\n /** Dismiss a single toast by id. */\n dismiss(id: number): void {\n const entry = this.active.find(t => t.id === id);\n if (entry?.timer) clearTimeout(entry.timer);\n this.active = this.active.filter(t => t.id !== id);\n this.pushToHost();\n if (this.active.length === 0) this.disposeHost();\n }\n\n /** Dismiss every visible toast. Wired to the host's \"Close all\" button. */\n dismissAll(): void {\n for (const entry of this.active) {\n if (entry.timer) clearTimeout(entry.timer);\n }\n this.active = [];\n this.disposeHost();\n }\n\n /** Change the corner the stack opens in. Affects future toasts. */\n setPosition(position: WrToastPosition): void {\n this.currentPosition = position;\n if (this.hostRef) this.hostRef.setInput('position', position);\n }\n\n /** Switch the layout mode at runtime. Persists across host re-creation. */\n setMode(mode: 'stack' | 'list'): void {\n this.currentMode = mode;\n if (this.hostRef) this.hostRef.setInput('mode', mode);\n }\n\n // Timer\n\n private startTimer(entry: ActiveEntry): void {\n if (entry.remaining <= 0) return;\n entry.startedAt = Date.now();\n entry.timer = setTimeout(() => this.dismiss(entry.id), entry.remaining);\n }\n\n private pauseTimer(entry: ActiveEntry): void {\n if (!entry.timer) return;\n clearTimeout(entry.timer);\n entry.timer = undefined;\n if (entry.startedAt) {\n entry.remaining = Math.max(0, entry.remaining - (Date.now() - entry.startedAt));\n }\n }\n\n // Host plumbing\n\n private ensureHost(position: WrToastPosition): void {\n if (this.overlayRef) {\n if (position !== this.currentPosition) this.setPosition(position);\n return;\n }\n\n this.currentPosition = position;\n\n this.overlayRef = this.overlay.create({\n positionStrategy: this.overlay.position().global(),\n scrollStrategy: this.overlay.scrollStrategies.noop(),\n hasBackdrop: false,\n panelClass: ['wr-toast-overlay'],\n });\n\n const portal = new ComponentPortal(WrToastHost);\n this.hostRef = this.overlayRef.attach(portal);\n this.hostRef.setInput('position', position);\n this.hostRef.setInput('mode', this.currentMode);\n this.hostRef.setInput('config', this.config);\n\n const inst = this.hostRef.instance;\n inst.dismissed.subscribe(id => this.dismiss(id));\n inst.dismissAllRequested.subscribe(() => this.dismissAll());\n inst.pauseRequested.subscribe(id => {\n const entry = this.active.find(t => t.id === id);\n if (entry) this.pauseTimer(entry);\n });\n inst.resumeRequested.subscribe(id => {\n const entry = this.active.find(t => t.id === id);\n if (entry) this.startTimer(entry);\n });\n }\n\n private enforceMaxStack(): void {\n const max = this.config.maxStack;\n if (max <= 0 || this.active.length <= max) return;\n const overflow = this.active.slice(0, this.active.length - max);\n for (const entry of overflow) {\n if (entry.timer) clearTimeout(entry.timer);\n }\n this.active = this.active.slice(this.active.length - max);\n }\n\n private pushToHost(): void {\n this.hostRef?.instance.toasts.set([...this.active]);\n }\n\n private disposeHost(): void {\n if (this.overlayRef) {\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.hostRef = null;\n }\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 { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { DEFAULT_TOAST_CONFIG } from './default-toast-config';\nimport type { WrToastConfig } from './interfaces';\nimport { WR_TOAST_CONFIG } from './tokens';\n\n/**\n * Registers a global {@link WrToastConfig} for {@link WrToast}. Any\n * field you omit falls back to {@link DEFAULT_TOAST_CONFIG}; the `labels`\n * sub-object is merged separately so you can override a single string at a\n * time (useful for i18n).\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrToastConfig({\n * position: 'bottom-end',\n * showCopy: true,\n * maxStack: 3,\n * labels: { close: 'Закрыть', copy: 'Копировать', copied: 'Скопировано', closeAll: 'Закрыть все' },\n * }),\n * ],\n * });\n * ```\n */\nexport function provideWrToastConfig(config: Partial<WrToastConfig>): EnvironmentProviders {\n const merged: WrToastConfig = {\n ...DEFAULT_TOAST_CONFIG,\n ...config,\n labels: { ...DEFAULT_TOAST_CONFIG.labels, ...config.labels },\n };\n return makeEnvironmentProviders([{ provide: WR_TOAST_CONFIG, useValue: merged }]);\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-toast.mjs","sources":["../../../projects/lib/toast/toast-item.ts","../../../projects/lib/toast/toast-item.html","../../../projects/lib/toast/toast-host.ts","../../../projects/lib/toast/toast-host.html","../../../projects/lib/toast/toast-ref.ts","../../../projects/lib/toast/default-toast-config.ts","../../../projects/lib/toast/tokens/toast-config.token.ts","../../../projects/lib/toast/services/toast.ts","../../../projects/lib/toast/provide-wr-toast-config.ts","../../../projects/lib/toast/ngwr-toast.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 { Component, ElementRef, ViewEncapsulation, computed, inject, input, output, signal } from '@angular/core';\n\nimport type { WrToastConfig, WrToastType } from './interfaces';\n\n/**\n * One toast row inside the toast host. Not used directly — see\n * `WrToast.show()`.\n *\n * @internal\n */\n@Component({\n selector: 'wr-toast',\n templateUrl: './toast-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style.--wr-toast-duration]': 'durationMs()',\n '[style.transform]': 'swipeTransform()',\n '[style.opacity]': 'swipeOpacity()',\n '[style.transition]': 'swiping() ? \"none\" : null',\n '[attr.role]': 'liveRole()',\n '[attr.aria-live]': 'liveLevel()',\n '(mouseenter)': 'pauseRequested.emit()',\n '(mouseleave)': 'resumeRequested.emit()',\n '(touchstart)': 'onSwipeStart($event)',\n '(touchmove)': 'onSwipeMove($event)',\n '(touchend)': 'onSwipeEnd()',\n '(touchcancel)': 'onSwipeEnd()',\n },\n})\nexport class WrToastItem {\n readonly type = input<WrToastType>('info');\n readonly title = input<string | null>(null);\n readonly message = input.required<string>();\n readonly dismissible = input<boolean>(true);\n readonly showProgress = input<boolean>(false);\n readonly showCopy = input<boolean>(false);\n /** Auto-dismiss duration in ms — used to scale the progress bar. `0` hides it. */\n readonly duration = input<number>(0);\n readonly labels = input.required<WrToastConfig['labels']>();\n\n readonly dismissed = output<void>();\n readonly pauseRequested = output<void>();\n readonly resumeRequested = output<void>();\n\n /** True for ~1.5s after a successful copy; flips the icon to a check. */\n protected readonly justCopied = signal(false);\n private copyResetTimer: ReturnType<typeof setTimeout> | null = null;\n\n protected readonly classes = computed(() => `wr-toast wr-toast--${this.type()}`);\n\n /** Escalate to `alert`/`assertive` for danger/warning toasts. */\n protected readonly liveRole = computed(() => (this.type() === 'danger' ? 'alert' : 'status'));\n protected readonly liveLevel = computed(() =>\n this.type() === 'danger' || this.type() === 'warning' ? 'assertive' : 'polite'\n );\n\n /** Inline CSS value for `--wr-toast-duration`. */\n protected readonly durationMs = computed(() => `${this.duration()}ms`);\n\n protected readonly progressVisible = computed(() => this.showProgress() && this.duration() > 0);\n\n protected async onCopy(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.message());\n this.justCopied.set(true);\n if (this.copyResetTimer) clearTimeout(this.copyResetTimer);\n this.copyResetTimer = setTimeout(() => this.justCopied.set(false), 1500);\n } catch {\n // Clipboard unavailable (insecure context / permission denied) — silent.\n }\n }\n\n // Swipe-sideways-to-dismiss. The toast follows the finger and fades; releasing\n // past 40% of its width emits `dismissed`, otherwise it snaps back.\n private readonly elRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private swipeStartX = 0;\n private swipeWidth = 0;\n protected readonly swipeX = signal(0);\n protected readonly swiping = signal(false);\n\n protected readonly swipeTransform = computed(() => (this.swipeX() === 0 ? null : `translateX(${this.swipeX()}px)`));\n protected readonly swipeOpacity = computed(() => {\n const dist = Math.abs(this.swipeX());\n return dist === 0 ? null : Math.max(0, 1 - dist / (this.swipeWidth || 1));\n });\n\n protected onSwipeStart(event: TouchEvent): void {\n if (!this.dismissible()) return;\n const touch = event.touches[0];\n if (!touch) return;\n this.swipeStartX = touch.clientX;\n this.swipeWidth = this.elRef.nativeElement.offsetWidth;\n this.swiping.set(true);\n }\n\n protected onSwipeMove(event: TouchEvent): void {\n if (!this.swiping()) return;\n const touch = event.touches[0];\n if (!touch) return;\n this.swipeX.set(touch.clientX - this.swipeStartX);\n }\n\n protected onSwipeEnd(): void {\n if (!this.swiping()) return;\n this.swiping.set(false);\n if (Math.abs(this.swipeX()) > (this.swipeWidth || 0) * 0.4) {\n this.dismissed.emit();\n } else {\n this.swipeX.set(0);\n }\n }\n}\n","<div class=\"wr-toast__body\">\n @if (title(); as text) {\n <p class=\"wr-toast__title\">{{ text }}</p>\n }\n <p class=\"wr-toast__message\">{{ message() }}</p>\n</div>\n\n<div class=\"wr-toast__actions\">\n @if (showCopy()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"justCopied() ? labels().copied : labels().copy\"\n [title]=\"justCopied() ? labels().copied : labels().copy\"\n (click)=\"onCopy()\"\n >\n @if (justCopied()) {\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=\"M20 6 9 17l-5-5\" />\n </svg>\n } @else {\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 <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n }\n </button>\n }\n\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"wr-toast__action\"\n [attr.aria-label]=\"labels().close\"\n [title]=\"labels().close\"\n (click)=\"dismissed.emit()\"\n >\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</div>\n\n@if (progressVisible()) {\n <span class=\"wr-toast__progress\" aria-hidden=\"true\"></span>\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 { Component, DestroyRef, ViewEncapsulation, computed, inject, input, output, signal } from '@angular/core';\n\nimport type { WrToastConfig, WrToastMode, WrToastOptions, WrToastPosition } from './interfaces';\nimport { WrToastItem } from './toast-item';\n\n/** ms before a mouseleave actually collapses the stack. Buffers the cursor\n * briefly leaving the host as toasts reflow underneath it. */\nconst COLLAPSE_DELAY_MS = 120;\n\n/** Active entry pushed by the service — adds the bookkeeping fields the host renders. */\ntype ActiveToast = WrToastOptions & {\n readonly id: number;\n readonly resolvedDuration: number;\n};\n\n/**\n * Internal host that lives inside the toast overlay and renders the\n * active stack. Owned by `WrToast`.\n *\n * @internal\n */\n@Component({\n selector: 'wr-toast-host',\n templateUrl: './toast-host.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n role: 'region',\n 'aria-label': 'Notifications',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave()',\n },\n imports: [WrToastItem],\n})\nexport class WrToastHost {\n readonly position = input<WrToastPosition>('top-end');\n readonly config = input.required<WrToastConfig>();\n /** Layout mode. @default 'stack' (Sonner-style; hover to fan out) */\n readonly mode = input<WrToastMode>('stack');\n\n /** @internal — hover toggles this in stack mode. */\n protected readonly expanded = signal(false);\n\n private readonly destroyRef = inject(DestroyRef);\n private collapseTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n this.destroyRef.onDestroy(() => this.clearCollapseTimer());\n }\n\n /** @internal */\n protected onMouseEnter(): void {\n this.clearCollapseTimer();\n this.expanded.set(true);\n }\n\n /** @internal — delay the collapse so cursor briefly slipping off the host\n * during a layout reflow doesn't cause a flicker. */\n protected onMouseLeave(): void {\n this.clearCollapseTimer();\n this.collapseTimer = setTimeout(() => {\n this.expanded.set(false);\n this.collapseTimer = null;\n }, COLLAPSE_DELAY_MS);\n }\n\n private clearCollapseTimer(): void {\n if (this.collapseTimer !== null) {\n clearTimeout(this.collapseTimer);\n this.collapseTimer = null;\n }\n }\n\n /** @internal — pushed by the service. */\n readonly toasts = signal<readonly ActiveToast[]>([]);\n\n /** @internal — service listens to update its internal state. */\n readonly dismissed = output<number>();\n readonly pauseRequested = output<number>();\n readonly resumeRequested = output<number>();\n readonly dismissAllRequested = output<void>();\n\n protected readonly classes = computed(() => {\n const parts = ['wr-toast-host', `wr-toast-host--${this.position()}`, `wr-toast-host--${this.mode()}`];\n if (this.mode() === 'stack' && this.expanded()) parts.push('wr-toast-host--expanded');\n return parts.join(' ');\n });\n\n /** Distance from the front of the stack (0 = newest / fully visible). */\n protected stackIndex(i: number): number {\n return this.toasts().length - 1 - i;\n }\n\n protected readonly closeAllVisible = computed(() => {\n const cfg = this.config();\n // In stack mode the toasts cascade absolutely while collapsed, which\n // makes the close-all button jump between layout positions on hover\n // (button moves → cursor leaves → host collapses → cycle = blink).\n // Only show it once the stack is expanded, or always in list mode.\n if (this.mode() === 'stack' && !this.expanded()) return false;\n return cfg.showCloseAll && this.toasts().length >= cfg.closeAllThreshold;\n });\n\n protected showProgressFor(t: WrToastOptions): boolean {\n return t.showProgress ?? this.config().showProgress;\n }\n\n protected showCopyFor(t: WrToastOptions): boolean {\n return t.showCopy ?? this.config().showCopy;\n }\n}\n","@if (closeAllVisible()) {\n <button type=\"button\" class=\"wr-toast-host__close-all\" (click)=\"dismissAllRequested.emit()\">\n {{ config().labels.closeAll }} ({{ toasts().length }})\n </button>\n}\n\n@for (toast of toasts(); track toast.id) {\n <wr-toast\n [style.--wr-toast-stack-index]=\"stackIndex($index)\"\n [type]=\"toast.type ?? 'info'\"\n [title]=\"toast.title ?? null\"\n [message]=\"toast.message\"\n [dismissible]=\"toast.dismissible ?? true\"\n [showProgress]=\"showProgressFor(toast)\"\n [showCopy]=\"showCopyFor(toast)\"\n [duration]=\"toast.resolvedDuration\"\n [labels]=\"config().labels\"\n (dismissed)=\"dismissed.emit(toast.id)\"\n (pauseRequested)=\"pauseRequested.emit(toast.id)\"\n (resumeRequested)=\"resumeRequested.emit(toast.id)\"\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 type { WrToastOptions } from './interfaces';\n\n/**\n * Handle returned by `WrToast.show()`. Call `dismiss()` to remove\n * the toast early. Inspect `options` to see what the caller requested.\n */\nexport class WrToastRef {\n constructor(\n public readonly id: number,\n public readonly options: WrToastOptions,\n private readonly onDismiss: (id: number) => void\n ) {}\n\n /** Remove this toast from the stack. */\n dismiss(): void {\n this.onDismiss(this.id);\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 type { WrToastConfig } from './interfaces';\n\n/**\n * Library defaults applied when no {@link provideWrToastConfig} call is\n * registered. Merged shallowly with the consumer's overrides (the `labels`\n * sub-object is merged separately so callers can override one string at a\n * time).\n */\nexport const DEFAULT_TOAST_CONFIG: WrToastConfig = {\n position: 'top-end',\n mode: 'stack',\n duration: 4000,\n showProgress: true,\n showCopy: false,\n showCloseAll: true,\n closeAllThreshold: 2,\n maxStack: 5,\n labels: {\n close: 'Close',\n copy: 'Copy',\n copied: 'Copied',\n closeAll: 'Close all',\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\nimport { DEFAULT_TOAST_CONFIG } from '../default-toast-config';\nimport type { WrToastConfig } from '../interfaces';\n\n/**\n * Holds the global {@link WrToastConfig} used by {@link WrToast}.\n * The default factory returns {@link DEFAULT_TOAST_CONFIG} so the service\n * works out of the box; override via {@link provideWrToastConfig}.\n */\nexport const WR_TOAST_CONFIG = new InjectionToken<WrToastConfig>('WR_TOAST_CONFIG', {\n providedIn: 'root',\n factory: () => DEFAULT_TOAST_CONFIG,\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 OverlayRef } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { type ComponentRef, Service, inject } from '@angular/core';\n\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\nimport type { WrToastOptions, WrToastPosition } from '../interfaces';\nimport { WrToastHost } from '../toast-host';\nimport { WrToastRef } from '../toast-ref';\nimport { WR_TOAST_CONFIG } from '../tokens';\n\ntype ActiveEntry = WrToastOptions & {\n readonly id: number;\n /** Resolved auto-dismiss duration in ms after merging with global config. */\n readonly resolvedDuration: number;\n /** Resolved corner for this stack. */\n readonly resolvedPosition: WrToastPosition;\n /** Pending timeout handle. */\n timer?: ReturnType<typeof setTimeout>;\n /** Timestamp of the last timer (re)start, used to compute remaining on pause. */\n startedAt?: number;\n /** Milliseconds left when paused. */\n remaining: number;\n};\n\n/**\n * Opens toast notifications in a single shared overlay.\n *\n * Global defaults come from {@link WR_TOAST_CONFIG}; register\n * {@link provideWrToastConfig} once at bootstrap to customise. Each\n * `show()` call accepts per-toast overrides via {@link WrToastOptions}.\n *\n * @example\n * ```ts\n * const toast = inject(WrToast);\n *\n * toast.show({ type: 'success', title: 'Saved', message: 'Profile updated.' });\n * toast.show({ type: 'danger', message: 'Network error', duration: 0 });\n * toast.show({ message: 'Permalink copied', position: 'bottom', showCopy: true });\n * ```\n *\n * @see https://ngwr.dev/components/toast\n */\n@Service()\nexport class WrToast {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly config = inject(WR_TOAST_CONFIG);\n\n private overlayRef: OverlayRef | null = null;\n private hostRef: ComponentRef<WrToastHost> | null = null;\n private currentPosition: WrToastPosition = this.config.position;\n private currentMode: 'stack' | 'list' = this.config.mode;\n private nextId = 1;\n private active: ActiveEntry[] = [];\n\n /** Open a toast. Returns a handle you can `dismiss()` early. */\n show(options: WrToastOptions): WrToastRef {\n const resolvedPosition = options.position ?? this.config.position;\n const resolvedDuration = options.duration ?? this.config.duration;\n\n this.ensureHost(resolvedPosition);\n\n const entry: ActiveEntry = {\n ...options,\n id: this.nextId++,\n resolvedDuration,\n resolvedPosition,\n remaining: resolvedDuration,\n };\n\n this.active = [...this.active, entry];\n this.enforceMaxStack();\n this.pushToHost();\n this.startTimer(entry);\n\n return new WrToastRef(entry.id, options, id => this.dismiss(id));\n }\n\n /** Dismiss a single toast by id. */\n dismiss(id: number): void {\n const entry = this.active.find(t => t.id === id);\n if (entry?.timer) clearTimeout(entry.timer);\n this.active = this.active.filter(t => t.id !== id);\n this.pushToHost();\n if (this.active.length === 0) this.disposeHost();\n }\n\n /** Dismiss every visible toast. Wired to the host's \"Close all\" button. */\n dismissAll(): void {\n for (const entry of this.active) {\n if (entry.timer) clearTimeout(entry.timer);\n }\n this.active = [];\n this.disposeHost();\n }\n\n /** Change the corner the stack opens in. Affects future toasts. */\n setPosition(position: WrToastPosition): void {\n this.currentPosition = position;\n if (this.hostRef) this.hostRef.setInput('position', position);\n }\n\n /** Switch the layout mode at runtime. Persists across host re-creation. */\n setMode(mode: 'stack' | 'list'): void {\n this.currentMode = mode;\n if (this.hostRef) this.hostRef.setInput('mode', mode);\n }\n\n // Timer\n\n private startTimer(entry: ActiveEntry): void {\n if (entry.remaining <= 0) return;\n entry.startedAt = Date.now();\n entry.timer = setTimeout(() => this.dismiss(entry.id), entry.remaining);\n }\n\n private pauseTimer(entry: ActiveEntry): void {\n if (!entry.timer) return;\n clearTimeout(entry.timer);\n entry.timer = undefined;\n if (entry.startedAt) {\n entry.remaining = Math.max(0, entry.remaining - (Date.now() - entry.startedAt));\n }\n }\n\n // Host plumbing\n\n private ensureHost(position: WrToastPosition): void {\n if (this.overlayRef) {\n if (position !== this.currentPosition) this.setPosition(position);\n return;\n }\n\n this.currentPosition = position;\n\n this.overlayRef = this.overlay.create({\n positionStrategy: this.overlay.position().global(),\n scrollStrategy: this.overlay.scrollStrategies.noop(),\n hasBackdrop: false,\n panelClass: ['wr-toast-overlay'],\n });\n\n const portal = new ComponentPortal(WrToastHost);\n this.hostRef = this.overlayRef.attach(portal);\n this.hostRef.setInput('position', position);\n this.hostRef.setInput('mode', this.currentMode);\n this.hostRef.setInput('config', this.config);\n\n const inst = this.hostRef.instance;\n inst.dismissed.subscribe(id => this.dismiss(id));\n inst.dismissAllRequested.subscribe(() => this.dismissAll());\n inst.pauseRequested.subscribe(id => {\n const entry = this.active.find(t => t.id === id);\n if (entry) this.pauseTimer(entry);\n });\n inst.resumeRequested.subscribe(id => {\n const entry = this.active.find(t => t.id === id);\n if (entry) this.startTimer(entry);\n });\n }\n\n private enforceMaxStack(): void {\n const max = this.config.maxStack;\n if (max <= 0 || this.active.length <= max) return;\n const overflow = this.active.slice(0, this.active.length - max);\n for (const entry of overflow) {\n if (entry.timer) clearTimeout(entry.timer);\n }\n this.active = this.active.slice(this.active.length - max);\n }\n\n private pushToHost(): void {\n this.hostRef?.instance.toasts.set([...this.active]);\n }\n\n private disposeHost(): void {\n if (this.overlayRef) {\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.hostRef = null;\n }\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 { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { DEFAULT_TOAST_CONFIG } from './default-toast-config';\nimport type { WrToastConfig } from './interfaces';\nimport { WR_TOAST_CONFIG } from './tokens';\n\n/**\n * Registers a global {@link WrToastConfig} for {@link WrToast}. Any\n * field you omit falls back to {@link DEFAULT_TOAST_CONFIG}; the `labels`\n * sub-object is merged separately so you can override a single string at a\n * time (useful for i18n).\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrToastConfig({\n * position: 'bottom-end',\n * showCopy: true,\n * maxStack: 3,\n * labels: { close: 'Закрыть', copy: 'Копировать', copied: 'Скопировано', closeAll: 'Закрыть все' },\n * }),\n * ],\n * });\n * ```\n */\nexport function provideWrToastConfig(config: Partial<WrToastConfig>): EnvironmentProviders {\n const merged: WrToastConfig = {\n ...DEFAULT_TOAST_CONFIG,\n ...config,\n labels: { ...DEFAULT_TOAST_CONFIG.labels, ...config.labels },\n };\n return makeEnvironmentProviders([{ provide: WR_TOAST_CONFIG, useValue: merged }]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { ViewEncapsulation, Component } from '@angular/core';
|
|
3
|
+
import { input, ViewEncapsulation, Component } from '@angular/core';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @license
|
|
@@ -30,13 +31,19 @@ import { ViewEncapsulation, Component } from '@angular/core';
|
|
|
30
31
|
* @see https://ngwr.dev/components/toolbar
|
|
31
32
|
*/
|
|
32
33
|
class WrToolbar {
|
|
34
|
+
/**
|
|
35
|
+
* Stack the zones vertically when the toolbar's own box is too narrow to fit
|
|
36
|
+
* them in a row (a container query on its own width, not the viewport — so it
|
|
37
|
+
* adapts inside a narrow column or split pane). @default false
|
|
38
|
+
*/
|
|
39
|
+
responsive = input(false, { ...(ngDevMode ? { debugName: "responsive" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
|
|
33
40
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrToolbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
41
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.2", type: WrToolbar, isStandalone: true, selector: "wr-toolbar", inputs: { responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "toolbar" }, properties: { "class.wr-toolbar--responsive": "responsive()" }, classAttribute: "wr-toolbar" }, ngImport: i0, template: "<div class=\"wr-toolbar__zone wr-toolbar__zone--start\">\n <ng-content select=\"[wrToolbarStart]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--center\">\n <ng-content select=\"[wrToolbarCenter]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--end\">\n <ng-content select=\"[wrToolbarEnd]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
|
|
35
42
|
}
|
|
36
43
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrToolbar, decorators: [{
|
|
37
44
|
type: Component,
|
|
38
|
-
args: [{ selector: 'wr-toolbar', encapsulation: ViewEncapsulation.None, host: { class: 'wr-toolbar', role: 'toolbar' }, template: "<div class=\"wr-toolbar__zone wr-toolbar__zone--start\">\n <ng-content select=\"[wrToolbarStart]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--center\">\n <ng-content select=\"[wrToolbarCenter]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--end\">\n <ng-content select=\"[wrToolbarEnd]\" />\n</div>\n" }]
|
|
39
|
-
}] });
|
|
45
|
+
args: [{ selector: 'wr-toolbar', encapsulation: ViewEncapsulation.None, host: { class: 'wr-toolbar', role: 'toolbar', '[class.wr-toolbar--responsive]': 'responsive()' }, template: "<div class=\"wr-toolbar__zone wr-toolbar__zone--start\">\n <ng-content select=\"[wrToolbarStart]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--center\">\n <ng-content select=\"[wrToolbarCenter]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--end\">\n <ng-content select=\"[wrToolbarEnd]\" />\n</div>\n" }]
|
|
46
|
+
}], propDecorators: { responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }] } });
|
|
40
47
|
|
|
41
48
|
/**
|
|
42
49
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-toolbar.mjs","sources":["../../../projects/lib/toolbar/toolbar.ts","../../../projects/lib/toolbar/toolbar.html","../../../projects/lib/toolbar/ngwr-toolbar.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 { Component, ViewEncapsulation } from '@angular/core';\n\n/**\n * Action bar with three named zones — `[wrToolbarStart]`,\n * `[wrToolbarCenter]`, `[wrToolbarEnd]`. Use any one or all three.\n *\n * @example\n * ```html\n * <wr-toolbar>\n * <div wrToolbarStart>\n * <button wrButton>Back</button>\n * <strong>Items</strong>\n * </div>\n * <div wrToolbarCenter>\n * <wr-segmented [(value)]=\"view\" [options]=\"['grid', 'list']\" />\n * </div>\n * <div wrToolbarEnd>\n * <button wrButton color=\"primary\">New</button>\n * </div>\n * </wr-toolbar>\n * ```\n *\n * @see https://ngwr.dev/components/toolbar\n */\n@Component({\n selector: 'wr-toolbar',\n templateUrl: './toolbar.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-toolbar', role: 'toolbar' },\n})\nexport class WrToolbar {}\n","<div class=\"wr-toolbar__zone wr-toolbar__zone--start\">\n <ng-content select=\"[wrToolbarStart]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--center\">\n <ng-content select=\"[wrToolbarCenter]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--end\">\n <ng-content select=\"[wrToolbarEnd]\" />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ngwr-toolbar.mjs","sources":["../../../projects/lib/toolbar/toolbar.ts","../../../projects/lib/toolbar/toolbar.html","../../../projects/lib/toolbar/ngwr-toolbar.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 { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, input } from '@angular/core';\n\n/**\n * Action bar with three named zones — `[wrToolbarStart]`,\n * `[wrToolbarCenter]`, `[wrToolbarEnd]`. Use any one or all three.\n *\n * @example\n * ```html\n * <wr-toolbar>\n * <div wrToolbarStart>\n * <button wrButton>Back</button>\n * <strong>Items</strong>\n * </div>\n * <div wrToolbarCenter>\n * <wr-segmented [(value)]=\"view\" [options]=\"['grid', 'list']\" />\n * </div>\n * <div wrToolbarEnd>\n * <button wrButton color=\"primary\">New</button>\n * </div>\n * </wr-toolbar>\n * ```\n *\n * @see https://ngwr.dev/components/toolbar\n */\n@Component({\n selector: 'wr-toolbar',\n templateUrl: './toolbar.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-toolbar', role: 'toolbar', '[class.wr-toolbar--responsive]': 'responsive()' },\n})\nexport class WrToolbar {\n /**\n * Stack the zones vertically when the toolbar's own box is too narrow to fit\n * them in a row (a container query on its own width, not the viewport — so it\n * adapts inside a narrow column or split pane). @default false\n */\n readonly responsive = input(false, { transform: coerceBooleanProperty });\n}\n","<div class=\"wr-toolbar__zone wr-toolbar__zone--start\">\n <ng-content select=\"[wrToolbarStart]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--center\">\n <ng-content select=\"[wrToolbarCenter]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--end\">\n <ng-content select=\"[wrToolbarEnd]\" />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAKH;;;;;;;;;;;;;;;;;;;;;AAqBG;MAOU,SAAS,CAAA;AACpB;;;;AAIG;IACM,UAAU,GAAG,KAAK,CAAC,KAAK,kFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;uGAN7D,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,oWCtCtB,gVASA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FD6Ba,SAAS,EAAA,UAAA,EAAA,CAAA;kBANrB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,iBAEP,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,gCAAgC,EAAE,cAAc,EAAE,EAAA,QAAA,EAAA,gVAAA,EAAA;;;AEpClG;;AAEG;;;;"}
|
|
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
|
|
|
16
16
|
* Distinct from `Version` exported by `@angular/core`, which reports the
|
|
17
17
|
* loaded Angular runtime version (e.g. `'21.2.13'`), not ngwr's.
|
|
18
18
|
*/
|
|
19
|
-
const NGWR_VERSION = '7.
|
|
19
|
+
const NGWR_VERSION = '7.3.0';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @license
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.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\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'21.2.13'`), not ngwr's.\n */\nexport const NGWR_VERSION = '7.
|
|
1
|
+
{"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.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\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'21.2.13'`), not ngwr's.\n */\nexport const NGWR_VERSION = '7.3.0';\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 { NGWR_VERSION } from './version';\n\n/**\n * Injection token holding the ngwr library version string.\n *\n * Default factory returns {@link NGWR_VERSION}. Override it in tests or in\n * apps that want to surface a custom build identifier.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class FooterComponent {\n * readonly version = inject(NGWR_VERSION_TOKEN);\n * }\n * ```\n */\nexport const NGWR_VERSION_TOKEN = new InjectionToken<string>('NGWR_VERSION_TOKEN', {\n providedIn: 'root',\n factory: () => NGWR_VERSION,\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAEH;;;;;;;;;AASG;AACI,MAAM,YAAY,GAAG;;ACjB5B;;;;;AAKG;AAMH;;;;;;;;;;;;;AAaG;MACU,kBAAkB,GAAG,IAAI,cAAc,CAAS,oBAAoB,EAAE;AACjF,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,YAAY;AAC5B,CAAA;;AC5BD;;AAEG;;;;"}
|