@mk-kit/ui 0.48.0 → 0.50.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.
@@ -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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mk-kit/ui",
3
- "version": "0.48.0",
3
+ "version": "0.50.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -39,6 +39,7 @@
39
39
  "rxjs": "^7.8.0"
40
40
  },
41
41
  "dependencies": {
42
+ "@mk-kit/core": "^0.1.0",
42
43
  "@mk-kit/validators": "^0.1.0",
43
44
  "tslib": "^2.3.0"
44
45
  },
@@ -1,11 +1,13 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { InjectionToken, OnDestroy, Signal, ComponentRef, Injector, Type, AfterViewInit, ElementRef, Provider } from '@angular/core';
3
+ import { MkPlacement, MkDateNames } from '@mk-kit/core';
4
+ export { MK_QUERY_OPERATORS, MK_QUERY_TEXT_EN, MK_QUERY_UNARY, MkAnchoredPosition, MkAnchoredPositionOptions, MkCodeLanguage, MkDateNames, MkPlacement, MkQueryCombinator, MkQueryField, MkQueryFieldOption, MkQueryGroup, MkQueryNode, MkQueryOperator, MkQueryRule, MkQueryTextStrings, MkQueryValueType, mkComputeAnchoredPosition, mkCreateQueryGroup, mkCreateQueryRule, mkHighlight, mkHighlightJson, mkIsQueryGroup, mkQueryCompact, mkQueryIsEmpty, mkQueryOperatorLabel, mkQueryOperatorsFor, mkQueryRuleCount, mkQueryRuleIsComplete, mkQueryRuleMatches, mkQueryToPredicate, mkQueryToText, mkUniqueId } from '@mk-kit/core';
3
5
  import { Observable } from 'rxjs';
4
6
  import { ValidationErrors } from '@angular/forms';
5
7
 
6
8
  /** Shared primitive types used across mk-kit components. */
7
9
  /** Control size scale. Maps to `--mk-control-height-*` tokens. */
8
- type MkSize$1 = 'sm' | 'md' | 'lg';
10
+ type MkSize = 'sm' | 'md' | 'lg';
9
11
  /** Semantic color tone. Each maps to a `--mk-<tone>*` token family. */
10
12
  type MkTone = 'primary' | 'neutral' | 'success' | 'warning' | 'danger' | 'info';
11
13
  /** Visual treatment for tinted/interactive surfaces. */
@@ -14,8 +16,6 @@ type MkVariant = 'solid' | 'soft' | 'outline' | 'ghost' | 'link';
14
16
  type MkThemePreference = 'light' | 'dark' | 'system';
15
17
  /** Concrete resolved theme (never `system`). */
16
18
  type MkResolvedTheme = 'light' | 'dark';
17
- /** Common placement values for overlays (menus, tooltips, popovers). */
18
- type MkPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end';
19
19
 
20
20
  /**
21
21
  * Global control-density mode.
@@ -218,15 +218,6 @@ declare class MkFocusTrap {
218
218
  private onKeydown;
219
219
  }
220
220
 
221
- /**
222
- * Generates a stable, unique DOM id for wiring `aria-*` relationships
223
- * (labels, descriptions, controls). Prefer this over `Math.random()` so
224
- * ids are deterministic within a render and SSR-safe.
225
- *
226
- * @param prefix short semantic prefix, e.g. `mk-input`.
227
- */
228
- declare function mkUniqueId(prefix?: string): string;
229
-
230
221
  /** Injection token exposing the data passed to an overlay component. */
231
222
  declare const MK_OVERLAY_DATA: InjectionToken<unknown>;
