@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.
- package/README.md +4 -2
- package/fesm2022/mk-kit-ui-core.mjs +9 -380
- package/fesm2022/mk-kit-ui-core.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-data.mjs +6 -842
- package/fesm2022/mk-kit-ui-data.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-datetime.mjs +4 -247
- package/fesm2022/mk-kit-ui-datetime.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-embed.mjs +24 -5
- package/fesm2022/mk-kit-ui-embed.mjs.map +1 -1
- package/package.json +2 -1
- package/types/mk-kit-ui-core.d.ts +7 -162
- package/types/mk-kit-ui-data.d.ts +6 -173
- package/types/mk-kit-ui-datetime.d.ts +5 -77
- package/types/mk-kit-ui-embed.d.ts +19 -2
|
@@ -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.
|
|
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
|
|
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
|
|
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
|
-
|
|
1444
|
-
type
|
|
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 };
|