@xui/panel-stack 2.0.0-alpha.20 → 2.0.0-alpha.22
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.
|
@@ -34,10 +34,14 @@ class XuiPanelStack {
|
|
|
34
34
|
/** The user-defined classes. Merged last so they win over the base classes. */
|
|
35
35
|
class = input('', /* @ts-ignore */
|
|
36
36
|
...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
37
|
+
/** The panel at the bottom of the stack. It cannot be popped — there is always something to show. */
|
|
37
38
|
initialPanel = input.required(/* @ts-ignore */
|
|
38
39
|
...(ngDevMode ? [{ debugName: "initialPanel" }] : /* istanbul ignore next */ []));
|
|
40
|
+
/** Show the header with the panel title and its back button. Turn it off to supply your own navigation. */
|
|
39
41
|
showPanelHeader = input(true, { ...(ngDevMode ? { debugName: "showPanelHeader" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
42
|
+
/** Emits the panel that was just pushed onto the stack. */
|
|
40
43
|
opened = output();
|
|
44
|
+
/** Emits the panel that was just popped off the stack. */
|
|
41
45
|
closed = output();
|
|
42
46
|
stack = signal([], /* @ts-ignore */
|
|
43
47
|
...(ngDevMode ? [{ debugName: "stack" }] : /* istanbul ignore next */ []));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xui-panel-stack.mjs","sources":["../../../../../../libs/ui/panel-stack/xui/src/lib/panel-stack.types.ts","../../../../../../libs/ui/panel-stack/xui/src/lib/panel-stack.ts","../../../../../../libs/ui/panel-stack/xui/src/index.ts","../../../../../../libs/ui/panel-stack/xui/src/xui-panel-stack.ts"],"sourcesContent":["import { InjectionToken, type TemplateRef, type Type } from '@angular/core';\n\n/**\n * Navigation handed to a panel's content — the two things a panel can do to the\n * stack it lives in.\n */\nexport interface XuiPanelStackController {\n /** Push a new panel on top, sliding it in. */\n openPanel<D>(panel: XuiPanel<D>): void;\n /** Pop this panel, sliding back to the one beneath. No-op on the root panel. */\n closePanel(): void;\n}\n\n/** One screen in the stack. */\nexport interface XuiPanel<D = unknown> {\n /** Shown in the header, and as the back label on the panel above. */\n title: string;\n /**\n * What to render. A `TemplateRef` receives `{ $implicit: data, stack }`; a\n * component type is created with `data` and the stack available through DI\n * (`XUI_PANEL_DATA`, `XUI_PANEL_STACK`).\n */\n content: TemplateRef<XuiPanelContext<D>> | Type<unknown>;\n data?: D;\n}\n\n/** Context a template panel destructures with `let-`. */\nexport interface XuiPanelContext<D> {\n $implicit: D;\n stack: XuiPanelStackController;\n}\n\n/** The controller, for a component panel to inject. */\nexport const XUI_PANEL_STACK = new InjectionToken<XuiPanelStackController>('XuiPanelStack');\n\n/** The active panel's `data`, for a component panel to inject. */\nexport const XUI_PANEL_DATA = new InjectionToken<unknown>('XuiPanelData');\n","import type { BooleanInput } from '@angular/cdk/coercion';\nimport { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n output,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport { matChevronLeftRound } from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { XuiIcon } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport { XUI_PANEL_DATA, XUI_PANEL_STACK, type XuiPanel } from './panel-stack.types';\n\n/**\n * A stack of screens with a back-navigating header — a master/detail flow in a\n * fixed space, the way a settings drill-down or a wizard reads.\n *\n * ```html\n * <xui-panel-stack [initialPanel]=\"{ title: 'Settings', content: settingsTpl }\" />\n * <ng-template #settingsTpl let-stack=\"stack\">\n * <button (click)=\"stack.openPanel({ title: 'Account', content: accountTpl })\">Account →</button>\n * </ng-template>\n * ```\n *\n * Only the top panel renders; pushing slides it in from the right, popping\n * slides back from the left (Web Animations API, no `@angular/animations`,\n * reduced-motion aware). Panel content drives navigation through the `stack`\n * handed to a template, or injected (`XUI_PANEL_STACK`) by a component panel.\n */\n@Component({\n selector: 'xui-panel-stack',\n imports: [NgTemplateOutlet, NgComponentOutlet, NgIcon, XuiIcon],\n viewProviders: [provideIcons({ matChevronLeftRound })],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (showPanelHeader()) {\n <header class=\"border-border flex h-(--control-height-lg) shrink-0 items-center border-b px-1\">\n @if (depth() > 1) {\n <button\n type=\"button\"\n class=\"text-foreground-muted hover:bg-hover-overlay hover:text-foreground flex h-(--control-height-md) items-center gap-0.5 rounded-md ps-1.5 pe-3 text-sm\"\n (click)=\"closePanel()\"\n >\n <ng-icon xui size=\"md\" name=\"matChevronLeftRound\" />\n {{ previousTitle() }}\n </button>\n }\n <span class=\"text-foreground pointer-events-none absolute left-1/2 -translate-x-1/2 text-sm font-semibold\">\n {{ current().title }}\n </span>\n </header>\n }\n\n <div #view class=\"min-h-0 flex-1 overflow-auto\">\n @if (templateContent(); as tpl) {\n <ng-container *ngTemplateOutlet=\"tpl; context: { $implicit: current().data, stack: controller }\" />\n } @else if (componentContent(); as cmp) {\n <ng-container *ngComponentOutlet=\"cmp; injector: panelInjector()\" />\n }\n </div>\n `,\n host: {\n '[class]': 'computedClass()'\n }\n})\nexport class XuiPanelStack<D = unknown> {\n private readonly host = inject(Injector);\n private readonly view = viewChild.required<ElementRef<HTMLElement>>('view');\n\n /** The user-defined classes. Merged last so they win over the base classes. */\n readonly class = input<ClassValue>('');\n readonly initialPanel = input.required<XuiPanel<D>>();\n readonly showPanelHeader = input<boolean, BooleanInput>(true, { transform: booleanAttribute });\n\n readonly opened = output<XuiPanel>();\n readonly closed = output<XuiPanel>();\n\n private readonly stack = signal<XuiPanel[]>([]);\n\n protected readonly current = computed(() => {\n const panels = this.stack();\n\n return panels.length ? panels[panels.length - 1] : (this.initialPanel() as XuiPanel);\n });\n protected readonly depth = computed(() => Math.max(this.stack().length, 1));\n protected readonly previousTitle = computed(() => {\n const panels = this.stack();\n\n return panels.length > 1 ? panels[panels.length - 2].title : '';\n });\n\n /** The handle passed to template panels and provided to component panels. */\n protected readonly controller = {\n openPanel: <P>(panel: XuiPanel<P>) => this.openPanel(panel as XuiPanel),\n closePanel: () => this.closePanel()\n };\n\n protected readonly templateContent = computed(() => {\n const content = this.current().content;\n\n return content instanceof TemplateRef ? (content as TemplateRef<unknown>) : null;\n });\n protected readonly componentContent = computed(() => {\n const content = this.current().content;\n\n return content instanceof TemplateRef ? null : content;\n });\n\n protected readonly panelInjector = computed(() =>\n Injector.create({\n providers: [\n { provide: XUI_PANEL_STACK, useValue: this.controller },\n { provide: XUI_PANEL_DATA, useValue: this.current().data }\n ],\n parent: this.host\n })\n );\n\n protected readonly computedClass = computed(() =>\n xui('bg-surface-raised border-border relative flex flex-col overflow-hidden rounded-lg border', this.class())\n );\n\n constructor() {\n // Seed the stack from the initial panel once it is available.\n effect(() => {\n const initial = this.initialPanel();\n\n untracked(() => {\n if (!this.stack().length) {\n this.stack.set([initial]);\n }\n });\n });\n\n // Slide whenever the depth changes — right-to-left on push, the reverse on pop.\n let previousDepth = 1;\n\n effect(() => {\n const depth = this.depth();\n\n untracked(() => {\n if (depth !== previousDepth) {\n this.slide(depth > previousDepth ? 1 : -1);\n previousDepth = depth;\n }\n });\n });\n }\n\n openPanel<P>(panel: XuiPanel<P>): void {\n this.stack.update(panels => [...panels, panel as XuiPanel]);\n this.opened.emit(panel as XuiPanel);\n }\n\n closePanel(): void {\n const panels = this.stack();\n\n if (panels.length <= 1) {\n return;\n }\n\n this.stack.set(panels.slice(0, -1));\n this.closed.emit(panels[panels.length - 1]);\n }\n\n private slide(direction: 1 | -1): void {\n if (globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches) {\n return;\n }\n\n const element = this.view().nativeElement;\n element.animate(\n [\n { transform: `translateX(${direction * 24}px)`, opacity: 0 },\n { transform: 'none', opacity: 1 }\n ],\n {\n duration: 180,\n easing: 'ease-out'\n }\n );\n }\n}\n","import { XuiPanelStack } from './lib/panel-stack';\n\nexport * from './lib/panel-stack';\nexport * from './lib/panel-stack.types';\n\nexport const XuiPanelStackImports = [XuiPanelStack] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"xui-panel-stack.mjs","sources":["../../../../../../libs/ui/panel-stack/xui/src/lib/panel-stack.types.ts","../../../../../../libs/ui/panel-stack/xui/src/lib/panel-stack.ts","../../../../../../libs/ui/panel-stack/xui/src/index.ts","../../../../../../libs/ui/panel-stack/xui/src/xui-panel-stack.ts"],"sourcesContent":["import { InjectionToken, type TemplateRef, type Type } from '@angular/core';\n\n/**\n * Navigation handed to a panel's content — the two things a panel can do to the\n * stack it lives in.\n */\nexport interface XuiPanelStackController {\n /** Push a new panel on top, sliding it in. */\n openPanel<D>(panel: XuiPanel<D>): void;\n /** Pop this panel, sliding back to the one beneath. No-op on the root panel. */\n closePanel(): void;\n}\n\n/** One screen in the stack. */\nexport interface XuiPanel<D = unknown> {\n /** Shown in the header, and as the back label on the panel above. */\n title: string;\n /**\n * What to render. A `TemplateRef` receives `{ $implicit: data, stack }`; a\n * component type is created with `data` and the stack available through DI\n * (`XUI_PANEL_DATA`, `XUI_PANEL_STACK`).\n */\n content: TemplateRef<XuiPanelContext<D>> | Type<unknown>;\n data?: D;\n}\n\n/** Context a template panel destructures with `let-`. */\nexport interface XuiPanelContext<D> {\n $implicit: D;\n stack: XuiPanelStackController;\n}\n\n/** The controller, for a component panel to inject. */\nexport const XUI_PANEL_STACK = new InjectionToken<XuiPanelStackController>('XuiPanelStack');\n\n/** The active panel's `data`, for a component panel to inject. */\nexport const XUI_PANEL_DATA = new InjectionToken<unknown>('XuiPanelData');\n","import type { BooleanInput } from '@angular/cdk/coercion';\nimport { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n output,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport { matChevronLeftRound } from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { XuiIcon } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport { XUI_PANEL_DATA, XUI_PANEL_STACK, type XuiPanel } from './panel-stack.types';\n\n/**\n * A stack of screens with a back-navigating header — a master/detail flow in a\n * fixed space, the way a settings drill-down or a wizard reads.\n *\n * ```html\n * <xui-panel-stack [initialPanel]=\"{ title: 'Settings', content: settingsTpl }\" />\n * <ng-template #settingsTpl let-stack=\"stack\">\n * <button (click)=\"stack.openPanel({ title: 'Account', content: accountTpl })\">Account →</button>\n * </ng-template>\n * ```\n *\n * Only the top panel renders; pushing slides it in from the right, popping\n * slides back from the left (Web Animations API, no `@angular/animations`,\n * reduced-motion aware). Panel content drives navigation through the `stack`\n * handed to a template, or injected (`XUI_PANEL_STACK`) by a component panel.\n */\n@Component({\n selector: 'xui-panel-stack',\n imports: [NgTemplateOutlet, NgComponentOutlet, NgIcon, XuiIcon],\n viewProviders: [provideIcons({ matChevronLeftRound })],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (showPanelHeader()) {\n <header class=\"border-border flex h-(--control-height-lg) shrink-0 items-center border-b px-1\">\n @if (depth() > 1) {\n <button\n type=\"button\"\n class=\"text-foreground-muted hover:bg-hover-overlay hover:text-foreground flex h-(--control-height-md) items-center gap-0.5 rounded-md ps-1.5 pe-3 text-sm\"\n (click)=\"closePanel()\"\n >\n <ng-icon xui size=\"md\" name=\"matChevronLeftRound\" />\n {{ previousTitle() }}\n </button>\n }\n <span class=\"text-foreground pointer-events-none absolute left-1/2 -translate-x-1/2 text-sm font-semibold\">\n {{ current().title }}\n </span>\n </header>\n }\n\n <div #view class=\"min-h-0 flex-1 overflow-auto\">\n @if (templateContent(); as tpl) {\n <ng-container *ngTemplateOutlet=\"tpl; context: { $implicit: current().data, stack: controller }\" />\n } @else if (componentContent(); as cmp) {\n <ng-container *ngComponentOutlet=\"cmp; injector: panelInjector()\" />\n }\n </div>\n `,\n host: {\n '[class]': 'computedClass()'\n }\n})\nexport class XuiPanelStack<D = unknown> {\n private readonly host = inject(Injector);\n private readonly view = viewChild.required<ElementRef<HTMLElement>>('view');\n\n /** The user-defined classes. Merged last so they win over the base classes. */\n readonly class = input<ClassValue>('');\n /** The panel at the bottom of the stack. It cannot be popped — there is always something to show. */\n readonly initialPanel = input.required<XuiPanel<D>>();\n /** Show the header with the panel title and its back button. Turn it off to supply your own navigation. */\n readonly showPanelHeader = input<boolean, BooleanInput>(true, { transform: booleanAttribute });\n\n /** Emits the panel that was just pushed onto the stack. */\n readonly opened = output<XuiPanel>();\n /** Emits the panel that was just popped off the stack. */\n readonly closed = output<XuiPanel>();\n\n private readonly stack = signal<XuiPanel[]>([]);\n\n protected readonly current = computed(() => {\n const panels = this.stack();\n\n return panels.length ? panels[panels.length - 1] : (this.initialPanel() as XuiPanel);\n });\n protected readonly depth = computed(() => Math.max(this.stack().length, 1));\n protected readonly previousTitle = computed(() => {\n const panels = this.stack();\n\n return panels.length > 1 ? panels[panels.length - 2].title : '';\n });\n\n /** The handle passed to template panels and provided to component panels. */\n protected readonly controller = {\n openPanel: <P>(panel: XuiPanel<P>) => this.openPanel(panel as XuiPanel),\n closePanel: () => this.closePanel()\n };\n\n protected readonly templateContent = computed(() => {\n const content = this.current().content;\n\n return content instanceof TemplateRef ? (content as TemplateRef<unknown>) : null;\n });\n protected readonly componentContent = computed(() => {\n const content = this.current().content;\n\n return content instanceof TemplateRef ? null : content;\n });\n\n protected readonly panelInjector = computed(() =>\n Injector.create({\n providers: [\n { provide: XUI_PANEL_STACK, useValue: this.controller },\n { provide: XUI_PANEL_DATA, useValue: this.current().data }\n ],\n parent: this.host\n })\n );\n\n protected readonly computedClass = computed(() =>\n xui('bg-surface-raised border-border relative flex flex-col overflow-hidden rounded-lg border', this.class())\n );\n\n constructor() {\n // Seed the stack from the initial panel once it is available.\n effect(() => {\n const initial = this.initialPanel();\n\n untracked(() => {\n if (!this.stack().length) {\n this.stack.set([initial]);\n }\n });\n });\n\n // Slide whenever the depth changes — right-to-left on push, the reverse on pop.\n let previousDepth = 1;\n\n effect(() => {\n const depth = this.depth();\n\n untracked(() => {\n if (depth !== previousDepth) {\n this.slide(depth > previousDepth ? 1 : -1);\n previousDepth = depth;\n }\n });\n });\n }\n\n openPanel<P>(panel: XuiPanel<P>): void {\n this.stack.update(panels => [...panels, panel as XuiPanel]);\n this.opened.emit(panel as XuiPanel);\n }\n\n closePanel(): void {\n const panels = this.stack();\n\n if (panels.length <= 1) {\n return;\n }\n\n this.stack.set(panels.slice(0, -1));\n this.closed.emit(panels[panels.length - 1]);\n }\n\n private slide(direction: 1 | -1): void {\n if (globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches) {\n return;\n }\n\n const element = this.view().nativeElement;\n element.animate(\n [\n { transform: `translateX(${direction * 24}px)`, opacity: 0 },\n { transform: 'none', opacity: 1 }\n ],\n {\n duration: 180,\n easing: 'ease-out'\n }\n );\n }\n}\n","import { XuiPanelStack } from './lib/panel-stack';\n\nexport * from './lib/panel-stack';\nexport * from './lib/panel-stack.types';\n\nexport const XuiPanelStackImports = [XuiPanelStack] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xui/panel-stack",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.22",
|
|
4
4
|
"description": "Modern Angular 22 UI Library based on TailwindCSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"@angular/core": "22",
|
|
42
42
|
"@ng-icons/core": "34",
|
|
43
43
|
"@ng-icons/material-icons": "34",
|
|
44
|
-
"@xui/core": "2.0.0-alpha.
|
|
45
|
-
"@xui/icon": "2.0.0-alpha.
|
|
44
|
+
"@xui/core": "2.0.0-alpha.22",
|
|
45
|
+
"@xui/icon": "2.0.0-alpha.22",
|
|
46
46
|
"clsx": "^2.1.1"
|
|
47
47
|
},
|
|
48
48
|
"publishConfig": {
|
|
@@ -56,9 +56,13 @@ declare class XuiPanelStack<D = unknown> {
|
|
|
56
56
|
private readonly view;
|
|
57
57
|
/** The user-defined classes. Merged last so they win over the base classes. */
|
|
58
58
|
readonly class: _angular_core.InputSignal<ClassValue>;
|
|
59
|
+
/** The panel at the bottom of the stack. It cannot be popped — there is always something to show. */
|
|
59
60
|
readonly initialPanel: _angular_core.InputSignal<XuiPanel<D>>;
|
|
61
|
+
/** Show the header with the panel title and its back button. Turn it off to supply your own navigation. */
|
|
60
62
|
readonly showPanelHeader: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
|
|
63
|
+
/** Emits the panel that was just pushed onto the stack. */
|
|
61
64
|
readonly opened: _angular_core.OutputEmitterRef<XuiPanel<unknown>>;
|
|
65
|
+
/** Emits the panel that was just popped off the stack. */
|
|
62
66
|
readonly closed: _angular_core.OutputEmitterRef<XuiPanel<unknown>>;
|
|
63
67
|
private readonly stack;
|
|
64
68
|
protected readonly current: _angular_core.Signal<XuiPanel<unknown>>;
|