232
223
  /**
@@ -386,42 +377,6 @@ declare class MkOverlayService implements OnDestroy {
386
377
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<MkOverlayService>;
387
378
  }
388
379
 
389
- /** Options controlling {@link mkComputeAnchoredPosition}. */
390
- interface MkAnchoredPositionOptions {
391
- placement: MkPlacement;
392
- gap: number;
393
- flip: boolean;
394
- clamp: boolean;
395
- /** Resolve `-start`/`-end` alignment against a right-to-left anchor. */
396
- rtl?: boolean;
397
- }
398
- interface MkRectLike {
399
- top: number;
400
- left: number;
401
- right: number;
402
- bottom: number;
403
- width: number;
404
- height: number;
405
- }
406
- interface MkSize {
407
- width: number;
408
- height: number;
409
- }
410
- /** Resolved coordinates (viewport-relative, for `position: fixed`). */
411
- interface MkAnchoredPosition {
412
- top: number;
413
- left: number;
414
- /** The placement actually used after any flip. */
415
- placement: MkPlacement;
416
- }
417
- /**
418
- * Pure viewport-positioning maths shared by every anchored overlay
419
- * ({@link MkAnchoredPanel} and the tooltip). Given the anchor rect, the panel
420
- * size and the viewport size, returns the top/left for a `position: fixed`
421
- * panel — flipping to the opposite side when it would overflow and clamping
422
- * back inside the viewport.
423
- */
424
- declare function mkComputeAnchoredPosition(anchor: MkRectLike, panel: MkSize, viewport: MkSize, opts: MkAnchoredPositionOptions): MkAnchoredPosition;
425
380
  /**
426
381
  * Anchored-overlay directive. Apply it to a floating panel element (a dropdown
427
382
  * list, calendar, menu, …) that is rendered inside its component's own template
@@ -507,23 +462,7 @@ declare class MkAnchoredPanel implements AfterViewInit, OnDestroy {
507
462
 
508
463
  /** Direction passed to the sort announcer. */
509
464
  type MkSortAnnounceDirection = 'asc' | 'desc';
510
- /**
511
- * Localised date-name tables consumed by the calendar, the date/month/week
512
- * pickers and `formatDate`. All arrays are full-length (12 months, 7 weekdays
513
- * starting with Sunday) — override the whole set for a locale.
514
- */
515
- interface MkDateNames {
516
- /** Full month names, January-first (12). */
517
- months: readonly string[];
518
- /** Abbreviated month names (12). */
519
- monthsShort: readonly string[];
520
- /** Full weekday names, Sunday-first (7). */
521
- weekdays: readonly string[];
522
- /** Abbreviated weekday names (7). */
523
- weekdaysShort: readonly string[];
524
- /** One/two-letter weekday names for calendar headers (7). */
525
- weekdaysNarrow: readonly string[];
526
- }
465
+
527
466
  /** Strings used by the block editor's chrome. */
