@akcelik/strct 5.10.0 → 5.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/akcelik-strct.mjs +1205 -59
- package/fesm2022/akcelik-strct.mjs.map +1 -1
- package/package.json +1 -1
- package/types/akcelik-strct.d.ts +243 -8
|
@@ -1890,6 +1890,16 @@ class StrctListItem {
|
|
|
1890
1890
|
* row at once; this is the per-row form.
|
|
1891
1891
|
*/
|
|
1892
1892
|
wrap = input(false, { ...(ngDevMode ? { debugName: "wrap" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1893
|
+
/**
|
|
1894
|
+
* The row cannot be activated — a conversation that cannot be switched away
|
|
1895
|
+
* from while a reply arrives. It keeps its tab stop and says
|
|
1896
|
+
* `aria-disabled`, so the reason can be read; a keyboard or touch user
|
|
1897
|
+
* never sees a `title`.
|
|
1898
|
+
*/
|
|
1899
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1900
|
+
/** Why it cannot be activated, read as the row's description. */
|
|
1901
|
+
disabledReason = input('', /* @ts-ignore */
|
|
1902
|
+
...(ngDevMode ? [{ debugName: "disabledReason" }] : /* istanbul ignore next */ []));
|
|
1893
1903
|
/** Marks the current row (`aria-current`). */
|
|
1894
1904
|
selected = input(false, { ...(ngDevMode ? { debugName: "selected" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1895
1905
|
/** Optional leading rail, as `strct-card [status]`. */
|
|
@@ -1898,16 +1908,19 @@ class StrctListItem {
|
|
|
1898
1908
|
/** Emitted when an `interactive` row is activated. */
|
|
1899
1909
|
activated = output();
|
|
1900
1910
|
onActivate() {
|
|
1901
|
-
if (this.interactive())
|
|
1911
|
+
if (this.interactive() && !this.disabled())
|
|
1902
1912
|
this.activated.emit();
|
|
1903
1913
|
}
|
|
1904
1914
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctListItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1905
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctListItem, isStandalone: true, selector: "strct-list-item", inputs: { interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activated: "activated" }, host: { attributes: { "role": "listitem" }, properties: { "class.strct-li--interactive": "interactive()", "class.strct-li--wrap": "wrap()", "class.strct-li--selected": "selected()", "class.strct-li--status": "status()", "attr.data-status": "status()" }, classAttribute: "strct-li" }, ngImport: i0, template: `
|
|
1915
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctListItem, isStandalone: true, selector: "strct-list-item", inputs: { interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, disabledReason: { classPropertyName: "disabledReason", publicName: "disabledReason", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activated: "activated" }, host: { attributes: { "role": "listitem" }, properties: { "class.strct-li--interactive": "interactive()", "class.strct-li--wrap": "wrap()", "class.strct-li--disabled": "disabled()", "class.strct-li--selected": "selected()", "class.strct-li--status": "status()", "attr.data-status": "status()" }, classAttribute: "strct-li" }, ngImport: i0, template: `
|
|
1906
1916
|
<div
|
|
1907
1917
|
class="strct-li__main"
|
|
1908
1918
|
[attr.role]="interactive() ? 'button' : null"
|
|
1909
1919
|
[attr.tabindex]="interactive() ? 0 : null"
|
|
1910
1920
|
[attr.aria-current]="selected() ? 'true' : null"
|
|
1921
|
+
[attr.aria-disabled]="disabled() ? 'true' : null"
|
|
1922
|
+
[attr.title]="disabledReason() || null"
|
|
1923
|
+
[attr.aria-description]="disabled() ? disabledReason() || null : null"
|
|
1911
1924
|
(click)="onActivate()"
|
|
1912
1925
|
(keydown.enter)="onActivate()"
|
|
1913
1926
|
(keydown.space)="$event.preventDefault(); onActivate()"
|
|
@@ -1920,7 +1933,7 @@ class StrctListItem {
|
|
|
1920
1933
|
<span class="strct-li__meta"><ng-content select="[strctListItemMeta]" /></span>
|
|
1921
1934
|
</div>
|
|
1922
1935
|
<span class="strct-li__trailing"><ng-content select="[strctListItemTrailing]" /></span>
|
|
1923
|
-
`, isInline: true, styles: [".strct-li{display:flex;align-items:center;gap:var(--space-2);padding-inline:var(--space-3);position:relative}.strct-list--flush .strct-li{padding-inline:0}.strct-list--dividers .strct-li+.strct-li{border-block-start:1px solid var(--b1)}.strct-li__main{display:flex;align-items:center;gap:var(--space-2);flex:1;min-width:0;min-height:44px;padding-block:6px;text-align:start;border-radius:var(--radius-sm)}.strct-list--dense .strct-li__main{min-height:32px;padding-block:2px}.strct-li--interactive .strct-li__main{cursor:pointer}.strct-li--interactive:hover{background:var(--bg-2)}.strct-li--selected{background:var(--acc-s)}.strct-li__main:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-li--status:before{content:\"\";position:absolute;inset-block:0;inset-inline-start:0;width:2px;background:var(--t3)}.strct-li[data-status=accent]:before{background:var(--acc)}.strct-li[data-status=success]:before{background:var(--success)}.strct-li[data-status=warning]:before{background:var(--warning)}.strct-li[data-status=critical]:before{background:var(--critical)}.strct-li--wrap .strct-li__main,.strct-list--wrap .strct-li__main{align-items:flex-start}.strct-li--wrap .strct-li__leading,.strct-list--wrap .strct-li__leading{min-height:calc(var(--text-md) * 1.45)}.strct-li--wrap .strct-li__title,.strct-li--wrap .strct-li__desc,.strct-list--wrap .strct-li__title,.strct-list--wrap .strct-li__desc{overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere}.strct-li--wrap .strct-li__meta,.strct-list--wrap .strct-li__meta{align-self:flex-start;min-height:calc(var(--text-md) * 1.45)}.strct-li__leading:empty,.strct-li__meta:empty,.strct-li__desc:empty,.strct-li__trailing:empty{display:none}.strct-li__leading{display:inline-flex;align-items:center;flex:none}.strct-li__text{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}.strct-li__title{font-size:var(--text-md);color:var(--t1);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__desc{font-size:var(--text-sm);color:var(--t3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__meta{display:inline-flex;align-items:center;flex:none;font-size:var(--text-sm);color:var(--t3);white-space:nowrap}.strct-li__trailing{display:inline-flex;align-items:center;gap:var(--space-2);flex:none}@container (max-width: 360px){.strct-li__main{flex-wrap:wrap}.strct-li__meta{flex-basis:100%;padding-inline-start:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1936
|
+
`, isInline: true, styles: [".strct-li{display:flex;align-items:center;gap:var(--space-2);padding-inline:var(--space-3);position:relative}.strct-list--flush .strct-li{padding-inline:0}.strct-list--dividers .strct-li+.strct-li{border-block-start:1px solid var(--b1)}.strct-li__main{display:flex;align-items:center;gap:var(--space-2);flex:1;min-width:0;min-height:44px;padding-block:6px;text-align:start;border-radius:var(--radius-sm)}.strct-list--dense .strct-li__main{min-height:32px;padding-block:2px}.strct-li--interactive .strct-li__main{cursor:pointer}.strct-li--disabled .strct-li__main{cursor:not-allowed;opacity:.6}.strct-li--disabled.strct-li--interactive:hover{background:none}.strct-li--interactive:hover{background:var(--bg-2)}.strct-li--selected{background:var(--acc-s)}.strct-li__main:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-li--status:before{content:\"\";position:absolute;inset-block:0;inset-inline-start:0;width:2px;background:var(--t3)}.strct-li[data-status=accent]:before{background:var(--acc)}.strct-li[data-status=success]:before{background:var(--success)}.strct-li[data-status=warning]:before{background:var(--warning)}.strct-li[data-status=critical]:before{background:var(--critical)}.strct-li--wrap .strct-li__main,.strct-list--wrap .strct-li__main{align-items:flex-start}.strct-li--wrap .strct-li__leading,.strct-list--wrap .strct-li__leading{min-height:calc(var(--text-md) * 1.45)}.strct-li--wrap .strct-li__title,.strct-li--wrap .strct-li__desc,.strct-list--wrap .strct-li__title,.strct-list--wrap .strct-li__desc{overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere}.strct-li--wrap .strct-li__meta,.strct-list--wrap .strct-li__meta{align-self:flex-start;min-height:calc(var(--text-md) * 1.45)}.strct-li__leading:empty,.strct-li__meta:empty,.strct-li__desc:empty,.strct-li__trailing:empty{display:none}.strct-li__leading{display:inline-flex;align-items:center;flex:none}.strct-li__text{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}.strct-li__title{font-size:var(--text-md);color:var(--t1);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__desc{font-size:var(--text-sm);color:var(--t3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__meta{display:inline-flex;align-items:center;flex:none;font-size:var(--text-sm);color:var(--t3);white-space:nowrap}.strct-li__trailing{display:inline-flex;align-items:center;gap:var(--space-2);flex:none}@container (max-width: 360px){.strct-li__main{flex-wrap:wrap}.strct-li__meta{flex-basis:100%;padding-inline-start:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1924
1937
|
}
|
|
1925
1938
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctListItem, decorators: [{
|
|
1926
1939
|
type: Component,
|
|
@@ -1930,6 +1943,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1930
1943
|
[attr.role]="interactive() ? 'button' : null"
|
|
1931
1944
|
[attr.tabindex]="interactive() ? 0 : null"
|
|
1932
1945
|
[attr.aria-current]="selected() ? 'true' : null"
|
|
1946
|
+
[attr.aria-disabled]="disabled() ? 'true' : null"
|
|
1947
|
+
[attr.title]="disabledReason() || null"
|
|
1948
|
+
[attr.aria-description]="disabled() ? disabledReason() || null : null"
|
|
1933
1949
|
(click)="onActivate()"
|
|
1934
1950
|
(keydown.enter)="onActivate()"
|
|
1935
1951
|
(keydown.space)="$event.preventDefault(); onActivate()"
|
|
@@ -1947,11 +1963,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1947
1963
|
role: 'listitem',
|
|
1948
1964
|
'[class.strct-li--interactive]': 'interactive()',
|
|
1949
1965
|
'[class.strct-li--wrap]': 'wrap()',
|
|
1966
|
+
'[class.strct-li--disabled]': 'disabled()',
|
|
1950
1967
|
'[class.strct-li--selected]': 'selected()',
|
|
1951
1968
|
'[class.strct-li--status]': 'status()',
|
|
1952
1969
|
'[attr.data-status]': 'status()',
|
|
1953
|
-
}, styles: [".strct-li{display:flex;align-items:center;gap:var(--space-2);padding-inline:var(--space-3);position:relative}.strct-list--flush .strct-li{padding-inline:0}.strct-list--dividers .strct-li+.strct-li{border-block-start:1px solid var(--b1)}.strct-li__main{display:flex;align-items:center;gap:var(--space-2);flex:1;min-width:0;min-height:44px;padding-block:6px;text-align:start;border-radius:var(--radius-sm)}.strct-list--dense .strct-li__main{min-height:32px;padding-block:2px}.strct-li--interactive .strct-li__main{cursor:pointer}.strct-li--interactive:hover{background:var(--bg-2)}.strct-li--selected{background:var(--acc-s)}.strct-li__main:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-li--status:before{content:\"\";position:absolute;inset-block:0;inset-inline-start:0;width:2px;background:var(--t3)}.strct-li[data-status=accent]:before{background:var(--acc)}.strct-li[data-status=success]:before{background:var(--success)}.strct-li[data-status=warning]:before{background:var(--warning)}.strct-li[data-status=critical]:before{background:var(--critical)}.strct-li--wrap .strct-li__main,.strct-list--wrap .strct-li__main{align-items:flex-start}.strct-li--wrap .strct-li__leading,.strct-list--wrap .strct-li__leading{min-height:calc(var(--text-md) * 1.45)}.strct-li--wrap .strct-li__title,.strct-li--wrap .strct-li__desc,.strct-list--wrap .strct-li__title,.strct-list--wrap .strct-li__desc{overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere}.strct-li--wrap .strct-li__meta,.strct-list--wrap .strct-li__meta{align-self:flex-start;min-height:calc(var(--text-md) * 1.45)}.strct-li__leading:empty,.strct-li__meta:empty,.strct-li__desc:empty,.strct-li__trailing:empty{display:none}.strct-li__leading{display:inline-flex;align-items:center;flex:none}.strct-li__text{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}.strct-li__title{font-size:var(--text-md);color:var(--t1);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__desc{font-size:var(--text-sm);color:var(--t3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__meta{display:inline-flex;align-items:center;flex:none;font-size:var(--text-sm);color:var(--t3);white-space:nowrap}.strct-li__trailing{display:inline-flex;align-items:center;gap:var(--space-2);flex:none}@container (max-width: 360px){.strct-li__main{flex-wrap:wrap}.strct-li__meta{flex-basis:100%;padding-inline-start:0}}\n"] }]
|
|
1954
|
-
}], propDecorators: { interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], wrap: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrap", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
|
|
1970
|
+
}, styles: [".strct-li{display:flex;align-items:center;gap:var(--space-2);padding-inline:var(--space-3);position:relative}.strct-list--flush .strct-li{padding-inline:0}.strct-list--dividers .strct-li+.strct-li{border-block-start:1px solid var(--b1)}.strct-li__main{display:flex;align-items:center;gap:var(--space-2);flex:1;min-width:0;min-height:44px;padding-block:6px;text-align:start;border-radius:var(--radius-sm)}.strct-list--dense .strct-li__main{min-height:32px;padding-block:2px}.strct-li--interactive .strct-li__main{cursor:pointer}.strct-li--disabled .strct-li__main{cursor:not-allowed;opacity:.6}.strct-li--disabled.strct-li--interactive:hover{background:none}.strct-li--interactive:hover{background:var(--bg-2)}.strct-li--selected{background:var(--acc-s)}.strct-li__main:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-li--status:before{content:\"\";position:absolute;inset-block:0;inset-inline-start:0;width:2px;background:var(--t3)}.strct-li[data-status=accent]:before{background:var(--acc)}.strct-li[data-status=success]:before{background:var(--success)}.strct-li[data-status=warning]:before{background:var(--warning)}.strct-li[data-status=critical]:before{background:var(--critical)}.strct-li--wrap .strct-li__main,.strct-list--wrap .strct-li__main{align-items:flex-start}.strct-li--wrap .strct-li__leading,.strct-list--wrap .strct-li__leading{min-height:calc(var(--text-md) * 1.45)}.strct-li--wrap .strct-li__title,.strct-li--wrap .strct-li__desc,.strct-list--wrap .strct-li__title,.strct-list--wrap .strct-li__desc{overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere}.strct-li--wrap .strct-li__meta,.strct-list--wrap .strct-li__meta{align-self:flex-start;min-height:calc(var(--text-md) * 1.45)}.strct-li__leading:empty,.strct-li__meta:empty,.strct-li__desc:empty,.strct-li__trailing:empty{display:none}.strct-li__leading{display:inline-flex;align-items:center;flex:none}.strct-li__text{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}.strct-li__title{font-size:var(--text-md);color:var(--t1);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__desc{font-size:var(--text-sm);color:var(--t3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-li__meta{display:inline-flex;align-items:center;flex:none;font-size:var(--text-sm);color:var(--t3);white-space:nowrap}.strct-li__trailing{display:inline-flex;align-items:center;gap:var(--space-2);flex:none}@container (max-width: 360px){.strct-li__main{flex-wrap:wrap}.strct-li__meta{flex-basis:100%;padding-inline-start:0}}\n"] }]
|
|
1971
|
+
}], propDecorators: { interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], wrap: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrap", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], disabledReason: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledReason", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
|
|
1955
1972
|
/**
|
|
1956
1973
|
* A short list of things with a status — alarms, findings, clusters in a
|
|
1957
1974
|
* summary. A table needs a header row and columns, a timeline implies time
|
|
@@ -2379,6 +2396,16 @@ class StrctTag {
|
|
|
2379
2396
|
*/
|
|
2380
2397
|
activateLabel = input('', /* @ts-ignore */
|
|
2381
2398
|
...(ngDevMode ? [{ debugName: "activateLabel" }] : /* istanbul ignore next */ []));
|
|
2399
|
+
/**
|
|
2400
|
+
* The tag's body is a link to this address — an object chip in a reply opens
|
|
2401
|
+
* the object's page. A link is what a middle click, a Ctrl/Cmd-click and
|
|
2402
|
+
* "copy link address" need; `interactive` cannot give them.
|
|
2403
|
+
*/
|
|
2404
|
+
href = input(null, /* @ts-ignore */
|
|
2405
|
+
...(ngDevMode ? [{ debugName: "href" }] : /* istanbul ignore next */ []));
|
|
2406
|
+
/** `_blank` adds the `rel` a new tab needs. */
|
|
2407
|
+
target = input('', /* @ts-ignore */
|
|
2408
|
+
...(ngDevMode ? [{ debugName: "target" }] : /* istanbul ignore next */ []));
|
|
2382
2409
|
/**
|
|
2383
2410
|
* The body becomes a control: pointer, hover, focus ring, and `activated` on
|
|
2384
2411
|
* click / Enter / Space. The × stays a separate tab stop, so "open it" and
|
|
@@ -2399,21 +2426,38 @@ class StrctTag {
|
|
|
2399
2426
|
this.activated.emit();
|
|
2400
2427
|
}
|
|
2401
2428
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2402
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctTag, isStandalone: true, selector: "strct-tag", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, activateLabel: { classPropertyName: "activateLabel", publicName: "activateLabel", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, mono: { classPropertyName: "mono", publicName: "mono", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed", activated: "activated" }, host: { properties: { "class.strct-tag--interactive": "interactive() && !disabled()", "class.strct-tag--pill": "shape() === 'pill'", "class.strct-tag--mono": "mono()", "class.strct-tag--accent": "status() === 'accent'", "class.strct-tag--success": "status() === 'success'", "class.strct-tag--warning": "status() === 'warning'", "class.strct-tag--critical": "status() === 'critical'" }, classAttribute: "strct-tag" }, ngImport: i0, template: `
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2429
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctTag, isStandalone: true, selector: "strct-tag", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, activateLabel: { classPropertyName: "activateLabel", publicName: "activateLabel", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, mono: { classPropertyName: "mono", publicName: "mono", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed", activated: "activated" }, host: { properties: { "class.strct-tag--interactive": "interactive() && !disabled()", "class.strct-tag--pill": "shape() === 'pill'", "class.strct-tag--mono": "mono()", "class.strct-tag--accent": "status() === 'accent'", "class.strct-tag--success": "status() === 'success'", "class.strct-tag--warning": "status() === 'warning'", "class.strct-tag--critical": "status() === 'critical'" }, classAttribute: "strct-tag" }, ngImport: i0, template: `
|
|
2430
|
+
<!-- With an href the body is a real link: Ctrl/Cmd-click opens a tab, the
|
|
2431
|
+
address shows on hover and it can be copied as a link — none of which
|
|
2432
|
+
a role="button" can do. The same text, the same focus ring. -->
|
|
2433
|
+
@if (href() && !disabled()) {
|
|
2434
|
+
<a
|
|
2435
|
+
class="strct-tag__text strct-tag__text--link"
|
|
2436
|
+
[attr.href]="href()"
|
|
2437
|
+
[attr.target]="target() || null"
|
|
2438
|
+
[attr.rel]="target() === '_blank' ? 'noopener noreferrer' : null"
|
|
2439
|
+
[attr.aria-label]="activateLabel() || null"
|
|
2440
|
+
(click)="onActivate()"
|
|
2441
|
+
>
|
|
2442
|
+
<ng-content select="[strctTagLeading]" />
|
|
2443
|
+
<ng-content />
|
|
2444
|
+
</a>
|
|
2445
|
+
} @else {
|
|
2446
|
+
<span
|
|
2447
|
+
class="strct-tag__text"
|
|
2448
|
+
[attr.role]="interactive() ? 'button' : null"
|
|
2449
|
+
[attr.tabindex]="interactive() && !disabled() ? 0 : null"
|
|
2450
|
+
[attr.aria-label]="interactive() && activateLabel() ? activateLabel() : null"
|
|
2451
|
+
(click)="onActivate()"
|
|
2452
|
+
(keydown.enter)="onActivate()"
|
|
2453
|
+
(keydown.space)="$event.preventDefault(); onActivate()"
|
|
2454
|
+
>
|
|
2455
|
+
<!-- Declared before the catch-all so the selector wins; it renders first
|
|
2413
2456
|
either way. -->
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2457
|
+
<ng-content select="[strctTagLeading]" />
|
|
2458
|
+
<ng-content />
|
|
2459
|
+
</span>
|
|
2460
|
+
}
|
|
2417
2461
|
@if (removable() && !disabled()) {
|
|
2418
2462
|
<button
|
|
2419
2463
|
type="button"
|
|
@@ -2424,25 +2468,42 @@ class StrctTag {
|
|
|
2424
2468
|
<strct-icon name="close" [size]="11" [strokeWidth]="1.6" />
|
|
2425
2469
|
</button>
|
|
2426
2470
|
}
|
|
2427
|
-
`, isInline: true, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__text{display:inline-flex;align-items:center;gap:5px}.strct-tag--interactive .strct-tag__text{cursor:pointer;border-radius:3px}.strct-tag--interactive:hover{border-color:var(--b3);background:var(--bg-2)}.strct-tag--interactive.strct-tag--accent:hover{border-color:var(--acc)}.strct-tag__text:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-tag--pill{border-radius:var(--radius-full, 999px);padding-inline:10px 5px}.strct-tag--pill:not(:has(.strct-tag__remove)){padding-inline-end:10px}.strct-tag--pill .strct-tag__remove{border-radius:999px}.strct-tag--mono{font-family:var(--mono)}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2471
|
+
`, isInline: true, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__text{display:inline-flex;align-items:center;gap:5px}.strct-tag__text--link{color:inherit;text-decoration:none;cursor:pointer}.strct-tag__text--link:hover{text-decoration:underline}.strct-tag--interactive .strct-tag__text{cursor:pointer;border-radius:3px}.strct-tag--interactive:hover{border-color:var(--b3);background:var(--bg-2)}.strct-tag--interactive.strct-tag--accent:hover{border-color:var(--acc)}.strct-tag__text:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-tag--pill{border-radius:var(--radius-full, 999px);padding-inline:10px 5px}.strct-tag--pill:not(:has(.strct-tag__remove)){padding-inline-end:10px}.strct-tag--pill .strct-tag__remove{border-radius:999px}.strct-tag--mono{font-family:var(--mono)}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2428
2472
|
}
|
|
2429
2473
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctTag, decorators: [{
|
|
2430
2474
|
type: Component,
|
|
2431
2475
|
args: [{ selector: 'strct-tag', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2476
|
+
<!-- With an href the body is a real link: Ctrl/Cmd-click opens a tab, the
|
|
2477
|
+
address shows on hover and it can be copied as a link — none of which
|
|
2478
|
+
a role="button" can do. The same text, the same focus ring. -->
|
|
2479
|
+
@if (href() && !disabled()) {
|
|
2480
|
+
<a
|
|
2481
|
+
class="strct-tag__text strct-tag__text--link"
|
|
2482
|
+
[attr.href]="href()"
|
|
2483
|
+
[attr.target]="target() || null"
|
|
2484
|
+
[attr.rel]="target() === '_blank' ? 'noopener noreferrer' : null"
|
|
2485
|
+
[attr.aria-label]="activateLabel() || null"
|
|
2486
|
+
(click)="onActivate()"
|
|
2487
|
+
>
|
|
2488
|
+
<ng-content select="[strctTagLeading]" />
|
|
2489
|
+
<ng-content />
|
|
2490
|
+
</a>
|
|
2491
|
+
} @else {
|
|
2492
|
+
<span
|
|
2493
|
+
class="strct-tag__text"
|
|
2494
|
+
[attr.role]="interactive() ? 'button' : null"
|
|
2495
|
+
[attr.tabindex]="interactive() && !disabled() ? 0 : null"
|
|
2496
|
+
[attr.aria-label]="interactive() && activateLabel() ? activateLabel() : null"
|
|
2497
|
+
(click)="onActivate()"
|
|
2498
|
+
(keydown.enter)="onActivate()"
|
|
2499
|
+
(keydown.space)="$event.preventDefault(); onActivate()"
|
|
2500
|
+
>
|
|
2501
|
+
<!-- Declared before the catch-all so the selector wins; it renders first
|
|
2442
2502
|
either way. -->
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2503
|
+
<ng-content select="[strctTagLeading]" />
|
|
2504
|
+
<ng-content />
|
|
2505
|
+
</span>
|
|
2506
|
+
}
|
|
2446
2507
|
@if (removable() && !disabled()) {
|
|
2447
2508
|
<button
|
|
2448
2509
|
type="button"
|
|
@@ -2462,8 +2523,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
2462
2523
|
'[class.strct-tag--success]': "status() === 'success'",
|
|
2463
2524
|
'[class.strct-tag--warning]': "status() === 'warning'",
|
|
2464
2525
|
'[class.strct-tag--critical]': "status() === 'critical'",
|
|
2465
|
-
}, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__text{display:inline-flex;align-items:center;gap:5px}.strct-tag--interactive .strct-tag__text{cursor:pointer;border-radius:3px}.strct-tag--interactive:hover{border-color:var(--b3);background:var(--bg-2)}.strct-tag--interactive.strct-tag--accent:hover{border-color:var(--acc)}.strct-tag__text:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-tag--pill{border-radius:var(--radius-full, 999px);padding-inline:10px 5px}.strct-tag--pill:not(:has(.strct-tag__remove)){padding-inline-end:10px}.strct-tag--pill .strct-tag__remove{border-radius:999px}.strct-tag--mono{font-family:var(--mono)}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"] }]
|
|
2466
|
-
}], ctorParameters: () => [], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], activateLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "activateLabel", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], mono: [{ type: i0.Input, args: [{ isSignal: true, alias: "mono", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
|
|
2526
|
+
}, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__text{display:inline-flex;align-items:center;gap:5px}.strct-tag__text--link{color:inherit;text-decoration:none;cursor:pointer}.strct-tag__text--link:hover{text-decoration:underline}.strct-tag--interactive .strct-tag__text{cursor:pointer;border-radius:3px}.strct-tag--interactive:hover{border-color:var(--b3);background:var(--bg-2)}.strct-tag--interactive.strct-tag--accent:hover{border-color:var(--acc)}.strct-tag__text:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-tag--pill{border-radius:var(--radius-full, 999px);padding-inline:10px 5px}.strct-tag--pill:not(:has(.strct-tag__remove)){padding-inline-end:10px}.strct-tag--pill .strct-tag__remove{border-radius:999px}.strct-tag--mono{font-family:var(--mono)}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"] }]
|
|
2527
|
+
}], ctorParameters: () => [], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], activateLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "activateLabel", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], mono: [{ type: i0.Input, args: [{ isSignal: true, alias: "mono", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
|
|
2467
2528
|
|
|
2468
2529
|
/**
|
|
2469
2530
|
* Circular avatar: an image when `src` is set, otherwise initials from `name`.
|
|
@@ -4996,6 +5057,15 @@ class StrctModal {
|
|
|
4996
5057
|
* `dismissible` for lightweight, transient dialogs where quick dismissal is fine.
|
|
4997
5058
|
*/
|
|
4998
5059
|
dismissible = input(false, { ...(ngDevMode ? { debugName: "dismissible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
5060
|
+
/**
|
|
5061
|
+
* Escape closes the dialog. Defaults to `dismissible`; set it on its own for
|
|
5062
|
+
* a window that should close on Escape — nothing is lost — but not on a
|
|
5063
|
+
* stray click outside it. An Escape a focused control already handled
|
|
5064
|
+
* (`defaultPrevented`) is left alone.
|
|
5065
|
+
*/
|
|
5066
|
+
closeOnEscape = input(null, { ...(ngDevMode ? { debugName: "closeOnEscape" } : /* istanbul ignore next */ {}), transform: (v) => (v === null || v === undefined ? null : booleanAttribute(v)) });
|
|
5067
|
+
/** A click on the backdrop closes it. Defaults to `dismissible`. */
|
|
5068
|
+
closeOnBackdrop = input(null, { ...(ngDevMode ? { debugName: "closeOnBackdrop" } : /* istanbul ignore next */ {}), transform: (v) => (v === null || v === undefined ? null : booleanAttribute(v)) });
|
|
4999
5069
|
/** Allow repositioning the dialog by dragging its header (mouse + touch). */
|
|
5000
5070
|
draggable = input(false, { ...(ngDevMode ? { debugName: "draggable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
5001
5071
|
/** Extra class(es) added to the dialog panel — style it from app-global CSS. */
|
|
@@ -5073,12 +5143,17 @@ class StrctModal {
|
|
|
5073
5143
|
// that bubbled up from a child (e.g. a space typed in an input/textarea).
|
|
5074
5144
|
if (event && event.target !== event.currentTarget)
|
|
5075
5145
|
return;
|
|
5076
|
-
if (this.dismissible())
|
|
5146
|
+
if (this.closeOnBackdrop() ?? this.dismissible())
|
|
5077
5147
|
this.close();
|
|
5078
5148
|
}
|
|
5079
|
-
onEscape() {
|
|
5149
|
+
onEscape(event) {
|
|
5150
|
+
// A control that used Escape first keeps it: an IME composition, a
|
|
5151
|
+
// searchbox that clears. Both mark the event handled.
|
|
5152
|
+
if (event?.defaultPrevented)
|
|
5153
|
+
return;
|
|
5080
5154
|
// With several modals open, only the topmost one reacts to Escape.
|
|
5081
|
-
|
|
5155
|
+
const allowed = this.closeOnEscape() ?? this.dismissible();
|
|
5156
|
+
if (this.open() && allowed && isTopmostModal(this))
|
|
5082
5157
|
this.close();
|
|
5083
5158
|
}
|
|
5084
5159
|
/** Wrap Tab focus within the dialog. */
|
|
@@ -5167,7 +5242,7 @@ class StrctModal {
|
|
|
5167
5242
|
(items[0] ?? this.dialog())?.focus();
|
|
5168
5243
|
}
|
|
5169
5244
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5170
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctModal, isStandalone: true, selector: "strct-modal", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, hideFooter: { classPropertyName: "hideFooter", publicName: "hideFooter", isSignal: true, isRequired: false, transformFunction: null }, chromeless: { classPropertyName: "chromeless", publicName: "chromeless", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", closed: "closed" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, queries: [{ propertyName: "lazyContent", first: true, predicate: StrctModalContent, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
5245
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctModal, isStandalone: true, selector: "strct-modal", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, hideFooter: { classPropertyName: "hideFooter", publicName: "hideFooter", isSignal: true, isRequired: false, transformFunction: null }, chromeless: { classPropertyName: "chromeless", publicName: "chromeless", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", closed: "closed" }, host: { listeners: { "document:keydown.escape": "onEscape($event)" } }, queries: [{ propertyName: "lazyContent", first: true, predicate: StrctModalContent, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
5171
5246
|
@if (open()) {
|
|
5172
5247
|
<!-- Backdrop: pointer-only dismiss target. No role/tabindex — keyboard users
|
|
5173
5248
|
dismiss via Escape, and the focus trap makes the backdrop unreachable
|
|
@@ -5288,9 +5363,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
5288
5363
|
</div>
|
|
5289
5364
|
}
|
|
5290
5365
|
`, host: {
|
|
5291
|
-
'(document:keydown.escape)': 'onEscape()',
|
|
5366
|
+
'(document:keydown.escape)': 'onEscape($event)',
|
|
5292
5367
|
}, styles: [".strct-modal__overlay{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:var(--space-5);background:var(--backdrop);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);animation:strct-modal-fade .12s ease}@media(max-width:768px){.strct-modal__overlay{padding:var(--space-3)}}.strct-modal__dialog{width:100%;max-height:calc(100vh - 48px);display:flex;flex-direction:column;background:var(--bg-1);border:1px solid var(--b2);border-radius:var(--radius-xl);box-shadow:var(--shadow-elevated);overflow:hidden;animation:strct-modal-rise .14s ease}.strct-modal__dialog--sm{max-width:min(480px,calc(100vw - 32px))}.strct-modal__dialog--md{max-width:min(640px,calc(100vw - 32px))}.strct-modal__dialog--lg{max-width:min(860px,calc(100vw - 32px))}.strct-modal__dialog--xl{max-width:min(1080px,calc(100vw - 32px))}.strct-modal__head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--b1)}.strct-modal__head--drag{cursor:move;-webkit-user-select:none;user-select:none;touch-action:none}.strct-modal__overlay--glass{background:#00000061;-webkit-backdrop-filter:blur(10px) saturate(1.25);backdrop-filter:blur(10px) saturate(1.25)}.strct-modal__dialog--glass{background:color-mix(in srgb,var(--bg-1) 72%,transparent);-webkit-backdrop-filter:blur(24px) saturate(1.4);backdrop-filter:blur(24px) saturate(1.4)}.strct-modal__dialog--glass .strct-modal__foot{background:color-mix(in srgb,var(--bg-2) 55%,transparent)}.strct-modal__title{font-size:14px;font-weight:600;color:var(--t1)}.strct-modal__close{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer}.strct-modal__close:hover{color:var(--t1);background:var(--bg-3)}.strct-modal__body{padding:var(--space-4);overflow-y:auto;color:var(--t2);font-size:13px}.strct-modal__dialog--chromeless{width:calc(232px + var(--strct-wiz-content-min, 864px) + 2px);max-width:calc(100vw - 32px)}.strct-modal__dialog--chromeless:has(.strct-wiz__layout--aside){width:calc(232px + var(--strct-wiz-content-min, 864px) + 280px + 2px)}.strct-modal__dialog--chromeless .strct-modal__body{padding:0;overflow:hidden;display:flex;flex-direction:column;flex:1;min-height:0}.strct-modal__dialog--chromeless .strct-modal__body>*{flex:1;min-height:0}.strct-modal__foot{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);padding:var(--space-3) var(--space-4);border-top:1px solid var(--b1);background:var(--bg-2)}@keyframes strct-modal-fade{0%{opacity:0}}@keyframes strct-modal-rise{0%{opacity:0;transform:translateY(8px) scale(.98)}}@media(prefers-reduced-motion:reduce){.strct-modal__overlay,.strct-modal__dialog{animation:none}}\n"] }]
|
|
5293
|
-
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], hideFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideFooter", required: false }] }], chromeless: [{ type: i0.Input, args: [{ isSignal: true, alias: "chromeless", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], backdropClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClass", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], lazyContent: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctModalContent), { isSignal: true }] }] } });
|
|
5368
|
+
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], hideFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideFooter", required: false }] }], chromeless: [{ type: i0.Input, args: [{ isSignal: true, alias: "chromeless", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeOnBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdrop", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], backdropClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClass", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], lazyContent: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctModalContent), { isSignal: true }] }] } });
|
|
5294
5369
|
|
|
5295
5370
|
/** Marks the drawer's footer action area: `<ng-container strctDrawerFooter>…`. */
|
|
5296
5371
|
class StrctDrawerFooter {
|
|
@@ -10001,7 +10076,7 @@ class StrctChips {
|
|
|
10001
10076
|
(blur)="commitDraft(); onTouched()"
|
|
10002
10077
|
/>
|
|
10003
10078
|
</div>
|
|
10004
|
-
`, isInline: true, styles: [".strct-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;width:100%;min-height:38px;padding:5px 8px;background:var(--bg-2);border:1px solid var(--b2);border-radius:6px;cursor:text;transition:border-color .14s ease,box-shadow .14s ease}.strct-chips:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-chips__input{flex:1;min-width:80px;border:0;outline:none;background:transparent;font-family:var(--font);font-size:13px;color:var(--t1);padding:3px 2px}.strct-chips__input::placeholder{color:var(--t3)}\n"], dependencies: [{ kind: "component", type: StrctTag, selector: "strct-tag", inputs: ["status", "removable", "disabled", "removeLabel", "activateLabel", "interactive", "shape", "mono"], outputs: ["removed", "activated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
10079
|
+
`, isInline: true, styles: [".strct-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;width:100%;min-height:38px;padding:5px 8px;background:var(--bg-2);border:1px solid var(--b2);border-radius:6px;cursor:text;transition:border-color .14s ease,box-shadow .14s ease}.strct-chips:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-chips__input{flex:1;min-width:80px;border:0;outline:none;background:transparent;font-family:var(--font);font-size:13px;color:var(--t1);padding:3px 2px}.strct-chips__input::placeholder{color:var(--t3)}\n"], dependencies: [{ kind: "component", type: StrctTag, selector: "strct-tag", inputs: ["status", "removable", "disabled", "removeLabel", "activateLabel", "href", "target", "interactive", "shape", "mono"], outputs: ["removed", "activated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
10005
10080
|
}
|
|
10006
10081
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChips, decorators: [{
|
|
10007
10082
|
type: Component,
|
|
@@ -25542,6 +25617,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
25542
25617
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], restoreLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreLabel", required: false }] }], itemTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctWindowDockItem), { ...{ read: TemplateRef }, isSignal: true }] }], restoreMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreMode", required: false }] }], restoreRequest: [{ type: i0.Output, args: ["restoreRequest"] }] } });
|
|
25543
25618
|
|
|
25544
25619
|
/** A card the message carries — an action to approve, a result to read. */
|
|
25620
|
+
/** A quiet row under the bubble — copy, a status, a fold. */
|
|
25621
|
+
class StrctChatMessageActions {
|
|
25622
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChatMessageActions, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
25623
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctChatMessageActions, isStandalone: true, selector: "[strctChatMessageActions]", ngImport: i0 });
|
|
25624
|
+
}
|
|
25625
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChatMessageActions, decorators: [{
|
|
25626
|
+
type: Directive,
|
|
25627
|
+
args: [{ selector: '[strctChatMessageActions]' }]
|
|
25628
|
+
}] });
|
|
25545
25629
|
class StrctChatAttachment {
|
|
25546
25630
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChatAttachment, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
25547
25631
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctChatAttachment, isStandalone: true, selector: "[strctChatAttachment]", host: { classAttribute: "strct-chat__attachment" }, ngImport: i0 });
|
|
@@ -25710,8 +25794,14 @@ class StrctChatMessage {
|
|
|
25710
25794
|
}
|
|
25711
25795
|
</div>
|
|
25712
25796
|
<ng-content select="[strctChatAttachment]" />
|
|
25797
|
+
<!-- Copy, a status ("Stopped", "Model call failed"), a quiet "Used 3
|
|
25798
|
+
tools" fold. It was going into the attachment slot, which the
|
|
25799
|
+
library documents as a card the message carries. -->
|
|
25800
|
+
<div class="strct-msg__actions">
|
|
25801
|
+
<ng-content select="[strctChatMessageActions]" />
|
|
25802
|
+
</div>
|
|
25713
25803
|
</div>
|
|
25714
|
-
`, isInline: true, styles: [".strct-msg{display:flex;align-items:flex-start;gap:var(--space-2);min-width:0}.strct-msg[data-author=user]{flex-direction:row-reverse}.strct-msg[data-author=system]{justify-content:center}.strct-msg__avatar{flex:none}.strct-msg__body{display:flex;flex-direction:column;gap:4px;min-width:0;max-width:80%}.strct-msg[data-author=user] .strct-msg__body{align-items:flex-end}.strct-msg__meta{display:flex;align-items:baseline;gap:6px;font-size:var(--text-sm);color:var(--t3)}.strct-msg__name{font-weight:600}.strct-msg__bubble{padding:var(--space-2) var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);color:var(--t1);font-size:13px;line-height:1.5;min-width:0;overflow-wrap:anywhere}.strct-msg[data-author=user] .strct-msg__bubble{background:var(--acc-s);border-color:var(--acc30)}.strct-msg[data-author=system] .strct-msg__bubble{border:0;background:none;color:var(--t3);font-size:var(--text-sm);text-align:center}.strct-msg__caret{display:inline-block;width:2px;height:1em;margin-inline-start:2px;vertical-align:text-bottom;background:var(--acc);animation:strct-chat-caret 1s steps(2,start) infinite}@keyframes strct-chat-caret{to{opacity:0}}@media(prefers-reduced-motion:reduce){.strct-msg__caret{animation:none}}.strct-chat__attachment{display:block;margin-block-start:4px}\n"], dependencies: [{ kind: "component", type: StrctAvatar, selector: "strct-avatar", inputs: ["icon", "shape", "tone", "src", "name", "size", "status"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
25804
|
+
`, isInline: true, styles: [".strct-msg{display:flex;align-items:flex-start;gap:var(--space-2);min-width:0}.strct-msg[data-author=user]{flex-direction:row-reverse}.strct-msg[data-author=system]{justify-content:center}.strct-msg__avatar{flex:none}.strct-msg__body{display:flex;flex-direction:column;gap:4px;min-width:0;max-width:80%}.strct-msg[data-author=user] .strct-msg__body{align-items:flex-end}.strct-msg__meta{display:flex;align-items:baseline;gap:6px;font-size:var(--text-sm);color:var(--t3)}.strct-msg__name{font-weight:600}.strct-msg__actions:empty{display:none}.strct-msg__actions{display:flex;align-items:center;gap:var(--space-2);margin-block-start:4px;font-size:var(--text-sm);color:var(--t3)}.strct-msg__bubble{padding:var(--space-2) var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);color:var(--t1);font-size:13px;line-height:1.5;min-width:0;overflow-wrap:anywhere}.strct-msg[data-author=user] .strct-msg__bubble{background:var(--acc-s);border-color:var(--acc30)}.strct-msg[data-author=system] .strct-msg__bubble{border:0;background:none;color:var(--t3);font-size:var(--text-sm);text-align:center}.strct-msg__caret{display:inline-block;width:2px;height:1em;margin-inline-start:2px;vertical-align:text-bottom;background:var(--acc);animation:strct-chat-caret 1s steps(2,start) infinite}@keyframes strct-chat-caret{to{opacity:0}}@media(prefers-reduced-motion:reduce){.strct-msg__caret{animation:none}}.strct-chat__attachment{display:block;margin-block-start:4px}\n"], dependencies: [{ kind: "component", type: StrctAvatar, selector: "strct-avatar", inputs: ["icon", "shape", "tone", "src", "name", "size", "status"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
25715
25805
|
}
|
|
25716
25806
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChatMessage, decorators: [{
|
|
25717
25807
|
type: Component,
|
|
@@ -25743,6 +25833,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
25743
25833
|
}
|
|
25744
25834
|
</div>
|
|
25745
25835
|
<ng-content select="[strctChatAttachment]" />
|
|
25836
|
+
<!-- Copy, a status ("Stopped", "Model call failed"), a quiet "Used 3
|
|
25837
|
+
tools" fold. It was going into the attachment slot, which the
|
|
25838
|
+
library documents as a card the message carries. -->
|
|
25839
|
+
<div class="strct-msg__actions">
|
|
25840
|
+
<ng-content select="[strctChatMessageActions]" />
|
|
25841
|
+
</div>
|
|
25746
25842
|
</div>
|
|
25747
25843
|
`, host: {
|
|
25748
25844
|
class: 'strct-msg',
|
|
@@ -25751,7 +25847,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
25751
25847
|
'[attr.aria-label]': 'displayName()',
|
|
25752
25848
|
// A streaming reply is announced when it finishes, not token by token.
|
|
25753
25849
|
'[attr.aria-busy]': 'streaming() ? "true" : null',
|
|
25754
|
-
}, styles: [".strct-msg{display:flex;align-items:flex-start;gap:var(--space-2);min-width:0}.strct-msg[data-author=user]{flex-direction:row-reverse}.strct-msg[data-author=system]{justify-content:center}.strct-msg__avatar{flex:none}.strct-msg__body{display:flex;flex-direction:column;gap:4px;min-width:0;max-width:80%}.strct-msg[data-author=user] .strct-msg__body{align-items:flex-end}.strct-msg__meta{display:flex;align-items:baseline;gap:6px;font-size:var(--text-sm);color:var(--t3)}.strct-msg__name{font-weight:600}.strct-msg__bubble{padding:var(--space-2) var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);color:var(--t1);font-size:13px;line-height:1.5;min-width:0;overflow-wrap:anywhere}.strct-msg[data-author=user] .strct-msg__bubble{background:var(--acc-s);border-color:var(--acc30)}.strct-msg[data-author=system] .strct-msg__bubble{border:0;background:none;color:var(--t3);font-size:var(--text-sm);text-align:center}.strct-msg__caret{display:inline-block;width:2px;height:1em;margin-inline-start:2px;vertical-align:text-bottom;background:var(--acc);animation:strct-chat-caret 1s steps(2,start) infinite}@keyframes strct-chat-caret{to{opacity:0}}@media(prefers-reduced-motion:reduce){.strct-msg__caret{animation:none}}.strct-chat__attachment{display:block;margin-block-start:4px}\n"] }]
|
|
25850
|
+
}, styles: [".strct-msg{display:flex;align-items:flex-start;gap:var(--space-2);min-width:0}.strct-msg[data-author=user]{flex-direction:row-reverse}.strct-msg[data-author=system]{justify-content:center}.strct-msg__avatar{flex:none}.strct-msg__body{display:flex;flex-direction:column;gap:4px;min-width:0;max-width:80%}.strct-msg[data-author=user] .strct-msg__body{align-items:flex-end}.strct-msg__meta{display:flex;align-items:baseline;gap:6px;font-size:var(--text-sm);color:var(--t3)}.strct-msg__name{font-weight:600}.strct-msg__actions:empty{display:none}.strct-msg__actions{display:flex;align-items:center;gap:var(--space-2);margin-block-start:4px;font-size:var(--text-sm);color:var(--t3)}.strct-msg__bubble{padding:var(--space-2) var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);color:var(--t1);font-size:13px;line-height:1.5;min-width:0;overflow-wrap:anywhere}.strct-msg[data-author=user] .strct-msg__bubble{background:var(--acc-s);border-color:var(--acc30)}.strct-msg[data-author=system] .strct-msg__bubble{border:0;background:none;color:var(--t3);font-size:var(--text-sm);text-align:center}.strct-msg__caret{display:inline-block;width:2px;height:1em;margin-inline-start:2px;vertical-align:text-bottom;background:var(--acc);animation:strct-chat-caret 1s steps(2,start) infinite}@keyframes strct-chat-caret{to{opacity:0}}@media(prefers-reduced-motion:reduce){.strct-msg__caret{animation:none}}.strct-chat__attachment{display:block;margin-block-start:4px}\n"] }]
|
|
25755
25851
|
}], propDecorators: { author: [{ type: i0.Input, args: [{ isSignal: true, alias: "author", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], avatarIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarIcon", required: false }] }], streaming: [{ type: i0.Input, args: [{ isSignal: true, alias: "streaming", required: false }] }], time: [{ type: i0.Input, args: [{ isSignal: true, alias: "time", required: false }] }], timeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeFormat", required: false }] }], authorNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorNames", required: false }] }] } });
|
|
25756
25852
|
/**
|
|
25757
25853
|
* The box the user writes in: it grows with the text up to `maxRows`, sends on
|
|
@@ -25775,6 +25871,17 @@ class StrctChatComposer {
|
|
|
25775
25871
|
* while a reply is still streaming. `disabled` stops the typing as well.
|
|
25776
25872
|
*/
|
|
25777
25873
|
sendDisabled = input(false, { ...(ngDevMode ? { debugName: "sendDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
25874
|
+
/**
|
|
25875
|
+
* A reply is streaming: the one button becomes Stop, where every chat the
|
|
25876
|
+
* operators know puts it. It is enabled whatever the draft holds, and Enter
|
|
25877
|
+
* still never sends — the draft stays editable meanwhile.
|
|
25878
|
+
*/
|
|
25879
|
+
busy = input(false, { ...(ngDevMode ? { debugName: "busy" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
25880
|
+
/** What the Stop button is called. */
|
|
25881
|
+
stopLabel = input('Stop', /* @ts-ignore */
|
|
25882
|
+
...(ngDevMode ? [{ debugName: "stopLabel" }] : /* istanbul ignore next */ []));
|
|
25883
|
+
/** The reader asked for the reply to stop. */
|
|
25884
|
+
stop = output();
|
|
25778
25885
|
/** How tall the box grows before it scrolls. */
|
|
25779
25886
|
maxRows = input(8, /* @ts-ignore */
|
|
25780
25887
|
...(ngDevMode ? [{ debugName: "maxRows" }] : /* istanbul ignore next */ []));
|
|
@@ -25807,7 +25914,7 @@ class StrctChatComposer {
|
|
|
25807
25914
|
}
|
|
25808
25915
|
submit() {
|
|
25809
25916
|
const text = this.value().trim();
|
|
25810
|
-
if (!text || this.disabled() || this.sendDisabled())
|
|
25917
|
+
if (!text || this.disabled() || this.sendDisabled() || this.busy())
|
|
25811
25918
|
return;
|
|
25812
25919
|
this.send.emit(text);
|
|
25813
25920
|
this.value.set('');
|
|
@@ -25819,7 +25926,7 @@ class StrctChatComposer {
|
|
|
25819
25926
|
}
|
|
25820
25927
|
}
|
|
25821
25928
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChatComposer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
25822
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
25929
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctChatComposer, isStandalone: true, selector: "strct-chat-composer", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, sendDisabled: { classPropertyName: "sendDisabled", publicName: "sendDisabled", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, stopLabel: { classPropertyName: "stopLabel", publicName: "stopLabel", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, sendLabel: { classPropertyName: "sendLabel", publicName: "sendLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", stop: "stop", send: "send" }, host: { classAttribute: "strct-composer" }, ngImport: i0, template: `
|
|
25823
25930
|
<label class="strct-composer__label" [attr.for]="inputId">{{ label() }}</label>
|
|
25824
25931
|
<div class="strct-composer__box">
|
|
25825
25932
|
<textarea
|
|
@@ -25838,14 +25945,19 @@ class StrctChatComposer {
|
|
|
25838
25945
|
<button
|
|
25839
25946
|
type="button"
|
|
25840
25947
|
class="strct-composer__send"
|
|
25841
|
-
[
|
|
25842
|
-
[
|
|
25843
|
-
|
|
25948
|
+
[class.strct-composer__send--stop]="busy()"
|
|
25949
|
+
[attr.aria-label]="busy() ? stopLabel() : sendLabel()"
|
|
25950
|
+
[disabled]="busy() ? disabled() : disabled() || sendDisabled() || !value().trim()"
|
|
25951
|
+
(click)="busy() ? stop.emit() : submit()"
|
|
25844
25952
|
>
|
|
25845
|
-
|
|
25953
|
+
@if (busy()) {
|
|
25954
|
+
<span class="strct-composer__stopmark" aria-hidden="true"></span>
|
|
25955
|
+
} @else {
|
|
25956
|
+
<strct-icon strictName="arrowUp" [size]="15" [strokeWidth]="1.8" />
|
|
25957
|
+
}
|
|
25846
25958
|
</button>
|
|
25847
25959
|
</div>
|
|
25848
|
-
`, isInline: true, styles: [".strct-composer{display:block}.strct-composer__label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-composer__box{display:flex;align-items:flex-end;gap:4px;padding:4px 4px 4px var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);transition:border-color .14s ease,box-shadow .14s ease}.strct-composer__box:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-composer__input{flex:1;min-width:0;border:0;background:none;resize:none;padding:6px 0;font-family:var(--font);font-size:13px;line-height:20px;color:var(--t1);overflow-y:auto}.strct-composer__input:focus{outline:none}.strct-composer__input::placeholder{color:var(--t3)}.strct-composer__send{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;border:0;border-radius:var(--radius-md);background:var(--acc);color:var(--inv);cursor:pointer}.strct-composer__send:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.strct-composer__send:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
25960
|
+
`, isInline: true, styles: [".strct-composer{display:block}.strct-composer__label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-composer__box{display:flex;align-items:flex-end;gap:4px;padding:4px 4px 4px var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);transition:border-color .14s ease,box-shadow .14s ease}.strct-composer__box:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-composer__input{flex:1;min-width:0;border:0;background:none;resize:none;padding:6px 0;font-family:var(--font);font-size:13px;line-height:20px;color:var(--t1);overflow-y:auto}.strct-composer__input:focus{outline:none}.strct-composer__input::placeholder{color:var(--t3)}.strct-composer__send{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;border:0;border-radius:var(--radius-md);background:var(--acc);color:var(--inv);cursor:pointer}.strct-composer__stopmark{width:10px;height:10px;border-radius:2px;background:currentColor}.strct-composer__send:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.strct-composer__send:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
25849
25961
|
}
|
|
25850
25962
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChatComposer, decorators: [{
|
|
25851
25963
|
type: Component,
|
|
@@ -25868,15 +25980,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
25868
25980
|
<button
|
|
25869
25981
|
type="button"
|
|
25870
25982
|
class="strct-composer__send"
|
|
25871
|
-
[
|
|
25872
|
-
[
|
|
25873
|
-
|
|
25983
|
+
[class.strct-composer__send--stop]="busy()"
|
|
25984
|
+
[attr.aria-label]="busy() ? stopLabel() : sendLabel()"
|
|
25985
|
+
[disabled]="busy() ? disabled() : disabled() || sendDisabled() || !value().trim()"
|
|
25986
|
+
(click)="busy() ? stop.emit() : submit()"
|
|
25874
25987
|
>
|
|
25875
|
-
|
|
25988
|
+
@if (busy()) {
|
|
25989
|
+
<span class="strct-composer__stopmark" aria-hidden="true"></span>
|
|
25990
|
+
} @else {
|
|
25991
|
+
<strct-icon strictName="arrowUp" [size]="15" [strokeWidth]="1.8" />
|
|
25992
|
+
}
|
|
25876
25993
|
</button>
|
|
25877
25994
|
</div>
|
|
25878
|
-
`, host: { class: 'strct-composer' }, styles: [".strct-composer{display:block}.strct-composer__label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-composer__box{display:flex;align-items:flex-end;gap:4px;padding:4px 4px 4px var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);transition:border-color .14s ease,box-shadow .14s ease}.strct-composer__box:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-composer__input{flex:1;min-width:0;border:0;background:none;resize:none;padding:6px 0;font-family:var(--font);font-size:13px;line-height:20px;color:var(--t1);overflow-y:auto}.strct-composer__input:focus{outline:none}.strct-composer__input::placeholder{color:var(--t3)}.strct-composer__send{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;border:0;border-radius:var(--radius-md);background:var(--acc);color:var(--inv);cursor:pointer}.strct-composer__send:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.strct-composer__send:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}\n"] }]
|
|
25879
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], sendDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendDisabled", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], sendLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendLabel", required: false }] }], send: [{ type: i0.Output, args: ["send"] }] } });
|
|
25995
|
+
`, host: { class: 'strct-composer' }, styles: [".strct-composer{display:block}.strct-composer__label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-composer__box{display:flex;align-items:flex-end;gap:4px;padding:4px 4px 4px var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);transition:border-color .14s ease,box-shadow .14s ease}.strct-composer__box:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-composer__input{flex:1;min-width:0;border:0;background:none;resize:none;padding:6px 0;font-family:var(--font);font-size:13px;line-height:20px;color:var(--t1);overflow-y:auto}.strct-composer__input:focus{outline:none}.strct-composer__input::placeholder{color:var(--t3)}.strct-composer__send{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;border:0;border-radius:var(--radius-md);background:var(--acc);color:var(--inv);cursor:pointer}.strct-composer__stopmark{width:10px;height:10px;border-radius:2px;background:currentColor}.strct-composer__send:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.strct-composer__send:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}\n"] }]
|
|
25996
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], sendDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendDisabled", required: false }] }], busy: [{ type: i0.Input, args: [{ isSignal: true, alias: "busy", required: false }] }], stopLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopLabel", required: false }] }], stop: [{ type: i0.Output, args: ["stop"] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], sendLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendLabel", required: false }] }], send: [{ type: i0.Output, args: ["send"] }] } });
|
|
25880
25997
|
let composerCounter = 0;
|
|
25881
25998
|
|
|
25882
25999
|
/**
|
|
@@ -26704,7 +26821,7 @@ class StrctConfirmOutlet {
|
|
|
26704
26821
|
</ng-container>
|
|
26705
26822
|
}
|
|
26706
26823
|
</strct-modal>
|
|
26707
|
-
`, isInline: true, styles: [".strct-confirm__message{margin:0;color:var(--t2)}\n"], dependencies: [{ kind: "component", type: StrctModal, selector: "strct-modal", inputs: ["open", "title", "size", "hideFooter", "chromeless", "closeLabel", "dismissible", "draggable", "panelClass", "backdropClass", "variant"], outputs: ["openChange", "closed"] }, { kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
26824
|
+
`, isInline: true, styles: [".strct-confirm__message{margin:0;color:var(--t2)}\n"], dependencies: [{ kind: "component", type: StrctModal, selector: "strct-modal", inputs: ["open", "title", "size", "hideFooter", "chromeless", "closeLabel", "dismissible", "closeOnEscape", "closeOnBackdrop", "draggable", "panelClass", "backdropClass", "variant"], outputs: ["openChange", "closed"] }, { kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
26708
26825
|
}
|
|
26709
26826
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctConfirmOutlet, decorators: [{
|
|
26710
26827
|
type: Component,
|
|
@@ -28294,6 +28411,1035 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
28294
28411
|
`, host: { class: 'strct-heatmap' }, styles: [".strct-heatmap{display:block}.strct-heatmap__svg{width:100%;display:block}.strct-heatmap__empty{display:flex;align-items:center;justify-content:center;min-height:60px;font-size:12px;color:var(--t3)}.strct-heatmap__label{fill:var(--t3);font-size:10px}.strct-heatmap__label--row{font-family:var(--font)}.strct-heatmap__label--col{font-family:var(--mono);font-variant-numeric:tabular-nums}.strct-heatmap__cell{stroke:var(--bg-1);stroke-width:1}@media(prefers-reduced-motion:no-preference){.strct-heatmap__cell{transition:opacity .12s ease}}.strct-heatmap__cell:hover{opacity:.75}\n"] }]
|
|
28295
28412
|
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], cols: [{ type: i0.Input, args: [{ isSignal: true, alias: "cols", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], colLabelEvery: [{ type: i0.Input, args: [{ isSignal: true, alias: "colLabelEvery", required: false }] }], colLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "colLabel", required: false }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], thresholds: [{ type: i0.Input, args: [{ isSignal: true, alias: "thresholds", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], summaryFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "summaryFormat", required: false }] }], cellHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellHeight", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], rowLabelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowLabelWidth", required: false }] }] } });
|
|
28296
28413
|
|
|
28414
|
+
/**
|
|
28415
|
+
* A Markdown reader that produces plain objects — never HTML.
|
|
28416
|
+
*
|
|
28417
|
+
* A model's reply is Markdown, and an app that reaches for a Markdown library
|
|
28418
|
+
* ends up handing the browser a string of HTML (`innerHTML` plus a sanitiser),
|
|
28419
|
+
* which a sealed, reviewed build cannot accept. This reader returns a tree the
|
|
28420
|
+
* templates draw with ordinary bindings, so every word reaches the page as a
|
|
28421
|
+
* text node and raw HTML is shown as the characters it is.
|
|
28422
|
+
*
|
|
28423
|
+
* It is deliberately a subset of CommonMark + GFM: paragraphs, ATX headings,
|
|
28424
|
+
* fenced code, lists (nested), block quotes, thematic breaks, tables with
|
|
28425
|
+
* alignment, and inline emphasis / strong / strikethrough / code / links /
|
|
28426
|
+
* autolinks. Everything else is text.
|
|
28427
|
+
*
|
|
28428
|
+
* Every loop is bounded, because the input is a remote model's output.
|
|
28429
|
+
*/
|
|
28430
|
+
/** Hard limits, so hostile input costs a known amount of work. */
|
|
28431
|
+
const STRCT_MD_LIMITS = {
|
|
28432
|
+
/** Characters of source read at all. */
|
|
28433
|
+
source: 256 * 1024,
|
|
28434
|
+
/** Lines read at all. */
|
|
28435
|
+
lines: 20000,
|
|
28436
|
+
/** How deep lists and quotes may nest. */
|
|
28437
|
+
depth: 8,
|
|
28438
|
+
/** Inline delimiter runs considered per text span. */
|
|
28439
|
+
delimiters: 2000,
|
|
28440
|
+
};
|
|
28441
|
+
const RULE = /^ {0,3}((\*\s*){3,}|(-\s*){3,}|(_\s*){3,})$/;
|
|
28442
|
+
const ATX = /^ {0,3}(#{1,6})\s+(.*?)\s*#*\s*$/;
|
|
28443
|
+
const FENCE = /^ {0,3}(`{3,}|~{3,})\s*([^`]*)$/;
|
|
28444
|
+
const UL = /^(\s*)([-*+])\s+(.*)$/;
|
|
28445
|
+
const OL = /^(\s*)(\d{1,9})[.)]\s+(.*)$/;
|
|
28446
|
+
const QUOTE = /^ {0,3}>\s?(.*)$/;
|
|
28447
|
+
const TABLE_DELIM = /^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/;
|
|
28448
|
+
/**
|
|
28449
|
+
* Read Markdown into blocks.
|
|
28450
|
+
*
|
|
28451
|
+
* `streaming` says the source may be cut mid-token: an unterminated fence is
|
|
28452
|
+
* still a code block, so a reply that streams code looks like code from its
|
|
28453
|
+
* first line rather than flashing as a paragraph and then becoming one.
|
|
28454
|
+
*/
|
|
28455
|
+
function strctParseMarkdown(source, options = {}) {
|
|
28456
|
+
const text = source.length > STRCT_MD_LIMITS.source ? source.slice(0, STRCT_MD_LIMITS.source) : source;
|
|
28457
|
+
const lines = text.replace(/\r\n?/g, '\n').split('\n').slice(0, STRCT_MD_LIMITS.lines);
|
|
28458
|
+
return parseBlocks(lines, 0, options);
|
|
28459
|
+
}
|
|
28460
|
+
function parseBlocks(lines, depth, options) {
|
|
28461
|
+
const out = [];
|
|
28462
|
+
let i = 0;
|
|
28463
|
+
const paragraph = [];
|
|
28464
|
+
const flushParagraph = () => {
|
|
28465
|
+
if (!paragraph.length)
|
|
28466
|
+
return;
|
|
28467
|
+
out.push({ kind: 'p', inlines: parseInlines(paragraph.join('\n'), options) });
|
|
28468
|
+
paragraph.length = 0;
|
|
28469
|
+
};
|
|
28470
|
+
while (i < lines.length) {
|
|
28471
|
+
const line = lines[i];
|
|
28472
|
+
// Blank line: ends a paragraph, nothing else.
|
|
28473
|
+
if (!line.trim()) {
|
|
28474
|
+
flushParagraph();
|
|
28475
|
+
i++;
|
|
28476
|
+
continue;
|
|
28477
|
+
}
|
|
28478
|
+
// Fenced code. An unclosed fence is still code while streaming.
|
|
28479
|
+
const fence = FENCE.exec(line);
|
|
28480
|
+
if (fence) {
|
|
28481
|
+
flushParagraph();
|
|
28482
|
+
const marker = fence[1][0];
|
|
28483
|
+
const width = fence[1].length;
|
|
28484
|
+
const lang = fence[2].trim();
|
|
28485
|
+
const body = [];
|
|
28486
|
+
let closed = false;
|
|
28487
|
+
i++;
|
|
28488
|
+
while (i < lines.length) {
|
|
28489
|
+
const candidate = lines[i];
|
|
28490
|
+
const end = new RegExp(`^ {0,3}${marker === '`' ? '`' : '~'}{${width},}\\s*$`).test(candidate);
|
|
28491
|
+
if (end) {
|
|
28492
|
+
closed = true;
|
|
28493
|
+
i++;
|
|
28494
|
+
break;
|
|
28495
|
+
}
|
|
28496
|
+
body.push(candidate);
|
|
28497
|
+
i++;
|
|
28498
|
+
}
|
|
28499
|
+
out.push({ kind: 'code', text: body.join('\n'), lang, closed });
|
|
28500
|
+
continue;
|
|
28501
|
+
}
|
|
28502
|
+
// Thematic break.
|
|
28503
|
+
if (RULE.test(line)) {
|
|
28504
|
+
flushParagraph();
|
|
28505
|
+
out.push({ kind: 'rule' });
|
|
28506
|
+
i++;
|
|
28507
|
+
continue;
|
|
28508
|
+
}
|
|
28509
|
+
// ATX heading.
|
|
28510
|
+
const atx = ATX.exec(line);
|
|
28511
|
+
if (atx) {
|
|
28512
|
+
flushParagraph();
|
|
28513
|
+
out.push({
|
|
28514
|
+
kind: 'heading',
|
|
28515
|
+
level: atx[1].length,
|
|
28516
|
+
inlines: parseInlines(atx[2], options),
|
|
28517
|
+
});
|
|
28518
|
+
i++;
|
|
28519
|
+
continue;
|
|
28520
|
+
}
|
|
28521
|
+
// Block quote: take the run of quoted lines and read them as blocks.
|
|
28522
|
+
const quote = QUOTE.exec(line);
|
|
28523
|
+
if (quote && depth < STRCT_MD_LIMITS.depth) {
|
|
28524
|
+
flushParagraph();
|
|
28525
|
+
const inner = [];
|
|
28526
|
+
while (i < lines.length) {
|
|
28527
|
+
const m = QUOTE.exec(lines[i]);
|
|
28528
|
+
if (m) {
|
|
28529
|
+
inner.push(m[1]);
|
|
28530
|
+
i++;
|
|
28531
|
+
}
|
|
28532
|
+
else if (lines[i].trim() && inner.length) {
|
|
28533
|
+
// A lazy continuation line belongs to the quote's last paragraph.
|
|
28534
|
+
inner.push(lines[i]);
|
|
28535
|
+
i++;
|
|
28536
|
+
}
|
|
28537
|
+
else
|
|
28538
|
+
break;
|
|
28539
|
+
}
|
|
28540
|
+
out.push({ kind: 'quote', blocks: parseBlocks(inner, depth + 1, options) });
|
|
28541
|
+
continue;
|
|
28542
|
+
}
|
|
28543
|
+
// Table: a header row followed by a delimiter row.
|
|
28544
|
+
if (line.includes('|') && i + 1 < lines.length && TABLE_DELIM.test(lines[i + 1])) {
|
|
28545
|
+
flushParagraph();
|
|
28546
|
+
const head = splitRow(lines[i]).map((c) => parseInlines(c, options));
|
|
28547
|
+
const align = splitRow(lines[i + 1]).map(toAlign);
|
|
28548
|
+
const rows = [];
|
|
28549
|
+
i += 2;
|
|
28550
|
+
while (i < lines.length && lines[i].includes('|') && lines[i].trim()) {
|
|
28551
|
+
rows.push(splitRow(lines[i]).map((c) => parseInlines(c, options)));
|
|
28552
|
+
i++;
|
|
28553
|
+
}
|
|
28554
|
+
out.push({ kind: 'table', head, align, rows });
|
|
28555
|
+
continue;
|
|
28556
|
+
}
|
|
28557
|
+
// Lists.
|
|
28558
|
+
const item = UL.exec(line) ?? OL.exec(line);
|
|
28559
|
+
if (item && depth < STRCT_MD_LIMITS.depth) {
|
|
28560
|
+
flushParagraph();
|
|
28561
|
+
const ordered = !UL.test(line);
|
|
28562
|
+
const start = ordered ? Number(OL.exec(line)[2]) : 1;
|
|
28563
|
+
const items = [];
|
|
28564
|
+
const baseIndent = item[1].length;
|
|
28565
|
+
while (i < lines.length) {
|
|
28566
|
+
const m = UL.exec(lines[i]) ?? OL.exec(lines[i]);
|
|
28567
|
+
const sameKind = m && !UL.test(lines[i]) === ordered;
|
|
28568
|
+
if (!m || !sameKind || m[1].length < baseIndent)
|
|
28569
|
+
break;
|
|
28570
|
+
if (m[1].length > baseIndent)
|
|
28571
|
+
break; // a deeper list is the item's own
|
|
28572
|
+
const buffer = [m[3]];
|
|
28573
|
+
i++;
|
|
28574
|
+
// Continuation lines: anything indented past the marker, and blanks
|
|
28575
|
+
// between them, belong to this item.
|
|
28576
|
+
while (i < lines.length) {
|
|
28577
|
+
const next = lines[i];
|
|
28578
|
+
if (!next.trim()) {
|
|
28579
|
+
const after = lines[i + 1] ?? '';
|
|
28580
|
+
if (after.trim() && /^\s{2,}/.test(after)) {
|
|
28581
|
+
buffer.push('');
|
|
28582
|
+
i++;
|
|
28583
|
+
continue;
|
|
28584
|
+
}
|
|
28585
|
+
break;
|
|
28586
|
+
}
|
|
28587
|
+
if (/^\s{2,}/.test(next) && !UL.test(next.slice(baseIndent)) === false) {
|
|
28588
|
+
buffer.push(next.slice(Math.min(baseIndent + 2, next.length - next.trimStart().length)));
|
|
28589
|
+
i++;
|
|
28590
|
+
continue;
|
|
28591
|
+
}
|
|
28592
|
+
if (/^\s{2,}/.test(next)) {
|
|
28593
|
+
buffer.push(next.trimStart());
|
|
28594
|
+
i++;
|
|
28595
|
+
continue;
|
|
28596
|
+
}
|
|
28597
|
+
break;
|
|
28598
|
+
}
|
|
28599
|
+
items.push(parseBlocks(buffer, depth + 1, options));
|
|
28600
|
+
}
|
|
28601
|
+
out.push({ kind: 'list', ordered, start, items });
|
|
28602
|
+
continue;
|
|
28603
|
+
}
|
|
28604
|
+
paragraph.push(line);
|
|
28605
|
+
i++;
|
|
28606
|
+
}
|
|
28607
|
+
flushParagraph();
|
|
28608
|
+
return out;
|
|
28609
|
+
}
|
|
28610
|
+
function splitRow(line) {
|
|
28611
|
+
const trimmed = line.trim().replace(/^\|/, '').replace(/\|$/, '');
|
|
28612
|
+
const cells = [];
|
|
28613
|
+
let cur = '';
|
|
28614
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
28615
|
+
const ch = trimmed[i];
|
|
28616
|
+
if (ch === '\\' && trimmed[i + 1] === '|') {
|
|
28617
|
+
cur += '|';
|
|
28618
|
+
i++;
|
|
28619
|
+
continue;
|
|
28620
|
+
}
|
|
28621
|
+
if (ch === '|') {
|
|
28622
|
+
cells.push(cur.trim());
|
|
28623
|
+
cur = '';
|
|
28624
|
+
continue;
|
|
28625
|
+
}
|
|
28626
|
+
cur += ch;
|
|
28627
|
+
}
|
|
28628
|
+
cells.push(cur.trim());
|
|
28629
|
+
return cells;
|
|
28630
|
+
}
|
|
28631
|
+
function toAlign(cell) {
|
|
28632
|
+
const c = cell.trim();
|
|
28633
|
+
const left = c.startsWith(':');
|
|
28634
|
+
const right = c.endsWith(':');
|
|
28635
|
+
if (left && right)
|
|
28636
|
+
return 'center';
|
|
28637
|
+
if (right)
|
|
28638
|
+
return 'end';
|
|
28639
|
+
if (left)
|
|
28640
|
+
return 'start';
|
|
28641
|
+
return null;
|
|
28642
|
+
}
|
|
28643
|
+
/**
|
|
28644
|
+
* Inline reading. Code spans win over everything (their content is literal),
|
|
28645
|
+
* then links, then the emphasis delimiters — each bounded.
|
|
28646
|
+
*/
|
|
28647
|
+
function parseInlines(source, options = {}) {
|
|
28648
|
+
const out = [];
|
|
28649
|
+
let buf = '';
|
|
28650
|
+
let i = 0;
|
|
28651
|
+
let budget = STRCT_MD_LIMITS.delimiters;
|
|
28652
|
+
const flush = () => {
|
|
28653
|
+
if (!buf)
|
|
28654
|
+
return;
|
|
28655
|
+
out.push(...applyTokens(buf, options.tokenize));
|
|
28656
|
+
buf = '';
|
|
28657
|
+
};
|
|
28658
|
+
while (i < source.length) {
|
|
28659
|
+
const ch = source[i];
|
|
28660
|
+
// A backslash escapes the next punctuation character.
|
|
28661
|
+
if (ch === '\\' && i + 1 < source.length && /[\\`*_{}[\]()#+\-.!|~>]/.test(source[i + 1])) {
|
|
28662
|
+
buf += source[i + 1];
|
|
28663
|
+
i += 2;
|
|
28664
|
+
continue;
|
|
28665
|
+
}
|
|
28666
|
+
// Code span: the longest run of backticks closes it.
|
|
28667
|
+
if (ch === '`') {
|
|
28668
|
+
const run = /^`+/.exec(source.slice(i))[0];
|
|
28669
|
+
const close = source.indexOf(run, i + run.length);
|
|
28670
|
+
if (close !== -1) {
|
|
28671
|
+
flush();
|
|
28672
|
+
out.push({ kind: 'code', text: source.slice(i + run.length, close).trim() });
|
|
28673
|
+
i = close + run.length;
|
|
28674
|
+
continue;
|
|
28675
|
+
}
|
|
28676
|
+
}
|
|
28677
|
+
// Hard break: two spaces at the end of a line, or a backslash.
|
|
28678
|
+
if (ch === '\n') {
|
|
28679
|
+
const hard = buf.endsWith(' ') || buf.endsWith('\\');
|
|
28680
|
+
buf = buf.replace(/( {2,}|\\)$/, '');
|
|
28681
|
+
flush();
|
|
28682
|
+
out.push(hard ? { kind: 'break' } : { kind: 'text', text: ' ' });
|
|
28683
|
+
i++;
|
|
28684
|
+
continue;
|
|
28685
|
+
}
|
|
28686
|
+
// Autolink.
|
|
28687
|
+
if (ch === '<') {
|
|
28688
|
+
const auto = /^<((?:https?:\/\/|mailto:)[^ >]+)>/.exec(source.slice(i));
|
|
28689
|
+
if (auto) {
|
|
28690
|
+
flush();
|
|
28691
|
+
out.push({ kind: 'link', href: auto[1], children: [{ kind: 'text', text: auto[1] }] });
|
|
28692
|
+
i += auto[0].length;
|
|
28693
|
+
continue;
|
|
28694
|
+
}
|
|
28695
|
+
}
|
|
28696
|
+
// Link. An image is read as a link's text — nothing is ever loaded.
|
|
28697
|
+
if ((ch === '[' || (ch === '!' && source[i + 1] === '[')) && budget-- > 0) {
|
|
28698
|
+
const at = ch === '!' ? i + 1 : i;
|
|
28699
|
+
const close = matchBracket(source, at);
|
|
28700
|
+
if (close !== -1 && source[close + 1] === '(') {
|
|
28701
|
+
const end = source.indexOf(')', close + 2);
|
|
28702
|
+
if (end !== -1) {
|
|
28703
|
+
const label = source.slice(at + 1, close);
|
|
28704
|
+
const href = source
|
|
28705
|
+
.slice(close + 2, end)
|
|
28706
|
+
.trim()
|
|
28707
|
+
.split(/\s+/)[0];
|
|
28708
|
+
flush();
|
|
28709
|
+
if (ch === '!') {
|
|
28710
|
+
// An image's alt text is all a reader gets: no request is made.
|
|
28711
|
+
out.push({ kind: 'text', text: label });
|
|
28712
|
+
}
|
|
28713
|
+
else {
|
|
28714
|
+
out.push({ kind: 'link', href, children: parseInlines(label, options) });
|
|
28715
|
+
}
|
|
28716
|
+
i = end + 1;
|
|
28717
|
+
continue;
|
|
28718
|
+
}
|
|
28719
|
+
}
|
|
28720
|
+
}
|
|
28721
|
+
// Emphasis, strong, strikethrough. A delimiter only opens when something
|
|
28722
|
+
// follows it immediately and only closes when something precedes it —
|
|
28723
|
+
// the flanking rule, which is what keeps "2 * 3 * 4" arithmetic.
|
|
28724
|
+
if ((ch === '*' || ch === '_' || ch === '~') && budget-- > 0) {
|
|
28725
|
+
const run = new RegExp(`^\\${ch}+`).exec(source.slice(i))[0];
|
|
28726
|
+
const len = ch === '~' ? (run.length >= 2 ? 2 : 0) : Math.min(run.length, 2);
|
|
28727
|
+
const opens = !/^\s|^$/.test(source.slice(i + run.length, i + run.length + 1) || '');
|
|
28728
|
+
if (len && opens) {
|
|
28729
|
+
const marker = ch.repeat(len);
|
|
28730
|
+
const close = findCloser(source, marker, i + len);
|
|
28731
|
+
if (close !== -1 && close > i + len) {
|
|
28732
|
+
const inner = source.slice(i + len, close);
|
|
28733
|
+
flush();
|
|
28734
|
+
const children = parseInlines(inner, options);
|
|
28735
|
+
out.push(ch === '~'
|
|
28736
|
+
? { kind: 'del', children }
|
|
28737
|
+
: len === 2
|
|
28738
|
+
? { kind: 'strong', children }
|
|
28739
|
+
: { kind: 'em', children });
|
|
28740
|
+
i = close + len;
|
|
28741
|
+
continue;
|
|
28742
|
+
}
|
|
28743
|
+
}
|
|
28744
|
+
}
|
|
28745
|
+
buf += ch;
|
|
28746
|
+
i++;
|
|
28747
|
+
}
|
|
28748
|
+
flush();
|
|
28749
|
+
return out;
|
|
28750
|
+
}
|
|
28751
|
+
/**
|
|
28752
|
+
* The next closing delimiter: one with a non-space before it. An opener with
|
|
28753
|
+
* no such closer is not a delimiter at all, it is the character written.
|
|
28754
|
+
*/
|
|
28755
|
+
function findCloser(source, marker, from) {
|
|
28756
|
+
let at = source.indexOf(marker, from);
|
|
28757
|
+
while (at !== -1) {
|
|
28758
|
+
const before = source[at - 1];
|
|
28759
|
+
if (before && !/\s/.test(before))
|
|
28760
|
+
return at;
|
|
28761
|
+
at = source.indexOf(marker, at + marker.length);
|
|
28762
|
+
}
|
|
28763
|
+
return -1;
|
|
28764
|
+
}
|
|
28765
|
+
/** The index of the `]` matching the `[` at `from`, or -1. */
|
|
28766
|
+
function matchBracket(source, from) {
|
|
28767
|
+
let depth = 0;
|
|
28768
|
+
for (let i = from; i < source.length; i++) {
|
|
28769
|
+
if (source[i] === '\\') {
|
|
28770
|
+
i++;
|
|
28771
|
+
continue;
|
|
28772
|
+
}
|
|
28773
|
+
if (source[i] === '[')
|
|
28774
|
+
depth++;
|
|
28775
|
+
else if (source[i] === ']') {
|
|
28776
|
+
depth--;
|
|
28777
|
+
if (!depth)
|
|
28778
|
+
return i;
|
|
28779
|
+
}
|
|
28780
|
+
}
|
|
28781
|
+
return -1;
|
|
28782
|
+
}
|
|
28783
|
+
/** Hand a run of plain text to the consumer's tokenizer, if it gave one. */
|
|
28784
|
+
function applyTokens(text, tokenize) {
|
|
28785
|
+
if (!tokenize)
|
|
28786
|
+
return [{ kind: 'text', text }];
|
|
28787
|
+
let found;
|
|
28788
|
+
try {
|
|
28789
|
+
found = tokenize(text) ?? [];
|
|
28790
|
+
}
|
|
28791
|
+
catch {
|
|
28792
|
+
return [{ kind: 'text', text }];
|
|
28793
|
+
}
|
|
28794
|
+
const valid = found
|
|
28795
|
+
.filter((t) => t && t.length > 0 && t.start >= 0 && t.start + t.length <= text.length)
|
|
28796
|
+
.sort((a, b) => a.start - b.start);
|
|
28797
|
+
const out = [];
|
|
28798
|
+
let at = 0;
|
|
28799
|
+
for (const t of valid) {
|
|
28800
|
+
if (t.start < at)
|
|
28801
|
+
continue; // overlapping claims are dropped
|
|
28802
|
+
if (t.start > at)
|
|
28803
|
+
out.push({ kind: 'text', text: text.slice(at, t.start) });
|
|
28804
|
+
out.push({
|
|
28805
|
+
kind: 'token',
|
|
28806
|
+
token: t.token,
|
|
28807
|
+
text: text.slice(t.start, t.start + t.length),
|
|
28808
|
+
data: t.data,
|
|
28809
|
+
});
|
|
28810
|
+
at = t.start + t.length;
|
|
28811
|
+
}
|
|
28812
|
+
if (at < text.length)
|
|
28813
|
+
out.push({ kind: 'text', text: text.slice(at) });
|
|
28814
|
+
return out.length ? out : [{ kind: 'text', text }];
|
|
28815
|
+
}
|
|
28816
|
+
/**
|
|
28817
|
+
* What a link may do. Anything that is not plainly safe stays the text the
|
|
28818
|
+
* model wrote: `javascript:`, `data:`, a protocol-relative `//host`, or
|
|
28819
|
+
* anything this does not recognise.
|
|
28820
|
+
*/
|
|
28821
|
+
function strctClassifyHref(href) {
|
|
28822
|
+
const raw = (href ?? '').trim();
|
|
28823
|
+
if (!raw)
|
|
28824
|
+
return null;
|
|
28825
|
+
// Control characters and whitespace inside a URL are a smuggling trick.
|
|
28826
|
+
if (/[\u0000-\u001f\u007f\s]/.test(raw))
|
|
28827
|
+
return null;
|
|
28828
|
+
if (/^https?:\/\/[^/]/i.test(raw))
|
|
28829
|
+
return 'external';
|
|
28830
|
+
if (/^mailto:[^@\s]+@[^@\s]+$/i.test(raw))
|
|
28831
|
+
return 'external';
|
|
28832
|
+
if (raw.startsWith('//'))
|
|
28833
|
+
return null;
|
|
28834
|
+
if (raw.startsWith('/'))
|
|
28835
|
+
return 'internal';
|
|
28836
|
+
return null;
|
|
28837
|
+
}
|
|
28838
|
+
|
|
28839
|
+
/**
|
|
28840
|
+
* A template for a span the consumer claimed through `tokens`, keyed by the
|
|
28841
|
+
* token's kind:
|
|
28842
|
+
*
|
|
28843
|
+
* <ng-template strctMarkdownToken="object" let-text let-data="data">
|
|
28844
|
+
* <strct-tag [href]="data.url">{{ text }}</strct-tag>
|
|
28845
|
+
* </ng-template>
|
|
28846
|
+
*/
|
|
28847
|
+
class StrctMarkdownToken {
|
|
28848
|
+
/** Which token kind this template draws. */
|
|
28849
|
+
strctMarkdownToken = input('', /* @ts-ignore */
|
|
28850
|
+
...(ngDevMode ? [{ debugName: "strctMarkdownToken" }] : /* istanbul ignore next */ []));
|
|
28851
|
+
template = inject(TemplateRef);
|
|
28852
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMarkdownToken, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
28853
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: StrctMarkdownToken, isStandalone: true, selector: "ng-template[strctMarkdownToken]", inputs: { strctMarkdownToken: { classPropertyName: "strctMarkdownToken", publicName: "strctMarkdownToken", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
28854
|
+
}
|
|
28855
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMarkdownToken, decorators: [{
|
|
28856
|
+
type: Directive,
|
|
28857
|
+
args: [{ selector: 'ng-template[strctMarkdownToken]' }]
|
|
28858
|
+
}], propDecorators: { strctMarkdownToken: [{ type: i0.Input, args: [{ isSignal: true, alias: "strctMarkdownToken", required: false }] }] } });
|
|
28859
|
+
/**
|
|
28860
|
+
* Markdown as a tree of components, never as HTML.
|
|
28861
|
+
*
|
|
28862
|
+
* <strct-markdown [source]="reply()" [streaming]="busy()" />
|
|
28863
|
+
*
|
|
28864
|
+
* A model's reply is Markdown: drawn as plain text it leaves tables as rows of
|
|
28865
|
+
* pipes and `**` everywhere, and an app that reaches for a Markdown library
|
|
28866
|
+
* ends up handing the browser HTML — `innerHTML` plus a sanitiser — which a
|
|
28867
|
+
* sealed, reviewed build cannot accept.
|
|
28868
|
+
*
|
|
28869
|
+
* Every word reaches the page as a text node. Raw HTML is shown as the
|
|
28870
|
+
* characters it is. Images are never loaded: an image's alt text is all a
|
|
28871
|
+
* reader gets. A link opens in a new tab only when it is plainly http(s);
|
|
28872
|
+
* an in-app path is handed to `(navigate)`; anything else — `javascript:`,
|
|
28873
|
+
* `data:`, `//host` — stays the text the model wrote.
|
|
28874
|
+
*/
|
|
28875
|
+
class StrctMarkdown {
|
|
28876
|
+
/** The Markdown to read. */
|
|
28877
|
+
source = input('', /* @ts-ignore */
|
|
28878
|
+
...(ngDevMode ? [{ debugName: "source" }] : /* istanbul ignore next */ []));
|
|
28879
|
+
/**
|
|
28880
|
+
* A tree read elsewhere, instead of `source` — how the component draws the
|
|
28881
|
+
* blocks inside a list item or a quote without re-reading them.
|
|
28882
|
+
*/
|
|
28883
|
+
tree = input(null, /* @ts-ignore */
|
|
28884
|
+
...(ngDevMode ? [{ debugName: "tree" }] : /* istanbul ignore next */ []));
|
|
28885
|
+
/**
|
|
28886
|
+
* The reply is still arriving: an unterminated fence is already a code
|
|
28887
|
+
* block, so streamed code does not flash as a paragraph first, and the
|
|
28888
|
+
* caret sits at the end of the last line.
|
|
28889
|
+
*/
|
|
28890
|
+
streaming = input(false, { ...(ngDevMode ? { debugName: "streaming" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
28891
|
+
/**
|
|
28892
|
+
* How far the model's headings are pulled down. A message is a region
|
|
28893
|
+
* inside a dialog, so `#` should not be the page's `h1`: the default of 2
|
|
28894
|
+
* makes it an `h3`.
|
|
28895
|
+
*/
|
|
28896
|
+
headingOffset = input(2, /* @ts-ignore */
|
|
28897
|
+
...(ngDevMode ? [{ debugName: "headingOffset" }] : /* istanbul ignore next */ []));
|
|
28898
|
+
/**
|
|
28899
|
+
* What a link may do, when the default rule is not what the app wants.
|
|
28900
|
+
* Returning `null` leaves the link as text.
|
|
28901
|
+
*/
|
|
28902
|
+
linkPolicy = input(null, /* @ts-ignore */
|
|
28903
|
+
...(ngDevMode ? [{ debugName: "linkPolicy" }] : /* istanbul ignore next */ []));
|
|
28904
|
+
/** Claim runs of plain text — an inventory id becomes an object chip. */
|
|
28905
|
+
tokens = input(null, /* @ts-ignore */
|
|
28906
|
+
...(ngDevMode ? [{ debugName: "tokens" }] : /* istanbul ignore next */ []));
|
|
28907
|
+
/** An in-app link was followed; the consumer routes it. */
|
|
28908
|
+
navigate = output();
|
|
28909
|
+
tokenDefs = contentChildren(StrctMarkdownToken, /* @ts-ignore */
|
|
28910
|
+
...(ngDevMode ? [{ debugName: "tokenDefs" }] : /* istanbul ignore next */ []));
|
|
28911
|
+
blocks = computed(() => {
|
|
28912
|
+
const given = this.tree();
|
|
28913
|
+
if (given)
|
|
28914
|
+
return given;
|
|
28915
|
+
return strctParseMarkdown(this.source(), {
|
|
28916
|
+
streaming: this.streaming(),
|
|
28917
|
+
tokenize: this.tokens() ?? undefined,
|
|
28918
|
+
});
|
|
28919
|
+
}, /* @ts-ignore */
|
|
28920
|
+
...(ngDevMode ? [{ debugName: "blocks" }] : /* istanbul ignore next */ []));
|
|
28921
|
+
level(level) {
|
|
28922
|
+
return Math.min(6, Math.max(1, level + this.headingOffset()));
|
|
28923
|
+
}
|
|
28924
|
+
hrefKind(href) {
|
|
28925
|
+
const own = this.linkPolicy();
|
|
28926
|
+
return own ? own(href) : strctClassifyHref(href);
|
|
28927
|
+
}
|
|
28928
|
+
tokenTemplate(kind) {
|
|
28929
|
+
return this.tokenDefs().find((d) => d.strctMarkdownToken() === kind)?.template ?? null;
|
|
28930
|
+
}
|
|
28931
|
+
/** The caret belongs to the last block, and only while streaming. */
|
|
28932
|
+
caretOn(index) {
|
|
28933
|
+
return this.streaming() && !this.tree() && index === this.blocks().length - 1;
|
|
28934
|
+
}
|
|
28935
|
+
onInternal(event, href) {
|
|
28936
|
+
// A modified click is the browser's — a new tab, a saved link.
|
|
28937
|
+
const e = event;
|
|
28938
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0)
|
|
28939
|
+
return;
|
|
28940
|
+
event.preventDefault();
|
|
28941
|
+
this.navigate.emit(href);
|
|
28942
|
+
}
|
|
28943
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMarkdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
28944
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctMarkdown, isStandalone: true, selector: "strct-markdown", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, streaming: { classPropertyName: "streaming", publicName: "streaming", isSignal: true, isRequired: false, transformFunction: null }, headingOffset: { classPropertyName: "headingOffset", publicName: "headingOffset", isSignal: true, isRequired: false, transformFunction: null }, linkPolicy: { classPropertyName: "linkPolicy", publicName: "linkPolicy", isSignal: true, isRequired: false, transformFunction: null }, tokens: { classPropertyName: "tokens", publicName: "tokens", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { navigate: "navigate" }, host: { classAttribute: "strct-md" }, queries: [{ propertyName: "tokenDefs", predicate: StrctMarkdownToken, isSignal: true }], ngImport: i0, template: `
|
|
28945
|
+
@for (block of blocks(); track $index) {
|
|
28946
|
+
@switch (block.kind) {
|
|
28947
|
+
@case ('p') {
|
|
28948
|
+
<p class="strct-md__p">
|
|
28949
|
+
<ng-container
|
|
28950
|
+
[ngTemplateOutlet]="inlineRun"
|
|
28951
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
28952
|
+
/>
|
|
28953
|
+
@if (caretOn($index)) {
|
|
28954
|
+
<span class="strct-md__caret" aria-hidden="true"></span>
|
|
28955
|
+
}
|
|
28956
|
+
</p>
|
|
28957
|
+
}
|
|
28958
|
+
@case ('heading') {
|
|
28959
|
+
<!-- A message is a region inside a dialog, so the document's own
|
|
28960
|
+
outline is not the model's to set: the offset pulls them down. -->
|
|
28961
|
+
@switch (level(block.level)) {
|
|
28962
|
+
@case (1) {
|
|
28963
|
+
<h1 class="strct-md__h">
|
|
28964
|
+
<ng-container
|
|
28965
|
+
[ngTemplateOutlet]="inlineRun"
|
|
28966
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
28967
|
+
/>
|
|
28968
|
+
</h1>
|
|
28969
|
+
}
|
|
28970
|
+
@case (2) {
|
|
28971
|
+
<h2 class="strct-md__h">
|
|
28972
|
+
<ng-container
|
|
28973
|
+
[ngTemplateOutlet]="inlineRun"
|
|
28974
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
28975
|
+
/>
|
|
28976
|
+
</h2>
|
|
28977
|
+
}
|
|
28978
|
+
@case (3) {
|
|
28979
|
+
<h3 class="strct-md__h">
|
|
28980
|
+
<ng-container
|
|
28981
|
+
[ngTemplateOutlet]="inlineRun"
|
|
28982
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
28983
|
+
/>
|
|
28984
|
+
</h3>
|
|
28985
|
+
}
|
|
28986
|
+
@case (4) {
|
|
28987
|
+
<h4 class="strct-md__h">
|
|
28988
|
+
<ng-container
|
|
28989
|
+
[ngTemplateOutlet]="inlineRun"
|
|
28990
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
28991
|
+
/>
|
|
28992
|
+
</h4>
|
|
28993
|
+
}
|
|
28994
|
+
@case (5) {
|
|
28995
|
+
<h5 class="strct-md__h">
|
|
28996
|
+
<ng-container
|
|
28997
|
+
[ngTemplateOutlet]="inlineRun"
|
|
28998
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
28999
|
+
/>
|
|
29000
|
+
</h5>
|
|
29001
|
+
}
|
|
29002
|
+
@default {
|
|
29003
|
+
<h6 class="strct-md__h">
|
|
29004
|
+
<ng-container
|
|
29005
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29006
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29007
|
+
/>
|
|
29008
|
+
</h6>
|
|
29009
|
+
}
|
|
29010
|
+
}
|
|
29011
|
+
}
|
|
29012
|
+
@case ('code') {
|
|
29013
|
+
<strct-code class="strct-md__code" [code]="block.text" [language]="block.lang" wrap />
|
|
29014
|
+
}
|
|
29015
|
+
@case ('rule') {
|
|
29016
|
+
<hr class="strct-md__rule" />
|
|
29017
|
+
}
|
|
29018
|
+
@case ('quote') {
|
|
29019
|
+
<blockquote class="strct-md__quote">
|
|
29020
|
+
<ng-container
|
|
29021
|
+
[ngTemplateOutlet]="blockRun"
|
|
29022
|
+
[ngTemplateOutletContext]="{ $implicit: block.blocks }"
|
|
29023
|
+
/>
|
|
29024
|
+
</blockquote>
|
|
29025
|
+
}
|
|
29026
|
+
@case ('list') {
|
|
29027
|
+
@if (block.ordered) {
|
|
29028
|
+
<ol class="strct-md__list" [attr.start]="block.start">
|
|
29029
|
+
@for (item of block.items; track $index) {
|
|
29030
|
+
<li>
|
|
29031
|
+
<ng-container
|
|
29032
|
+
[ngTemplateOutlet]="blockRun"
|
|
29033
|
+
[ngTemplateOutletContext]="{ $implicit: item }"
|
|
29034
|
+
/>
|
|
29035
|
+
</li>
|
|
29036
|
+
}
|
|
29037
|
+
</ol>
|
|
29038
|
+
} @else {
|
|
29039
|
+
<ul class="strct-md__list">
|
|
29040
|
+
@for (item of block.items; track $index) {
|
|
29041
|
+
<li>
|
|
29042
|
+
<ng-container
|
|
29043
|
+
[ngTemplateOutlet]="blockRun"
|
|
29044
|
+
[ngTemplateOutletContext]="{ $implicit: item }"
|
|
29045
|
+
/>
|
|
29046
|
+
</li>
|
|
29047
|
+
}
|
|
29048
|
+
</ul>
|
|
29049
|
+
}
|
|
29050
|
+
}
|
|
29051
|
+
@case ('table') {
|
|
29052
|
+
<div class="strct-md__tablewrap">
|
|
29053
|
+
<table class="strct-md__table">
|
|
29054
|
+
<thead>
|
|
29055
|
+
<tr>
|
|
29056
|
+
@for (cell of block.head; track $index) {
|
|
29057
|
+
<th scope="col" [style.text-align]="block.align[$index] ?? 'start'">
|
|
29058
|
+
<ng-container
|
|
29059
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29060
|
+
[ngTemplateOutletContext]="{ $implicit: cell }"
|
|
29061
|
+
/>
|
|
29062
|
+
</th>
|
|
29063
|
+
}
|
|
29064
|
+
</tr>
|
|
29065
|
+
</thead>
|
|
29066
|
+
<tbody>
|
|
29067
|
+
@for (row of block.rows; track $index) {
|
|
29068
|
+
<tr>
|
|
29069
|
+
@for (cell of row; track $index) {
|
|
29070
|
+
<td [style.text-align]="block.align[$index] ?? 'start'">
|
|
29071
|
+
<ng-container
|
|
29072
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29073
|
+
[ngTemplateOutletContext]="{ $implicit: cell }"
|
|
29074
|
+
/>
|
|
29075
|
+
</td>
|
|
29076
|
+
}
|
|
29077
|
+
</tr>
|
|
29078
|
+
}
|
|
29079
|
+
</tbody>
|
|
29080
|
+
</table>
|
|
29081
|
+
</div>
|
|
29082
|
+
}
|
|
29083
|
+
}
|
|
29084
|
+
}
|
|
29085
|
+
|
|
29086
|
+
<!-- Blocks inside a list item or a quote. -->
|
|
29087
|
+
<ng-template #blockRun let-blocks>
|
|
29088
|
+
@for (b of blocks; track $index) {
|
|
29089
|
+
<strct-markdown
|
|
29090
|
+
[tree]="[b]"
|
|
29091
|
+
[headingOffset]="headingOffset()"
|
|
29092
|
+
[linkPolicy]="linkPolicy()"
|
|
29093
|
+
(navigate)="navigate.emit($event)"
|
|
29094
|
+
/>
|
|
29095
|
+
}
|
|
29096
|
+
</ng-template>
|
|
29097
|
+
|
|
29098
|
+
<!-- One run of inline nodes. -->
|
|
29099
|
+
<ng-template #inlineRun let-inlines>
|
|
29100
|
+
@for (node of inlines; track $index) {
|
|
29101
|
+
@switch (node.kind) {
|
|
29102
|
+
@case ('text') {
|
|
29103
|
+
<ng-container>{{ node.text }}</ng-container>
|
|
29104
|
+
}
|
|
29105
|
+
@case ('code') {
|
|
29106
|
+
<code class="strct-md__codespan">{{ node.text }}</code>
|
|
29107
|
+
}
|
|
29108
|
+
@case ('break') {
|
|
29109
|
+
<br />
|
|
29110
|
+
}
|
|
29111
|
+
@case ('strong') {
|
|
29112
|
+
<strong>
|
|
29113
|
+
<ng-container
|
|
29114
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29115
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29116
|
+
/>
|
|
29117
|
+
</strong>
|
|
29118
|
+
}
|
|
29119
|
+
@case ('em') {
|
|
29120
|
+
<em>
|
|
29121
|
+
<ng-container
|
|
29122
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29123
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29124
|
+
/>
|
|
29125
|
+
</em>
|
|
29126
|
+
}
|
|
29127
|
+
@case ('del') {
|
|
29128
|
+
<del>
|
|
29129
|
+
<ng-container
|
|
29130
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29131
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29132
|
+
/>
|
|
29133
|
+
</del>
|
|
29134
|
+
}
|
|
29135
|
+
@case ('token') {
|
|
29136
|
+
@if (tokenTemplate(node.token); as tpl) {
|
|
29137
|
+
<ng-container
|
|
29138
|
+
[ngTemplateOutlet]="tpl"
|
|
29139
|
+
[ngTemplateOutletContext]="{ $implicit: node.text, data: node.data }"
|
|
29140
|
+
/>
|
|
29141
|
+
} @else {
|
|
29142
|
+
<ng-container>{{ node.text }}</ng-container>
|
|
29143
|
+
}
|
|
29144
|
+
}
|
|
29145
|
+
@case ('link') {
|
|
29146
|
+
@switch (hrefKind(node.href)) {
|
|
29147
|
+
@case ('external') {
|
|
29148
|
+
<a
|
|
29149
|
+
class="strct-md__link"
|
|
29150
|
+
[attr.href]="node.href"
|
|
29151
|
+
target="_blank"
|
|
29152
|
+
rel="noopener noreferrer"
|
|
29153
|
+
>
|
|
29154
|
+
<ng-container
|
|
29155
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29156
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29157
|
+
/>
|
|
29158
|
+
<strct-icon
|
|
29159
|
+
class="strct-md__ext"
|
|
29160
|
+
strictName="externalLink"
|
|
29161
|
+
[size]="11"
|
|
29162
|
+
aria-hidden="true"
|
|
29163
|
+
/>
|
|
29164
|
+
</a>
|
|
29165
|
+
}
|
|
29166
|
+
@case ('internal') {
|
|
29167
|
+
<a
|
|
29168
|
+
class="strct-md__link"
|
|
29169
|
+
[attr.href]="node.href"
|
|
29170
|
+
(click)="onInternal($event, node.href)"
|
|
29171
|
+
>
|
|
29172
|
+
<ng-container
|
|
29173
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29174
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29175
|
+
/>
|
|
29176
|
+
</a>
|
|
29177
|
+
}
|
|
29178
|
+
@default {
|
|
29179
|
+
<!-- Not a link we will follow: the characters, as written. -->
|
|
29180
|
+
<ng-container
|
|
29181
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29182
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29183
|
+
/>
|
|
29184
|
+
}
|
|
29185
|
+
}
|
|
29186
|
+
}
|
|
29187
|
+
}
|
|
29188
|
+
}
|
|
29189
|
+
</ng-template>
|
|
29190
|
+
`, isInline: true, styles: [".strct-md{display:block;color:var(--t1);font-size:13px;line-height:1.55}.strct-md__p{margin:0 0 var(--space-2)}.strct-md__p:last-child{margin-bottom:0}.strct-md__h{margin:var(--space-3) 0 var(--space-2);font-size:14px;font-weight:600;color:var(--t1)}.strct-md__h:first-child{margin-top:0}.strct-md__list{margin:0 0 var(--space-2);padding-inline-start:20px}.strct-md__list li{margin-block:2px}.strct-md__quote{margin:0 0 var(--space-2);padding-inline-start:var(--space-3);border-inline-start:2px solid var(--b2);color:var(--t2)}.strct-md__rule{border:0;border-block-start:1px solid var(--b1);margin:var(--space-3) 0}.strct-md__codespan{font-family:var(--mono);font-size:.92em;background:var(--bg-2);border-radius:var(--radius-sm);padding:1px 4px}.strct-md__code{margin-block-end:var(--space-2)}.strct-md__link{color:var(--acc)}.strct-md__ext{margin-inline-start:2px;vertical-align:-1px}.strct-md__tablewrap{overflow-x:auto;margin-block-end:var(--space-2)}.strct-md__table{border-collapse:collapse;width:max-content;min-width:100%}.strct-md__table th,.strct-md__table td{border:1px solid var(--b1);padding:4px 8px;text-align:start}.strct-md__table th{background:var(--bg-2);font-weight:600}.strct-md__caret{display:inline-block;width:2px;height:1em;margin-inline-start:2px;vertical-align:-2px;background:var(--acc);animation:strct-md-caret 1s steps(2) infinite}@keyframes strct-md-caret{50%{opacity:0}}@media(prefers-reduced-motion:reduce){.strct-md__caret{animation:none}}\n"], dependencies: [{ kind: "component", type: StrctMarkdown, selector: "strct-markdown", inputs: ["source", "tree", "streaming", "headingOffset", "linkPolicy", "tokens"], outputs: ["navigate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrctCode, selector: "strct-code", inputs: ["code", "title", "language", "copyable", "collapsible", "collapsed", "lineNumbers", "wrap", "maxHeight", "collapseLabel", "expandLabel", "regionLabel"], outputs: ["collapsedChange"] }, { kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
29191
|
+
}
|
|
29192
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMarkdown, decorators: [{
|
|
29193
|
+
type: Component,
|
|
29194
|
+
args: [{ selector: 'strct-markdown', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet, StrctCode, StrctIcon], template: `
|
|
29195
|
+
@for (block of blocks(); track $index) {
|
|
29196
|
+
@switch (block.kind) {
|
|
29197
|
+
@case ('p') {
|
|
29198
|
+
<p class="strct-md__p">
|
|
29199
|
+
<ng-container
|
|
29200
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29201
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29202
|
+
/>
|
|
29203
|
+
@if (caretOn($index)) {
|
|
29204
|
+
<span class="strct-md__caret" aria-hidden="true"></span>
|
|
29205
|
+
}
|
|
29206
|
+
</p>
|
|
29207
|
+
}
|
|
29208
|
+
@case ('heading') {
|
|
29209
|
+
<!-- A message is a region inside a dialog, so the document's own
|
|
29210
|
+
outline is not the model's to set: the offset pulls them down. -->
|
|
29211
|
+
@switch (level(block.level)) {
|
|
29212
|
+
@case (1) {
|
|
29213
|
+
<h1 class="strct-md__h">
|
|
29214
|
+
<ng-container
|
|
29215
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29216
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29217
|
+
/>
|
|
29218
|
+
</h1>
|
|
29219
|
+
}
|
|
29220
|
+
@case (2) {
|
|
29221
|
+
<h2 class="strct-md__h">
|
|
29222
|
+
<ng-container
|
|
29223
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29224
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29225
|
+
/>
|
|
29226
|
+
</h2>
|
|
29227
|
+
}
|
|
29228
|
+
@case (3) {
|
|
29229
|
+
<h3 class="strct-md__h">
|
|
29230
|
+
<ng-container
|
|
29231
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29232
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29233
|
+
/>
|
|
29234
|
+
</h3>
|
|
29235
|
+
}
|
|
29236
|
+
@case (4) {
|
|
29237
|
+
<h4 class="strct-md__h">
|
|
29238
|
+
<ng-container
|
|
29239
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29240
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29241
|
+
/>
|
|
29242
|
+
</h4>
|
|
29243
|
+
}
|
|
29244
|
+
@case (5) {
|
|
29245
|
+
<h5 class="strct-md__h">
|
|
29246
|
+
<ng-container
|
|
29247
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29248
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29249
|
+
/>
|
|
29250
|
+
</h5>
|
|
29251
|
+
}
|
|
29252
|
+
@default {
|
|
29253
|
+
<h6 class="strct-md__h">
|
|
29254
|
+
<ng-container
|
|
29255
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29256
|
+
[ngTemplateOutletContext]="{ $implicit: block.inlines }"
|
|
29257
|
+
/>
|
|
29258
|
+
</h6>
|
|
29259
|
+
}
|
|
29260
|
+
}
|
|
29261
|
+
}
|
|
29262
|
+
@case ('code') {
|
|
29263
|
+
<strct-code class="strct-md__code" [code]="block.text" [language]="block.lang" wrap />
|
|
29264
|
+
}
|
|
29265
|
+
@case ('rule') {
|
|
29266
|
+
<hr class="strct-md__rule" />
|
|
29267
|
+
}
|
|
29268
|
+
@case ('quote') {
|
|
29269
|
+
<blockquote class="strct-md__quote">
|
|
29270
|
+
<ng-container
|
|
29271
|
+
[ngTemplateOutlet]="blockRun"
|
|
29272
|
+
[ngTemplateOutletContext]="{ $implicit: block.blocks }"
|
|
29273
|
+
/>
|
|
29274
|
+
</blockquote>
|
|
29275
|
+
}
|
|
29276
|
+
@case ('list') {
|
|
29277
|
+
@if (block.ordered) {
|
|
29278
|
+
<ol class="strct-md__list" [attr.start]="block.start">
|
|
29279
|
+
@for (item of block.items; track $index) {
|
|
29280
|
+
<li>
|
|
29281
|
+
<ng-container
|
|
29282
|
+
[ngTemplateOutlet]="blockRun"
|
|
29283
|
+
[ngTemplateOutletContext]="{ $implicit: item }"
|
|
29284
|
+
/>
|
|
29285
|
+
</li>
|
|
29286
|
+
}
|
|
29287
|
+
</ol>
|
|
29288
|
+
} @else {
|
|
29289
|
+
<ul class="strct-md__list">
|
|
29290
|
+
@for (item of block.items; track $index) {
|
|
29291
|
+
<li>
|
|
29292
|
+
<ng-container
|
|
29293
|
+
[ngTemplateOutlet]="blockRun"
|
|
29294
|
+
[ngTemplateOutletContext]="{ $implicit: item }"
|
|
29295
|
+
/>
|
|
29296
|
+
</li>
|
|
29297
|
+
}
|
|
29298
|
+
</ul>
|
|
29299
|
+
}
|
|
29300
|
+
}
|
|
29301
|
+
@case ('table') {
|
|
29302
|
+
<div class="strct-md__tablewrap">
|
|
29303
|
+
<table class="strct-md__table">
|
|
29304
|
+
<thead>
|
|
29305
|
+
<tr>
|
|
29306
|
+
@for (cell of block.head; track $index) {
|
|
29307
|
+
<th scope="col" [style.text-align]="block.align[$index] ?? 'start'">
|
|
29308
|
+
<ng-container
|
|
29309
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29310
|
+
[ngTemplateOutletContext]="{ $implicit: cell }"
|
|
29311
|
+
/>
|
|
29312
|
+
</th>
|
|
29313
|
+
}
|
|
29314
|
+
</tr>
|
|
29315
|
+
</thead>
|
|
29316
|
+
<tbody>
|
|
29317
|
+
@for (row of block.rows; track $index) {
|
|
29318
|
+
<tr>
|
|
29319
|
+
@for (cell of row; track $index) {
|
|
29320
|
+
<td [style.text-align]="block.align[$index] ?? 'start'">
|
|
29321
|
+
<ng-container
|
|
29322
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29323
|
+
[ngTemplateOutletContext]="{ $implicit: cell }"
|
|
29324
|
+
/>
|
|
29325
|
+
</td>
|
|
29326
|
+
}
|
|
29327
|
+
</tr>
|
|
29328
|
+
}
|
|
29329
|
+
</tbody>
|
|
29330
|
+
</table>
|
|
29331
|
+
</div>
|
|
29332
|
+
}
|
|
29333
|
+
}
|
|
29334
|
+
}
|
|
29335
|
+
|
|
29336
|
+
<!-- Blocks inside a list item or a quote. -->
|
|
29337
|
+
<ng-template #blockRun let-blocks>
|
|
29338
|
+
@for (b of blocks; track $index) {
|
|
29339
|
+
<strct-markdown
|
|
29340
|
+
[tree]="[b]"
|
|
29341
|
+
[headingOffset]="headingOffset()"
|
|
29342
|
+
[linkPolicy]="linkPolicy()"
|
|
29343
|
+
(navigate)="navigate.emit($event)"
|
|
29344
|
+
/>
|
|
29345
|
+
}
|
|
29346
|
+
</ng-template>
|
|
29347
|
+
|
|
29348
|
+
<!-- One run of inline nodes. -->
|
|
29349
|
+
<ng-template #inlineRun let-inlines>
|
|
29350
|
+
@for (node of inlines; track $index) {
|
|
29351
|
+
@switch (node.kind) {
|
|
29352
|
+
@case ('text') {
|
|
29353
|
+
<ng-container>{{ node.text }}</ng-container>
|
|
29354
|
+
}
|
|
29355
|
+
@case ('code') {
|
|
29356
|
+
<code class="strct-md__codespan">{{ node.text }}</code>
|
|
29357
|
+
}
|
|
29358
|
+
@case ('break') {
|
|
29359
|
+
<br />
|
|
29360
|
+
}
|
|
29361
|
+
@case ('strong') {
|
|
29362
|
+
<strong>
|
|
29363
|
+
<ng-container
|
|
29364
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29365
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29366
|
+
/>
|
|
29367
|
+
</strong>
|
|
29368
|
+
}
|
|
29369
|
+
@case ('em') {
|
|
29370
|
+
<em>
|
|
29371
|
+
<ng-container
|
|
29372
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29373
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29374
|
+
/>
|
|
29375
|
+
</em>
|
|
29376
|
+
}
|
|
29377
|
+
@case ('del') {
|
|
29378
|
+
<del>
|
|
29379
|
+
<ng-container
|
|
29380
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29381
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29382
|
+
/>
|
|
29383
|
+
</del>
|
|
29384
|
+
}
|
|
29385
|
+
@case ('token') {
|
|
29386
|
+
@if (tokenTemplate(node.token); as tpl) {
|
|
29387
|
+
<ng-container
|
|
29388
|
+
[ngTemplateOutlet]="tpl"
|
|
29389
|
+
[ngTemplateOutletContext]="{ $implicit: node.text, data: node.data }"
|
|
29390
|
+
/>
|
|
29391
|
+
} @else {
|
|
29392
|
+
<ng-container>{{ node.text }}</ng-container>
|
|
29393
|
+
}
|
|
29394
|
+
}
|
|
29395
|
+
@case ('link') {
|
|
29396
|
+
@switch (hrefKind(node.href)) {
|
|
29397
|
+
@case ('external') {
|
|
29398
|
+
<a
|
|
29399
|
+
class="strct-md__link"
|
|
29400
|
+
[attr.href]="node.href"
|
|
29401
|
+
target="_blank"
|
|
29402
|
+
rel="noopener noreferrer"
|
|
29403
|
+
>
|
|
29404
|
+
<ng-container
|
|
29405
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29406
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29407
|
+
/>
|
|
29408
|
+
<strct-icon
|
|
29409
|
+
class="strct-md__ext"
|
|
29410
|
+
strictName="externalLink"
|
|
29411
|
+
[size]="11"
|
|
29412
|
+
aria-hidden="true"
|
|
29413
|
+
/>
|
|
29414
|
+
</a>
|
|
29415
|
+
}
|
|
29416
|
+
@case ('internal') {
|
|
29417
|
+
<a
|
|
29418
|
+
class="strct-md__link"
|
|
29419
|
+
[attr.href]="node.href"
|
|
29420
|
+
(click)="onInternal($event, node.href)"
|
|
29421
|
+
>
|
|
29422
|
+
<ng-container
|
|
29423
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29424
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29425
|
+
/>
|
|
29426
|
+
</a>
|
|
29427
|
+
}
|
|
29428
|
+
@default {
|
|
29429
|
+
<!-- Not a link we will follow: the characters, as written. -->
|
|
29430
|
+
<ng-container
|
|
29431
|
+
[ngTemplateOutlet]="inlineRun"
|
|
29432
|
+
[ngTemplateOutletContext]="{ $implicit: node.children }"
|
|
29433
|
+
/>
|
|
29434
|
+
}
|
|
29435
|
+
}
|
|
29436
|
+
}
|
|
29437
|
+
}
|
|
29438
|
+
}
|
|
29439
|
+
</ng-template>
|
|
29440
|
+
`, host: { class: 'strct-md' }, styles: [".strct-md{display:block;color:var(--t1);font-size:13px;line-height:1.55}.strct-md__p{margin:0 0 var(--space-2)}.strct-md__p:last-child{margin-bottom:0}.strct-md__h{margin:var(--space-3) 0 var(--space-2);font-size:14px;font-weight:600;color:var(--t1)}.strct-md__h:first-child{margin-top:0}.strct-md__list{margin:0 0 var(--space-2);padding-inline-start:20px}.strct-md__list li{margin-block:2px}.strct-md__quote{margin:0 0 var(--space-2);padding-inline-start:var(--space-3);border-inline-start:2px solid var(--b2);color:var(--t2)}.strct-md__rule{border:0;border-block-start:1px solid var(--b1);margin:var(--space-3) 0}.strct-md__codespan{font-family:var(--mono);font-size:.92em;background:var(--bg-2);border-radius:var(--radius-sm);padding:1px 4px}.strct-md__code{margin-block-end:var(--space-2)}.strct-md__link{color:var(--acc)}.strct-md__ext{margin-inline-start:2px;vertical-align:-1px}.strct-md__tablewrap{overflow-x:auto;margin-block-end:var(--space-2)}.strct-md__table{border-collapse:collapse;width:max-content;min-width:100%}.strct-md__table th,.strct-md__table td{border:1px solid var(--b1);padding:4px 8px;text-align:start}.strct-md__table th{background:var(--bg-2);font-weight:600}.strct-md__caret{display:inline-block;width:2px;height:1em;margin-inline-start:2px;vertical-align:-2px;background:var(--acc);animation:strct-md-caret 1s steps(2) infinite}@keyframes strct-md-caret{50%{opacity:0}}@media(prefers-reduced-motion:reduce){.strct-md__caret{animation:none}}\n"] }]
|
|
29441
|
+
}], propDecorators: { source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], streaming: [{ type: i0.Input, args: [{ isSignal: true, alias: "streaming", required: false }] }], headingOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingOffset", required: false }] }], linkPolicy: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkPolicy", required: false }] }], tokens: [{ type: i0.Input, args: [{ isSignal: true, alias: "tokens", required: false }] }], navigate: [{ type: i0.Output, args: ["navigate"] }], tokenDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctMarkdownToken), { isSignal: true }] }] } });
|
|
29442
|
+
|
|
28297
29443
|
/**
|
|
28298
29444
|
* Public API surface of the strct UI library.
|
|
28299
29445
|
*/
|
|
@@ -28303,5 +29449,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
28303
29449
|
* Generated bundle index. Do not edit.
|
|
28304
29450
|
*/
|
|
28305
29451
|
|
|
28306
|
-
export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAlertActions, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderLeading, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChange, StrctChart, StrctChatAttachment, StrctChatComposer, StrctChatMessage, StrctChatThread, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctControlDescription, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDetailPaneActions, StrctDetailPaneMeta, StrctDetailPaneTitle, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownItemAction, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFieldValue, StrctFile, StrctFilterBar, StrctFlow, StrctFlowNodeTemplate, StrctFooter, StrctGauge, StrctGroupHeaderDef, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLegend, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLiveIndicator, StrctLogViewer, StrctLogin, StrctMediaFrame, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctQr, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderGroup, StrctReorderHandle, StrctReorderItem, StrctResizeHandle, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctStepAction, StrctSteps, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctTagLeading, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWindow, StrctWindowDock, StrctWindowDockItem, StrctWindowService, StrctWizard, StrctWizardAside, __qrInternals, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctCheckHostDisplay, strctCheckHostInputs, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctQrMatrix, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
29452
|
+
export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_MD_LIMITS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAlertActions, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderLeading, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChange, StrctChart, StrctChatAttachment, StrctChatComposer, StrctChatMessage, StrctChatMessageActions, StrctChatThread, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctControlDescription, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDetailPaneActions, StrctDetailPaneMeta, StrctDetailPaneTitle, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownItemAction, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFieldValue, StrctFile, StrctFilterBar, StrctFlow, StrctFlowNodeTemplate, StrctFooter, StrctGauge, StrctGroupHeaderDef, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLegend, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLiveIndicator, StrctLogViewer, StrctLogin, StrctMarkdown, StrctMarkdownToken, StrctMediaFrame, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctQr, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderGroup, StrctReorderHandle, StrctReorderItem, StrctResizeHandle, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctStepAction, StrctSteps, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctTagLeading, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWindow, StrctWindowDock, StrctWindowDockItem, StrctWindowService, StrctWizard, StrctWizardAside, __qrInternals, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, parseInlines, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctCheckHostDisplay, strctCheckHostInputs, strctClassifyHref, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctParseMarkdown, strctQrMatrix, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
28307
29453
|
//# sourceMappingURL=akcelik-strct.mjs.map
|