@mk-kit/ui 0.49.0 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/mk-kit-ui-embed.mjs +24 -5
- package/fesm2022/mk-kit-ui-embed.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-feedback-prompt-dialog-DnxQ7M0h.mjs +49 -0
- package/fesm2022/mk-kit-ui-feedback-prompt-dialog-DnxQ7M0h.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-feedback.mjs +7 -43
- package/fesm2022/mk-kit-ui-feedback.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-testing.mjs +13 -2
- package/fesm2022/mk-kit-ui-testing.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mk-kit-ui-embed.d.ts +19 -2
- package/types/mk-kit-ui-feedback.d.ts +1 -22
- package/types/mk-kit-ui-testing.d.ts +6 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { provideZonelessChangeDetection, createComponent, ChangeDetectionStrategy, Component, reflectComponentType } from '@angular/core';
|
|
2
|
+
import { CSP_NONCE, provideZonelessChangeDetection, createComponent, ChangeDetectionStrategy, Component, reflectComponentType } from '@angular/core';
|
|
3
3
|
import { createApplication } from '@angular/platform-browser';
|
|
4
4
|
import { MK_OVERLAY_ROOT } from '@mk-kit/ui/core';
|
|
5
5
|
|
|
@@ -69,7 +69,7 @@ class MkEmbedApp {
|
|
|
69
69
|
constructor(init = {}) {
|
|
70
70
|
this.init = init;
|
|
71
71
|
const styles = init.styles == null ? [] : typeof init.styles === 'string' ? [init.styles] : [...init.styles];
|
|
72
|
-
this._mkStyles = new MkEmbedStyles(styles);
|
|
72
|
+
this._mkStyles = new MkEmbedStyles(styles, init.styleUrls ?? [], init.nonce);
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
75
|
* Defines `tag` as a custom element rendering `component`. Chainable; a
|
|
@@ -112,9 +112,13 @@ class MkEmbedApp {
|
|
|
112
112
|
_mkApplication() {
|
|
113
113
|
if (this.destroyed)
|
|
114
114
|
return Promise.reject(new Error('This MkEmbedApp was destroyed.'));
|
|
115
|
+
if (typeof document === 'undefined') {
|
|
116
|
+
return Promise.reject(new Error('mkEmbed needs a browser — on the server, defining elements is a no-op and nothing should await ready().'));
|
|
117
|
+
}
|
|
115
118
|
this.appPromise ??= createApplication({
|
|
116
119
|
providers: [
|
|
117
120
|
provideZonelessChangeDetection(),
|
|
121
|
+
...(this.init.nonce ? [{ provide: CSP_NONCE, useValue: this.init.nonce }] : []),
|
|
118
122
|
...(this.init.overlays === false
|
|
119
123
|
? []
|
|
120
124
|
: [{ provide: MK_OVERLAY_ROOT, useValue: () => this.overlayRootElement() }]),
|
|
@@ -176,15 +180,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
176
180
|
}] });
|
|
177
181
|
/**
|
|
178
182
|
* The embed styles, parsed once and shared: constructable stylesheets where
|
|
179
|
-
* supported, cloned `<style>` elements otherwise
|
|
183
|
+
* supported, cloned `<style>` elements otherwise, plus `<link>` elements for
|
|
184
|
+
* `styleUrls`. The nonce lands on every element this class creates.
|
|
180
185
|
*/
|
|
181
186
|
class MkEmbedStyles {
|
|
182
187
|
css;
|
|
188
|
+
urls;
|
|
189
|
+
nonce;
|
|
183
190
|
sheets;
|
|
184
|
-
constructor(css) {
|
|
191
|
+
constructor(css, urls, nonce) {
|
|
185
192
|
this.css = css;
|
|
193
|
+
this.urls = urls;
|
|
194
|
+
this.nonce = nonce;
|
|
186
195
|
}
|
|
187
196
|
adopt(root) {
|
|
197
|
+
const doc = root.host.ownerDocument;
|
|
198
|
+
for (const url of this.urls) {
|
|
199
|
+
const link = doc.createElement('link');
|
|
200
|
+
link.rel = 'stylesheet';
|
|
201
|
+
link.href = url;
|
|
202
|
+
if (this.nonce)
|
|
203
|
+
link.setAttribute('nonce', this.nonce);
|
|
204
|
+
root.appendChild(link);
|
|
205
|
+
}
|
|
188
206
|
if (!this.css.length)
|
|
189
207
|
return;
|
|
190
208
|
if (this.sheets === undefined) {
|
|
@@ -208,10 +226,11 @@ class MkEmbedStyles {
|
|
|
208
226
|
// Fall through to <style> elements.
|
|
209
227
|
}
|
|
210
228
|
}
|
|
211
|
-
const doc = root.host.ownerDocument;
|
|
212
229
|
for (const text of this.css) {
|
|
213
230
|
const el = doc.createElement('style');
|
|
214
231
|
el.textContent = text;
|
|
232
|
+
if (this.nonce)
|
|
233
|
+
el.setAttribute('nonce', this.nonce);
|
|
215
234
|
root.appendChild(el);
|
|
216
235
|
}
|
|
217
236
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mk-kit-ui-embed.mjs","sources":["../../../projects/mk-kit/embed/shadow-css.ts","../../../projects/mk-kit/embed/embed.ts","../../../projects/mk-kit/embed/index.ts","../../../projects/mk-kit/embed/mk-kit-ui-embed.ts"],"sourcesContent":["/**\n * Rewrites a document-level stylesheet for adoption into a shadow root:\n * `:root` never matches inside one, so token blocks like mk-kit's\n * `:root { --mk-primary: … }` are retargeted to `:host`. Theme opt-ins keep\n * working — `:root:not([data-mk-theme='light'])` becomes\n * `:host:not([data-mk-theme='light'])`, so `<my-widget data-mk-theme=\"dark\">`\n * switches one embedded element to the dark palette.\n *\n * ```ts\n * import themeCss from '@mk-kit/ui/styles.css' with { type: 'text' };\n * mkEmbed({ styles: mkShadowCss(themeCss) });\n * ```\n */\nexport function mkShadowCss(css: string): string {\n return css.replace(/:root\\b/g, ':host');\n}\n","import {\n ApplicationRef,\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n type EnvironmentProviders,\n type Provider,\n type Type,\n createComponent,\n provideZonelessChangeDetection,\n reflectComponentType,\n} from '@angular/core';\nimport { createApplication } from '@angular/platform-browser';\nimport { MK_OVERLAY_ROOT } from '@mk-kit/ui/core';\n\n/** Options for {@link mkEmbed}. */\nexport interface MkEmbedInit {\n /**\n * CSS text adopted into every element's shadow root (and the overlay host).\n * Pass the mk-kit theme through {@link mkShadowCss} so its `:root` token\n * blocks target `:host`; append your own widget CSS after it. Shared as\n * constructable stylesheets when the browser supports them (one parse for\n * any number of instances), `<style>` elements otherwise.\n */\n styles?: string | readonly string[];\n /**\n * Extra providers for the shared application — `provideMkI18n(…)`,\n * `provideMkExtendedIcons()`, `provideHttpClient()`, your services.\n */\n providers?: Array<Provider | EnvironmentProviders>;\n /**\n * Mount mk-kit overlays (dialogs, anchored panels, toasts, tours) inside a\n * page-level shadow host that carries the same `styles`, instead of bare\n * `document.body`. Default `true`; set `false` to keep the application\n * default (overlays styled by the page's own stylesheets).\n */\n overlays?: boolean;\n}\n\n/**\n * Creates an embed application: a factory for custom elements that render\n * mk-kit-based Angular components behind shadow DOM.\n *\n * - **Lazy**: `element()` only defines the tag; the Angular application is\n * created on the first element actually connected to a document.\n * - **Shared**: every element of one `mkEmbed()` call runs in one zoneless\n * `ApplicationRef` with one provider set.\n * - **Isolated but themable**: the host page's CSS cannot reach the widget\n * internals, while `--mk-*` custom properties still inherit through the\n * shadow boundary — set them on the element (or any ancestor) to theme it.\n * - **Styled**: Angular routes each component's own styles into the shadow\n * root it renders in; the `styles` option supplies the token/theme layer.\n *\n * ```ts\n * import { mkEmbed, mkShadowCss } from '@mk-kit/ui/embed';\n * import themeCss from '@mk-kit/ui/styles.css' with { type: 'text' };\n *\n * mkEmbed({ styles: mkShadowCss(themeCss) })\n * .element('acme-reviews', ReviewsWidget)\n * .element('acme-signup', SignupWidget);\n * ```\n *\n * ```html\n * <acme-reviews product-id=\"42\" style=\"--mk-primary: #7c3aed\"></acme-reviews>\n * ```\n *\n * Inputs are exposed as dash-cased attributes (string values go through the\n * input's `transform`, so `booleanAttribute` / `numberAttribute` inputs coerce\n * as usual) and as camel-cased element properties (any value); outputs become\n * bubbling, composed `CustomEvent`s named after the output, with the emitted\n * value as `detail`.\n */\nexport function mkEmbed(init: MkEmbedInit = {}): MkEmbedApp {\n return new MkEmbedApp(init);\n}\n\n/** One shared embed application. Create it with {@link mkEmbed}. */\nexport class MkEmbedApp {\n /** @internal Adopted into every shadow root this app renders in. */\n readonly _mkStyles: MkEmbedStyles;\n\n private readonly init: MkEmbedInit;\n private appPromise: Promise<ApplicationRef> | null = null;\n private appRef: ApplicationRef | null = null;\n private overlayHost: HTMLElement | null = null;\n private overlayInner: HTMLElement | null = null;\n private destroyed = false;\n\n constructor(init: MkEmbedInit = {}) {\n this.init = init;\n const styles = init.styles == null ? [] : typeof init.styles === 'string' ? [init.styles] : [...init.styles];\n this._mkStyles = new MkEmbedStyles(styles);\n }\n\n /**\n * Defines `tag` as a custom element rendering `component`. Chainable; a\n * no-op when the tag is already defined (hot reload, duplicate script) or\n * outside a browser.\n */\n element(tag: string, component: Type<unknown>): this {\n if (typeof customElements === 'undefined') return this;\n if (customElements.get(tag)) return this;\n customElements.define(tag, createElementClass(this, component));\n return this;\n }\n\n /** Resolves when the shared application is running (created on demand). */\n ready(): Promise<void> {\n return this._mkApplication().then(() => undefined);\n }\n\n /** Resolves when the application has no pending change detection. */\n async whenStable(): Promise<void> {\n await this._mkApplication().then((app) => app.whenStable());\n }\n\n /**\n * Destroys the shared application, every mounted component and the overlay\n * host. Defined tags remain registered (the platform cannot undefine them)\n * but render nothing afterwards.\n */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.appRef?.destroy();\n this.appRef = null;\n this.appPromise = null;\n this.overlayHost?.remove();\n this.overlayHost = null;\n this.overlayInner = null;\n }\n\n /** @internal */\n _mkApplication(): Promise<ApplicationRef> {\n if (this.destroyed) return Promise.reject(new Error('This MkEmbedApp was destroyed.'));\n this.appPromise ??= createApplication({\n providers: [\n provideZonelessChangeDetection(),\n ...(this.init.overlays === false\n ? []\n : [{ provide: MK_OVERLAY_ROOT, useValue: () => this.overlayRootElement() }]),\n ...(this.init.providers ?? []),\n ],\n }).then((ref) => (this.appRef = ref));\n return this.appPromise;\n }\n\n /** @internal The running application — only valid once `ready()` resolved. */\n get _mkAppRef(): ApplicationRef {\n if (!this.appRef) throw new Error('The embed application is not running yet.');\n return this.appRef;\n }\n\n /**\n * Lazily builds the page-level overlay host: a shadow root carrying the\n * embed styles, with an inner container the overlay services append to.\n */\n private overlayRootElement(): HTMLElement {\n if (this.overlayInner) return this.overlayInner;\n const appRef = this._mkAppRef;\n const doc = document;\n const host = doc.createElement('mk-embed-overlays');\n const shadow = host.attachShadow({ mode: 'open' });\n this._mkStyles.adopt(shadow);\n const inner = doc.createElement('div');\n shadow.appendChild(inner);\n doc.body.appendChild(host);\n\n // Register this shadow root as an Angular styles host: creating one\n // component with an ATTACHED host element inside it makes Angular mirror\n // every component stylesheet here — including components created detached\n // and appended later (toast / snackbar containers) and anchored panels\n // teleported in from other roots. The anchor lives until destroy().\n const anchorHost = doc.createElement('div');\n inner.appendChild(anchorHost);\n const anchor = createComponent(MkEmbedStyleAnchor, {\n environmentInjector: appRef.injector,\n hostElement: anchorHost,\n });\n appRef.attachView(anchor.hostView);\n\n this.overlayHost = host;\n this.overlayInner = inner;\n return inner;\n }\n}\n\n/** Invisible component whose only job is registering a shadow styles host. */\n@Component({\n selector: 'mk-embed-style-anchor',\n template: '',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nclass MkEmbedStyleAnchor {}\n\n/**\n * The embed styles, parsed once and shared: constructable stylesheets where\n * supported, cloned `<style>` elements otherwise.\n */\nclass MkEmbedStyles {\n private sheets: CSSStyleSheet[] | null | undefined;\n\n constructor(private readonly css: readonly string[]) {}\n\n adopt(root: ShadowRoot): void {\n if (!this.css.length) return;\n if (this.sheets === undefined) {\n try {\n this.sheets = this.css.map((text) => {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(text);\n return sheet;\n });\n } catch {\n this.sheets = null;\n }\n }\n if (this.sheets) {\n try {\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, ...this.sheets];\n return;\n } catch {\n // Fall through to <style> elements.\n }\n }\n const doc = root.host.ownerDocument;\n for (const text of this.css) {\n const el = doc.createElement('style');\n el.textContent = text;\n root.appendChild(el);\n }\n }\n}\n\n/** `pageSize` → `page-size` (the attribute name of an input). */\nfunction dasherize(name: string): string {\n return name.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n}\n\ninterface OutputLike {\n subscribe?: (next: (value: unknown) => void) => { unsubscribe(): void };\n}\n\n/** Builds the custom-element class wrapping one Angular component. */\nfunction createElementClass(app: MkEmbedApp, component: Type<unknown>): CustomElementConstructor {\n const mirror = reflectComponentType(component);\n if (!mirror) {\n throw new Error('mkEmbed: the provided class is not an Angular component.');\n }\n const inputs = mirror.inputs;\n const outputs = mirror.outputs;\n const attrToInput = new Map<string, string>();\n for (const { templateName } of inputs) attrToInput.set(dasherize(templateName), templateName);\n\n class MkEmbeddedElement extends HTMLElement {\n static readonly observedAttributes = [...attrToInput.keys()];\n\n private _mkRef: ComponentRef<unknown> | null = null;\n private readonly _mkValues = new Map<string, unknown>();\n private _mkSubs: { unsubscribe(): void }[] = [];\n private _mkEpoch = 0;\n private _mkStylesAdopted = false;\n private _mkResolveReady!: () => void;\n\n /** Resolves once the Angular component is mounted in the shadow root. */\n readonly mkReady: Promise<void> = new Promise((resolve) => (this._mkResolveReady = resolve));\n\n /** The mounted Angular component instance, or `null` before/after. */\n get mkComponent(): unknown {\n return this._mkRef?.instance ?? null;\n }\n\n connectedCallback(): void {\n const epoch = ++this._mkEpoch;\n void app._mkApplication().then(() => {\n if (epoch !== this._mkEpoch || !this.isConnected || this._mkRef) return;\n this._mkMount();\n });\n }\n\n disconnectedCallback(): void {\n const epoch = ++this._mkEpoch;\n queueMicrotask(() => {\n // Moving an element fires disconnect + connect in one task — only\n // tear down when it is still detached by the end of the microtask.\n if (epoch === this._mkEpoch && !this.isConnected) this._mkUnmount();\n });\n }\n\n attributeChangedCallback(name: string, _prev: string | null, value: string | null): void {\n const input = attrToInput.get(name);\n if (input) this._mkApplyInput(input, value);\n }\n\n /** @internal Shared by attribute changes and property setters. */\n _mkApplyInput(name: string, value: unknown): void {\n this._mkValues.set(name, value);\n this._mkRef?.setInput(name, value);\n }\n\n /** @internal */\n _mkLastValue(name: string): unknown {\n return this._mkValues.get(name);\n }\n\n private _mkMount(): void {\n const shadow = this.shadowRoot ?? this.attachShadow({ mode: 'open' });\n if (!this._mkStylesAdopted) {\n app._mkStyles.adopt(shadow);\n this._mkStylesAdopted = true;\n }\n // An inner host element (rather than rendering into the shadow root\n // directly) is what routes the component's styles into this shadow\n // root: Angular resolves the style host from the host element's root\n // node at creation time.\n const host = this.ownerDocument.createElement('div');\n shadow.appendChild(host);\n const appRef = app._mkAppRef;\n const ref = createComponent(component, {\n environmentInjector: appRef.injector,\n hostElement: host,\n });\n for (const [name, value] of this._mkValues) ref.setInput(name, value);\n for (const { propName, templateName } of outputs) {\n const source = (ref.instance as Record<string, unknown>)[propName] as OutputLike | undefined;\n if (source && typeof source.subscribe === 'function') {\n this._mkSubs.push(\n source.subscribe((detail: unknown) => {\n this.dispatchEvent(new CustomEvent(templateName, { detail, bubbles: true, composed: true }));\n }),\n );\n }\n }\n appRef.attachView(ref.hostView);\n // First render happens before mkReady resolves — attachView alone only\n // schedules it for the next zoneless flush.\n ref.changeDetectorRef.detectChanges();\n this._mkRef = ref;\n this._mkResolveReady();\n }\n\n private _mkUnmount(): void {\n for (const sub of this._mkSubs) sub.unsubscribe();\n this._mkSubs = [];\n const host = this._mkRef?.location.nativeElement as HTMLElement | undefined;\n this._mkRef?.destroy();\n host?.remove();\n this._mkRef = null;\n }\n }\n\n // Property accessors for every input that does not collide with a native\n // element property (`title`, `hidden`, `dir`, …) or with the wrapper's own\n // surface — collisions stay reachable through the dash-cased attribute.\n for (const { templateName } of inputs) {\n if (templateName in MkEmbeddedElement.prototype) continue;\n Object.defineProperty(MkEmbeddedElement.prototype, templateName, {\n configurable: true,\n enumerable: true,\n get(this: MkEmbeddedElement) {\n return this._mkLastValue(templateName);\n },\n set(this: MkEmbeddedElement, value: unknown) {\n this._mkApplyInput(templateName, value);\n },\n });\n }\n\n return MkEmbeddedElement;\n}\n","/**\n * @mk-kit/ui/embed — ship mk-kit-based components as standalone custom\n * elements: shadow-DOM isolation from the host page's stylesheet, `--mk-*`\n * theming that still crosses the boundary, one lazily created zoneless\n * application shared by every element, and overlays (dialogs, selects,\n * toasts) confined to a themed shadow host of their own.\n */\nexport * from './shadow-css';\nexport * from './embed';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mk-kit-ui-embed.mjs","sources":["../../../projects/mk-kit/embed/shadow-css.ts","../../../projects/mk-kit/embed/embed.ts","../../../projects/mk-kit/embed/index.ts","../../../projects/mk-kit/embed/mk-kit-ui-embed.ts"],"sourcesContent":["/**\n * Rewrites a document-level stylesheet for adoption into a shadow root:\n * `:root` never matches inside one, so token blocks like mk-kit's\n * `:root { --mk-primary: … }` are retargeted to `:host`. Theme opt-ins keep\n * working — `:root:not([data-mk-theme='light'])` becomes\n * `:host:not([data-mk-theme='light'])`, so `<my-widget data-mk-theme=\"dark\">`\n * switches one embedded element to the dark palette.\n *\n * ```ts\n * import themeCss from '@mk-kit/ui/styles.css' with { type: 'text' };\n * mkEmbed({ styles: mkShadowCss(themeCss) });\n * ```\n */\nexport function mkShadowCss(css: string): string {\n return css.replace(/:root\\b/g, ':host');\n}\n","import {\n ApplicationRef,\n CSP_NONCE,\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n type EnvironmentProviders,\n type Provider,\n type Type,\n createComponent,\n provideZonelessChangeDetection,\n reflectComponentType,\n} from '@angular/core';\nimport { createApplication } from '@angular/platform-browser';\nimport { MK_OVERLAY_ROOT } from '@mk-kit/ui/core';\n\n/** Options for {@link mkEmbed}. */\nexport interface MkEmbedInit {\n /**\n * CSS text adopted into every element's shadow root (and the overlay host).\n * Pass the mk-kit theme through {@link mkShadowCss} so its `:root` token\n * blocks target `:host`; append your own widget CSS after it. Shared as\n * constructable stylesheets when the browser supports them (one parse for\n * any number of instances), `<style>` elements otherwise.\n */\n styles?: string | readonly string[];\n /**\n * Stylesheet URLs loaded as `<link rel=\"stylesheet\">` into every shadow\n * root (and the overlay host) — an alternative to inlining `styles` when\n * the theme lives on a CDN. Loaded per shadow root by the browser's cache,\n * so the network cost is paid once.\n */\n styleUrls?: readonly string[];\n /**\n * CSP nonce applied to every style and link element this app creates —\n * including Angular's own component styles (provided as `CSP_NONCE`) and\n * the `<style>` fallback when constructable stylesheets are unavailable.\n * For host pages with a `style-src` policy that forbids `'unsafe-inline'`.\n */\n nonce?: string;\n /**\n * Extra providers for the shared application — `provideMkI18n(…)`,\n * `provideMkExtendedIcons()`, `provideHttpClient()`, your services.\n */\n providers?: Array<Provider | EnvironmentProviders>;\n /**\n * Mount mk-kit overlays (dialogs, anchored panels, toasts, tours) inside a\n * page-level shadow host that carries the same `styles`, instead of bare\n * `document.body`. Default `true`; set `false` to keep the application\n * default (overlays styled by the page's own stylesheets).\n */\n overlays?: boolean;\n}\n\n/**\n * Creates an embed application: a factory for custom elements that render\n * mk-kit-based Angular components behind shadow DOM.\n *\n * - **Lazy**: `element()` only defines the tag; the Angular application is\n * created on the first element actually connected to a document.\n * - **Shared**: every element of one `mkEmbed()` call runs in one zoneless\n * `ApplicationRef` with one provider set.\n * - **Isolated but themable**: the host page's CSS cannot reach the widget\n * internals, while `--mk-*` custom properties still inherit through the\n * shadow boundary — set them on the element (or any ancestor) to theme it.\n * - **Styled**: Angular routes each component's own styles into the shadow\n * root it renders in; the `styles` option supplies the token/theme layer.\n *\n * ```ts\n * import { mkEmbed, mkShadowCss } from '@mk-kit/ui/embed';\n * import themeCss from '@mk-kit/ui/styles.css' with { type: 'text' };\n *\n * mkEmbed({ styles: mkShadowCss(themeCss) })\n * .element('acme-reviews', ReviewsWidget)\n * .element('acme-signup', SignupWidget);\n * ```\n *\n * ```html\n * <acme-reviews product-id=\"42\" style=\"--mk-primary: #7c3aed\"></acme-reviews>\n * ```\n *\n * Inputs are exposed as dash-cased attributes (string values go through the\n * input's `transform`, so `booleanAttribute` / `numberAttribute` inputs coerce\n * as usual) and as camel-cased element properties (any value); outputs become\n * bubbling, composed `CustomEvent`s named after the output, with the emitted\n * value as `detail`.\n */\nexport function mkEmbed(init: MkEmbedInit = {}): MkEmbedApp {\n return new MkEmbedApp(init);\n}\n\n/** One shared embed application. Create it with {@link mkEmbed}. */\nexport class MkEmbedApp {\n /** @internal Adopted into every shadow root this app renders in. */\n readonly _mkStyles: MkEmbedStyles;\n\n private readonly init: MkEmbedInit;\n private appPromise: Promise<ApplicationRef> | null = null;\n private appRef: ApplicationRef | null = null;\n private overlayHost: HTMLElement | null = null;\n private overlayInner: HTMLElement | null = null;\n private destroyed = false;\n\n constructor(init: MkEmbedInit = {}) {\n this.init = init;\n const styles = init.styles == null ? [] : typeof init.styles === 'string' ? [init.styles] : [...init.styles];\n this._mkStyles = new MkEmbedStyles(styles, init.styleUrls ?? [], init.nonce);\n }\n\n /**\n * Defines `tag` as a custom element rendering `component`. Chainable; a\n * no-op when the tag is already defined (hot reload, duplicate script) or\n * outside a browser.\n */\n element(tag: string, component: Type<unknown>): this {\n if (typeof customElements === 'undefined') return this;\n if (customElements.get(tag)) return this;\n customElements.define(tag, createElementClass(this, component));\n return this;\n }\n\n /** Resolves when the shared application is running (created on demand). */\n ready(): Promise<void> {\n return this._mkApplication().then(() => undefined);\n }\n\n /** Resolves when the application has no pending change detection. */\n async whenStable(): Promise<void> {\n await this._mkApplication().then((app) => app.whenStable());\n }\n\n /**\n * Destroys the shared application, every mounted component and the overlay\n * host. Defined tags remain registered (the platform cannot undefine them)\n * but render nothing afterwards.\n */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.appRef?.destroy();\n this.appRef = null;\n this.appPromise = null;\n this.overlayHost?.remove();\n this.overlayHost = null;\n this.overlayInner = null;\n }\n\n /** @internal */\n _mkApplication(): Promise<ApplicationRef> {\n if (this.destroyed) return Promise.reject(new Error('This MkEmbedApp was destroyed.'));\n if (typeof document === 'undefined') {\n return Promise.reject(\n new Error('mkEmbed needs a browser — on the server, defining elements is a no-op and nothing should await ready().'),\n );\n }\n this.appPromise ??= createApplication({\n providers: [\n provideZonelessChangeDetection(),\n ...(this.init.nonce ? [{ provide: CSP_NONCE, useValue: this.init.nonce }] : []),\n ...(this.init.overlays === false\n ? []\n : [{ provide: MK_OVERLAY_ROOT, useValue: () => this.overlayRootElement() }]),\n ...(this.init.providers ?? []),\n ],\n }).then((ref) => (this.appRef = ref));\n return this.appPromise;\n }\n\n /** @internal The running application — only valid once `ready()` resolved. */\n get _mkAppRef(): ApplicationRef {\n if (!this.appRef) throw new Error('The embed application is not running yet.');\n return this.appRef;\n }\n\n /**\n * Lazily builds the page-level overlay host: a shadow root carrying the\n * embed styles, with an inner container the overlay services append to.\n */\n private overlayRootElement(): HTMLElement {\n if (this.overlayInner) return this.overlayInner;\n const appRef = this._mkAppRef;\n const doc = document;\n const host = doc.createElement('mk-embed-overlays');\n const shadow = host.attachShadow({ mode: 'open' });\n this._mkStyles.adopt(shadow);\n const inner = doc.createElement('div');\n shadow.appendChild(inner);\n doc.body.appendChild(host);\n\n // Register this shadow root as an Angular styles host: creating one\n // component with an ATTACHED host element inside it makes Angular mirror\n // every component stylesheet here — including components created detached\n // and appended later (toast / snackbar containers) and anchored panels\n // teleported in from other roots. The anchor lives until destroy().\n const anchorHost = doc.createElement('div');\n inner.appendChild(anchorHost);\n const anchor = createComponent(MkEmbedStyleAnchor, {\n environmentInjector: appRef.injector,\n hostElement: anchorHost,\n });\n appRef.attachView(anchor.hostView);\n\n this.overlayHost = host;\n this.overlayInner = inner;\n return inner;\n }\n}\n\n/** Invisible component whose only job is registering a shadow styles host. */\n@Component({\n selector: 'mk-embed-style-anchor',\n template: '',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nclass MkEmbedStyleAnchor {}\n\n/**\n * The embed styles, parsed once and shared: constructable stylesheets where\n * supported, cloned `<style>` elements otherwise, plus `<link>` elements for\n * `styleUrls`. The nonce lands on every element this class creates.\n */\nclass MkEmbedStyles {\n private sheets: CSSStyleSheet[] | null | undefined;\n\n constructor(\n private readonly css: readonly string[],\n private readonly urls: readonly string[],\n private readonly nonce?: string,\n ) {}\n\n adopt(root: ShadowRoot): void {\n const doc = root.host.ownerDocument;\n for (const url of this.urls) {\n const link = doc.createElement('link');\n link.rel = 'stylesheet';\n link.href = url;\n if (this.nonce) link.setAttribute('nonce', this.nonce);\n root.appendChild(link);\n }\n if (!this.css.length) return;\n if (this.sheets === undefined) {\n try {\n this.sheets = this.css.map((text) => {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(text);\n return sheet;\n });\n } catch {\n this.sheets = null;\n }\n }\n if (this.sheets) {\n try {\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, ...this.sheets];\n return;\n } catch {\n // Fall through to <style> elements.\n }\n }\n for (const text of this.css) {\n const el = doc.createElement('style');\n el.textContent = text;\n if (this.nonce) el.setAttribute('nonce', this.nonce);\n root.appendChild(el);\n }\n }\n}\n\n/** `pageSize` → `page-size` (the attribute name of an input). */\nfunction dasherize(name: string): string {\n return name.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n}\n\ninterface OutputLike {\n subscribe?: (next: (value: unknown) => void) => { unsubscribe(): void };\n}\n\n/** Builds the custom-element class wrapping one Angular component. */\nfunction createElementClass(app: MkEmbedApp, component: Type<unknown>): CustomElementConstructor {\n const mirror = reflectComponentType(component);\n if (!mirror) {\n throw new Error('mkEmbed: the provided class is not an Angular component.');\n }\n const inputs = mirror.inputs;\n const outputs = mirror.outputs;\n const attrToInput = new Map<string, string>();\n for (const { templateName } of inputs) attrToInput.set(dasherize(templateName), templateName);\n\n class MkEmbeddedElement extends HTMLElement {\n static readonly observedAttributes = [...attrToInput.keys()];\n\n private _mkRef: ComponentRef<unknown> | null = null;\n private readonly _mkValues = new Map<string, unknown>();\n private _mkSubs: { unsubscribe(): void }[] = [];\n private _mkEpoch = 0;\n private _mkStylesAdopted = false;\n private _mkResolveReady!: () => void;\n\n /** Resolves once the Angular component is mounted in the shadow root. */\n readonly mkReady: Promise<void> = new Promise((resolve) => (this._mkResolveReady = resolve));\n\n /** The mounted Angular component instance, or `null` before/after. */\n get mkComponent(): unknown {\n return this._mkRef?.instance ?? null;\n }\n\n connectedCallback(): void {\n const epoch = ++this._mkEpoch;\n void app._mkApplication().then(() => {\n if (epoch !== this._mkEpoch || !this.isConnected || this._mkRef) return;\n this._mkMount();\n });\n }\n\n disconnectedCallback(): void {\n const epoch = ++this._mkEpoch;\n queueMicrotask(() => {\n // Moving an element fires disconnect + connect in one task — only\n // tear down when it is still detached by the end of the microtask.\n if (epoch === this._mkEpoch && !this.isConnected) this._mkUnmount();\n });\n }\n\n attributeChangedCallback(name: string, _prev: string | null, value: string | null): void {\n const input = attrToInput.get(name);\n if (input) this._mkApplyInput(input, value);\n }\n\n /** @internal Shared by attribute changes and property setters. */\n _mkApplyInput(name: string, value: unknown): void {\n this._mkValues.set(name, value);\n this._mkRef?.setInput(name, value);\n }\n\n /** @internal */\n _mkLastValue(name: string): unknown {\n return this._mkValues.get(name);\n }\n\n private _mkMount(): void {\n const shadow = this.shadowRoot ?? this.attachShadow({ mode: 'open' });\n if (!this._mkStylesAdopted) {\n app._mkStyles.adopt(shadow);\n this._mkStylesAdopted = true;\n }\n // An inner host element (rather than rendering into the shadow root\n // directly) is what routes the component's styles into this shadow\n // root: Angular resolves the style host from the host element's root\n // node at creation time.\n const host = this.ownerDocument.createElement('div');\n shadow.appendChild(host);\n const appRef = app._mkAppRef;\n const ref = createComponent(component, {\n environmentInjector: appRef.injector,\n hostElement: host,\n });\n for (const [name, value] of this._mkValues) ref.setInput(name, value);\n for (const { propName, templateName } of outputs) {\n const source = (ref.instance as Record<string, unknown>)[propName] as OutputLike | undefined;\n if (source && typeof source.subscribe === 'function') {\n this._mkSubs.push(\n source.subscribe((detail: unknown) => {\n this.dispatchEvent(new CustomEvent(templateName, { detail, bubbles: true, composed: true }));\n }),\n );\n }\n }\n appRef.attachView(ref.hostView);\n // First render happens before mkReady resolves — attachView alone only\n // schedules it for the next zoneless flush.\n ref.changeDetectorRef.detectChanges();\n this._mkRef = ref;\n this._mkResolveReady();\n }\n\n private _mkUnmount(): void {\n for (const sub of this._mkSubs) sub.unsubscribe();\n this._mkSubs = [];\n const host = this._mkRef?.location.nativeElement as HTMLElement | undefined;\n this._mkRef?.destroy();\n host?.remove();\n this._mkRef = null;\n }\n }\n\n // Property accessors for every input that does not collide with a native\n // element property (`title`, `hidden`, `dir`, …) or with the wrapper's own\n // surface — collisions stay reachable through the dash-cased attribute.\n for (const { templateName } of inputs) {\n if (templateName in MkEmbeddedElement.prototype) continue;\n Object.defineProperty(MkEmbeddedElement.prototype, templateName, {\n configurable: true,\n enumerable: true,\n get(this: MkEmbeddedElement) {\n return this._mkLastValue(templateName);\n },\n set(this: MkEmbeddedElement, value: unknown) {\n this._mkApplyInput(templateName, value);\n },\n });\n }\n\n return MkEmbeddedElement;\n}\n","/**\n * @mk-kit/ui/embed — ship mk-kit-based components as standalone custom\n * elements: shadow-DOM isolation from the host page's stylesheet, `--mk-*`\n * theming that still crosses the boundary, one lazily created zoneless\n * application shared by every element, and overlays (dialogs, selects,\n * toasts) confined to a themed shadow host of their own.\n */\nexport * from './shadow-css';\nexport * from './embed';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAAA;;;;;;;;;;;;AAYG;AACG,SAAU,WAAW,CAAC,GAAW,EAAA;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC;AACzC;;ACuCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCG;AACG,SAAU,OAAO,CAAC,IAAA,GAAoB,EAAE,EAAA;AAC5C,IAAA,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC;AAC7B;AAEA;MACa,UAAU,CAAA;;AAEZ,IAAA,SAAS;AAED,IAAA,IAAI;IACb,UAAU,GAAmC,IAAI;IACjD,MAAM,GAA0B,IAAI;IACpC,WAAW,GAAuB,IAAI;IACtC,YAAY,GAAuB,IAAI;IACvC,SAAS,GAAG,KAAK;AAEzB,IAAA,WAAA,CAAY,OAAoB,EAAE,EAAA;AAChC,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,GAAG,EAAE,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;AAC5G,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC;IAC9E;AAEA;;;;AAIG;IACH,OAAO,CAAC,GAAW,EAAE,SAAwB,EAAA;QAC3C,IAAI,OAAO,cAAc,KAAK,WAAW;AAAE,YAAA,OAAO,IAAI;AACtD,QAAA,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;AAAE,YAAA,OAAO,IAAI;AACxC,QAAA,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC/D,QAAA,OAAO,IAAI;IACb;;IAGA,KAAK,GAAA;AACH,QAAA,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC;IACpD;;AAGA,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,UAAU,EAAE,CAAC;IAC7D;AAEA;;;;AAIG;IACH,OAAO,GAAA;QACL,IAAI,IAAI,CAAC,SAAS;YAAE;AACpB,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE;AACtB,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AACtB,QAAA,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAC1B,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;AACvB,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI;IAC1B;;IAGA,cAAc,GAAA;QACZ,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;AACtF,QAAA,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,yGAAyG,CAAC,CACrH;QACH;AACA,QAAA,IAAI,CAAC,UAAU,KAAK,iBAAiB,CAAC;AACpC,YAAA,SAAS,EAAE;AACT,gBAAA,8BAA8B,EAAE;AAChC,gBAAA,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC;AAC/E,gBAAA,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK;AACzB,sBAAE;AACF,sBAAE,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;gBAC9E,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;AAC/B,aAAA;AACF,SAAA,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,UAAU;IACxB;;AAGA,IAAA,IAAI,SAAS,GAAA;QACX,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC;QAC9E,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA;;;AAGG;IACK,kBAAkB,GAAA;QACxB,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC,YAAY;AAC/C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS;QAC7B,MAAM,GAAG,GAAG,QAAQ;QACpB,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,mBAAmB,CAAC;AACnD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAClD,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC;AACtC,QAAA,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;AACzB,QAAA,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;;;;;;QAO1B,MAAM,UAAU,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC;AAC3C,QAAA,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC;AAC7B,QAAA,MAAM,MAAM,GAAG,eAAe,CAAC,kBAAkB,EAAE;YACjD,mBAAmB,EAAE,MAAM,CAAC,QAAQ;AACpC,YAAA,WAAW,EAAE,UAAU;AACxB,SAAA,CAAC;AACF,QAAA,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC;AAElC,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;AACvB,QAAA,IAAI,CAAC,YAAY,GAAG,KAAK;AACzB,QAAA,OAAO,KAAK;IACd;AACD;AAED;AACA,MAKM,kBAAkB,CAAA;uGAAlB,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,iFAHZ,EAAE,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAGR,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBALvB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,uBAAuB;AACjC,oBAAA,QAAQ,EAAE,EAAE;oBACZ,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAChD,iBAAA;;AAGD;;;;AAIG;AACH,MAAM,aAAa,CAAA;AAIE,IAAA,GAAA;AACA,IAAA,IAAA;AACA,IAAA,KAAA;AALX,IAAA,MAAM;AAEd,IAAA,WAAA,CACmB,GAAsB,EACtB,IAAuB,EACvB,KAAc,EAAA;QAFd,IAAA,CAAA,GAAG,GAAH,GAAG;QACH,IAAA,CAAA,IAAI,GAAJ,IAAI;QACJ,IAAA,CAAA,KAAK,GAAL,KAAK;IACrB;AAEH,IAAA,KAAK,CAAC,IAAgB,EAAA;AACpB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa;AACnC,QAAA,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE;YAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC;AACtC,YAAA,IAAI,CAAC,GAAG,GAAG,YAAY;AACvB,YAAA,IAAI,CAAC,IAAI,GAAG,GAAG;YACf,IAAI,IAAI,CAAC,KAAK;gBAAE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;AACtD,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QACxB;AACA,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;YAAE;AACtB,QAAA,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;AAC7B,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;AAClC,oBAAA,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE;AACjC,oBAAA,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;AACvB,oBAAA,OAAO,KAAK;AACd,gBAAA,CAAC,CAAC;YACJ;AAAE,YAAA,MAAM;AACN,gBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;YACpB;QACF;AACA,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,kBAAkB,GAAG,CAAC,GAAG,IAAI,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;gBACtE;YACF;AAAE,YAAA,MAAM;;YAER;QACF;AACA,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC;AACrC,YAAA,EAAE,CAAC,WAAW,GAAG,IAAI;YACrB,IAAI,IAAI,CAAC,KAAK;gBAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;AACpD,YAAA,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACtB;IACF;AACD;AAED;AACA,SAAS,SAAS,CAAC,IAAY,EAAA;AAC7B,IAAA,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA,CAAE,CAAC;AAC7D;AAMA;AACA,SAAS,kBAAkB,CAAC,GAAe,EAAE,SAAwB,EAAA;AACnE,IAAA,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC;IAC7E;AACA,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM;AAC5B,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO;AAC9B,IAAA,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB;AAC7C,IAAA,KAAK,MAAM,EAAE,YAAY,EAAE,IAAI,MAAM;QAAE,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAE7F,MAAM,iBAAkB,SAAQ,WAAW,CAAA;QACzC,OAAgB,kBAAkB,GAAG,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAEpD,MAAM,GAAiC,IAAI;AAClC,QAAA,SAAS,GAAG,IAAI,GAAG,EAAmB;QAC/C,OAAO,GAA8B,EAAE;QACvC,QAAQ,GAAG,CAAC;QACZ,gBAAgB,GAAG,KAAK;AACxB,QAAA,eAAe;;AAGd,QAAA,OAAO,GAAkB,IAAI,OAAO,CAAC,CAAC,OAAO,MAAM,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,CAAC;;AAG5F,QAAA,IAAI,WAAW,GAAA;AACb,YAAA,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI;QACtC;QAEA,iBAAiB,GAAA;AACf,YAAA,MAAM,KAAK,GAAG,EAAE,IAAI,CAAC,QAAQ;YAC7B,KAAK,GAAG,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,MAAK;AAClC,gBAAA,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM;oBAAE;gBACjE,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,CAAC,CAAC;QACJ;QAEA,oBAAoB,GAAA;AAClB,YAAA,MAAM,KAAK,GAAG,EAAE,IAAI,CAAC,QAAQ;YAC7B,cAAc,CAAC,MAAK;;;gBAGlB,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW;oBAAE,IAAI,CAAC,UAAU,EAAE;AACrE,YAAA,CAAC,CAAC;QACJ;AAEA,QAAA,wBAAwB,CAAC,IAAY,EAAE,KAAoB,EAAE,KAAoB,EAAA;YAC/E,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AACnC,YAAA,IAAI,KAAK;AAAE,gBAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;QAC7C;;QAGA,aAAa,CAAC,IAAY,EAAE,KAAc,EAAA;YACxC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;YAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QACpC;;AAGA,QAAA,YAAY,CAAC,IAAY,EAAA;YACvB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QACjC;QAEQ,QAAQ,GAAA;AACd,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACrE,YAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;AAC1B,gBAAA,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;AAC3B,gBAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;YAC9B;;;;;YAKA,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC;AACpD,YAAA,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;AACxB,YAAA,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS;AAC5B,YAAA,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,EAAE;gBACrC,mBAAmB,EAAE,MAAM,CAAC,QAAQ;AACpC,gBAAA,WAAW,EAAE,IAAI;AAClB,aAAA,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS;AAAE,gBAAA,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;YACrE,KAAK,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,OAAO,EAAE;gBAChD,MAAM,MAAM,GAAI,GAAG,CAAC,QAAoC,CAAC,QAAQ,CAA2B;gBAC5F,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE;AACpD,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CACf,MAAM,CAAC,SAAS,CAAC,CAAC,MAAe,KAAI;wBACnC,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC9F,CAAC,CAAC,CACH;gBACH;YACF;AACA,YAAA,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;;;AAG/B,YAAA,GAAG,CAAC,iBAAiB,CAAC,aAAa,EAAE;AACrC,YAAA,IAAI,CAAC,MAAM,GAAG,GAAG;YACjB,IAAI,CAAC,eAAe,EAAE;QACxB;QAEQ,UAAU,GAAA;AAChB,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO;gBAAE,GAAG,CAAC,WAAW,EAAE;AACjD,YAAA,IAAI,CAAC,OAAO,GAAG,EAAE;YACjB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,aAAwC;AAC3E,YAAA,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE;YACtB,IAAI,EAAE,MAAM,EAAE;AACd,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;QACpB;;;;;AAMF,IAAA,KAAK,MAAM,EAAE,YAAY,EAAE,IAAI,MAAM,EAAE;AACrC,QAAA,IAAI,YAAY,IAAI,iBAAiB,CAAC,SAAS;YAAE;QACjD,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,SAAS,EAAE,YAAY,EAAE;AAC/D,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,UAAU,EAAE,IAAI;YAChB,GAAG,GAAA;AACD,gBAAA,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;YACxC,CAAC;AACD,YAAA,GAAG,CAA0B,KAAc,EAAA;AACzC,gBAAA,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC;YACzC,CAAC;AACF,SAAA,CAAC;IACJ;AAEA,IAAA,OAAO,iBAAiB;AAC1B;;ACnZA;;;;;;AAMG;;ACNH;;AAEG;;;;"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, viewChild, ElementRef, signal, computed, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { MkOverlayRef, MK_OVERLAY_DATA, MK_I18N } from '@mk-kit/ui/core';
|
|
4
|
+
import { MkButton } from '@mk-kit/ui/button';
|
|
5
|
+
import { MkInput, MkFormField } from '@mk-kit/ui/forms';
|
|
6
|
+
import { MkDialog } from './mk-kit-ui-feedback.mjs';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Internal component backing `MkDialogService.prompt`. Renders a single text
|
|
10
|
+
* field and resolves the overlay ref with the entered string on confirm, or
|
|
11
|
+
* `null` on cancel / Escape / backdrop. Submitting the form (Enter) confirms.
|
|
12
|
+
*/
|
|
13
|
+
class MkPromptDialog {
|
|
14
|
+
ref = inject(MkOverlayRef);
|
|
15
|
+
data = inject(MK_OVERLAY_DATA);
|
|
16
|
+
i18n = inject(MK_I18N);
|
|
17
|
+
// `read: ElementRef` — the template ref also carries the MkInput directive, which would otherwise win.
|
|
18
|
+
inputRef = viewChild('input', { ...(ngDevMode ? { debugName: "inputRef" } : /* istanbul ignore next */ {}), read: ElementRef });
|
|
19
|
+
value = signal(this.data.value ?? '', /* @ts-ignore */
|
|
20
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
21
|
+
confirmText = computed(() => this.data.confirmText ?? this.i18n.ok, /* @ts-ignore */
|
|
22
|
+
...(ngDevMode ? [{ debugName: "confirmText" }] : /* istanbul ignore next */ []));
|
|
23
|
+
cancelText = computed(() => this.data.cancelText ?? this.i18n.cancel, /* @ts-ignore */
|
|
24
|
+
...(ngDevMode ? [{ debugName: "cancelText" }] : /* istanbul ignore next */ []));
|
|
25
|
+
canConfirm = computed(() => !this.data.required || this.value().trim().length > 0, /* @ts-ignore */
|
|
26
|
+
...(ngDevMode ? [{ debugName: "canConfirm" }] : /* istanbul ignore next */ []));
|
|
27
|
+
constructor() {
|
|
28
|
+
afterNextRender(() => this.inputRef()?.nativeElement?.focus());
|
|
29
|
+
}
|
|
30
|
+
onInput(event) {
|
|
31
|
+
this.value.set(event.target.value);
|
|
32
|
+
}
|
|
33
|
+
submit() {
|
|
34
|
+
if (this.canConfirm())
|
|
35
|
+
this.ref.close(this.value());
|
|
36
|
+
}
|
|
37
|
+
cancel() {
|
|
38
|
+
this.ref.close(null);
|
|
39
|
+
}
|
|
40
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkPromptDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
41
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkPromptDialog, isStandalone: true, selector: "mk-prompt-dialog", viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<mk-dialog [dialogTitle]=\"data.title\" hideClose>\n @if (data.message) {\n <p class=\"mk-confirm-dialog__message\">{{ data.message }}</p>\n }\n\n <mk-form-field [label]=\"data.label ?? ''\">\n <input\n #input\n mkInput\n [attr.type]=\"data.inputType ?? 'text'\"\n [value]=\"value()\"\n [attr.placeholder]=\"data.placeholder ?? null\"\n [attr.required]=\"data.required ? '' : null\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"submit()\"\n />\n </mk-form-field>\n\n <div mkDialogFooter>\n <button mkButton variant=\"ghost\" tone=\"neutral\" (click)=\"cancel()\">\n {{ cancelText() }}\n </button>\n <button mkButton (click)=\"submit()\" [disabled]=\"!canConfirm()\">\n {{ confirmText() }}\n </button>\n </div>\n</mk-dialog>\n", styles: [".mk-confirm-dialog__message{margin:0;color:var(--mk-text-muted);font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-relaxed)}.mk-confirm-dialog__body{display:flex;align-items:flex-start;gap:var(--mk-space-3)}.mk-confirm-dialog__icon{flex-shrink:0;margin-top:.125rem;color:var(--mk-text-muted)}.mk-confirm-dialog__icon--danger{color:var(--mk-danger-text)}\n"], dependencies: [{ kind: "component", type: MkDialog, selector: "mk-dialog", inputs: ["dialogTitle", "titleId", "hideClose", "draggable", "resizable"] }, { kind: "component", type: MkButton, selector: "button[mkButton], a[mkButton]", inputs: ["variant", "tone", "size", "loading", "fullWidth", "iconOnly", "disabled"] }, { kind: "component", type: MkInput, selector: "input[mkInput], textarea[mkInput]", inputs: ["size", "invalid"] }, { kind: "component", type: MkFormField, selector: "mk-form-field", inputs: ["label", "hint", "error", "errorMessages", "errorOn", "required", "disabled", "size", "labelPosition", "field"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
42
|
+
}
|
|
43
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkPromptDialog, decorators: [{
|
|
44
|
+
type: Component,
|
|
45
|
+
args: [{ selector: 'mk-prompt-dialog', imports: [MkDialog, MkButton, MkInput, MkFormField], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mk-dialog [dialogTitle]=\"data.title\" hideClose>\n @if (data.message) {\n <p class=\"mk-confirm-dialog__message\">{{ data.message }}</p>\n }\n\n <mk-form-field [label]=\"data.label ?? ''\">\n <input\n #input\n mkInput\n [attr.type]=\"data.inputType ?? 'text'\"\n [value]=\"value()\"\n [attr.placeholder]=\"data.placeholder ?? null\"\n [attr.required]=\"data.required ? '' : null\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"submit()\"\n />\n </mk-form-field>\n\n <div mkDialogFooter>\n <button mkButton variant=\"ghost\" tone=\"neutral\" (click)=\"cancel()\">\n {{ cancelText() }}\n </button>\n <button mkButton (click)=\"submit()\" [disabled]=\"!canConfirm()\">\n {{ confirmText() }}\n </button>\n </div>\n</mk-dialog>\n", styles: [".mk-confirm-dialog__message{margin:0;color:var(--mk-text-muted);font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-relaxed)}.mk-confirm-dialog__body{display:flex;align-items:flex-start;gap:var(--mk-space-3)}.mk-confirm-dialog__icon{flex-shrink:0;margin-top:.125rem;color:var(--mk-text-muted)}.mk-confirm-dialog__icon--danger{color:var(--mk-danger-text)}\n"] }]
|
|
46
|
+
}], ctorParameters: () => [], propDecorators: { inputRef: [{ type: i0.ViewChild, args: ['input', { ...{ read: ElementRef }, isSignal: true }] }] } });
|
|
47
|
+
|
|
48
|
+
export { MkPromptDialog };
|
|
49
|
+
//# sourceMappingURL=mk-kit-ui-feedback-prompt-dialog-DnxQ7M0h.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mk-kit-ui-feedback-prompt-dialog-DnxQ7M0h.mjs","sources":["../../../projects/mk-kit/feedback/dialog/prompt-dialog.ts","../../../projects/mk-kit/feedback/dialog/prompt-dialog.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n afterNextRender,\n computed,\n inject,\n signal,\n viewChild,\n ElementRef,\n} from '@angular/core';\nimport { MK_I18N } from '@mk-kit/ui/core';\nimport { MK_OVERLAY_DATA, MkOverlayRef } from '@mk-kit/ui/core';\nimport { MkButton } from '@mk-kit/ui/button';\nimport { MkInput } from '@mk-kit/ui/forms';\nimport { MkFormField } from '@mk-kit/ui/forms';\nimport { MkDialog } from './dialog';\n\n/** Data contract for {@link MkPromptDialog} / `MkDialogService.prompt`. */\nexport interface MkPromptDialogData {\n /** Heading text. */\n title: string;\n /** Optional body message shown above the input. */\n message?: string;\n /** Field label. */\n label?: string;\n /** Pre-filled value. */\n value?: string;\n /** Input placeholder. */\n placeholder?: string;\n /** Confirm button label. Default `OK`. */\n confirmText?: string;\n /** Cancel button label. Default `Cancel`. */\n cancelText?: string;\n /** Require a non-empty value before the confirm button enables. */\n required?: boolean;\n /** Native input type (e.g. `text`, `email`, `number`, `password`). */\n inputType?: string;\n}\n\n/**\n * Internal component backing `MkDialogService.prompt`. Renders a single text\n * field and resolves the overlay ref with the entered string on confirm, or\n * `null` on cancel / Escape / backdrop. Submitting the form (Enter) confirms.\n */\n@Component({\n selector: 'mk-prompt-dialog',\n imports: [MkDialog, MkButton, MkInput, MkFormField],\n templateUrl: './prompt-dialog.html',\n styleUrl: './confirm-dialog.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MkPromptDialog {\n private readonly ref = inject<MkOverlayRef<string | null>>(MkOverlayRef);\n protected readonly data = inject<MkPromptDialogData>(MK_OVERLAY_DATA);\n protected readonly i18n = inject(MK_I18N);\n // `read: ElementRef` — the template ref also carries the MkInput directive, which would otherwise win.\n private readonly inputRef = viewChild('input', { read: ElementRef });\n\n protected readonly value = signal(this.data.value ?? '');\n protected readonly confirmText = computed(\n () => this.data.confirmText ?? this.i18n.ok,\n );\n protected readonly cancelText = computed(\n () => this.data.cancelText ?? this.i18n.cancel,\n );\n protected readonly canConfirm = computed(\n () => !this.data.required || this.value().trim().length > 0,\n );\n\n constructor() {\n afterNextRender(() => (this.inputRef()?.nativeElement as HTMLInputElement | undefined)?.focus());\n }\n\n protected onInput(event: Event): void {\n this.value.set((event.target as HTMLInputElement).value);\n }\n\n protected submit(): void {\n if (this.canConfirm()) this.ref.close(this.value());\n }\n\n protected cancel(): void {\n this.ref.close(null);\n }\n}\n","<mk-dialog [dialogTitle]=\"data.title\" hideClose>\n @if (data.message) {\n <p class=\"mk-confirm-dialog__message\">{{ data.message }}</p>\n }\n\n <mk-form-field [label]=\"data.label ?? ''\">\n <input\n #input\n mkInput\n [attr.type]=\"data.inputType ?? 'text'\"\n [value]=\"value()\"\n [attr.placeholder]=\"data.placeholder ?? null\"\n [attr.required]=\"data.required ? '' : null\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"submit()\"\n />\n </mk-form-field>\n\n <div mkDialogFooter>\n <button mkButton variant=\"ghost\" tone=\"neutral\" (click)=\"cancel()\">\n {{ cancelText() }}\n </button>\n <button mkButton (click)=\"submit()\" [disabled]=\"!canConfirm()\">\n {{ confirmText() }}\n </button>\n </div>\n</mk-dialog>\n"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,6 @@ import { isPlatformBrowser } from '@angular/common';
|
|
|
5
5
|
import { MkButton } from '@mk-kit/ui/button';
|
|
6
6
|
import { MkBadge, MkEmptyState, MkSpinner } from '@mk-kit/ui/data';
|
|
7
7
|
import { MkIcon } from '@mk-kit/ui/icon';
|
|
8
|
-
import { MkInput, MkFormField } from '@mk-kit/ui/forms';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Alert — an inline banner that communicates a contextual status message.
|
|
@@ -1397,46 +1396,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
1397
1396
|
args: [{ selector: 'mk-confirm-dialog', imports: [MkDialog, MkButton, MkIcon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mk-dialog [dialogTitle]=\"data.title\" hideClose>\n <div class=\"mk-confirm-dialog__body\">\n @if (data.icon; as icon) {\n <mk-icon\n class=\"mk-confirm-dialog__icon\"\n [class.mk-confirm-dialog__icon--danger]=\"data.tone === 'danger'\"\n [name]=\"icon\"\n [size]=\"22\"\n />\n }\n <p class=\"mk-confirm-dialog__message\">{{ data.message }}</p>\n </div>\n\n <div mkDialogFooter>\n @if (!data.hideCancel) {\n <button mkButton variant=\"ghost\" tone=\"neutral\" (click)=\"cancel()\">\n {{ cancelText() }}\n </button>\n }\n <button mkButton [tone]=\"confirmTone()\" (click)=\"confirm()\">\n {{ confirmText() }}\n </button>\n </div>\n</mk-dialog>\n", styles: [".mk-confirm-dialog__message{margin:0;color:var(--mk-text-muted);font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-relaxed)}.mk-confirm-dialog__body{display:flex;align-items:flex-start;gap:var(--mk-space-3)}.mk-confirm-dialog__icon{flex-shrink:0;margin-top:.125rem;color:var(--mk-text-muted)}.mk-confirm-dialog__icon--danger{color:var(--mk-danger-text)}\n"] }]
|
|
1398
1397
|
}] });
|
|
1399
1398
|
|
|
1400
|
-
/**
|
|
1401
|
-
* Internal component backing `MkDialogService.prompt`. Renders a single text
|
|
1402
|
-
* field and resolves the overlay ref with the entered string on confirm, or
|
|
1403
|
-
* `null` on cancel / Escape / backdrop. Submitting the form (Enter) confirms.
|
|
1404
|
-
*/
|
|
1405
|
-
class MkPromptDialog {
|
|
1406
|
-
ref = inject(MkOverlayRef);
|
|
1407
|
-
data = inject(MK_OVERLAY_DATA);
|
|
1408
|
-
i18n = inject(MK_I18N);
|
|
1409
|
-
// `read: ElementRef` — the template ref also carries the MkInput directive, which would otherwise win.
|
|
1410
|
-
inputRef = viewChild('input', { ...(ngDevMode ? { debugName: "inputRef" } : /* istanbul ignore next */ {}), read: ElementRef });
|
|
1411
|
-
value = signal(this.data.value ?? '', /* @ts-ignore */
|
|
1412
|
-
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1413
|
-
confirmText = computed(() => this.data.confirmText ?? this.i18n.ok, /* @ts-ignore */
|
|
1414
|
-
...(ngDevMode ? [{ debugName: "confirmText" }] : /* istanbul ignore next */ []));
|
|
1415
|
-
cancelText = computed(() => this.data.cancelText ?? this.i18n.cancel, /* @ts-ignore */
|
|
1416
|
-
...(ngDevMode ? [{ debugName: "cancelText" }] : /* istanbul ignore next */ []));
|
|
1417
|
-
canConfirm = computed(() => !this.data.required || this.value().trim().length > 0, /* @ts-ignore */
|
|
1418
|
-
...(ngDevMode ? [{ debugName: "canConfirm" }] : /* istanbul ignore next */ []));
|
|
1419
|
-
constructor() {
|
|
1420
|
-
afterNextRender(() => this.inputRef()?.nativeElement?.focus());
|
|
1421
|
-
}
|
|
1422
|
-
onInput(event) {
|
|
1423
|
-
this.value.set(event.target.value);
|
|
1424
|
-
}
|
|
1425
|
-
submit() {
|
|
1426
|
-
if (this.canConfirm())
|
|
1427
|
-
this.ref.close(this.value());
|
|
1428
|
-
}
|
|
1429
|
-
cancel() {
|
|
1430
|
-
this.ref.close(null);
|
|
1431
|
-
}
|
|
1432
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkPromptDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1433
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkPromptDialog, isStandalone: true, selector: "mk-prompt-dialog", viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<mk-dialog [dialogTitle]=\"data.title\" hideClose>\n @if (data.message) {\n <p class=\"mk-confirm-dialog__message\">{{ data.message }}</p>\n }\n\n <mk-form-field [label]=\"data.label ?? ''\">\n <input\n #input\n mkInput\n [attr.type]=\"data.inputType ?? 'text'\"\n [value]=\"value()\"\n [attr.placeholder]=\"data.placeholder ?? null\"\n [attr.required]=\"data.required ? '' : null\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"submit()\"\n />\n </mk-form-field>\n\n <div mkDialogFooter>\n <button mkButton variant=\"ghost\" tone=\"neutral\" (click)=\"cancel()\">\n {{ cancelText() }}\n </button>\n <button mkButton (click)=\"submit()\" [disabled]=\"!canConfirm()\">\n {{ confirmText() }}\n </button>\n </div>\n</mk-dialog>\n", styles: [".mk-confirm-dialog__message{margin:0;color:var(--mk-text-muted);font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-relaxed)}.mk-confirm-dialog__body{display:flex;align-items:flex-start;gap:var(--mk-space-3)}.mk-confirm-dialog__icon{flex-shrink:0;margin-top:.125rem;color:var(--mk-text-muted)}.mk-confirm-dialog__icon--danger{color:var(--mk-danger-text)}\n"], dependencies: [{ kind: "component", type: MkDialog, selector: "mk-dialog", inputs: ["dialogTitle", "titleId", "hideClose", "draggable", "resizable"] }, { kind: "component", type: MkButton, selector: "button[mkButton], a[mkButton]", inputs: ["variant", "tone", "size", "loading", "fullWidth", "iconOnly", "disabled"] }, { kind: "component", type: MkInput, selector: "input[mkInput], textarea[mkInput]", inputs: ["size", "invalid"] }, { kind: "component", type: MkFormField, selector: "mk-form-field", inputs: ["label", "hint", "error", "errorMessages", "errorOn", "required", "disabled", "size", "labelPosition", "field"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1434
|
-
}
|
|
1435
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkPromptDialog, decorators: [{
|
|
1436
|
-
type: Component,
|
|
1437
|
-
args: [{ selector: 'mk-prompt-dialog', imports: [MkDialog, MkButton, MkInput, MkFormField], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mk-dialog [dialogTitle]=\"data.title\" hideClose>\n @if (data.message) {\n <p class=\"mk-confirm-dialog__message\">{{ data.message }}</p>\n }\n\n <mk-form-field [label]=\"data.label ?? ''\">\n <input\n #input\n mkInput\n [attr.type]=\"data.inputType ?? 'text'\"\n [value]=\"value()\"\n [attr.placeholder]=\"data.placeholder ?? null\"\n [attr.required]=\"data.required ? '' : null\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"submit()\"\n />\n </mk-form-field>\n\n <div mkDialogFooter>\n <button mkButton variant=\"ghost\" tone=\"neutral\" (click)=\"cancel()\">\n {{ cancelText() }}\n </button>\n <button mkButton (click)=\"submit()\" [disabled]=\"!canConfirm()\">\n {{ confirmText() }}\n </button>\n </div>\n</mk-dialog>\n", styles: [".mk-confirm-dialog__message{margin:0;color:var(--mk-text-muted);font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-relaxed)}.mk-confirm-dialog__body{display:flex;align-items:flex-start;gap:var(--mk-space-3)}.mk-confirm-dialog__icon{flex-shrink:0;margin-top:.125rem;color:var(--mk-text-muted)}.mk-confirm-dialog__icon--danger{color:var(--mk-danger-text)}\n"] }]
|
|
1438
|
-
}], ctorParameters: () => [], propDecorators: { inputRef: [{ type: i0.ViewChild, args: ['input', { ...{ read: ElementRef }, isSignal: true }] }] } });
|
|
1439
|
-
|
|
1440
1399
|
const DIALOG_PANEL_CLASS = 'mk-dialog-panel';
|
|
1441
1400
|
/**
|
|
1442
1401
|
* Dialog service — a thin, opinionated layer over {@link MkOverlayService} that
|
|
@@ -1496,7 +1455,12 @@ class MkDialogService {
|
|
|
1496
1455
|
* Open a single-field prompt dialog. Resolves with the entered string, or
|
|
1497
1456
|
* `null` if the user cancels, presses Escape, or clicks the backdrop.
|
|
1498
1457
|
*/
|
|
1499
|
-
prompt(data) {
|
|
1458
|
+
async prompt(data) {
|
|
1459
|
+
// Loaded on demand: the prompt dialog is the only thing in `feedback` that
|
|
1460
|
+
// needs `@mk-kit/ui/forms`, and a static reference here shipped the whole
|
|
1461
|
+
// forms entry (input, form field, and their dependencies) to every app
|
|
1462
|
+
// that injects this service — including ones that never prompt.
|
|
1463
|
+
const { MkPromptDialog } = await import('./mk-kit-ui-feedback-prompt-dialog-DnxQ7M0h.mjs');
|
|
1500
1464
|
const ref = this.open(MkPromptDialog, { data, ariaLabel: data.title });
|
|
1501
1465
|
return ref.afterClosed.then((result) => result ?? null);
|
|
1502
1466
|
}
|
|
@@ -2818,5 +2782,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
2818
2782
|
* Generated bundle index. Do not edit.
|
|
2819
2783
|
*/
|
|
2820
2784
|
|
|
2821
|
-
export { MK_TOUR_DATA, MkAlert, MkBanner, MkBlockUi, MkBlockUiOverlay, MkBlockUiService, MkBottomSheet, MkBottomSheetService, MkConfirmDialog, MkDialog, MkDialogService, MkDialogTitle, MkHovercard, MkHovercardTrigger, MkLoadingBar, MkLoadingBarService, MkNotificationCenter, MkPopconfirm, MkPopconfirmTrigger, MkPopover, MkPopoverTrigger,
|
|
2785
|
+
export { MK_TOUR_DATA, MkAlert, MkBanner, MkBlockUi, MkBlockUiOverlay, MkBlockUiService, MkBottomSheet, MkBottomSheetService, MkConfirmDialog, MkDialog, MkDialogService, MkDialogTitle, MkHovercard, MkHovercardTrigger, MkLoadingBar, MkLoadingBarService, MkNotificationCenter, MkPopconfirm, MkPopconfirmTrigger, MkPopover, MkPopoverTrigger, MkResult, MkSnackbar, MkSnackbarContainer, MkSnackbarRef, MkSnackbarService, MkToast, MkToastContainer, MkToastService, MkTooltip, MkTooltipPanel, MkTourPopup, MkTourService };
|
|
2822
2786
|
//# sourceMappingURL=mk-kit-ui-feedback.mjs.map
|