528
467
  interface MkBlockEditorStrings {
529
468
  addBlock: string;
@@ -1289,7 +1228,7 @@ declare abstract class MkFieldContext {
1289
1228
  /** Id of the field's label element, for `aria-labelledby`. */
1290
1229
  abstract readonly labelId: string;
1291
1230
  /** The field's visual size, mirrored onto the nested control. */
1292
- abstract readonly size: Signal<MkSize$1>;
1231
+ abstract readonly size: Signal<MkSize>;
1293
1232
  /** Whether the field is required (explicitly or via the bound control). */
1294
1233
  abstract readonly isRequired: Signal<boolean>;
1295
1234
  /** Whether the field currently shows an error. */
@@ -1301,22 +1240,6 @@ declare abstract class MkFieldContext {
1301
1240
  abstract readonly describedBy: Signal<string | null>;
1302
1241
  }
1303
1242
 
1304
- /**
1305
- * Dependency-free syntax highlighting for {@link MkCodeEditor}. Each function
1306
- * takes source text and returns an HTML string of `<span class="mk-tok-…">`
1307
- * tokens. Input is HTML-escaped first, so the result is safe to render.
1308
- */
1309
- /** Languages with built-in highlighting. Unknown values render plain text. */
1310
- type MkCodeLanguage = 'json' | 'plaintext';
1311
- /**
1312
- * Highlight a JSON document. Recognises object keys, strings, numbers, the
1313
- * `true`/`false`/`null` literals and structural punctuation. Invalid JSON is
1314
- * still highlighted token-by-token (the editor validates separately).
1315
- */
1316
- declare function mkHighlightJson(src: string): string;
1317
- /** Highlight `src` for `language`, falling back to escaped plain text. */
1318
- declare function mkHighlight(src: string, language: string): string;
1319
-
1320
1243
  /**
1321
1244
  * Handle returned by {@link mkValidatorChange}, wiring a component's
1322
1245
  * `registerOnValidatorChange` callback to a set of reactive dependencies.
@@ -1440,83 +1363,5 @@ declare function mkSignalErrorMessage(errors: readonly MkSignalValidationError[]
1440
1363
  */
1441
1364
  declare function mkInjectFieldTouched(): Signal<boolean>;
1442
1365
 
1443
- /** Value kind of a filterable field; decides the editor and the operators offered. */
1444
- type MkQueryValueType = 'string' | 'number' | 'boolean' | 'date' | 'select';
1445
- /** A choice for `select` fields. */
1446
- interface MkQueryFieldOption {
1447
- label: string;
1448
- value: unknown;
1449
- }
1450
- /** A field the user can filter on. */
1451
- interface MkQueryField {
1452
- /** Property key on the row objects / the API's filter name. */
1453
- key: string;
1454
- /** Label shown in the field picker. */
1455
- label: string;
1456
- /** Default `string`. */
1457
- type?: MkQueryValueType;
1458
- /** Choices for `select` fields. */
1459
- options?: readonly MkQueryFieldOption[];
1460
- /** Restrict / reorder the operators offered (default: all for the type). */
1461
- operators?: readonly MkQueryOperator[];
1462
- /** Placeholder of the value editor. */
1463
- placeholder?: string;
1464
- }
1465
- /** Comparison operators. Which apply depends on the field type. */
1466
- type MkQueryOperator = 'eq' | 'neq' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'in' | 'notIn' | 'before' | 'after' | 'empty' | 'notEmpty';
1467
- /** A leaf condition. `value` is `[from, to]` for `between`, an array for `in` / `notIn`, absent for `empty` / `notEmpty`. Dates are ISO strings. */
1468
- interface MkQueryRule {
1469
- id: string;
1470
- field: string;
1471
- operator: MkQueryOperator;
1472
- value?: unknown;
1473
- }
1474
- type MkQueryCombinator = 'and' | 'or';
1475
- /** A group of rules and nested groups joined by one combinator, optionally negated. */
1476
- interface MkQueryGroup {
1477
- id: string;
1478
- combinator: MkQueryCombinator;
1479
- /** Negate the whole group. */
1480
- not?: boolean;
1481
- rules: MkQueryNode[];
1482
- }
1483
- type MkQueryNode = MkQueryRule | MkQueryGroup;
1484
-
1485
- /** Operators offered per field type, in menu order. */
1486
- declare const MK_QUERY_OPERATORS: Readonly<Record<MkQueryValueType, readonly MkQueryOperator[]>>;
1487
- /** Operators that take no value. */
1488
- declare const MK_QUERY_UNARY: ReadonlySet<MkQueryOperator>;
1489
- /** True for a group node (as opposed to a rule). */
1490
- declare function mkIsQueryGroup(node: MkQueryNode): node is MkQueryGroup;
1491
- /** A fresh empty group. */
1492
- declare function mkCreateQueryGroup(init?: Partial<Omit<MkQueryGroup, 'id'>>): MkQueryGroup;
1493
- /** A fresh rule on `field`, using its first operator. */
1494
- declare function mkCreateQueryRule(field: MkQueryField): MkQueryRule;
1495
- /** Operators a field offers (its own list, else the defaults for its type). */
1496
- declare function mkQueryOperatorsFor(field: MkQueryField | undefined): readonly MkQueryOperator[];
1497
- /** True when the tree holds no rule at all (empty groups only). */
1498
- declare function mkQueryIsEmpty(group: MkQueryGroup): boolean;
1499
- /** Number of rules in the tree. */
1500
- declare function mkQueryRuleCount(group: MkQueryGroup): number;
1501
- /** Drop empty groups and rules that still need a value, so the API gets only complete conditions. */
1502
- declare function mkQueryCompact(group: MkQueryGroup): MkQueryGroup;
1503
- /** A rule is complete when its operator needs no value or has one. */
1504
- declare function mkQueryRuleIsComplete(rule: MkQueryRule): boolean;
1505
- /** Evaluate one rule against a row. */
1506
- declare function mkQueryRuleMatches(rule: MkQueryRule, row: Record<string, unknown>, field?: MkQueryField): boolean;
1507
- /**
1508
- * Compile a query into a row predicate for client-side filtering
1509
- * (`rows.filter(mkQueryToPredicate(query, fields))`). Unfinished rules are
1510
- * ignored, so a half-edited query never blanks the table.
1511
- */
1512
- declare function mkQueryToPredicate<T extends object = Record<string, unknown>>(group: MkQueryGroup, fields?: readonly MkQueryField[]): (row: T) => boolean;
1513
- /** Localised label of an operator. */
1514
- declare function mkQueryOperatorLabel(op: MkQueryOperator, i18n?: MkI18nStrings): string;
1515
- /**
1516
- * Human-readable sentence for a query, e.g.
1517
- * `(Name contains "ada" and Orders at least 10) or Status is any of Active, Invited`.
1518
- */
1519
- declare function mkQueryToText(group: MkQueryGroup, fields?: readonly MkQueryField[], i18n?: MkI18nStrings): string;
1520
-
1521
- export { MK_BREAKPOINTS, MK_DEFAULT_BREAKPOINTS, MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MK_OVERLAY_ROOT, MK_QUERY_OPERATORS, MK_QUERY_UNARY, MkAnchoredPanel, MkBreakpointService, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkBodyLevelAncestor, mkComputeAnchoredPosition, mkCreateQueryGroup, mkCreateQueryRule, mkFirstErrorMessage, mkGetFocusable, mkHighlight, mkHighlightJson, mkInjectFieldTouched, mkIsQueryGroup, mkIsResponsive, mkMergeI18n, mkQueryCompact, mkQueryIsEmpty, mkQueryOperatorLabel, mkQueryOperatorsFor, mkQueryRuleCount, mkQueryRuleIsComplete, mkQueryRuleMatches, mkQueryToPredicate, mkQueryToText, mkSignalErrorMessage, mkSignalErrorsToValidationErrors, mkUniqueId, mkValidatorChange, provideMkI18n };
1522
- export type { MkAnchoredPosition, MkAnchoredPositionOptions, MkAriaLivePoliteness, MkBlockEditorStrings, MkBreakpoint, MkBreakpoints, MkCodeLanguage, MkContrastPreference, MkDateNames, MkDensity, MkErrorMessages, MkI18nOverrides, MkI18nStrings, MkOverlayConfig, MkOverlayRootFn, MkPlacement, MkQueryCombinator, MkQueryField, MkQueryFieldOption, MkQueryGroup, MkQueryNode, MkQueryOperator, MkQueryRule, MkQueryValueType, MkResolvedContrast, MkResolvedTheme, MkResponsive, MkSignalValidationError, MkSize$1 as MkSize, MkSortAnnounceDirection, MkThemePreference, MkTone, MkValidationStrings, MkValidatorChangeRef, MkVariant };
1366
+ export { MK_BREAKPOINTS, MK_DEFAULT_BREAKPOINTS, MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MK_OVERLAY_ROOT, MkAnchoredPanel, MkBreakpointService, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkBodyLevelAncestor, mkFirstErrorMessage, mkGetFocusable, mkInjectFieldTouched, mkIsResponsive, mkMergeI18n, mkSignalErrorMessage, mkSignalErrorsToValidationErrors, mkValidatorChange, provideMkI18n };
1367
+ export type { MkAriaLivePoliteness, MkBlockEditorStrings, MkBreakpoint, MkBreakpoints, MkContrastPreference, MkDensity, MkErrorMessages, MkI18nOverrides, MkI18nStrings, MkOverlayConfig, MkOverlayRootFn, MkResolvedContrast, MkResolvedTheme, MkResponsive, MkSignalValidationError, MkSize, MkSortAnnounceDirection, MkThemePreference, MkTone, MkValidationStrings, MkValidatorChangeRef, MkVariant };