@frame-kit/ui-ng 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +33 -2
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +46 -12
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -1
- package/package.json +1 -1
- package/types/frame-kit-ui-ng-ui-dialog.d.ts +20 -1
- package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +50 -5
- package/ui/dialog/README.md +1 -0
- package/ui/wizard-dialog/README.md +74 -0
|
@@ -170,11 +170,11 @@ class DialogComponent {
|
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
173
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DialogComponent, isStandalone: true, selector: "fk-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, preventClose: { classPropertyName: "preventClose", publicName: "preventClose", isSignal: true, isRequired: false, transformFunction: null }, canClose: { classPropertyName: "canClose", publicName: "canClose", isSignal: true, isRequired: false, transformFunction: null }, fullscreenMobile: { classPropertyName: "fullscreenMobile", publicName: "fullscreenMobile", isSignal: true, isRequired: false, transformFunction: null }, flexBody: { classPropertyName: "flexBody", publicName: "flexBody", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openChange: "openChange", beforeOpen: "beforeOpen", opened: "opened", beforeClose: "beforeClose", closed: "closed" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, queries: [{ propertyName: "customHeader", first: true, predicate: FkDialogHeaderDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n", styles: [":host{display:contents}.fk-dialog__panel{display:flex;flex-direction:column;background:var(--fk-dialog-panel-bg, var(--fk-color-surface, #ffffff));border:var(--fk-dialog-panel-border, none);border-radius:var(--fk-dialog-panel-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-dialog-panel-shadow, 0 8px 32px rgba(0, 0, 0, .12));max-height:var(--fk-dialog-panel-max-height, 85vh);width:calc(100vw - 2 * var(--fk-dialog-panel-margin, var(--fk-rhythm-4, 1rem)));overflow:clip}.fk-dialog__panel--sm{max-width:var(--fk-dialog-width-sm, 24rem)}.fk-dialog__panel--md{max-width:var(--fk-dialog-width-md, 32rem)}.fk-dialog__panel--lg{max-width:var(--fk-dialog-width-lg, 40rem)}.fk-dialog__panel--xl{max-width:var(--fk-dialog-width-xl, 52rem)}.fk-dialog__panel--fullscreen{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}@media(max-width:47.999em){.fk-dialog__panel--fullscreen-auto{max-width:none;max-height:none;width:100%;height:100%;border-radius:0}}.fk-dialog__panel--top{align-self:flex-start}.fk-dialog__panel.fk-dialog__animate-panel--scale-fade{animation:fk-dialog-scale-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--scale-fade{animation:fk-dialog-scale-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--fade{animation:fk-dialog-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--fade{animation:fk-dialog-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-up{animation:fk-dialog-slide-up-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-up{animation:fk-dialog-slide-up-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-down{animation:fk-dialog-slide-down-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-down{animation:fk-dialog-slide-down-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__header{display:flex;align-items:center;justify-content:center;position:relative;padding:var(--fk-dialog-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem)));flex-shrink:0}.fk-dialog__title{font-family:var(--fk-dialog-title-font-family, var(--fk-font-family-display, var(--fk-font-family-base, sans-serif)));font-size:var(--fk-typography-h4-font-size, 1.125rem);font-weight:var(--fk-font-weight-semibold, 600);color:var(--fk-color-text, #1f2d3d);line-height:var(--fk-typography-h4-line-height, 1.25);padding-inline-end:var(--fk-rhythm-7, 2rem)}.fk-dialog__close{position:absolute;right:var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem));display:flex;align-items:center;justify-content:center;width:var(--fk-dialog-close-size, 2rem);height:var(--fk-dialog-close-size, 2rem);padding:0;border:none;border-radius:var(--fk-radius-sm, .25rem);background:transparent;color:var(--fk-dialog-close-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-font-size-xl, 1.25rem);line-height:1;cursor:pointer;transition:color .15s ease,background-color .15s ease}.fk-dialog__close:hover{color:var(--fk-dialog-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-color-surface-muted, #f7f9fb)}.fk-dialog__close:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-dialog__body{flex:1;padding:var(--fk-dialog-body-padding, var(--fk-rhythm-6, 1.5rem));overflow-y:auto;overscroll-behavior:contain;container-type:inline-size}.fk-dialog__body--flex{display:flex;flex-direction:column;overflow:hidden}::ng-deep [libDialogFooter]{display:flex;align-items:center;justify-content:center;gap:var(--fk-dialog-footer-gap, .75rem);padding:var(--fk-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}::ng-deep [libDialogFooter]>*{flex:1 1 0;min-width:0}::ng-deep [fkDialogActions]{display:flex;gap:var(--fk-dialog-actions-gap, var(--fk-rhythm-3, .75rem));margin-top:var(--fk-dialog-actions-margin-top, var(--fk-rhythm-5, 1.25rem))}::ng-deep [fkDialogActions]>*{flex:1 1 0;min-width:0}@container (max-width: 24rem){::ng-deep [fkDialogActions]{flex-direction:column-reverse}::ng-deep [fkDialogActions]>*{flex:none;width:100%}}@keyframes fk-dialog-scale-fade-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fk-dialog-scale-fade-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes fk-dialog-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-dialog-fade-out{0%{opacity:1}to{opacity:0}}@keyframes fk-dialog-slide-up-in{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-up-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes fk-dialog-slide-down-in{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-down-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-1rem)}}@media(prefers-reduced-motion:reduce){.fk-dialog__animate-panel--scale-fade,.fk-dialog__animate-panel--fade,.fk-dialog__animate-panel--slide-up,.fk-dialog__animate-panel--slide-down,.fk-dialog__animate-panel-out--scale-fade,.fk-dialog__animate-panel-out--fade,.fk-dialog__animate-panel-out--slide-up,.fk-dialog__animate-panel-out--slide-down{animation:none}}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
173
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DialogComponent, isStandalone: true, selector: "fk-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, preventClose: { classPropertyName: "preventClose", publicName: "preventClose", isSignal: true, isRequired: false, transformFunction: null }, canClose: { classPropertyName: "canClose", publicName: "canClose", isSignal: true, isRequired: false, transformFunction: null }, fullscreenMobile: { classPropertyName: "fullscreenMobile", publicName: "fullscreenMobile", isSignal: true, isRequired: false, transformFunction: null }, flexBody: { classPropertyName: "flexBody", publicName: "flexBody", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openChange: "openChange", beforeOpen: "beforeOpen", opened: "opened", beforeClose: "beforeClose", closed: "closed" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, queries: [{ propertyName: "customHeader", first: true, predicate: FkDialogHeaderDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n", styles: [":host{display:contents}.fk-dialog__panel{display:flex;flex-direction:column;background:var(--fk-dialog-panel-bg, var(--fk-color-surface, #ffffff));border:var(--fk-dialog-panel-border, none);border-radius:var(--fk-dialog-panel-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-dialog-panel-shadow, 0 8px 32px rgba(0, 0, 0, .12));max-height:var(--fk-dialog-panel-max-height, 85vh);width:calc(100vw - 2 * var(--fk-dialog-panel-margin, var(--fk-rhythm-4, 1rem)));overflow:clip}.fk-dialog__panel--sm{max-width:var(--fk-dialog-width-sm, 24rem)}.fk-dialog__panel--md{max-width:var(--fk-dialog-width-md, 32rem)}.fk-dialog__panel--lg{max-width:var(--fk-dialog-width-lg, 40rem)}.fk-dialog__panel--xl{max-width:var(--fk-dialog-width-xl, 52rem)}.fk-dialog__panel--fullscreen{max-width:none;max-height:none;width:100vw;height:100dvh;border-radius:0}@media(max-width:47.999em){.fk-dialog__panel--fullscreen-auto{max-width:none;max-height:none;width:100vw;height:100dvh;border-radius:0}}.fk-dialog__panel--top{align-self:flex-start}.fk-dialog__panel.fk-dialog__animate-panel--scale-fade{animation:fk-dialog-scale-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--scale-fade{animation:fk-dialog-scale-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--fade{animation:fk-dialog-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--fade{animation:fk-dialog-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-up{animation:fk-dialog-slide-up-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-up{animation:fk-dialog-slide-up-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-down{animation:fk-dialog-slide-down-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-down{animation:fk-dialog-slide-down-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__header{display:flex;align-items:center;justify-content:center;position:relative;padding:var(--fk-dialog-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem)));flex-shrink:0}.fk-dialog__title{font-family:var(--fk-dialog-title-font-family, var(--fk-font-family-display, var(--fk-font-family-base, sans-serif)));font-size:var(--fk-typography-h4-font-size, 1.125rem);font-weight:var(--fk-font-weight-semibold, 600);color:var(--fk-color-text, #1f2d3d);line-height:var(--fk-typography-h4-line-height, 1.25);padding-inline-end:var(--fk-rhythm-7, 2rem)}.fk-dialog__close{position:absolute;right:var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem));display:flex;align-items:center;justify-content:center;width:var(--fk-dialog-close-size, 2rem);height:var(--fk-dialog-close-size, 2rem);padding:0;border:none;border-radius:var(--fk-radius-sm, .25rem);background:transparent;color:var(--fk-dialog-close-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-font-size-xl, 1.25rem);line-height:1;cursor:pointer;transition:color .15s ease,background-color .15s ease}.fk-dialog__close:hover{color:var(--fk-dialog-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-color-surface-muted, #f7f9fb)}.fk-dialog__close:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-dialog__body{flex:1;padding:var(--fk-dialog-body-padding, var(--fk-rhythm-6, 1.5rem));overflow-y:auto;overscroll-behavior:contain;container-type:inline-size}.fk-dialog__body--flex{display:flex;flex-direction:column;overflow:hidden}::ng-deep [libDialogFooter]{display:flex;align-items:center;justify-content:center;gap:var(--fk-dialog-footer-gap, .75rem);padding:var(--fk-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}::ng-deep [libDialogFooter]>*{flex:1 1 0;min-width:0}::ng-deep [fkDialogActions]{display:flex;gap:var(--fk-dialog-actions-gap, var(--fk-rhythm-3, .75rem));margin-top:var(--fk-dialog-actions-margin-top, var(--fk-rhythm-5, 1.25rem))}::ng-deep [fkDialogActions]>*{flex:1 1 0;min-width:0}@container (max-width: 24rem){::ng-deep [fkDialogActions]{flex-direction:column-reverse}::ng-deep [fkDialogActions]>*{flex:none;width:100%}}@keyframes fk-dialog-scale-fade-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fk-dialog-scale-fade-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes fk-dialog-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-dialog-fade-out{0%{opacity:1}to{opacity:0}}@keyframes fk-dialog-slide-up-in{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-up-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes fk-dialog-slide-down-in{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-down-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-1rem)}}@media(prefers-reduced-motion:reduce){.fk-dialog__animate-panel--scale-fade,.fk-dialog__animate-panel--fade,.fk-dialog__animate-panel--slide-up,.fk-dialog__animate-panel--slide-down,.fk-dialog__animate-panel-out--scale-fade,.fk-dialog__animate-panel-out--fade,.fk-dialog__animate-panel-out--slide-up,.fk-dialog__animate-panel-out--slide-down{animation:none}}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
174
174
|
}
|
|
175
175
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DialogComponent, decorators: [{
|
|
176
176
|
type: Component,
|
|
177
|
-
args: [{ selector: 'fk-dialog', standalone: true, imports: [A11yModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n", styles: [":host{display:contents}.fk-dialog__panel{display:flex;flex-direction:column;background:var(--fk-dialog-panel-bg, var(--fk-color-surface, #ffffff));border:var(--fk-dialog-panel-border, none);border-radius:var(--fk-dialog-panel-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-dialog-panel-shadow, 0 8px 32px rgba(0, 0, 0, .12));max-height:var(--fk-dialog-panel-max-height, 85vh);width:calc(100vw - 2 * var(--fk-dialog-panel-margin, var(--fk-rhythm-4, 1rem)));overflow:clip}.fk-dialog__panel--sm{max-width:var(--fk-dialog-width-sm, 24rem)}.fk-dialog__panel--md{max-width:var(--fk-dialog-width-md, 32rem)}.fk-dialog__panel--lg{max-width:var(--fk-dialog-width-lg, 40rem)}.fk-dialog__panel--xl{max-width:var(--fk-dialog-width-xl, 52rem)}.fk-dialog__panel--fullscreen{max-width:none;max-height:none;width:
|
|
177
|
+
args: [{ selector: 'fk-dialog', standalone: true, imports: [A11yModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n", styles: [":host{display:contents}.fk-dialog__panel{display:flex;flex-direction:column;background:var(--fk-dialog-panel-bg, var(--fk-color-surface, #ffffff));border:var(--fk-dialog-panel-border, none);border-radius:var(--fk-dialog-panel-border-radius, var(--fk-radius-lg, .75rem));box-shadow:var(--fk-dialog-panel-shadow, 0 8px 32px rgba(0, 0, 0, .12));max-height:var(--fk-dialog-panel-max-height, 85vh);width:calc(100vw - 2 * var(--fk-dialog-panel-margin, var(--fk-rhythm-4, 1rem)));overflow:clip}.fk-dialog__panel--sm{max-width:var(--fk-dialog-width-sm, 24rem)}.fk-dialog__panel--md{max-width:var(--fk-dialog-width-md, 32rem)}.fk-dialog__panel--lg{max-width:var(--fk-dialog-width-lg, 40rem)}.fk-dialog__panel--xl{max-width:var(--fk-dialog-width-xl, 52rem)}.fk-dialog__panel--fullscreen{max-width:none;max-height:none;width:100vw;height:100dvh;border-radius:0}@media(max-width:47.999em){.fk-dialog__panel--fullscreen-auto{max-width:none;max-height:none;width:100vw;height:100dvh;border-radius:0}}.fk-dialog__panel--top{align-self:flex-start}.fk-dialog__panel.fk-dialog__animate-panel--scale-fade{animation:fk-dialog-scale-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--scale-fade{animation:fk-dialog-scale-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--fade{animation:fk-dialog-fade-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--fade{animation:fk-dialog-fade-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-up{animation:fk-dialog-slide-up-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-up{animation:fk-dialog-slide-up-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel--slide-down{animation:fk-dialog-slide-down-in .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__panel.fk-dialog__animate-panel-out--slide-down{animation:fk-dialog-slide-down-out .2s cubic-bezier(.4,0,.2,1) both}.fk-dialog__header{display:flex;align-items:center;justify-content:center;position:relative;padding:var(--fk-dialog-header-padding, var(--fk-rhythm-4, 1rem) var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem)));flex-shrink:0}.fk-dialog__title{font-family:var(--fk-dialog-title-font-family, var(--fk-font-family-display, var(--fk-font-family-base, sans-serif)));font-size:var(--fk-typography-h4-font-size, 1.125rem);font-weight:var(--fk-font-weight-semibold, 600);color:var(--fk-color-text, #1f2d3d);line-height:var(--fk-typography-h4-line-height, 1.25);padding-inline-end:var(--fk-rhythm-7, 2rem)}.fk-dialog__close{position:absolute;right:var(--fk-dialog-header-padding-inline, var(--fk-rhythm-6, 1.5rem));display:flex;align-items:center;justify-content:center;width:var(--fk-dialog-close-size, 2rem);height:var(--fk-dialog-close-size, 2rem);padding:0;border:none;border-radius:var(--fk-radius-sm, .25rem);background:transparent;color:var(--fk-dialog-close-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-font-size-xl, 1.25rem);line-height:1;cursor:pointer;transition:color .15s ease,background-color .15s ease}.fk-dialog__close:hover{color:var(--fk-dialog-close-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-color-surface-muted, #f7f9fb)}.fk-dialog__close:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-dialog__body{flex:1;padding:var(--fk-dialog-body-padding, var(--fk-rhythm-6, 1.5rem));overflow-y:auto;overscroll-behavior:contain;container-type:inline-size}.fk-dialog__body--flex{display:flex;flex-direction:column;overflow:hidden}::ng-deep [libDialogFooter]{display:flex;align-items:center;justify-content:center;gap:var(--fk-dialog-footer-gap, .75rem);padding:var(--fk-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}::ng-deep [libDialogFooter]>*{flex:1 1 0;min-width:0}::ng-deep [fkDialogActions]{display:flex;gap:var(--fk-dialog-actions-gap, var(--fk-rhythm-3, .75rem));margin-top:var(--fk-dialog-actions-margin-top, var(--fk-rhythm-5, 1.25rem))}::ng-deep [fkDialogActions]>*{flex:1 1 0;min-width:0}@container (max-width: 24rem){::ng-deep [fkDialogActions]{flex-direction:column-reverse}::ng-deep [fkDialogActions]>*{flex:none;width:100%}}@keyframes fk-dialog-scale-fade-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fk-dialog-scale-fade-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}@keyframes fk-dialog-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fk-dialog-fade-out{0%{opacity:1}to{opacity:0}}@keyframes fk-dialog-slide-up-in{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-up-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes fk-dialog-slide-down-in{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes fk-dialog-slide-down-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-1rem)}}@media(prefers-reduced-motion:reduce){.fk-dialog__animate-panel--scale-fade,.fk-dialog__animate-panel--fade,.fk-dialog__animate-panel--slide-up,.fk-dialog__animate-panel--slide-down,.fk-dialog__animate-panel-out--scale-fade,.fk-dialog__animate-panel-out--fade,.fk-dialog__animate-panel-out--slide-up,.fk-dialog__animate-panel-out--slide-down{animation:none}}\n"] }]
|
|
178
178
|
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], restoreFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocus", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], preventClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventClose", required: false }] }], canClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "canClose", required: false }] }], fullscreenMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullscreenMobile", required: false }] }], flexBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "flexBody", required: false }] }], customHeader: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FkDialogHeaderDirective), { isSignal: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], openChange: [{ type: i0.Output, args: ["openChange"] }], beforeOpen: [{ type: i0.Output, args: ["beforeOpen"] }], opened: [{ type: i0.Output, args: ["opened"] }], beforeClose: [{ type: i0.Output, args: ["beforeClose"] }], closed: [{ type: i0.Output, args: ["closed"] }], hostClass: [{
|
|
179
179
|
type: HostBinding,
|
|
180
180
|
args: ['class']
|
|
@@ -207,15 +207,41 @@ class DialogRef {
|
|
|
207
207
|
afterOpenedSubject = new Subject();
|
|
208
208
|
beforeCloseSubject = new Subject();
|
|
209
209
|
afterClosedSubject = new Subject();
|
|
210
|
+
sizeSignal;
|
|
210
211
|
closed = false;
|
|
211
212
|
closeGuard = null;
|
|
213
|
+
sizeUpdater = null;
|
|
212
214
|
config;
|
|
215
|
+
/**
|
|
216
|
+
* The dialog's current panel size. Starts at the opening config's size
|
|
217
|
+
* and tracks every `updateSize` call — chrome components (e.g. an
|
|
218
|
+
* expand/collapse toggle) can render their state from it.
|
|
219
|
+
*/
|
|
220
|
+
size;
|
|
213
221
|
constructor(config = {}) {
|
|
214
222
|
this.config = config;
|
|
223
|
+
this.sizeSignal = signal(config.size ?? 'md', ...(ngDevMode ? [{ debugName: "sizeSignal" }] : /* istanbul ignore next */ []));
|
|
224
|
+
this.size = this.sizeSignal.asReadonly();
|
|
215
225
|
if (config.canClose) {
|
|
216
226
|
this.closeGuard = config.canClose;
|
|
217
227
|
}
|
|
218
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Resize the open dialog in place — e.g. toggle between the opened
|
|
231
|
+
* size and `"fullscreen"` from an expand button in custom chrome. The
|
|
232
|
+
* panel transitions its size classes reactively; no reopen needed.
|
|
233
|
+
*/
|
|
234
|
+
updateSize(size) {
|
|
235
|
+
this.sizeSignal.set(size);
|
|
236
|
+
this.sizeUpdater?.(size);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* @internal Wired by DialogService after the host is created so
|
|
240
|
+
* `updateSize` can reach the host component's `size` input.
|
|
241
|
+
*/
|
|
242
|
+
bindSizeUpdater(updater) {
|
|
243
|
+
this.sizeUpdater = updater;
|
|
244
|
+
}
|
|
219
245
|
get data() {
|
|
220
246
|
return this.config.data;
|
|
221
247
|
}
|
|
@@ -333,6 +359,11 @@ class DialogService {
|
|
|
333
359
|
};
|
|
334
360
|
this.activeDialogs.push(entry);
|
|
335
361
|
this.applyConfig(hostRef, mergedConfig);
|
|
362
|
+
// Let ref.updateSize() reach the live host — `size` is a reactive
|
|
363
|
+
// input, so the panel restyles in place without reopening.
|
|
364
|
+
dialogRef.bindSizeUpdater((size) => {
|
|
365
|
+
hostRef.setInput('size', size);
|
|
366
|
+
});
|
|
336
367
|
// CDK dispatches these to the top overlay only, so Escape / an outside
|
|
337
368
|
// press dismisses the topmost dialog. `dialogRef.close()` runs the
|
|
338
369
|
// preventClose + canClose guards.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-kit-ui-ng-ui-dialog.mjs","sources":["../../../../packages/ui-ng/ui/dialog/dialog-header.directive.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.html","../../../../packages/ui-ng/ui/dialog/dialog.config.ts","../../../../packages/ui-ng/ui/dialog/dialog-ref.ts","../../../../packages/ui-ng/ui/dialog/dialog.service.ts","../../../../packages/ui-ng/ui/dialog/dialog-actions.directive.ts","../../../../packages/ui-ng/ui/dialog/frame-kit-ui-ng-ui-dialog.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogHeader]',\n standalone: true,\n})\nexport class FkDialogHeaderDirective {}\n","import { A11yModule } from '@angular/cdk/a11y';\nimport { DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n HostBinding,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\nimport { FkDialogHeaderDirective } from './dialog-header.directive';\n\nlet nextDialogId = 0;\n\n/**\n * Dialog panel chrome.\n *\n * Hosted inside a CDK overlay by `DialogService`, so the overlay layer owns\n * the backdrop, scroll blocking, positioning, stacking, and Escape / outside\n * dispatch. This component renders the panel itself: header / body / footer\n * projection, sizing, the enter animation, focus trapping, and the close\n * guard.\n */\n@Component({\n selector: 'fk-dialog',\n standalone: true,\n imports: [A11yModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './dialog.component.html',\n styleUrl: './dialog.component.scss',\n})\nexport class DialogComponent {\n // ===== INPUTS =====\n /** Controls whether the dialog is open. */\n readonly open = input(false);\n /** When true, marks the panel `aria-modal` and traps focus. */\n readonly modal = input(true);\n /** When true, shows the close button in the dialog header. */\n readonly closable = input(true);\n /** Size variant that controls the dialog's max-width. */\n readonly size = input<DialogSize>('md');\n /** Where the dialog is anchored on screen. */\n readonly position = input<DialogPosition>('center');\n /** Optional title text rendered in the dialog header and used for `aria-labelledby`. */\n readonly header = input<string | null>(null);\n /** When true, focus returns to the previously focused element when the dialog closes. */\n readonly restoreFocus = input(true);\n /** When true, CDK auto-focus is applied when the dialog opens. */\n readonly autoFocus = input(true);\n /** Entry/exit animation applied to the dialog panel. */\n readonly animation = input<DialogAnimation>('scale-fade');\n /** When true, all close mechanisms (Escape, backdrop, button) are blocked. */\n readonly preventClose = input(false);\n /** Async guard function called before closing; return false to cancel the close. */\n readonly canClose = input<CanCloseFn | null>(null);\n /** When true, the dialog expands to full-screen on mobile viewports. */\n readonly fullscreenMobile = input(false);\n /** When true, the dialog body uses a flex column layout. */\n readonly flexBody = input(false);\n\n // ===== CONTENT CHILDREN =====\n readonly customHeader = contentChild(FkDialogHeaderDirective);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n readonly ariaDescribedBy = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires when the dialog's open state should change, emitting the new boolean. */\n readonly openChange = output<boolean>();\n /** Fires immediately before the dialog begins its open animation. */\n readonly beforeOpen = output<void>();\n /** Fires after the dialog is fully open and visible. */\n readonly opened = output<void>();\n /** Fires immediately before the dialog begins its close animation. */\n readonly beforeClose = output<void>();\n /** Fires after the dialog is fully closed. */\n readonly closed = output<void>();\n\n // ===== INTERNAL STATE =====\n private readonly doc = inject(DOCUMENT);\n readonly titleId = `fk-dialog-title-${nextDialogId++}`;\n private previouslyFocusedElement: HTMLElement | null = null;\n private closeGuardRunning = false;\n\n /** Whether the dialog DOM is rendered (stays true during exit animation). */\n readonly visible = signal(false);\n\n /** Whether the dialog is animating out. */\n readonly animatingOut = signal(false);\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return ['fk-dialog', this.className()].filter(Boolean).join(' ');\n });\n\n readonly ariaLabelledBy = computed(() => {\n if (this.ariaLabel()) {\n return null;\n }\n\n return this.header() ? this.titleId : null;\n });\n\n constructor() {\n effect(() => {\n const isOpen = this.open();\n\n if (isOpen) {\n this.onDialogOpen();\n } else {\n this.onDialogClose();\n }\n });\n }\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.id')\n get hostId() {\n return this.id();\n }\n\n // ===== ACTIONS =====\n /** Closes the dialog, running any `canClose` guard first; no-ops when `preventClose` is true. */\n async close() {\n if (this.closeGuardRunning) {\n return;\n }\n\n if (this.preventClose()) {\n return;\n }\n\n const guard = this.canClose();\n\n if (guard) {\n this.closeGuardRunning = true;\n\n try {\n const allowed = await Promise.resolve(guard());\n\n if (!allowed) {\n return;\n }\n } finally {\n this.closeGuardRunning = false;\n }\n }\n\n this.beforeClose.emit();\n this.openChange.emit(false);\n this.closed.emit();\n }\n\n /** Called when the panel exit animation finishes. */\n onExitAnimationDone() {\n if (this.animatingOut()) {\n this.animatingOut.set(false);\n this.visible.set(false);\n }\n }\n\n // ===== LIFECYCLE =====\n private onDialogOpen() {\n this.previouslyFocusedElement =\n (this.doc.activeElement as HTMLElement) ?? null;\n\n this.beforeOpen.emit();\n this.animatingOut.set(false);\n this.visible.set(true);\n this.opened.emit();\n }\n\n private onDialogClose() {\n if (this.visible()) {\n if (this.animation() !== 'none') {\n this.animatingOut.set(true);\n } else {\n this.visible.set(false);\n }\n }\n\n if (this.restoreFocus() && this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n }\n}\n","@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n","import type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\n\nexport interface DialogConfig<TData = unknown> {\n modal?: boolean;\n closable?: boolean;\n closeOnEscape?: boolean;\n closeOnBackdrop?: boolean;\n size?: DialogSize;\n position?: DialogPosition;\n animation?: DialogAnimation;\n header?: string | null;\n restoreFocus?: boolean;\n autoFocus?: boolean;\n preventClose?: boolean;\n canClose?: CanCloseFn;\n fullscreenMobile?: boolean;\n flexBody?: boolean;\n className?: string;\n ariaLabel?: string | null;\n ariaDescribedBy?: string | null;\n data?: TData;\n}\n\nexport const DEFAULT_DIALOG_CONFIG: DialogConfig = {\n modal: true,\n closable: true,\n closeOnEscape: true,\n closeOnBackdrop: false,\n size: 'md',\n position: 'center',\n animation: 'scale-fade',\n header: null,\n restoreFocus: true,\n autoFocus: true,\n preventClose: false,\n fullscreenMobile: false,\n flexBody: false,\n className: '',\n ariaLabel: null,\n ariaDescribedBy: null,\n};\n","import { Observable, Subject } from 'rxjs';\nimport { take } from 'rxjs/operators';\n\nimport type { DialogConfig } from './dialog.config';\nimport type { CanCloseFn } from './dialog.types';\n\nexport class DialogRef<TResult = unknown, TData = unknown> {\n private readonly beforeOpenSubject = new Subject<void>();\n private readonly afterOpenedSubject = new Subject<void>();\n private readonly beforeCloseSubject = new Subject<void>();\n private readonly afterClosedSubject = new Subject<TResult | undefined>();\n private closed = false;\n private closeGuard: CanCloseFn | null = null;\n\n readonly config: DialogConfig<TData>;\n\n constructor(config: DialogConfig<TData> = {} as DialogConfig<TData>) {\n this.config = config;\n\n if (config.canClose) {\n this.closeGuard = config.canClose;\n }\n }\n\n get data(): TData | undefined {\n return this.config.data;\n }\n\n setCanClose(guard: CanCloseFn | null) {\n this.closeGuard = guard;\n }\n\n async close(result?: TResult) {\n if (this.closed) {\n return;\n }\n\n if (this.config.preventClose) {\n return;\n }\n\n if (this.closeGuard) {\n const allowed = await Promise.resolve(this.closeGuard());\n\n if (!allowed) {\n return;\n }\n }\n\n this.beforeCloseSubject.next();\n this.beforeCloseSubject.complete();\n\n this.closed = true;\n this.afterClosedSubject.next(result);\n this.afterClosedSubject.complete();\n }\n\n beforeOpen(): Observable<void> {\n return this.beforeOpenSubject.asObservable().pipe(take(1));\n }\n\n afterOpened(): Observable<void> {\n return this.afterOpenedSubject.asObservable().pipe(take(1));\n }\n\n beforeClose(): Observable<void> {\n return this.beforeCloseSubject.asObservable().pipe(take(1));\n }\n\n afterClosed(): Observable<TResult | undefined> {\n return this.afterClosedSubject.asObservable().pipe(take(1));\n }\n\n /** @internal */\n markBeforeOpen() {\n this.beforeOpenSubject.next();\n this.beforeOpenSubject.complete();\n }\n\n /** @internal */\n markOpened() {\n this.afterOpenedSubject.next();\n this.afterOpenedSubject.complete();\n }\n}\n","import { ESCAPE } from '@angular/cdk/keycodes';\nimport { Overlay, OverlayRef } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { DOCUMENT } from '@angular/common';\nimport {\n ApplicationRef,\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n inject,\n Injectable,\n Injector,\n Type,\n} from '@angular/core';\n\nimport { DialogComponent } from './dialog.component';\nimport { DEFAULT_DIALOG_CONFIG, DialogConfig } from './dialog.config';\nimport { DialogRef } from './dialog-ref';\n\nexport const DIALOG_DATA = Symbol('DIALOG_DATA');\nexport const DIALOG_REF = Symbol('DIALOG_REF');\n\ninterface DialogEntry {\n ref: DialogRef;\n overlayRef: OverlayRef;\n hostRef: ComponentRef<DialogComponent>;\n contentRef: ComponentRef<unknown>;\n}\n\n/**\n * Opens dialogs as CDK overlays.\n *\n * CDK owns the cross-cutting overlay concerns — backdrop, scroll blocking,\n * centered positioning, z-index stacking (overlays layer by open order), and\n * top-of-stack dispatch of Escape / outside clicks. The `DialogComponent` it\n * hosts is just the panel chrome (header / body / footer, sizing, enter\n * animation, focus trap). There is no global \"opening X closes lower overlays\"\n * rule: a dialog opened over a drawer stacks on top of it, and Escape / an\n * outside press dismisses whichever overlay is on top.\n */\n@Injectable({ providedIn: 'root' })\nexport class DialogService {\n private readonly overlay = inject(Overlay);\n private readonly appRef = inject(ApplicationRef);\n private readonly injector = inject(EnvironmentInjector);\n private readonly doc = inject(DOCUMENT);\n\n private activeDialogs: DialogEntry[] = [];\n\n get openCount(): number {\n return this.activeDialogs.length;\n }\n\n open<TResult = unknown, TData = unknown>(\n content: Type<unknown>,\n config?: DialogConfig<TData>,\n ): DialogRef<TResult, TData> {\n const mergedConfig = {\n ...DEFAULT_DIALOG_CONFIG,\n ...config,\n } as DialogConfig<TData>;\n const dialogRef = new DialogRef<TResult, TData>(mergedConfig);\n\n const positionStrategy = this.overlay\n .position()\n .global()\n .centerHorizontally();\n\n if (mergedConfig.position === 'top') {\n positionStrategy.top('10vh');\n } else {\n positionStrategy.centerVertically();\n }\n\n const overlayRef = this.overlay.create({\n hasBackdrop: mergedConfig.modal ?? true,\n backdropClass: 'fk-dialog__backdrop',\n panelClass: 'fk-dialog__pane',\n scrollStrategy: this.overlay.scrollStrategies.block(),\n positionStrategy,\n disposeOnNavigation: true,\n });\n\n const childInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: DIALOG_DATA as never, useValue: mergedConfig.data },\n { provide: DIALOG_REF as never, useValue: dialogRef },\n ],\n });\n\n const hostRef = overlayRef.attach(\n new ComponentPortal(DialogComponent, null, childInjector),\n );\n\n const contentRef = createComponent(content, {\n environmentInjector: this.injector,\n elementInjector: childInjector,\n hostElement: this.doc.createElement('div'),\n });\n\n this.appRef.attachView(contentRef.hostView);\n\n const entry: DialogEntry = {\n ref: dialogRef as DialogRef<unknown, unknown>,\n overlayRef,\n hostRef,\n contentRef,\n };\n\n this.activeDialogs.push(entry);\n\n this.applyConfig(hostRef, mergedConfig);\n\n // CDK dispatches these to the top overlay only, so Escape / an outside\n // press dismisses the topmost dialog. `dialogRef.close()` runs the\n // preventClose + canClose guards.\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.keyCode === ESCAPE && mergedConfig.closeOnEscape) {\n dialogRef.close();\n }\n });\n\n overlayRef.backdropClick().subscribe(() => {\n if (mergedConfig.closeOnBackdrop) {\n dialogRef.close();\n }\n });\n\n hostRef.instance.beforeOpen.subscribe(() => {\n dialogRef.markBeforeOpen();\n });\n\n hostRef.instance.opened.subscribe(() => {\n dialogRef.markOpened();\n });\n\n hostRef.instance.closed.subscribe(() => {\n dialogRef.close();\n });\n\n dialogRef.afterClosed().subscribe(() => {\n this.destroyDialog(entry);\n });\n\n hostRef.setInput('open', true);\n hostRef.changeDetectorRef.detectChanges();\n\n const panelBody =\n overlayRef.overlayElement.querySelector('.fk-dialog__body');\n\n if (panelBody) {\n panelBody.appendChild(contentRef.location.nativeElement);\n contentRef.changeDetectorRef.detectChanges();\n\n // Move [libDialogFooter] elements out of the body to the panel root so\n // they render in the pinned footer area (after fk-dialog__body).\n const panel = panelBody.closest('.fk-dialog__panel');\n const footerEls = panelBody.querySelectorAll('[libDialogFooter]');\n\n footerEls.forEach((el: Element) => {\n panel?.appendChild(el);\n });\n }\n\n return dialogRef;\n }\n\n closeAll() {\n [...this.activeDialogs].forEach((entry) => entry.ref.close());\n }\n\n private applyConfig(\n hostRef: ComponentRef<DialogComponent>,\n config: DialogConfig,\n ) {\n hostRef.setInput('modal', config.modal ?? true);\n hostRef.setInput('closable', config.closable ?? true);\n hostRef.setInput('size', config.size ?? 'md');\n hostRef.setInput('position', config.position ?? 'center');\n hostRef.setInput('animation', config.animation ?? 'scale-fade');\n hostRef.setInput('header', config.header ?? null);\n hostRef.setInput('restoreFocus', config.restoreFocus ?? true);\n hostRef.setInput('autoFocus', config.autoFocus ?? true);\n hostRef.setInput('className', config.className ?? '');\n hostRef.setInput('preventClose', config.preventClose ?? false);\n hostRef.setInput('canClose', config.canClose ?? null);\n hostRef.setInput('fullscreenMobile', config.fullscreenMobile ?? false);\n hostRef.setInput('flexBody', config.flexBody ?? false);\n hostRef.setInput('ariaLabel', config.ariaLabel ?? null);\n hostRef.setInput('ariaDescribedBy', config.ariaDescribedBy ?? null);\n }\n\n private destroyDialog(entry: DialogEntry) {\n const idx = this.activeDialogs.indexOf(entry);\n\n if (idx > -1) {\n this.activeDialogs.splice(idx, 1);\n }\n\n // Let the component restore focus before the overlay (and its hosted\n // component) are torn down.\n entry.hostRef.setInput('open', false);\n entry.hostRef.changeDetectorRef.detectChanges();\n\n this.appRef.detachView(entry.contentRef.hostView);\n entry.contentRef.destroy();\n\n // Disposing the overlay detaches + destroys the hosted DialogComponent,\n // removes the backdrop, and releases the scroll-block strategy.\n entry.overlayRef.dispose();\n }\n}\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogActions]',\n standalone: true,\n})\nexport class FkDialogActionsDirective {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-dialog.mjs","sources":["../../../../packages/ui-ng/ui/dialog/dialog-header.directive.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.ts","../../../../packages/ui-ng/ui/dialog/dialog.component.html","../../../../packages/ui-ng/ui/dialog/dialog.config.ts","../../../../packages/ui-ng/ui/dialog/dialog-ref.ts","../../../../packages/ui-ng/ui/dialog/dialog.service.ts","../../../../packages/ui-ng/ui/dialog/dialog-actions.directive.ts","../../../../packages/ui-ng/ui/dialog/frame-kit-ui-ng-ui-dialog.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogHeader]',\n standalone: true,\n})\nexport class FkDialogHeaderDirective {}\n","import { A11yModule } from '@angular/cdk/a11y';\nimport { DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n HostBinding,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\nimport { FkDialogHeaderDirective } from './dialog-header.directive';\n\nlet nextDialogId = 0;\n\n/**\n * Dialog panel chrome.\n *\n * Hosted inside a CDK overlay by `DialogService`, so the overlay layer owns\n * the backdrop, scroll blocking, positioning, stacking, and Escape / outside\n * dispatch. This component renders the panel itself: header / body / footer\n * projection, sizing, the enter animation, focus trapping, and the close\n * guard.\n */\n@Component({\n selector: 'fk-dialog',\n standalone: true,\n imports: [A11yModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './dialog.component.html',\n styleUrl: './dialog.component.scss',\n})\nexport class DialogComponent {\n // ===== INPUTS =====\n /** Controls whether the dialog is open. */\n readonly open = input(false);\n /** When true, marks the panel `aria-modal` and traps focus. */\n readonly modal = input(true);\n /** When true, shows the close button in the dialog header. */\n readonly closable = input(true);\n /** Size variant that controls the dialog's max-width. */\n readonly size = input<DialogSize>('md');\n /** Where the dialog is anchored on screen. */\n readonly position = input<DialogPosition>('center');\n /** Optional title text rendered in the dialog header and used for `aria-labelledby`. */\n readonly header = input<string | null>(null);\n /** When true, focus returns to the previously focused element when the dialog closes. */\n readonly restoreFocus = input(true);\n /** When true, CDK auto-focus is applied when the dialog opens. */\n readonly autoFocus = input(true);\n /** Entry/exit animation applied to the dialog panel. */\n readonly animation = input<DialogAnimation>('scale-fade');\n /** When true, all close mechanisms (Escape, backdrop, button) are blocked. */\n readonly preventClose = input(false);\n /** Async guard function called before closing; return false to cancel the close. */\n readonly canClose = input<CanCloseFn | null>(null);\n /** When true, the dialog expands to full-screen on mobile viewports. */\n readonly fullscreenMobile = input(false);\n /** When true, the dialog body uses a flex column layout. */\n readonly flexBody = input(false);\n\n // ===== CONTENT CHILDREN =====\n readonly customHeader = contentChild(FkDialogHeaderDirective);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n readonly ariaDescribedBy = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires when the dialog's open state should change, emitting the new boolean. */\n readonly openChange = output<boolean>();\n /** Fires immediately before the dialog begins its open animation. */\n readonly beforeOpen = output<void>();\n /** Fires after the dialog is fully open and visible. */\n readonly opened = output<void>();\n /** Fires immediately before the dialog begins its close animation. */\n readonly beforeClose = output<void>();\n /** Fires after the dialog is fully closed. */\n readonly closed = output<void>();\n\n // ===== INTERNAL STATE =====\n private readonly doc = inject(DOCUMENT);\n readonly titleId = `fk-dialog-title-${nextDialogId++}`;\n private previouslyFocusedElement: HTMLElement | null = null;\n private closeGuardRunning = false;\n\n /** Whether the dialog DOM is rendered (stays true during exit animation). */\n readonly visible = signal(false);\n\n /** Whether the dialog is animating out. */\n readonly animatingOut = signal(false);\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return ['fk-dialog', this.className()].filter(Boolean).join(' ');\n });\n\n readonly ariaLabelledBy = computed(() => {\n if (this.ariaLabel()) {\n return null;\n }\n\n return this.header() ? this.titleId : null;\n });\n\n constructor() {\n effect(() => {\n const isOpen = this.open();\n\n if (isOpen) {\n this.onDialogOpen();\n } else {\n this.onDialogClose();\n }\n });\n }\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.id')\n get hostId() {\n return this.id();\n }\n\n // ===== ACTIONS =====\n /** Closes the dialog, running any `canClose` guard first; no-ops when `preventClose` is true. */\n async close() {\n if (this.closeGuardRunning) {\n return;\n }\n\n if (this.preventClose()) {\n return;\n }\n\n const guard = this.canClose();\n\n if (guard) {\n this.closeGuardRunning = true;\n\n try {\n const allowed = await Promise.resolve(guard());\n\n if (!allowed) {\n return;\n }\n } finally {\n this.closeGuardRunning = false;\n }\n }\n\n this.beforeClose.emit();\n this.openChange.emit(false);\n this.closed.emit();\n }\n\n /** Called when the panel exit animation finishes. */\n onExitAnimationDone() {\n if (this.animatingOut()) {\n this.animatingOut.set(false);\n this.visible.set(false);\n }\n }\n\n // ===== LIFECYCLE =====\n private onDialogOpen() {\n this.previouslyFocusedElement =\n (this.doc.activeElement as HTMLElement) ?? null;\n\n this.beforeOpen.emit();\n this.animatingOut.set(false);\n this.visible.set(true);\n this.opened.emit();\n }\n\n private onDialogClose() {\n if (this.visible()) {\n if (this.animation() !== 'none') {\n this.animatingOut.set(true);\n } else {\n this.visible.set(false);\n }\n }\n\n if (this.restoreFocus() && this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n }\n}\n","@if (visible()) {\n <div\n class=\"fk-dialog__panel\"\n [class.fk-dialog__animate-panel--scale-fade]=\"\n animation() === 'scale-fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--fade]=\"\n animation() === 'fade' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-up]=\"\n animation() === 'slide-up' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel--slide-down]=\"\n animation() === 'slide-down' && !animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--scale-fade]=\"\n animation() === 'scale-fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--fade]=\"\n animation() === 'fade' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-up]=\"\n animation() === 'slide-up' && animatingOut()\n \"\n [class.fk-dialog__animate-panel-out--slide-down]=\"\n animation() === 'slide-down' && animatingOut()\n \"\n [class.fk-dialog__panel--sm]=\"size() === 'sm'\"\n [class.fk-dialog__panel--md]=\"size() === 'md'\"\n [class.fk-dialog__panel--lg]=\"size() === 'lg'\"\n [class.fk-dialog__panel--xl]=\"size() === 'xl'\"\n [class.fk-dialog__panel--fullscreen]=\"size() === 'fullscreen'\"\n [class.fk-dialog__panel--fullscreen-auto]=\"fullscreenMobile()\"\n [class.fk-dialog__panel--top]=\"position() === 'top'\"\n role=\"dialog\"\n [attr.aria-modal]=\"modal() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [cdkTrapFocus]=\"modal()\"\n [cdkTrapFocusAutoCapture]=\"autoFocus()\"\n (animationend)=\"onExitAnimationDone()\"\n >\n @if (customHeader() || header() || closable()) {\n <div class=\"fk-dialog__header\">\n <ng-content select=\"[fkDialogHeader]\" />\n\n @if (!customHeader() && header()) {\n <span class=\"fk-dialog__title\" [id]=\"titleId\">{{ header() }}</span>\n }\n\n @if (closable()) {\n <button\n class=\"fk-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n ×\n </button>\n }\n </div>\n }\n\n <div class=\"fk-dialog__body\" [class.fk-dialog__body--flex]=\"flexBody()\">\n <ng-content />\n </div>\n\n <ng-content select=\"[libDialogFooter]\" />\n </div>\n}\n","import type {\n CanCloseFn,\n DialogAnimation,\n DialogPosition,\n DialogSize,\n} from './dialog.types';\n\nexport interface DialogConfig<TData = unknown> {\n modal?: boolean;\n closable?: boolean;\n closeOnEscape?: boolean;\n closeOnBackdrop?: boolean;\n size?: DialogSize;\n position?: DialogPosition;\n animation?: DialogAnimation;\n header?: string | null;\n restoreFocus?: boolean;\n autoFocus?: boolean;\n preventClose?: boolean;\n canClose?: CanCloseFn;\n fullscreenMobile?: boolean;\n flexBody?: boolean;\n className?: string;\n ariaLabel?: string | null;\n ariaDescribedBy?: string | null;\n data?: TData;\n}\n\nexport const DEFAULT_DIALOG_CONFIG: DialogConfig = {\n modal: true,\n closable: true,\n closeOnEscape: true,\n closeOnBackdrop: false,\n size: 'md',\n position: 'center',\n animation: 'scale-fade',\n header: null,\n restoreFocus: true,\n autoFocus: true,\n preventClose: false,\n fullscreenMobile: false,\n flexBody: false,\n className: '',\n ariaLabel: null,\n ariaDescribedBy: null,\n};\n","import type { Signal } from '@angular/core';\nimport { signal } from '@angular/core';\n\nimport { Observable, Subject } from 'rxjs';\nimport { take } from 'rxjs/operators';\n\nimport type { DialogConfig } from './dialog.config';\nimport type { CanCloseFn, DialogSize } from './dialog.types';\n\nexport class DialogRef<TResult = unknown, TData = unknown> {\n private readonly beforeOpenSubject = new Subject<void>();\n private readonly afterOpenedSubject = new Subject<void>();\n private readonly beforeCloseSubject = new Subject<void>();\n private readonly afterClosedSubject = new Subject<TResult | undefined>();\n private readonly sizeSignal;\n private closed = false;\n private closeGuard: CanCloseFn | null = null;\n private sizeUpdater: ((size: DialogSize) => void) | null = null;\n\n readonly config: DialogConfig<TData>;\n\n /**\n * The dialog's current panel size. Starts at the opening config's size\n * and tracks every `updateSize` call — chrome components (e.g. an\n * expand/collapse toggle) can render their state from it.\n */\n readonly size: Signal<DialogSize>;\n\n constructor(config: DialogConfig<TData> = {} as DialogConfig<TData>) {\n this.config = config;\n this.sizeSignal = signal<DialogSize>(config.size ?? 'md');\n this.size = this.sizeSignal.asReadonly();\n\n if (config.canClose) {\n this.closeGuard = config.canClose;\n }\n }\n\n /**\n * Resize the open dialog in place — e.g. toggle between the opened\n * size and `\"fullscreen\"` from an expand button in custom chrome. The\n * panel transitions its size classes reactively; no reopen needed.\n */\n updateSize(size: DialogSize): void {\n this.sizeSignal.set(size);\n this.sizeUpdater?.(size);\n }\n\n /**\n * @internal Wired by DialogService after the host is created so\n * `updateSize` can reach the host component's `size` input.\n */\n bindSizeUpdater(updater: (size: DialogSize) => void): void {\n this.sizeUpdater = updater;\n }\n\n get data(): TData | undefined {\n return this.config.data;\n }\n\n setCanClose(guard: CanCloseFn | null) {\n this.closeGuard = guard;\n }\n\n async close(result?: TResult) {\n if (this.closed) {\n return;\n }\n\n if (this.config.preventClose) {\n return;\n }\n\n if (this.closeGuard) {\n const allowed = await Promise.resolve(this.closeGuard());\n\n if (!allowed) {\n return;\n }\n }\n\n this.beforeCloseSubject.next();\n this.beforeCloseSubject.complete();\n\n this.closed = true;\n this.afterClosedSubject.next(result);\n this.afterClosedSubject.complete();\n }\n\n beforeOpen(): Observable<void> {\n return this.beforeOpenSubject.asObservable().pipe(take(1));\n }\n\n afterOpened(): Observable<void> {\n return this.afterOpenedSubject.asObservable().pipe(take(1));\n }\n\n beforeClose(): Observable<void> {\n return this.beforeCloseSubject.asObservable().pipe(take(1));\n }\n\n afterClosed(): Observable<TResult | undefined> {\n return this.afterClosedSubject.asObservable().pipe(take(1));\n }\n\n /** @internal */\n markBeforeOpen() {\n this.beforeOpenSubject.next();\n this.beforeOpenSubject.complete();\n }\n\n /** @internal */\n markOpened() {\n this.afterOpenedSubject.next();\n this.afterOpenedSubject.complete();\n }\n}\n","import { ESCAPE } from '@angular/cdk/keycodes';\nimport { Overlay, OverlayRef } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { DOCUMENT } from '@angular/common';\nimport {\n ApplicationRef,\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n inject,\n Injectable,\n Injector,\n Type,\n} from '@angular/core';\n\nimport { DialogComponent } from './dialog.component';\nimport { DEFAULT_DIALOG_CONFIG, DialogConfig } from './dialog.config';\nimport { DialogRef } from './dialog-ref';\n\nexport const DIALOG_DATA = Symbol('DIALOG_DATA');\nexport const DIALOG_REF = Symbol('DIALOG_REF');\n\ninterface DialogEntry {\n ref: DialogRef;\n overlayRef: OverlayRef;\n hostRef: ComponentRef<DialogComponent>;\n contentRef: ComponentRef<unknown>;\n}\n\n/**\n * Opens dialogs as CDK overlays.\n *\n * CDK owns the cross-cutting overlay concerns — backdrop, scroll blocking,\n * centered positioning, z-index stacking (overlays layer by open order), and\n * top-of-stack dispatch of Escape / outside clicks. The `DialogComponent` it\n * hosts is just the panel chrome (header / body / footer, sizing, enter\n * animation, focus trap). There is no global \"opening X closes lower overlays\"\n * rule: a dialog opened over a drawer stacks on top of it, and Escape / an\n * outside press dismisses whichever overlay is on top.\n */\n@Injectable({ providedIn: 'root' })\nexport class DialogService {\n private readonly overlay = inject(Overlay);\n private readonly appRef = inject(ApplicationRef);\n private readonly injector = inject(EnvironmentInjector);\n private readonly doc = inject(DOCUMENT);\n\n private activeDialogs: DialogEntry[] = [];\n\n get openCount(): number {\n return this.activeDialogs.length;\n }\n\n open<TResult = unknown, TData = unknown>(\n content: Type<unknown>,\n config?: DialogConfig<TData>,\n ): DialogRef<TResult, TData> {\n const mergedConfig = {\n ...DEFAULT_DIALOG_CONFIG,\n ...config,\n } as DialogConfig<TData>;\n const dialogRef = new DialogRef<TResult, TData>(mergedConfig);\n\n const positionStrategy = this.overlay\n .position()\n .global()\n .centerHorizontally();\n\n if (mergedConfig.position === 'top') {\n positionStrategy.top('10vh');\n } else {\n positionStrategy.centerVertically();\n }\n\n const overlayRef = this.overlay.create({\n hasBackdrop: mergedConfig.modal ?? true,\n backdropClass: 'fk-dialog__backdrop',\n panelClass: 'fk-dialog__pane',\n scrollStrategy: this.overlay.scrollStrategies.block(),\n positionStrategy,\n disposeOnNavigation: true,\n });\n\n const childInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: DIALOG_DATA as never, useValue: mergedConfig.data },\n { provide: DIALOG_REF as never, useValue: dialogRef },\n ],\n });\n\n const hostRef = overlayRef.attach(\n new ComponentPortal(DialogComponent, null, childInjector),\n );\n\n const contentRef = createComponent(content, {\n environmentInjector: this.injector,\n elementInjector: childInjector,\n hostElement: this.doc.createElement('div'),\n });\n\n this.appRef.attachView(contentRef.hostView);\n\n const entry: DialogEntry = {\n ref: dialogRef as DialogRef<unknown, unknown>,\n overlayRef,\n hostRef,\n contentRef,\n };\n\n this.activeDialogs.push(entry);\n\n this.applyConfig(hostRef, mergedConfig);\n\n // Let ref.updateSize() reach the live host — `size` is a reactive\n // input, so the panel restyles in place without reopening.\n dialogRef.bindSizeUpdater((size) => {\n hostRef.setInput('size', size);\n });\n\n // CDK dispatches these to the top overlay only, so Escape / an outside\n // press dismisses the topmost dialog. `dialogRef.close()` runs the\n // preventClose + canClose guards.\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.keyCode === ESCAPE && mergedConfig.closeOnEscape) {\n dialogRef.close();\n }\n });\n\n overlayRef.backdropClick().subscribe(() => {\n if (mergedConfig.closeOnBackdrop) {\n dialogRef.close();\n }\n });\n\n hostRef.instance.beforeOpen.subscribe(() => {\n dialogRef.markBeforeOpen();\n });\n\n hostRef.instance.opened.subscribe(() => {\n dialogRef.markOpened();\n });\n\n hostRef.instance.closed.subscribe(() => {\n dialogRef.close();\n });\n\n dialogRef.afterClosed().subscribe(() => {\n this.destroyDialog(entry);\n });\n\n hostRef.setInput('open', true);\n hostRef.changeDetectorRef.detectChanges();\n\n const panelBody =\n overlayRef.overlayElement.querySelector('.fk-dialog__body');\n\n if (panelBody) {\n panelBody.appendChild(contentRef.location.nativeElement);\n contentRef.changeDetectorRef.detectChanges();\n\n // Move [libDialogFooter] elements out of the body to the panel root so\n // they render in the pinned footer area (after fk-dialog__body).\n const panel = panelBody.closest('.fk-dialog__panel');\n const footerEls = panelBody.querySelectorAll('[libDialogFooter]');\n\n footerEls.forEach((el: Element) => {\n panel?.appendChild(el);\n });\n }\n\n return dialogRef;\n }\n\n closeAll() {\n [...this.activeDialogs].forEach((entry) => entry.ref.close());\n }\n\n private applyConfig(\n hostRef: ComponentRef<DialogComponent>,\n config: DialogConfig,\n ) {\n hostRef.setInput('modal', config.modal ?? true);\n hostRef.setInput('closable', config.closable ?? true);\n hostRef.setInput('size', config.size ?? 'md');\n hostRef.setInput('position', config.position ?? 'center');\n hostRef.setInput('animation', config.animation ?? 'scale-fade');\n hostRef.setInput('header', config.header ?? null);\n hostRef.setInput('restoreFocus', config.restoreFocus ?? true);\n hostRef.setInput('autoFocus', config.autoFocus ?? true);\n hostRef.setInput('className', config.className ?? '');\n hostRef.setInput('preventClose', config.preventClose ?? false);\n hostRef.setInput('canClose', config.canClose ?? null);\n hostRef.setInput('fullscreenMobile', config.fullscreenMobile ?? false);\n hostRef.setInput('flexBody', config.flexBody ?? false);\n hostRef.setInput('ariaLabel', config.ariaLabel ?? null);\n hostRef.setInput('ariaDescribedBy', config.ariaDescribedBy ?? null);\n }\n\n private destroyDialog(entry: DialogEntry) {\n const idx = this.activeDialogs.indexOf(entry);\n\n if (idx > -1) {\n this.activeDialogs.splice(idx, 1);\n }\n\n // Let the component restore focus before the overlay (and its hosted\n // component) are torn down.\n entry.hostRef.setInput('open', false);\n entry.hostRef.changeDetectorRef.detectChanges();\n\n this.appRef.detachView(entry.contentRef.hostView);\n entry.contentRef.destroy();\n\n // Disposing the overlay detaches + destroys the hosted DialogComponent,\n // removes the backdrop, and releases the scroll-block strategy.\n entry.overlayRef.dispose();\n }\n}\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[fkDialogActions]',\n standalone: true,\n})\nexport class FkDialogActionsDirective {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,14 @@ class WizardDialogRef {
|
|
|
21
21
|
headerComponent;
|
|
22
22
|
/** Inputs applied to `headerComponent` when it is created. */
|
|
23
23
|
headerInputs;
|
|
24
|
+
/** Optional consumer-supplied footer, replacing the built-in buttons. */
|
|
25
|
+
footerComponent;
|
|
26
|
+
/** Inputs applied to `footerComponent` when it is created. */
|
|
27
|
+
footerInputs;
|
|
28
|
+
/** Optional consumer-supplied stepper, replacing the built-in pill row. */
|
|
29
|
+
stepperComponent;
|
|
30
|
+
/** Inputs applied to `stepperComponent` when it is created. */
|
|
31
|
+
stepperInputs;
|
|
24
32
|
// ===== NAVIGATION STATE =====
|
|
25
33
|
currentIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentIndex" }] : /* istanbul ignore next */ []));
|
|
26
34
|
highestVisitedIndex = signal(0, ...(ngDevMode ? [{ debugName: "highestVisitedIndex" }] : /* istanbul ignore next */ []));
|
|
@@ -52,6 +60,10 @@ class WizardDialogRef {
|
|
|
52
60
|
this.backLabel = config.backLabel ?? 'Back';
|
|
53
61
|
this.headerComponent = config.headerComponent ?? null;
|
|
54
62
|
this.headerInputs = config.headerInputs ?? {};
|
|
63
|
+
this.footerComponent = config.footerComponent ?? null;
|
|
64
|
+
this.footerInputs = config.footerInputs ?? {};
|
|
65
|
+
this.stepperComponent = config.stepperComponent ?? null;
|
|
66
|
+
this.stepperInputs = config.stepperInputs ?? {};
|
|
55
67
|
this.consumerData = config.data;
|
|
56
68
|
}
|
|
57
69
|
get data() {
|
|
@@ -103,6 +115,21 @@ class WizardDialogRef {
|
|
|
103
115
|
afterClosed() {
|
|
104
116
|
return this.dialogRef.afterClosed();
|
|
105
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* The underlying dialog's current panel size — see `DialogRef.size`.
|
|
120
|
+
* Custom chrome renders expand/collapse state from it.
|
|
121
|
+
*/
|
|
122
|
+
size() {
|
|
123
|
+
return this.dialogRef.size();
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Resize the open wizard in place — see `DialogRef.updateSize`.
|
|
127
|
+
* Typically toggled between the opened size and `"fullscreen"` by an
|
|
128
|
+
* expand button in custom header chrome.
|
|
129
|
+
*/
|
|
130
|
+
updateSize(size) {
|
|
131
|
+
this.dialogRef.updateSize(size);
|
|
132
|
+
}
|
|
106
133
|
// ===== INTERNAL =====
|
|
107
134
|
/** @internal Called by container when submit button is clicked. */
|
|
108
135
|
emitSubmit() {
|
|
@@ -119,6 +146,8 @@ class WizardDialogContainerComponent {
|
|
|
119
146
|
injector = inject(Injector);
|
|
120
147
|
bodyOutlet = viewChild('bodyOutlet', { ...(ngDevMode ? { debugName: "bodyOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
121
148
|
headerOutlet = viewChild('headerOutlet', { ...(ngDevMode ? { debugName: "headerOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
149
|
+
footerOutlet = viewChild('footerOutlet', { ...(ngDevMode ? { debugName: "footerOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
150
|
+
stepperOutlet = viewChild('stepperOutlet', { ...(ngDevMode ? { debugName: "stepperOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
122
151
|
ref = this.data.wizardRef;
|
|
123
152
|
classes = computed(() => 'fk-wizard-dialog', ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
124
153
|
get hostClass() {
|
|
@@ -131,7 +160,9 @@ class WizardDialogContainerComponent {
|
|
|
131
160
|
parent: this.injector,
|
|
132
161
|
providers: [{ provide: WIZARD_DIALOG_REF, useValue: this.ref }],
|
|
133
162
|
});
|
|
134
|
-
this.
|
|
163
|
+
this.mountRegion(this.headerOutlet(), this.ref.headerComponent, this.ref.headerInputs, childInjector);
|
|
164
|
+
this.mountRegion(this.footerOutlet(), this.ref.footerComponent, this.ref.footerInputs, childInjector);
|
|
165
|
+
this.mountRegion(this.stepperOutlet(), this.ref.stepperComponent, this.ref.stepperInputs, childInjector);
|
|
135
166
|
const outlet = this.bodyOutlet();
|
|
136
167
|
if (!outlet) {
|
|
137
168
|
return;
|
|
@@ -141,18 +172,17 @@ class WizardDialogContainerComponent {
|
|
|
141
172
|
});
|
|
142
173
|
}
|
|
143
174
|
/**
|
|
144
|
-
* Render
|
|
145
|
-
*
|
|
146
|
-
* declaratively from the wizard config.
|
|
175
|
+
* Render an optional consumer-supplied region (header or footer) into its
|
|
176
|
+
* fixed outlet, applying the configured inputs so consumers configure it
|
|
177
|
+
* declaratively from the wizard config. Shares the wizard injector, so the
|
|
178
|
+
* component can inject `WIZARD_DIALOG_REF`.
|
|
147
179
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const outlet = this.headerOutlet();
|
|
151
|
-
if (!headerComponent || !outlet) {
|
|
180
|
+
mountRegion(outlet, component, inputs, injector) {
|
|
181
|
+
if (!component || !outlet) {
|
|
152
182
|
return;
|
|
153
183
|
}
|
|
154
|
-
const componentRef = outlet.createComponent(
|
|
155
|
-
for (const [name, value] of Object.entries(
|
|
184
|
+
const componentRef = outlet.createComponent(component, { injector });
|
|
185
|
+
for (const [name, value] of Object.entries(inputs)) {
|
|
156
186
|
componentRef.setInput(name, value);
|
|
157
187
|
}
|
|
158
188
|
componentRef.changeDetectorRef.detectChanges();
|
|
@@ -164,15 +194,19 @@ class WizardDialogContainerComponent {
|
|
|
164
194
|
this.ref.emitSubmit();
|
|
165
195
|
}
|
|
166
196
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WizardDialogContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
167
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WizardDialogContainerComponent, isStandalone: true, selector: "fk-wizard-dialog-container", host: { properties: { "class": "this.hostClass" } }, viewQueries: [{ propertyName: "bodyOutlet", first: true, predicate: ["bodyOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "headerOutlet", first: true, predicate: ["headerOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<!-- Consumer-supplied header (fixed, above the stepper) -->\n@if (ref.headerComponent) {\n <div class=\"fk-wizard-dialog__header\">\n <ng-template #headerOutlet />\n </div>\n}\n\n<!-- Stepper -->\n<div\n class=\"fk-wizard-dialog__stepper\"\n
|
|
197
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WizardDialogContainerComponent, isStandalone: true, selector: "fk-wizard-dialog-container", host: { properties: { "class": "this.hostClass" } }, viewQueries: [{ propertyName: "bodyOutlet", first: true, predicate: ["bodyOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "headerOutlet", first: true, predicate: ["headerOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "footerOutlet", first: true, predicate: ["footerOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "stepperOutlet", first: true, predicate: ["stepperOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<!-- Consumer-supplied header (fixed, above the stepper) -->\n@if (ref.headerComponent) {\n <div class=\"fk-wizard-dialog__header\">\n <ng-template #headerOutlet />\n </div>\n}\n\n<!-- Stepper -->\n@if (ref.stepperComponent) {\n <div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n >\n <ng-template #stepperOutlet />\n </div>\n} @else {\n <div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n role=\"tablist\"\n >\n @for (step of ref.steps; track $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"fk-wizard-dialog__step\"\n [class.fk-wizard-dialog__step--active]=\"$index === ref.currentIndex()\"\n [class.fk-wizard-dialog__step--completed]=\"$index < ref.currentIndex()\"\n [attr.aria-selected]=\"$index === ref.currentIndex()\"\n [disabled]=\"ref.linear && $index > ref.highestVisitedIndex()\"\n (click)=\"ref.goTo($index)\"\n >\n <span class=\"fk-wizard-dialog__step-number\">{{ $index + 1 }}</span>\n <span class=\"fk-wizard-dialog__step-title\">{{ step.title }}</span>\n @if (step.optional) {\n <span class=\"fk-wizard-dialog__step-optional\">(Optional)</span>\n }\n </button>\n }\n </div>\n\n <!-- Scrollable body -->\n}\n\n<div class=\"fk-wizard-dialog__body\">\n <ng-template #bodyOutlet />\n</div>\n\n<!-- Footer (moved to dialog footer by DialogService) -->\n<div\n class=\"fk-wizard-dialog__footer\"\n [class.fk-wizard-dialog__footer--hidden]=\"!ref.chromeVisible()\"\n libDialogFooter\n>\n @if (ref.footerComponent) {\n <ng-template #footerOutlet />\n } @else {\n @if (ref.isFirstStep()) {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"onCancel()\">\n {{ ref.cancelLabel }}\n </fk-button>\n } @else {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"ref.previous()\">\n {{ ref.backLabel }}\n </fk-button>\n }\n\n @if (ref.extraAction(); as action) {\n <fk-button\n [variant]=\"action.variant ?? 'outline'\"\n type=\"button\"\n (click)=\"action.onClick()\"\n >\n {{ action.label }}\n </fk-button>\n }\n\n @if (ref.isLastStep()) {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.submitDisabled()\"\n (click)=\"onSubmit()\"\n >\n {{ ref.submitLabel }}\n </fk-button>\n } @else {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.nextDisabled()\"\n (click)=\"ref.next()\"\n >\n {{ ref.nextLabel }}\n </fk-button>\n }\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden;margin-top:var(--fk-wizard-dialog-top-offset, -1rem)}.fk-wizard-dialog__header{padding:var(--fk-wizard-dialog-header-padding, 0);flex-shrink:0}.fk-wizard-dialog__stepper{display:flex;gap:var(--fk-wizard-dialog-stepper-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-wizard-dialog-stepper-padding, 0 0 .75rem);flex-shrink:0}.fk-wizard-dialog__stepper--hidden{display:none}.fk-wizard-dialog__step{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fk-rhythm-2, .5rem);padding:var(--fk-rhythm-2, .5rem);font-family:var(--fk-input-font-family, inherit);font-size:var(--fk-form-label-font-size, var(--fk-typography-label-font-size, .875rem));color:var(--fk-wizard-dialog-step-color, var(--fk-form-hint-color, #6b7280));background:transparent;border:none;cursor:pointer}.fk-wizard-dialog__step:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18));border-radius:var(--fk-radius-sm, .25rem)}.fk-wizard-dialog__step:disabled{opacity:.5;cursor:not-allowed}.fk-wizard-dialog__step--active{color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step--completed{color:var(--fk-wizard-dialog-step-completed-color, var(--fk-form-label-color, #0b1420))}.fk-wizard-dialog__step-number{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;font-size:var(--fk-font-size-xs, .75rem);font-weight:600;border-radius:50%;border:1px solid currentColor}.fk-wizard-dialog__step--active .fk-wizard-dialog__step-number{background:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff));color:var(--fk-wizard-dialog-step-number-active-color, #fff);border-color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step-optional{font-size:var(--fk-font-size-xs, .75rem);opacity:.7}.fk-wizard-dialog__body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;padding:var(--fk-wizard-dialog-body-padding, var(--fk-rhythm-4, 1rem) 0);--fk-form-field-gap: 0}.fk-wizard-dialog__footer{display:flex;gap:var(--fk-wizard-dialog-footer-gap, var(--fk-rhythm-3, .75rem));padding:var(--fk-wizard-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-wizard-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}.fk-wizard-dialog__footer--hidden{display:none}.fk-wizard-dialog__footer>*{flex:1 1 0;min-width:0}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "fk-button", inputs: ["variant", "size", "loading", "disabled", "type", "fullWidth", "id", "className", "ariaLabel", "ariaDescribedBy"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
168
198
|
}
|
|
169
199
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WizardDialogContainerComponent, decorators: [{
|
|
170
200
|
type: Component,
|
|
171
|
-
args: [{ selector: 'fk-wizard-dialog-container', standalone: true, imports: [ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Consumer-supplied header (fixed, above the stepper) -->\n@if (ref.headerComponent) {\n <div class=\"fk-wizard-dialog__header\">\n <ng-template #headerOutlet />\n </div>\n}\n\n<!-- Stepper -->\n<div\n class=\"fk-wizard-dialog__stepper\"\n
|
|
201
|
+
args: [{ selector: 'fk-wizard-dialog-container', standalone: true, imports: [ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Consumer-supplied header (fixed, above the stepper) -->\n@if (ref.headerComponent) {\n <div class=\"fk-wizard-dialog__header\">\n <ng-template #headerOutlet />\n </div>\n}\n\n<!-- Stepper -->\n@if (ref.stepperComponent) {\n <div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n >\n <ng-template #stepperOutlet />\n </div>\n} @else {\n <div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n role=\"tablist\"\n >\n @for (step of ref.steps; track $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"fk-wizard-dialog__step\"\n [class.fk-wizard-dialog__step--active]=\"$index === ref.currentIndex()\"\n [class.fk-wizard-dialog__step--completed]=\"$index < ref.currentIndex()\"\n [attr.aria-selected]=\"$index === ref.currentIndex()\"\n [disabled]=\"ref.linear && $index > ref.highestVisitedIndex()\"\n (click)=\"ref.goTo($index)\"\n >\n <span class=\"fk-wizard-dialog__step-number\">{{ $index + 1 }}</span>\n <span class=\"fk-wizard-dialog__step-title\">{{ step.title }}</span>\n @if (step.optional) {\n <span class=\"fk-wizard-dialog__step-optional\">(Optional)</span>\n }\n </button>\n }\n </div>\n\n <!-- Scrollable body -->\n}\n\n<div class=\"fk-wizard-dialog__body\">\n <ng-template #bodyOutlet />\n</div>\n\n<!-- Footer (moved to dialog footer by DialogService) -->\n<div\n class=\"fk-wizard-dialog__footer\"\n [class.fk-wizard-dialog__footer--hidden]=\"!ref.chromeVisible()\"\n libDialogFooter\n>\n @if (ref.footerComponent) {\n <ng-template #footerOutlet />\n } @else {\n @if (ref.isFirstStep()) {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"onCancel()\">\n {{ ref.cancelLabel }}\n </fk-button>\n } @else {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"ref.previous()\">\n {{ ref.backLabel }}\n </fk-button>\n }\n\n @if (ref.extraAction(); as action) {\n <fk-button\n [variant]=\"action.variant ?? 'outline'\"\n type=\"button\"\n (click)=\"action.onClick()\"\n >\n {{ action.label }}\n </fk-button>\n }\n\n @if (ref.isLastStep()) {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.submitDisabled()\"\n (click)=\"onSubmit()\"\n >\n {{ ref.submitLabel }}\n </fk-button>\n } @else {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.nextDisabled()\"\n (click)=\"ref.next()\"\n >\n {{ ref.nextLabel }}\n </fk-button>\n }\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden;margin-top:var(--fk-wizard-dialog-top-offset, -1rem)}.fk-wizard-dialog__header{padding:var(--fk-wizard-dialog-header-padding, 0);flex-shrink:0}.fk-wizard-dialog__stepper{display:flex;gap:var(--fk-wizard-dialog-stepper-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-wizard-dialog-stepper-padding, 0 0 .75rem);flex-shrink:0}.fk-wizard-dialog__stepper--hidden{display:none}.fk-wizard-dialog__step{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fk-rhythm-2, .5rem);padding:var(--fk-rhythm-2, .5rem);font-family:var(--fk-input-font-family, inherit);font-size:var(--fk-form-label-font-size, var(--fk-typography-label-font-size, .875rem));color:var(--fk-wizard-dialog-step-color, var(--fk-form-hint-color, #6b7280));background:transparent;border:none;cursor:pointer}.fk-wizard-dialog__step:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18));border-radius:var(--fk-radius-sm, .25rem)}.fk-wizard-dialog__step:disabled{opacity:.5;cursor:not-allowed}.fk-wizard-dialog__step--active{color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step--completed{color:var(--fk-wizard-dialog-step-completed-color, var(--fk-form-label-color, #0b1420))}.fk-wizard-dialog__step-number{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;font-size:var(--fk-font-size-xs, .75rem);font-weight:600;border-radius:50%;border:1px solid currentColor}.fk-wizard-dialog__step--active .fk-wizard-dialog__step-number{background:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff));color:var(--fk-wizard-dialog-step-number-active-color, #fff);border-color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step-optional{font-size:var(--fk-font-size-xs, .75rem);opacity:.7}.fk-wizard-dialog__body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;padding:var(--fk-wizard-dialog-body-padding, var(--fk-rhythm-4, 1rem) 0);--fk-form-field-gap: 0}.fk-wizard-dialog__footer{display:flex;gap:var(--fk-wizard-dialog-footer-gap, var(--fk-rhythm-3, .75rem));padding:var(--fk-wizard-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-wizard-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}.fk-wizard-dialog__footer--hidden{display:none}.fk-wizard-dialog__footer>*{flex:1 1 0;min-width:0}\n"] }]
|
|
172
202
|
}], propDecorators: { bodyOutlet: [{ type: i0.ViewChild, args: ['bodyOutlet', { ...{
|
|
173
203
|
read: ViewContainerRef,
|
|
174
204
|
}, isSignal: true }] }], headerOutlet: [{ type: i0.ViewChild, args: ['headerOutlet', { ...{
|
|
175
205
|
read: ViewContainerRef,
|
|
206
|
+
}, isSignal: true }] }], footerOutlet: [{ type: i0.ViewChild, args: ['footerOutlet', { ...{
|
|
207
|
+
read: ViewContainerRef,
|
|
208
|
+
}, isSignal: true }] }], stepperOutlet: [{ type: i0.ViewChild, args: ['stepperOutlet', { ...{
|
|
209
|
+
read: ViewContainerRef,
|
|
176
210
|
}, isSignal: true }] }], hostClass: [{
|
|
177
211
|
type: HostBinding,
|
|
178
212
|
args: ['class']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-kit-ui-ng-ui-wizard-dialog.mjs","sources":["../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-ref.ts","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-container.component.ts","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-container.component.html","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog.service.ts","../../../../packages/ui-ng/ui/wizard-dialog/frame-kit-ui-ng-ui-wizard-dialog.ts"],"sourcesContent":["import type { Type } from '@angular/core';\nimport { computed, signal } from '@angular/core';\n\nimport { Observable, Subject } from 'rxjs';\n\nimport type { DialogRef } from '@frame-kit/ui-ng/ui/dialog';\nimport type {\n WizardDialogConfig,\n WizardDialogStep,\n} from './wizard-dialog.types';\n\n/**\n * Optional extra footer button the consumer can surface on any step\n * — typically a \"View X\" jump-off on the results/last step. Sits\n * between Back and Submit in the wizard's footer. Set via\n * `WizardDialogRef.extraAction.set(...)` on step entry; clear with\n * `null` on step exit (or just rely on swapping it out).\n */\nexport interface WizardExtraAction {\n /** Button label, e.g. \"View Identities\". */\n label: string;\n /** Visual variant. Defaults to `\"outline\"` so the extra action\n * doesn't compete with the primary Submit button. */\n variant?: 'primary' | 'outline' | 'secondary' | 'danger';\n /** Click handler — typically closes the wizard with a sentinel. */\n onClick: () => void;\n}\n\nexport const WIZARD_DIALOG_REF = Symbol('WIZARD_DIALOG_REF');\n\nexport class WizardDialogRef<TResult = unknown, TData = unknown> {\n private dialogRef!: DialogRef<TResult>;\n private readonly consumerData: TData | undefined;\n private readonly submitSubject = new Subject<void>();\n private readonly stepChangeSubject = new Subject<number>();\n\n // ===== CONFIG =====\n\n readonly steps: WizardDialogStep[];\n readonly linear: boolean;\n readonly submitLabel: string;\n readonly cancelLabel: string;\n readonly nextLabel: string;\n readonly backLabel: string;\n\n /** Optional consumer-supplied header rendered above the stepper. */\n readonly headerComponent: Type<unknown> | null;\n\n /** Inputs applied to `headerComponent` when it is created. */\n readonly headerInputs: Record<string, unknown>;\n\n // ===== NAVIGATION STATE =====\n\n readonly currentIndex = signal(0);\n readonly highestVisitedIndex = signal(0);\n\n readonly totalSteps = computed(() => this.steps.length);\n\n readonly isFirstStep = computed(() => this.currentIndex() === 0);\n\n readonly isLastStep = computed(\n () => this.currentIndex() === this.steps.length - 1,\n );\n\n readonly currentStep = computed(() => this.steps[this.currentIndex()]);\n\n // ===== CONSUMER-CONTROLLED STATE =====\n\n readonly submitDisabled = signal(false);\n readonly nextDisabled = signal(false);\n readonly chromeVisible = signal(true);\n /**\n * Optional third footer button. When non-null, the wizard chrome\n * renders an additional `<fk-button>` between Back and Submit\n * using this metadata. Consumers typically wire this in an\n * `effect` keyed on `currentIndex` so the button only appears on\n * the step(s) that need it.\n */\n readonly extraAction = signal<WizardExtraAction | null>(null);\n\n // ===== OBSERVABLES =====\n\n readonly submitted: Observable<void> = this.submitSubject.asObservable();\n readonly stepChanged: Observable<number> =\n this.stepChangeSubject.asObservable();\n\n constructor(config: WizardDialogConfig<TData>) {\n this.steps = config.steps;\n this.linear = config.linear ?? true;\n this.submitLabel = config.submitLabel ?? 'Submit';\n this.cancelLabel = config.cancelLabel ?? 'Cancel';\n this.nextLabel = config.nextLabel ?? 'Next';\n this.backLabel = config.backLabel ?? 'Back';\n this.headerComponent = config.headerComponent ?? null;\n this.headerInputs = config.headerInputs ?? {};\n this.consumerData = config.data;\n }\n\n get data(): TData | undefined {\n return this.consumerData;\n }\n\n // ===== NAVIGATION =====\n\n next(): boolean {\n if (this.isLastStep()) {\n return false;\n }\n\n this.currentIndex.update((i) => i + 1);\n this.updateHighestVisited();\n this.stepChangeSubject.next(this.currentIndex());\n\n return true;\n }\n\n previous(): boolean {\n if (this.isFirstStep()) {\n return false;\n }\n\n this.currentIndex.update((i) => i - 1);\n this.stepChangeSubject.next(this.currentIndex());\n\n return true;\n }\n\n goTo(index: number): boolean {\n if (index < 0 || index >= this.steps.length) {\n return false;\n }\n\n if (this.linear && index > this.highestVisitedIndex()) {\n return false;\n }\n\n if (index > this.currentIndex() && this.nextDisabled()) {\n return false;\n }\n\n this.currentIndex.set(index);\n this.updateHighestVisited();\n this.stepChangeSubject.next(index);\n\n return true;\n }\n\n private updateHighestVisited(): void {\n const current = this.currentIndex();\n\n if (current > this.highestVisitedIndex()) {\n this.highestVisitedIndex.set(current);\n }\n }\n\n // ===== DIALOG LIFECYCLE =====\n\n close(result?: TResult): void {\n this.dialogRef.close(result);\n }\n\n afterClosed(): Observable<TResult | undefined> {\n return this.dialogRef.afterClosed();\n }\n\n // ===== INTERNAL =====\n\n /** @internal Called by container when submit button is clicked. */\n emitSubmit(): void {\n this.submitSubject.next();\n }\n\n /** @internal Called by WizardDialogService after dialog is opened. */\n setDialogRef(ref: DialogRef<TResult>): void {\n this.dialogRef = ref;\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n inject,\n Injector,\n viewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { ButtonComponent } from '@frame-kit/ui-ng/ui/button';\nimport { DIALOG_DATA } from '@frame-kit/ui-ng/ui/dialog';\nimport type { WizardDialogContainerData } from './wizard-dialog.service';\nimport { WIZARD_DIALOG_REF, WizardDialogRef } from './wizard-dialog-ref';\n\n@Component({\n selector: 'fk-wizard-dialog-container',\n standalone: true,\n imports: [ButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './wizard-dialog-container.component.html',\n styleUrl: './wizard-dialog-container.component.scss',\n})\nexport class WizardDialogContainerComponent implements AfterViewInit {\n private readonly data = inject(\n DIALOG_DATA as never,\n ) as WizardDialogContainerData;\n private readonly injector = inject(Injector);\n private readonly bodyOutlet = viewChild('bodyOutlet', {\n read: ViewContainerRef,\n });\n private readonly headerOutlet = viewChild('headerOutlet', {\n read: ViewContainerRef,\n });\n\n readonly ref: WizardDialogRef = this.data.wizardRef;\n\n readonly classes = computed(() => 'fk-wizard-dialog');\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n ngAfterViewInit(): void {\n // One injector for both regions so a consumer-supplied header can inject\n // WIZARD_DIALOG_REF exactly like the step content does.\n const childInjector = Injector.create({\n parent: this.injector,\n providers: [{ provide: WIZARD_DIALOG_REF as never, useValue: this.ref }],\n });\n\n this.mountHeader(childInjector);\n\n const outlet = this.bodyOutlet();\n\n if (!outlet) {\n return;\n }\n\n outlet.createComponent(this.data.contentComponent, {\n injector: childInjector,\n });\n }\n\n /**\n * Render the optional consumer-supplied header into the fixed region above\n * the stepper, applying `headerInputs` so the consumer configures it\n * declaratively from the wizard config.\n */\n private mountHeader(injector: Injector): void {\n const headerComponent = this.ref.headerComponent;\n const outlet = this.headerOutlet();\n\n if (!headerComponent || !outlet) {\n return;\n }\n\n const componentRef = outlet.createComponent(headerComponent, { injector });\n\n for (const [name, value] of Object.entries(this.ref.headerInputs)) {\n componentRef.setInput(name, value);\n }\n\n componentRef.changeDetectorRef.detectChanges();\n }\n\n onCancel(): void {\n this.ref.close();\n }\n\n onSubmit(): void {\n this.ref.emitSubmit();\n }\n}\n","<!-- Consumer-supplied header (fixed, above the stepper) -->\n@if (ref.headerComponent) {\n <div class=\"fk-wizard-dialog__header\">\n <ng-template #headerOutlet />\n </div>\n}\n\n<!-- Stepper -->\n<div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n role=\"tablist\"\n>\n @for (step of ref.steps; track $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"fk-wizard-dialog__step\"\n [class.fk-wizard-dialog__step--active]=\"$index === ref.currentIndex()\"\n [class.fk-wizard-dialog__step--completed]=\"$index < ref.currentIndex()\"\n [attr.aria-selected]=\"$index === ref.currentIndex()\"\n [disabled]=\"ref.linear && $index > ref.highestVisitedIndex()\"\n (click)=\"ref.goTo($index)\"\n >\n <span class=\"fk-wizard-dialog__step-number\">{{ $index + 1 }}</span>\n <span class=\"fk-wizard-dialog__step-title\">{{ step.title }}</span>\n @if (step.optional) {\n <span class=\"fk-wizard-dialog__step-optional\">(Optional)</span>\n }\n </button>\n }\n</div>\n\n<!-- Scrollable body -->\n<div class=\"fk-wizard-dialog__body\">\n <ng-template #bodyOutlet />\n</div>\n\n<!-- Footer (moved to dialog footer by DialogService) -->\n<div\n class=\"fk-wizard-dialog__footer\"\n [class.fk-wizard-dialog__footer--hidden]=\"!ref.chromeVisible()\"\n libDialogFooter\n>\n @if (ref.isFirstStep()) {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"onCancel()\">\n {{ ref.cancelLabel }}\n </fk-button>\n } @else {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"ref.previous()\">\n {{ ref.backLabel }}\n </fk-button>\n }\n\n @if (ref.extraAction(); as action) {\n <fk-button\n [variant]=\"action.variant ?? 'outline'\"\n type=\"button\"\n (click)=\"action.onClick()\"\n >\n {{ action.label }}\n </fk-button>\n }\n\n @if (ref.isLastStep()) {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.submitDisabled()\"\n (click)=\"onSubmit()\"\n >\n {{ ref.submitLabel }}\n </fk-button>\n } @else {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.nextDisabled()\"\n (click)=\"ref.next()\"\n >\n {{ ref.nextLabel }}\n </fk-button>\n }\n</div>\n","import { inject, Injectable, Type } from '@angular/core';\n\nimport { DialogService } from '@frame-kit/ui-ng/ui/dialog';\nimport type { DialogRef } from '@frame-kit/ui-ng/ui/dialog';\nimport type { WizardDialogConfig } from './wizard-dialog.types';\nimport { WizardDialogContainerComponent } from './wizard-dialog-container.component';\nimport { WizardDialogRef } from './wizard-dialog-ref';\n\nexport interface WizardDialogContainerData {\n wizardRef: WizardDialogRef;\n contentComponent: Type<unknown>;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class WizardDialogService {\n private readonly dialogService = inject(DialogService);\n\n open<TResult = unknown, TData = unknown>(\n content: Type<unknown>,\n config: WizardDialogConfig<TData>,\n ): WizardDialogRef<TResult, TData> {\n const wizardRef = new WizardDialogRef<TResult, TData>(config);\n\n const dialogRef = this.dialogService.open<\n TResult,\n WizardDialogContainerData\n >(WizardDialogContainerComponent, {\n header: config.header,\n size: config.size ?? 'lg',\n closable: config.closable,\n closeOnEscape: config.closeOnEscape,\n closeOnBackdrop: config.closeOnBackdrop,\n animation: config.animation,\n fullscreenMobile: config.fullscreenMobile,\n className: ['fk-wizard-dialog-host', config.className]\n .filter(Boolean)\n .join(' '),\n ariaLabel: config.ariaLabel,\n ariaDescribedBy: config.ariaDescribedBy,\n flexBody: true,\n data: {\n wizardRef: wizardRef as WizardDialogRef,\n contentComponent: content,\n },\n });\n\n wizardRef.setDialogRef(dialogRef as DialogRef<TResult>);\n\n return wizardRef;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-wizard-dialog.mjs","sources":["../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-ref.ts","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-container.component.ts","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-container.component.html","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog.service.ts","../../../../packages/ui-ng/ui/wizard-dialog/frame-kit-ui-ng-ui-wizard-dialog.ts"],"sourcesContent":["import type { Type } from '@angular/core';\nimport { computed, signal } from '@angular/core';\n\nimport { Observable, Subject } from 'rxjs';\n\nimport type { DialogRef, DialogSize } from '@frame-kit/ui-ng/ui/dialog';\nimport type {\n WizardDialogConfig,\n WizardDialogStep,\n} from './wizard-dialog.types';\n\n/**\n * Optional extra footer button the consumer can surface on any step\n * — typically a \"View X\" jump-off on the results/last step. Sits\n * between Back and Submit in the wizard's footer. Set via\n * `WizardDialogRef.extraAction.set(...)` on step entry; clear with\n * `null` on step exit (or just rely on swapping it out).\n */\nexport interface WizardExtraAction {\n /** Button label, e.g. \"View Identities\". */\n label: string;\n /** Visual variant. Defaults to `\"outline\"` so the extra action\n * doesn't compete with the primary Submit button. */\n variant?: 'primary' | 'outline' | 'secondary' | 'danger';\n /** Click handler — typically closes the wizard with a sentinel. */\n onClick: () => void;\n}\n\nexport const WIZARD_DIALOG_REF = Symbol('WIZARD_DIALOG_REF');\n\nexport class WizardDialogRef<TResult = unknown, TData = unknown> {\n private dialogRef!: DialogRef<TResult>;\n private readonly consumerData: TData | undefined;\n private readonly submitSubject = new Subject<void>();\n private readonly stepChangeSubject = new Subject<number>();\n\n // ===== CONFIG =====\n\n readonly steps: WizardDialogStep[];\n readonly linear: boolean;\n readonly submitLabel: string;\n readonly cancelLabel: string;\n readonly nextLabel: string;\n readonly backLabel: string;\n\n /** Optional consumer-supplied header rendered above the stepper. */\n readonly headerComponent: Type<unknown> | null;\n\n /** Inputs applied to `headerComponent` when it is created. */\n readonly headerInputs: Record<string, unknown>;\n\n /** Optional consumer-supplied footer, replacing the built-in buttons. */\n readonly footerComponent: Type<unknown> | null;\n\n /** Inputs applied to `footerComponent` when it is created. */\n readonly footerInputs: Record<string, unknown>;\n\n /** Optional consumer-supplied stepper, replacing the built-in pill row. */\n readonly stepperComponent: Type<unknown> | null;\n\n /** Inputs applied to `stepperComponent` when it is created. */\n readonly stepperInputs: Record<string, unknown>;\n\n // ===== NAVIGATION STATE =====\n\n readonly currentIndex = signal(0);\n readonly highestVisitedIndex = signal(0);\n\n readonly totalSteps = computed(() => this.steps.length);\n\n readonly isFirstStep = computed(() => this.currentIndex() === 0);\n\n readonly isLastStep = computed(\n () => this.currentIndex() === this.steps.length - 1,\n );\n\n readonly currentStep = computed(() => this.steps[this.currentIndex()]);\n\n // ===== CONSUMER-CONTROLLED STATE =====\n\n readonly submitDisabled = signal(false);\n readonly nextDisabled = signal(false);\n readonly chromeVisible = signal(true);\n /**\n * Optional third footer button. When non-null, the wizard chrome\n * renders an additional `<fk-button>` between Back and Submit\n * using this metadata. Consumers typically wire this in an\n * `effect` keyed on `currentIndex` so the button only appears on\n * the step(s) that need it.\n */\n readonly extraAction = signal<WizardExtraAction | null>(null);\n\n // ===== OBSERVABLES =====\n\n readonly submitted: Observable<void> = this.submitSubject.asObservable();\n readonly stepChanged: Observable<number> =\n this.stepChangeSubject.asObservable();\n\n constructor(config: WizardDialogConfig<TData>) {\n this.steps = config.steps;\n this.linear = config.linear ?? true;\n this.submitLabel = config.submitLabel ?? 'Submit';\n this.cancelLabel = config.cancelLabel ?? 'Cancel';\n this.nextLabel = config.nextLabel ?? 'Next';\n this.backLabel = config.backLabel ?? 'Back';\n this.headerComponent = config.headerComponent ?? null;\n this.headerInputs = config.headerInputs ?? {};\n this.footerComponent = config.footerComponent ?? null;\n this.footerInputs = config.footerInputs ?? {};\n this.stepperComponent = config.stepperComponent ?? null;\n this.stepperInputs = config.stepperInputs ?? {};\n this.consumerData = config.data;\n }\n\n get data(): TData | undefined {\n return this.consumerData;\n }\n\n // ===== NAVIGATION =====\n\n next(): boolean {\n if (this.isLastStep()) {\n return false;\n }\n\n this.currentIndex.update((i) => i + 1);\n this.updateHighestVisited();\n this.stepChangeSubject.next(this.currentIndex());\n\n return true;\n }\n\n previous(): boolean {\n if (this.isFirstStep()) {\n return false;\n }\n\n this.currentIndex.update((i) => i - 1);\n this.stepChangeSubject.next(this.currentIndex());\n\n return true;\n }\n\n goTo(index: number): boolean {\n if (index < 0 || index >= this.steps.length) {\n return false;\n }\n\n if (this.linear && index > this.highestVisitedIndex()) {\n return false;\n }\n\n if (index > this.currentIndex() && this.nextDisabled()) {\n return false;\n }\n\n this.currentIndex.set(index);\n this.updateHighestVisited();\n this.stepChangeSubject.next(index);\n\n return true;\n }\n\n private updateHighestVisited(): void {\n const current = this.currentIndex();\n\n if (current > this.highestVisitedIndex()) {\n this.highestVisitedIndex.set(current);\n }\n }\n\n // ===== DIALOG LIFECYCLE =====\n\n close(result?: TResult): void {\n this.dialogRef.close(result);\n }\n\n afterClosed(): Observable<TResult | undefined> {\n return this.dialogRef.afterClosed();\n }\n\n /**\n * The underlying dialog's current panel size — see `DialogRef.size`.\n * Custom chrome renders expand/collapse state from it.\n */\n size(): DialogSize {\n return this.dialogRef.size();\n }\n\n /**\n * Resize the open wizard in place — see `DialogRef.updateSize`.\n * Typically toggled between the opened size and `\"fullscreen\"` by an\n * expand button in custom header chrome.\n */\n updateSize(size: DialogSize): void {\n this.dialogRef.updateSize(size);\n }\n\n // ===== INTERNAL =====\n\n /** @internal Called by container when submit button is clicked. */\n emitSubmit(): void {\n this.submitSubject.next();\n }\n\n /** @internal Called by WizardDialogService after dialog is opened. */\n setDialogRef(ref: DialogRef<TResult>): void {\n this.dialogRef = ref;\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n inject,\n Injector,\n viewChild,\n Type,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { ButtonComponent } from '@frame-kit/ui-ng/ui/button';\nimport { DIALOG_DATA } from '@frame-kit/ui-ng/ui/dialog';\nimport type { WizardDialogContainerData } from './wizard-dialog.service';\nimport { WIZARD_DIALOG_REF, WizardDialogRef } from './wizard-dialog-ref';\n\n@Component({\n selector: 'fk-wizard-dialog-container',\n standalone: true,\n imports: [ButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './wizard-dialog-container.component.html',\n styleUrl: './wizard-dialog-container.component.scss',\n})\nexport class WizardDialogContainerComponent implements AfterViewInit {\n private readonly data = inject(\n DIALOG_DATA as never,\n ) as WizardDialogContainerData;\n private readonly injector = inject(Injector);\n private readonly bodyOutlet = viewChild('bodyOutlet', {\n read: ViewContainerRef,\n });\n private readonly headerOutlet = viewChild('headerOutlet', {\n read: ViewContainerRef,\n });\n private readonly footerOutlet = viewChild('footerOutlet', {\n read: ViewContainerRef,\n });\n private readonly stepperOutlet = viewChild('stepperOutlet', {\n read: ViewContainerRef,\n });\n\n readonly ref: WizardDialogRef = this.data.wizardRef;\n\n readonly classes = computed(() => 'fk-wizard-dialog');\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n ngAfterViewInit(): void {\n // One injector for both regions so a consumer-supplied header can inject\n // WIZARD_DIALOG_REF exactly like the step content does.\n const childInjector = Injector.create({\n parent: this.injector,\n providers: [{ provide: WIZARD_DIALOG_REF as never, useValue: this.ref }],\n });\n\n this.mountRegion(\n this.headerOutlet(),\n this.ref.headerComponent,\n this.ref.headerInputs,\n childInjector,\n );\n\n this.mountRegion(\n this.footerOutlet(),\n this.ref.footerComponent,\n this.ref.footerInputs,\n childInjector,\n );\n\n this.mountRegion(\n this.stepperOutlet(),\n this.ref.stepperComponent,\n this.ref.stepperInputs,\n childInjector,\n );\n\n const outlet = this.bodyOutlet();\n\n if (!outlet) {\n return;\n }\n\n outlet.createComponent(this.data.contentComponent, {\n injector: childInjector,\n });\n }\n\n /**\n * Render an optional consumer-supplied region (header or footer) into its\n * fixed outlet, applying the configured inputs so consumers configure it\n * declaratively from the wizard config. Shares the wizard injector, so the\n * component can inject `WIZARD_DIALOG_REF`.\n */\n private mountRegion(\n outlet: ViewContainerRef | undefined,\n component: Type<unknown> | null,\n inputs: Record<string, unknown>,\n injector: Injector,\n ): void {\n if (!component || !outlet) {\n return;\n }\n\n const componentRef = outlet.createComponent(component, { injector });\n\n for (const [name, value] of Object.entries(inputs)) {\n componentRef.setInput(name, value);\n }\n\n componentRef.changeDetectorRef.detectChanges();\n }\n\n onCancel(): void {\n this.ref.close();\n }\n\n onSubmit(): void {\n this.ref.emitSubmit();\n }\n}\n","<!-- Consumer-supplied header (fixed, above the stepper) -->\n@if (ref.headerComponent) {\n <div class=\"fk-wizard-dialog__header\">\n <ng-template #headerOutlet />\n </div>\n}\n\n<!-- Stepper -->\n@if (ref.stepperComponent) {\n <div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n >\n <ng-template #stepperOutlet />\n </div>\n} @else {\n <div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n role=\"tablist\"\n >\n @for (step of ref.steps; track $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"fk-wizard-dialog__step\"\n [class.fk-wizard-dialog__step--active]=\"$index === ref.currentIndex()\"\n [class.fk-wizard-dialog__step--completed]=\"$index < ref.currentIndex()\"\n [attr.aria-selected]=\"$index === ref.currentIndex()\"\n [disabled]=\"ref.linear && $index > ref.highestVisitedIndex()\"\n (click)=\"ref.goTo($index)\"\n >\n <span class=\"fk-wizard-dialog__step-number\">{{ $index + 1 }}</span>\n <span class=\"fk-wizard-dialog__step-title\">{{ step.title }}</span>\n @if (step.optional) {\n <span class=\"fk-wizard-dialog__step-optional\">(Optional)</span>\n }\n </button>\n }\n </div>\n\n <!-- Scrollable body -->\n}\n\n<div class=\"fk-wizard-dialog__body\">\n <ng-template #bodyOutlet />\n</div>\n\n<!-- Footer (moved to dialog footer by DialogService) -->\n<div\n class=\"fk-wizard-dialog__footer\"\n [class.fk-wizard-dialog__footer--hidden]=\"!ref.chromeVisible()\"\n libDialogFooter\n>\n @if (ref.footerComponent) {\n <ng-template #footerOutlet />\n } @else {\n @if (ref.isFirstStep()) {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"onCancel()\">\n {{ ref.cancelLabel }}\n </fk-button>\n } @else {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"ref.previous()\">\n {{ ref.backLabel }}\n </fk-button>\n }\n\n @if (ref.extraAction(); as action) {\n <fk-button\n [variant]=\"action.variant ?? 'outline'\"\n type=\"button\"\n (click)=\"action.onClick()\"\n >\n {{ action.label }}\n </fk-button>\n }\n\n @if (ref.isLastStep()) {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.submitDisabled()\"\n (click)=\"onSubmit()\"\n >\n {{ ref.submitLabel }}\n </fk-button>\n } @else {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.nextDisabled()\"\n (click)=\"ref.next()\"\n >\n {{ ref.nextLabel }}\n </fk-button>\n }\n }\n</div>\n","import { inject, Injectable, Type } from '@angular/core';\n\nimport { DialogService } from '@frame-kit/ui-ng/ui/dialog';\nimport type { DialogRef } from '@frame-kit/ui-ng/ui/dialog';\nimport type { WizardDialogConfig } from './wizard-dialog.types';\nimport { WizardDialogContainerComponent } from './wizard-dialog-container.component';\nimport { WizardDialogRef } from './wizard-dialog-ref';\n\nexport interface WizardDialogContainerData {\n wizardRef: WizardDialogRef;\n contentComponent: Type<unknown>;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class WizardDialogService {\n private readonly dialogService = inject(DialogService);\n\n open<TResult = unknown, TData = unknown>(\n content: Type<unknown>,\n config: WizardDialogConfig<TData>,\n ): WizardDialogRef<TResult, TData> {\n const wizardRef = new WizardDialogRef<TResult, TData>(config);\n\n const dialogRef = this.dialogService.open<\n TResult,\n WizardDialogContainerData\n >(WizardDialogContainerComponent, {\n header: config.header,\n size: config.size ?? 'lg',\n closable: config.closable,\n closeOnEscape: config.closeOnEscape,\n closeOnBackdrop: config.closeOnBackdrop,\n animation: config.animation,\n fullscreenMobile: config.fullscreenMobile,\n className: ['fk-wizard-dialog-host', config.className]\n .filter(Boolean)\n .join(' '),\n ariaLabel: config.ariaLabel,\n ariaDescribedBy: config.ariaDescribedBy,\n flexBody: true,\n data: {\n wizardRef: wizardRef as WizardDialogRef,\n contentComponent: content,\n },\n });\n\n wizardRef.setDialogRef(dialogRef as DialogRef<TResult>);\n\n return wizardRef;\n }\n}\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,5 +1,5 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { Type } from '@angular/core';
|
|
2
|
+
import { Signal, Type } from '@angular/core';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
4
|
|
|
5
5
|
type DialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';
|
|
@@ -113,10 +113,29 @@ declare class DialogRef<TResult = unknown, TData = unknown> {
|
|
|
113
113
|
private readonly afterOpenedSubject;
|
|
114
114
|
private readonly beforeCloseSubject;
|
|
115
115
|
private readonly afterClosedSubject;
|
|
116
|
+
private readonly sizeSignal;
|
|
116
117
|
private closed;
|
|
117
118
|
private closeGuard;
|
|
119
|
+
private sizeUpdater;
|
|
118
120
|
readonly config: DialogConfig<TData>;
|
|
121
|
+
/**
|
|
122
|
+
* The dialog's current panel size. Starts at the opening config's size
|
|
123
|
+
* and tracks every `updateSize` call — chrome components (e.g. an
|
|
124
|
+
* expand/collapse toggle) can render their state from it.
|
|
125
|
+
*/
|
|
126
|
+
readonly size: Signal<DialogSize>;
|
|
119
127
|
constructor(config?: DialogConfig<TData>);
|
|
128
|
+
/**
|
|
129
|
+
* Resize the open dialog in place — e.g. toggle between the opened
|
|
130
|
+
* size and `"fullscreen"` from an expand button in custom chrome. The
|
|
131
|
+
* panel transitions its size classes reactively; no reopen needed.
|
|
132
|
+
*/
|
|
133
|
+
updateSize(size: DialogSize): void;
|
|
134
|
+
/**
|
|
135
|
+
* @internal Wired by DialogService after the host is created so
|
|
136
|
+
* `updateSize` can reach the host component's `size` input.
|
|
137
|
+
*/
|
|
138
|
+
bindSizeUpdater(updater: (size: DialogSize) => void): void;
|
|
120
139
|
get data(): TData | undefined;
|
|
121
140
|
setCanClose(guard: CanCloseFn | null): void;
|
|
122
141
|
close(result?: TResult): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { Type, AfterViewInit } from '@angular/core';
|
|
3
|
-
import { DialogConfig, DialogRef } from '@frame-kit/ui-ng/ui/dialog';
|
|
3
|
+
import { DialogConfig, DialogSize, DialogRef } from '@frame-kit/ui-ng/ui/dialog';
|
|
4
4
|
import { Observable } from 'rxjs';
|
|
5
5
|
|
|
6
6
|
interface WizardDialogStep {
|
|
@@ -39,6 +39,29 @@ interface WizardDialogConfig<TData = unknown> extends Pick<DialogConfig<TData>,
|
|
|
39
39
|
* `{ icon: 'key-outline', title: 'Create API Key' }`.
|
|
40
40
|
*/
|
|
41
41
|
headerInputs?: Record<string, unknown>;
|
|
42
|
+
/**
|
|
43
|
+
* Component rendered in place of the built-in footer buttons. Use this when
|
|
44
|
+
* the default Cancel/Back + Next/Submit row isn't enough (e.g. a step
|
|
45
|
+
* counter, icon-bearing buttons).
|
|
46
|
+
*
|
|
47
|
+
* The component is created with the wizard's injector, so it can inject
|
|
48
|
+
* `WIZARD_DIALOG_REF` to drive navigation (`next()`, `previous()`, `close()`)
|
|
49
|
+
* and read step state.
|
|
50
|
+
*/
|
|
51
|
+
footerComponent?: Type<unknown>;
|
|
52
|
+
/** Inputs applied to `footerComponent` via `setInput`. */
|
|
53
|
+
footerInputs?: Record<string, unknown>;
|
|
54
|
+
/**
|
|
55
|
+
* Component rendered in place of the built-in stepper. Use this when the
|
|
56
|
+
* default numbered-pill row isn't enough (e.g. connecting progress lines,
|
|
57
|
+
* per-step kickers, completion checks).
|
|
58
|
+
*
|
|
59
|
+
* The component is created with the wizard's injector, so it can inject
|
|
60
|
+
* `WIZARD_DIALOG_REF` to read `steps` / `currentIndex` and call `goTo()`.
|
|
61
|
+
*/
|
|
62
|
+
stepperComponent?: Type<unknown>;
|
|
63
|
+
/** Inputs applied to `stepperComponent` via `setInput`. */
|
|
64
|
+
stepperInputs?: Record<string, unknown>;
|
|
42
65
|
}
|
|
43
66
|
|
|
44
67
|
/**
|
|
@@ -73,6 +96,14 @@ declare class WizardDialogRef<TResult = unknown, TData = unknown> {
|
|
|
73
96
|
readonly headerComponent: Type<unknown> | null;
|
|
74
97
|
/** Inputs applied to `headerComponent` when it is created. */
|
|
75
98
|
readonly headerInputs: Record<string, unknown>;
|
|
99
|
+
/** Optional consumer-supplied footer, replacing the built-in buttons. */
|
|
100
|
+
readonly footerComponent: Type<unknown> | null;
|
|
101
|
+
/** Inputs applied to `footerComponent` when it is created. */
|
|
102
|
+
readonly footerInputs: Record<string, unknown>;
|
|
103
|
+
/** Optional consumer-supplied stepper, replacing the built-in pill row. */
|
|
104
|
+
readonly stepperComponent: Type<unknown> | null;
|
|
105
|
+
/** Inputs applied to `stepperComponent` when it is created. */
|
|
106
|
+
readonly stepperInputs: Record<string, unknown>;
|
|
76
107
|
readonly currentIndex: _angular_core.WritableSignal<number>;
|
|
77
108
|
readonly highestVisitedIndex: _angular_core.WritableSignal<number>;
|
|
78
109
|
readonly totalSteps: _angular_core.Signal<number>;
|
|
@@ -100,6 +131,17 @@ declare class WizardDialogRef<TResult = unknown, TData = unknown> {
|
|
|
100
131
|
private updateHighestVisited;
|
|
101
132
|
close(result?: TResult): void;
|
|
102
133
|
afterClosed(): Observable<TResult | undefined>;
|
|
134
|
+
/**
|
|
135
|
+
* The underlying dialog's current panel size — see `DialogRef.size`.
|
|
136
|
+
* Custom chrome renders expand/collapse state from it.
|
|
137
|
+
*/
|
|
138
|
+
size(): DialogSize;
|
|
139
|
+
/**
|
|
140
|
+
* Resize the open wizard in place — see `DialogRef.updateSize`.
|
|
141
|
+
* Typically toggled between the opened size and `"fullscreen"` by an
|
|
142
|
+
* expand button in custom header chrome.
|
|
143
|
+
*/
|
|
144
|
+
updateSize(size: DialogSize): void;
|
|
103
145
|
/** @internal Called by container when submit button is clicked. */
|
|
104
146
|
emitSubmit(): void;
|
|
105
147
|
/** @internal Called by WizardDialogService after dialog is opened. */
|
|
@@ -122,16 +164,19 @@ declare class WizardDialogContainerComponent implements AfterViewInit {
|
|
|
122
164
|
private readonly injector;
|
|
123
165
|
private readonly bodyOutlet;
|
|
124
166
|
private readonly headerOutlet;
|
|
167
|
+
private readonly footerOutlet;
|
|
168
|
+
private readonly stepperOutlet;
|
|
125
169
|
readonly ref: WizardDialogRef;
|
|
126
170
|
readonly classes: _angular_core.Signal<string>;
|
|
127
171
|
get hostClass(): string;
|
|
128
172
|
ngAfterViewInit(): void;
|
|
129
173
|
/**
|
|
130
|
-
* Render
|
|
131
|
-
*
|
|
132
|
-
* declaratively from the wizard config.
|
|
174
|
+
* Render an optional consumer-supplied region (header or footer) into its
|
|
175
|
+
* fixed outlet, applying the configured inputs so consumers configure it
|
|
176
|
+
* declaratively from the wizard config. Shares the wizard injector, so the
|
|
177
|
+
* component can inject `WIZARD_DIALOG_REF`.
|
|
133
178
|
*/
|
|
134
|
-
private
|
|
179
|
+
private mountRegion;
|
|
135
180
|
onCancel(): void;
|
|
136
181
|
onSubmit(): void;
|
|
137
182
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WizardDialogContainerComponent, never>;
|
package/ui/dialog/README.md
CHANGED
|
@@ -58,6 +58,7 @@ An accessible, token-driven dialog / modal component with focus management, scro
|
|
|
58
58
|
- Portalled dialog with backdrop, scroll locking, and focus restoration
|
|
59
59
|
- Configurable size, position, and animation
|
|
60
60
|
- Guardable close behavior (`preventClose`, `canClose`)
|
|
61
|
+
- Runtime resizing — `DialogRef.updateSize(size)` restyles the open panel in place (with a readable `size` signal for chrome like expand/collapse toggles)
|
|
61
62
|
- Escape and backdrop handling
|
|
62
63
|
- Default header via `header` input, or fully custom header via `[fkDialogHeader]` directive
|
|
63
64
|
- Footer slot with built-in flex layout
|
|
@@ -54,6 +54,8 @@ A service-driven wizard dialog for multi-step workflows. Opens its own dialog vi
|
|
|
54
54
|
| `previous()` | `boolean` | Go back one step |
|
|
55
55
|
| `goTo(index)` | `boolean` | Jump to step (respects linear mode) |
|
|
56
56
|
| `close(result?)` | `void` | Close the dialog |
|
|
57
|
+
| `size()` | `DialogSize` | Current panel size of the underlying dialog |
|
|
58
|
+
| `updateSize(size)` | `void` | Resize the open wizard in place (e.g. toggle `"fullscreen"` from custom chrome) |
|
|
57
59
|
| `afterClosed()` | `Observable<TResult>` | Emitted after dialog closes |
|
|
58
60
|
|
|
59
61
|
### WizardExtraAction
|
|
@@ -89,6 +91,77 @@ wizardDialog.open(CreateApiKeyWizard, {
|
|
|
89
91
|
The header is created with the wizard's own injector, so it can
|
|
90
92
|
`inject(WIZARD_DIALOG_REF)` to read step state or close the wizard.
|
|
91
93
|
|
|
94
|
+
### Custom footer
|
|
95
|
+
|
|
96
|
+
Same mechanism for the footer. Supply `footerComponent` to replace the built-in
|
|
97
|
+
Cancel/Back + Next/Submit row — useful for a step counter, icon-bearing
|
|
98
|
+
buttons, or any layout the defaults don't cover. It renders inside the wizard's
|
|
99
|
+
own fixed footer region, so it stays pinned while the body scrolls.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
wizardDialog.open(CreateApiKeyWizard, {
|
|
103
|
+
footerComponent: MyWizardFooterComponent,
|
|
104
|
+
steps: [...],
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Like the header, it's created with the wizard's injector — so it can
|
|
109
|
+
`inject(WIZARD_DIALOG_REF)` and drive navigation via `next()`, `previous()`,
|
|
110
|
+
and `close()`.
|
|
111
|
+
|
|
112
|
+
### Custom stepper
|
|
113
|
+
|
|
114
|
+
`stepperComponent` replaces the built-in numbered-pill row — for progress
|
|
115
|
+
lines, per-step kickers, completion checks, or any other treatment. It renders
|
|
116
|
+
in the same fixed stepper region and respects `chromeVisible`.
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
wizardDialog.open(CreateApiKeyWizard, {
|
|
120
|
+
stepperComponent: MyWizardStepperComponent,
|
|
121
|
+
steps: [...],
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
It reads `steps`, `currentIndex`, and `highestVisitedIndex` off the injected
|
|
126
|
+
`WIZARD_DIALOG_REF`, and calls `goTo()` to navigate. A custom stepper owns its
|
|
127
|
+
own ARIA — the built-in `role="tablist"` markup is not applied to it.
|
|
128
|
+
|
|
129
|
+
### Custom chrome: host display requirement
|
|
130
|
+
|
|
131
|
+
Each region wrapper is a flex container that mounts your component's **host
|
|
132
|
+
element** as its flex item. A host defaults to `display: block`, which
|
|
133
|
+
collapses the component's own internal layout (spacers, right-aligned
|
|
134
|
+
buttons). Every custom header / stepper / footer component must declare its
|
|
135
|
+
host display:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
@Component({
|
|
139
|
+
// ...
|
|
140
|
+
styles: `
|
|
141
|
+
:host {
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
width: 100%;
|
|
145
|
+
}
|
|
146
|
+
`,
|
|
147
|
+
})
|
|
148
|
+
export class MyWizardFooterComponent {}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Symptom if you forget: the footer's spacer does nothing and buttons bunch to
|
|
152
|
+
the left.
|
|
153
|
+
|
|
154
|
+
### Chrome slots at a glance
|
|
155
|
+
|
|
156
|
+
All three regions follow the same pattern, so a consumer can override one and
|
|
157
|
+
keep the library defaults for the rest:
|
|
158
|
+
|
|
159
|
+
| Region | Config option | Falls back to |
|
|
160
|
+
| ------- | ------------------ | ---------------------------------- |
|
|
161
|
+
| Header | `headerComponent` | none (no default header) |
|
|
162
|
+
| Stepper | `stepperComponent` | built-in numbered pills |
|
|
163
|
+
| Footer | `footerComponent` | built-in Cancel/Back + Next/Submit |
|
|
164
|
+
|
|
92
165
|
## Features
|
|
93
166
|
|
|
94
167
|
- Service-driven: opens its own dialog with proper footer pinning
|
|
@@ -273,6 +346,7 @@ The footer's existing flex layout (`flex: 1 1 0` on each child) stretches all th
|
|
|
273
346
|
## Design Tokens
|
|
274
347
|
|
|
275
348
|
```scss
|
|
349
|
+
--fk-wizard-dialog-top-offset
|
|
276
350
|
--fk-wizard-dialog-header-padding
|
|
277
351
|
--fk-wizard-dialog-stepper-gap
|
|
278
352
|
--fk-wizard-dialog-stepper-padding
|