@akcelik/strct 4.23.0 → 4.25.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 +774 -41
- package/fesm2022/akcelik-strct.mjs.map +1 -1
- package/package.json +1 -1
- package/types/akcelik-strct.d.ts +111 -4
|
@@ -1515,13 +1515,79 @@ class StrctLogin {
|
|
|
1515
1515
|
...(ngDevMode ? [{ debugName: "maxWidth" }] : /* istanbul ignore next */ []));
|
|
1516
1516
|
/** Enable two-panel split layout. */
|
|
1517
1517
|
split = input(false, { ...(ngDevMode ? { debugName: "split" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1518
|
+
/**
|
|
1519
|
+
* The aside's built-in art: `network` is the node diagram over the glow and
|
|
1520
|
+
* dot grid; `grid` is the glow and grid alone. Palette tokens only, so it
|
|
1521
|
+
* follows every scheme, and it is decorative — hidden from assistive tech.
|
|
1522
|
+
*/
|
|
1523
|
+
art = input('none', /* @ts-ignore */
|
|
1524
|
+
...(ngDevMode ? [{ debugName: "art" }] : /* istanbul ignore next */ []));
|
|
1525
|
+
/** An icon tile beside the product name. */
|
|
1526
|
+
brandIcon = input('', /* @ts-ignore */
|
|
1527
|
+
...(ngDevMode ? [{ debugName: "brandIcon" }] : /* istanbul ignore next */ []));
|
|
1528
|
+
/** The product name, in the aside's brand row. */
|
|
1529
|
+
brandName = input('', /* @ts-ignore */
|
|
1530
|
+
...(ngDevMode ? [{ debugName: "brandName" }] : /* istanbul ignore next */ []));
|
|
1531
|
+
/** The kicker line above the aside's content. */
|
|
1532
|
+
tagline = input('', /* @ts-ignore */
|
|
1533
|
+
...(ngDevMode ? [{ debugName: "tagline" }] : /* istanbul ignore next */ []));
|
|
1534
|
+
/** The network's nodes: x, y, radius and which pulse phase they follow. */
|
|
1535
|
+
NODES = [
|
|
1536
|
+
{ x: 48, y: 96, r: 3, phase: 1 },
|
|
1537
|
+
{ x: 142, y: 158, r: 4.5, phase: 2 },
|
|
1538
|
+
{ x: 262, y: 118, r: 3, phase: 3 },
|
|
1539
|
+
{ x: 104, y: 272, r: 3, phase: 2 },
|
|
1540
|
+
{ x: 224, y: 312, r: 4.5, phase: 3 },
|
|
1541
|
+
{ x: 300, y: 222, r: 3, phase: 1 },
|
|
1542
|
+
];
|
|
1518
1543
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctLogin, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1519
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctLogin, isStandalone: true, selector: "strct-login", inputs: { maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, split: { classPropertyName: "split", publicName: "split", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-login" }, ngImport: i0, template: `
|
|
1544
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctLogin, isStandalone: true, selector: "strct-login", inputs: { maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, split: { classPropertyName: "split", publicName: "split", isSignal: true, isRequired: false, transformFunction: null }, art: { classPropertyName: "art", publicName: "art", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, brandName: { classPropertyName: "brandName", publicName: "brandName", isSignal: true, isRequired: false, transformFunction: null }, tagline: { classPropertyName: "tagline", publicName: "tagline", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-login" }, ngImport: i0, template: `
|
|
1520
1545
|
@if (split()) {
|
|
1521
1546
|
<div class="strct-login__card" [style.max-width.px]="maxWidth()">
|
|
1522
|
-
<aside class="strct-login__aside">
|
|
1547
|
+
<aside class="strct-login__aside" [attr.data-art]="art() === 'none' ? null : art()">
|
|
1548
|
+
@if (art() !== 'none') {
|
|
1549
|
+
<!-- Ambient layers, from palette tokens only, so the art follows
|
|
1550
|
+
every scheme. Decorative: hidden from assistive tech. -->
|
|
1551
|
+
<div class="strct-login__glow strct-login__glow--a" aria-hidden="true"></div>
|
|
1552
|
+
<div class="strct-login__glow strct-login__glow--b" aria-hidden="true"></div>
|
|
1553
|
+
<div class="strct-login__matrix" aria-hidden="true"></div>
|
|
1554
|
+
@if (art() === 'network') {
|
|
1555
|
+
<svg class="strct-login__net" viewBox="0 0 340 430" aria-hidden="true">
|
|
1556
|
+
<path
|
|
1557
|
+
class="strct-login__link"
|
|
1558
|
+
d="M48 96 L142 158 L262 118 M142 158 L104 272 L224 312 L300 222 L262 118"
|
|
1559
|
+
/>
|
|
1560
|
+
@for (n of NODES; track $index) {
|
|
1561
|
+
<circle
|
|
1562
|
+
class="strct-login__node strct-login__node--p{{ n.phase }}"
|
|
1563
|
+
[attr.cx]="n.x"
|
|
1564
|
+
[attr.cy]="n.y"
|
|
1565
|
+
[attr.r]="n.r"
|
|
1566
|
+
/>
|
|
1567
|
+
}
|
|
1568
|
+
</svg>
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1523
1571
|
<div class="strct-login__aside-inner">
|
|
1524
|
-
|
|
1572
|
+
@if (brandIcon() || brandName()) {
|
|
1573
|
+
<div class="strct-login__brand">
|
|
1574
|
+
@if (brandIcon()) {
|
|
1575
|
+
<span class="strct-login__mark">
|
|
1576
|
+
<strct-icon [name]="brandIcon()" [size]="18" [strokeWidth]="1.5" />
|
|
1577
|
+
</span>
|
|
1578
|
+
}
|
|
1579
|
+
@if (brandName()) {
|
|
1580
|
+
<span class="strct-login__brandname">{{ brandName() }}</span>
|
|
1581
|
+
}
|
|
1582
|
+
</div>
|
|
1583
|
+
}
|
|
1584
|
+
<div class="strct-login__asidebody">
|
|
1585
|
+
@if (tagline()) {
|
|
1586
|
+
<div class="strct-login__kicker">{{ tagline() }}</div>
|
|
1587
|
+
}
|
|
1588
|
+
<ng-content select="[strctLoginAside]" />
|
|
1589
|
+
</div>
|
|
1590
|
+
<div class="strct-login__status"><ng-content select="[strctLoginStatus]" /></div>
|
|
1525
1591
|
</div>
|
|
1526
1592
|
</aside>
|
|
1527
1593
|
<div class="strct-login__main"><ng-content select="[strctLoginMain]" /></div>
|
|
@@ -1529,16 +1595,57 @@ class StrctLogin {
|
|
|
1529
1595
|
} @else {
|
|
1530
1596
|
<div class="strct-login__inner" [style.max-width.px]="maxWidth()"><ng-content /></div>
|
|
1531
1597
|
}
|
|
1532
|
-
`, isInline: true, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;padding:34px 36px}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1598
|
+
`, isInline: true, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;gap:var(--space-5);padding:34px 36px}.strct-login__glow,.strct-login__matrix,.strct-login__net{position:absolute;inset:-36px;pointer-events:none}.strct-login__glow{filter:blur(46px)}.strct-login__glow--a{background:radial-gradient(360px 300px at 12% 8%,var(--acc30),transparent 70%)}.strct-login__glow--b{background:radial-gradient(320px 300px at 92% 96%,var(--acc18),transparent 70%)}.strct-login__matrix{background-image:radial-gradient(var(--acc30) 1px,transparent 1.4px);background-size:22px 22px;opacity:.4;-webkit-mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%);mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%)}.strct-login__net{width:calc(100% + 72px);height:calc(100% + 72px)}.strct-login__link{fill:none;stroke:var(--acc30);stroke-width:1}.strct-login__node{fill:var(--acc);opacity:.55}@media(prefers-reduced-motion:no-preference){.strct-login__node{animation:strct-login-pulse 4.5s ease-in-out infinite}.strct-login__node--p2{animation-delay:1.4s}.strct-login__node--p3{animation-delay:2.8s}}@keyframes strct-login-pulse{0%,to{opacity:.35}50%{opacity:.85}}.strct-login__brand{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:10px}.strct-login__mark{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:9px;background:var(--acc-m);border:1px solid var(--acc30);color:var(--acc)}.strct-login__brandname{font-size:13px;font-weight:700;letter-spacing:2px;color:var(--t1)}.strct-login__asidebody{position:relative}.strct-login__kicker{font-size:11.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;margin-block-end:10px;color:var(--acc)}.strct-login__status:empty{display:none}.strct-login__status{position:relative}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\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 });
|
|
1533
1599
|
}
|
|
1534
1600
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctLogin, decorators: [{
|
|
1535
1601
|
type: Component,
|
|
1536
|
-
args: [{ selector: 'strct-login', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
|
|
1602
|
+
args: [{ selector: 'strct-login', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
|
|
1537
1603
|
@if (split()) {
|
|
1538
1604
|
<div class="strct-login__card" [style.max-width.px]="maxWidth()">
|
|
1539
|
-
<aside class="strct-login__aside">
|
|
1605
|
+
<aside class="strct-login__aside" [attr.data-art]="art() === 'none' ? null : art()">
|
|
1606
|
+
@if (art() !== 'none') {
|
|
1607
|
+
<!-- Ambient layers, from palette tokens only, so the art follows
|
|
1608
|
+
every scheme. Decorative: hidden from assistive tech. -->
|
|
1609
|
+
<div class="strct-login__glow strct-login__glow--a" aria-hidden="true"></div>
|
|
1610
|
+
<div class="strct-login__glow strct-login__glow--b" aria-hidden="true"></div>
|
|
1611
|
+
<div class="strct-login__matrix" aria-hidden="true"></div>
|
|
1612
|
+
@if (art() === 'network') {
|
|
1613
|
+
<svg class="strct-login__net" viewBox="0 0 340 430" aria-hidden="true">
|
|
1614
|
+
<path
|
|
1615
|
+
class="strct-login__link"
|
|
1616
|
+
d="M48 96 L142 158 L262 118 M142 158 L104 272 L224 312 L300 222 L262 118"
|
|
1617
|
+
/>
|
|
1618
|
+
@for (n of NODES; track $index) {
|
|
1619
|
+
<circle
|
|
1620
|
+
class="strct-login__node strct-login__node--p{{ n.phase }}"
|
|
1621
|
+
[attr.cx]="n.x"
|
|
1622
|
+
[attr.cy]="n.y"
|
|
1623
|
+
[attr.r]="n.r"
|
|
1624
|
+
/>
|
|
1625
|
+
}
|
|
1626
|
+
</svg>
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1540
1629
|
<div class="strct-login__aside-inner">
|
|
1541
|
-
|
|
1630
|
+
@if (brandIcon() || brandName()) {
|
|
1631
|
+
<div class="strct-login__brand">
|
|
1632
|
+
@if (brandIcon()) {
|
|
1633
|
+
<span class="strct-login__mark">
|
|
1634
|
+
<strct-icon [name]="brandIcon()" [size]="18" [strokeWidth]="1.5" />
|
|
1635
|
+
</span>
|
|
1636
|
+
}
|
|
1637
|
+
@if (brandName()) {
|
|
1638
|
+
<span class="strct-login__brandname">{{ brandName() }}</span>
|
|
1639
|
+
}
|
|
1640
|
+
</div>
|
|
1641
|
+
}
|
|
1642
|
+
<div class="strct-login__asidebody">
|
|
1643
|
+
@if (tagline()) {
|
|
1644
|
+
<div class="strct-login__kicker">{{ tagline() }}</div>
|
|
1645
|
+
}
|
|
1646
|
+
<ng-content select="[strctLoginAside]" />
|
|
1647
|
+
</div>
|
|
1648
|
+
<div class="strct-login__status"><ng-content select="[strctLoginStatus]" /></div>
|
|
1542
1649
|
</div>
|
|
1543
1650
|
</aside>
|
|
1544
1651
|
<div class="strct-login__main"><ng-content select="[strctLoginMain]" /></div>
|
|
@@ -1546,8 +1653,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1546
1653
|
} @else {
|
|
1547
1654
|
<div class="strct-login__inner" [style.max-width.px]="maxWidth()"><ng-content /></div>
|
|
1548
1655
|
}
|
|
1549
|
-
`, host: { class: 'strct-login' }, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;padding:34px 36px}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\n"] }]
|
|
1550
|
-
}], propDecorators: { maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], split: [{ type: i0.Input, args: [{ isSignal: true, alias: "split", required: false }] }] } });
|
|
1656
|
+
`, host: { class: 'strct-login' }, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;gap:var(--space-5);padding:34px 36px}.strct-login__glow,.strct-login__matrix,.strct-login__net{position:absolute;inset:-36px;pointer-events:none}.strct-login__glow{filter:blur(46px)}.strct-login__glow--a{background:radial-gradient(360px 300px at 12% 8%,var(--acc30),transparent 70%)}.strct-login__glow--b{background:radial-gradient(320px 300px at 92% 96%,var(--acc18),transparent 70%)}.strct-login__matrix{background-image:radial-gradient(var(--acc30) 1px,transparent 1.4px);background-size:22px 22px;opacity:.4;-webkit-mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%);mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%)}.strct-login__net{width:calc(100% + 72px);height:calc(100% + 72px)}.strct-login__link{fill:none;stroke:var(--acc30);stroke-width:1}.strct-login__node{fill:var(--acc);opacity:.55}@media(prefers-reduced-motion:no-preference){.strct-login__node{animation:strct-login-pulse 4.5s ease-in-out infinite}.strct-login__node--p2{animation-delay:1.4s}.strct-login__node--p3{animation-delay:2.8s}}@keyframes strct-login-pulse{0%,to{opacity:.35}50%{opacity:.85}}.strct-login__brand{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:10px}.strct-login__mark{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:9px;background:var(--acc-m);border:1px solid var(--acc30);color:var(--acc)}.strct-login__brandname{font-size:13px;font-weight:700;letter-spacing:2px;color:var(--t1)}.strct-login__asidebody{position:relative}.strct-login__kicker{font-size:11.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;margin-block-end:10px;color:var(--acc)}.strct-login__status:empty{display:none}.strct-login__status{position:relative}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\n"] }]
|
|
1657
|
+
}], propDecorators: { maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], split: [{ type: i0.Input, args: [{ isSignal: true, alias: "split", required: false }] }], art: [{ type: i0.Input, args: [{ isSignal: true, alias: "art", required: false }] }], brandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIcon", required: false }] }], brandName: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandName", required: false }] }], tagline: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagline", required: false }] }] } });
|
|
1551
1658
|
|
|
1552
1659
|
/** Marks the breadcrumb row projected above the title. */
|
|
1553
1660
|
class StrctPageHeaderCrumbs {
|
|
@@ -2021,8 +2128,117 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
2021
2128
|
args: [{ selector: 'strct-button-group', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `<ng-content />`, host: { class: 'strct-btn-group', role: 'group' }, styles: [".strct-btn-group{display:inline-flex}.strct-btn-group>.strct-btn{border-radius:0}.strct-btn-group>.strct-btn:not(:first-child){margin-inline-start:-1px}.strct-btn-group>.strct-btn:first-child{border-start-start-radius:var(--radius-md);border-end-start-radius:var(--radius-md)}.strct-btn-group>.strct-btn:last-child{border-start-end-radius:var(--radius-md);border-end-end-radius:var(--radius-md)}.strct-btn-group>.strct-btn:hover,.strct-btn-group>.strct-btn:focus-visible{position:relative;z-index:var(--z-base)}\n"] }]
|
|
2022
2129
|
}] });
|
|
2023
2130
|
|
|
2131
|
+
/**
|
|
2132
|
+
* Dev-mode diagnostics for combinations a component accepts but cannot honour.
|
|
2133
|
+
*
|
|
2134
|
+
* Every message names what was ignored and what to do instead. Keyed: a
|
|
2135
|
+
* condition warns once per page load, not once per change detection.
|
|
2136
|
+
*
|
|
2137
|
+
* Production cost: none, PROVIDED each call site is guarded INLINE with
|
|
2138
|
+
* if (typeof ngDevMode !== 'undefined' && ngDevMode) { … }
|
|
2139
|
+
* Production builds define `ngDevMode` as false, and the minifier then drops
|
|
2140
|
+
* the whole block — messages included. A helper function returning that same
|
|
2141
|
+
* expression would NOT be folded across the call, so the check and its
|
|
2142
|
+
* strings would ship; that is why no such helper exists here.
|
|
2143
|
+
*/
|
|
2144
|
+
const warned = new Set();
|
|
2145
|
+
function strctDevWarn(key, message) {
|
|
2146
|
+
if (typeof ngDevMode === 'undefined' || !ngDevMode || warned.has(key))
|
|
2147
|
+
return;
|
|
2148
|
+
warned.add(key);
|
|
2149
|
+
console.warn(message);
|
|
2150
|
+
}
|
|
2151
|
+
/** Test hook: forget which warnings have fired. Not part of the public API. */
|
|
2152
|
+
function resetStrctDevWarnings() {
|
|
2153
|
+
warned.clear();
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
/**
|
|
2157
|
+
* Dev-mode diagnostics for attributes a component does not have.
|
|
2158
|
+
*
|
|
2159
|
+
* Writing a component the way a sibling component is written must not fail
|
|
2160
|
+
* silently: `<strct-alert variant="warning">` compiles, because a static
|
|
2161
|
+
* attribute is just an HTML attribute to Angular, renders the info-blue
|
|
2162
|
+
* default, and nobody finds out.
|
|
2163
|
+
*
|
|
2164
|
+
* Every call site must guard inline with `ngDevMode`, as `dev-warn` explains —
|
|
2165
|
+
* then production drops the calls, nothing references this module, and the
|
|
2166
|
+
* whole of it (messages included) is tree-shaken away.
|
|
2167
|
+
*/
|
|
2168
|
+
/**
|
|
2169
|
+
* The closed, small list of input names that exist on *other* strct
|
|
2170
|
+
* components. Only these are ever flagged, so ordinary HTML and ARIA
|
|
2171
|
+
* attributes, `class`, `style` and `data-*` are never touched.
|
|
2172
|
+
*/
|
|
2173
|
+
const BORROWED = [
|
|
2174
|
+
'variant',
|
|
2175
|
+
'size',
|
|
2176
|
+
'tone',
|
|
2177
|
+
'status',
|
|
2178
|
+
'type',
|
|
2179
|
+
'dense',
|
|
2180
|
+
'compact',
|
|
2181
|
+
'heading',
|
|
2182
|
+
'label',
|
|
2183
|
+
];
|
|
2184
|
+
/**
|
|
2185
|
+
* Warn about a borrowed input name the component does not have.
|
|
2186
|
+
*
|
|
2187
|
+
* @param host the component's own element
|
|
2188
|
+
* @param selector what to call it in the message, e.g. `strct-alert`
|
|
2189
|
+
* @param owns the component's inputs from that list: name → its values,
|
|
2190
|
+
* used to suggest the right one
|
|
2191
|
+
*/
|
|
2192
|
+
function strctCheckHostInputs(host, selector, owns) {
|
|
2193
|
+
const ownNames = Object.keys(owns);
|
|
2194
|
+
for (const name of BORROWED) {
|
|
2195
|
+
if (!host.hasAttribute(name) || name in owns)
|
|
2196
|
+
continue;
|
|
2197
|
+
// Suggest the input that actually takes the value written, when there is
|
|
2198
|
+
// one — "variant=warning" on an alert means `type`, not `icon`.
|
|
2199
|
+
const written = host.getAttribute(name)?.trim() ?? '';
|
|
2200
|
+
const match = ownNames.find((n) => owns[n]
|
|
2201
|
+
.split(',')
|
|
2202
|
+
.map((v) => v.trim())
|
|
2203
|
+
.includes(written)) ?? (ownNames.length === 1 ? ownNames[0] : null);
|
|
2204
|
+
const hint = match
|
|
2205
|
+
? ` — did you mean "${match}"? (values: ${owns[match]})`
|
|
2206
|
+
: ownNames.length
|
|
2207
|
+
? ` — its inputs are: ${ownNames.map((n) => `"${n}"`).join(', ')}`
|
|
2208
|
+
: '';
|
|
2209
|
+
strctDevWarn(`host-input:${selector}:${name}`, `[strct] <${selector}> has no "${name}" input${hint}. ` +
|
|
2210
|
+
`The attribute was ignored, so the default rendered.`);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Warn when a consumer's `display` overrides the one the component's layout
|
|
2215
|
+
* depends on — the usual way to give a custom element margins, and the usual
|
|
2216
|
+
* way to break a flex host.
|
|
2217
|
+
*/
|
|
2218
|
+
function strctCheckHostDisplay(host, selector, expected) {
|
|
2219
|
+
const actual = getComputedStyle(host).display;
|
|
2220
|
+
if (actual === expected)
|
|
2221
|
+
return;
|
|
2222
|
+
strctDevWarn(`host-display:${selector}`, `[strct] <${selector}> needs display: ${expected}, but it computes to ${actual}. ` +
|
|
2223
|
+
`Wrap it, or set the margin on a wrapper, rather than changing its display.`);
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2024
2226
|
/** Small inline status pill: `<strct-badge status="success">Active</strct-badge>`. */
|
|
2025
2227
|
class StrctBadge {
|
|
2228
|
+
hostEl = inject(ElementRef);
|
|
2229
|
+
constructor() {
|
|
2230
|
+
// Dev-only: writing this component the way a sibling is written must not
|
|
2231
|
+
// fail silently. Guarded inline, so production drops the call — and with it
|
|
2232
|
+
// the whole diagnostics module.
|
|
2233
|
+
afterNextRender(() => {
|
|
2234
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
2235
|
+
const el = this.hostEl.nativeElement;
|
|
2236
|
+
strctCheckHostInputs(el, 'strct-badge', {
|
|
2237
|
+
status: 'neutral, accent, success, warning, critical',
|
|
2238
|
+
});
|
|
2239
|
+
}
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2026
2242
|
/** Visual status color. */
|
|
2027
2243
|
status = input('neutral', /* @ts-ignore */
|
|
2028
2244
|
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
@@ -2043,7 +2259,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
2043
2259
|
'[class.strct-badge--critical]': "status() === 'critical'",
|
|
2044
2260
|
'[class.strct-badge--solid]': 'solid()',
|
|
2045
2261
|
}, styles: [".strct-badge{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:600;line-height:1;letter-spacing:.2px;padding-block:3px;padding-inline:9px 7px;border-radius:var(--radius-sm);white-space:nowrap;color:var(--t2);background:transparent;border:1px solid var(--b3);border-inline-start-width:3px}.strct-badge--accent{color:var(--acc);border-color:var(--acc30)}.strct-badge--success{color:var(--success);border-color:var(--success)}.strct-badge--warning{color:var(--warning);border-color:var(--warning)}.strct-badge--critical{color:var(--critical);border-color:var(--critical)}.strct-badge--solid{color:var(--t1);background:var(--bg-a);border-color:transparent;border-inline-start-width:1px;padding-inline-start:7px}.strct-badge--solid.strct-badge--accent{background:var(--acc);color:var(--inv)}.strct-badge--solid.strct-badge--success{background:var(--success);color:var(--inv)}.strct-badge--solid.strct-badge--warning{background:var(--warning);color:var(--inv)}.strct-badge--solid.strct-badge--critical{background:var(--critical);color:var(--inv)}\n"] }]
|
|
2046
|
-
}], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], solid: [{ type: i0.Input, args: [{ isSignal: true, alias: "solid", required: false }] }] } });
|
|
2262
|
+
}], ctorParameters: () => [], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], solid: [{ type: i0.Input, args: [{ isSignal: true, alias: "solid", required: false }] }] } });
|
|
2047
2263
|
|
|
2048
2264
|
/** Content rendered before the tag's text — a status dot, an icon. */
|
|
2049
2265
|
class StrctTagLeading {
|
|
@@ -2059,6 +2275,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
2059
2275
|
* <strct-tag status="accent" removable (removed)="drop()">Frontend</strct-tag>
|
|
2060
2276
|
*/
|
|
2061
2277
|
class StrctTag {
|
|
2278
|
+
hostEl = inject(ElementRef);
|
|
2279
|
+
constructor() {
|
|
2280
|
+
// Dev-only: writing this component the way a sibling is written must not
|
|
2281
|
+
// fail silently. Guarded inline, so production drops the call — and with it
|
|
2282
|
+
// the whole diagnostics module.
|
|
2283
|
+
afterNextRender(() => {
|
|
2284
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
2285
|
+
const el = this.hostEl.nativeElement;
|
|
2286
|
+
strctCheckHostInputs(el, 'strct-tag', {
|
|
2287
|
+
status: 'neutral, accent, success, warning, critical',
|
|
2288
|
+
shape: 'default, pill',
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2291
|
+
});
|
|
2292
|
+
}
|
|
2062
2293
|
/** Visual status color. */
|
|
2063
2294
|
status = input('neutral', /* @ts-ignore */
|
|
2064
2295
|
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
@@ -2151,7 +2382,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
2151
2382
|
'[class.strct-tag--warning]': "status() === 'warning'",
|
|
2152
2383
|
'[class.strct-tag--critical]': "status() === 'critical'",
|
|
2153
2384
|
}, 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"] }]
|
|
2154
|
-
}], 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 }] }], 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"] }] } });
|
|
2385
|
+
}], 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 }] }], 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"] }] } });
|
|
2155
2386
|
|
|
2156
2387
|
/**
|
|
2157
2388
|
* Circular avatar: an image when `src` is set, otherwise initials from `name`.
|
|
@@ -4471,31 +4702,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
4471
4702
|
}, styles: [".strct-tree{display:block}.strct-tree--framed{border:1px solid var(--b2);border-radius:var(--radius-md);background:var(--bg-1);padding:var(--space-1)}.strct-tree[style*=max-height]{overflow:auto}.strct-tree--comfortable .strct-tnode__row{gap:7px;padding:6px 10px;border-radius:6px;font-size:14px}.strct-tree--comfortable .strct-tnode__chevron{margin:-4px;margin-inline-end:-9px}.strct-tree--comfortable .strct-tnode__spacer{width:16px}.strct-tree--comfortable .strct-tnode__children{margin-inline-start:19px}\n"] }]
|
|
4472
4703
|
}], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], framed: [{ type: i0.Input, args: [{ isSignal: true, alias: "framed", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], nodeMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeMenu", required: false }] }], canDrag: [{ type: i0.Input, args: [{ isSignal: true, alias: "canDrag", required: false }] }], canDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "canDrop", required: false }] }], dragExpandDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragExpandDelay", required: false }] }], nodeDrop: [{ type: i0.Output, args: ["nodeDrop"] }], chevronAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "chevronAriaLabel", required: false }] }], nodeActivated: [{ type: i0.Output, args: ["nodeActivated"] }], nodeMenuSelect: [{ type: i0.Output, args: ["nodeMenuSelect"] }], expandedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedIds", required: false }] }, { type: i0.Output, args: ["expandedIdsChange"] }], expandedChange: [{ type: i0.Output, args: ["expandedChange"] }], nodeToggled: [{ type: i0.Output, args: ["nodeToggled"] }], projectedNodes: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctTreeNode), { ...{ descendants: false }, isSignal: true }] }] } });
|
|
4473
4704
|
|
|
4474
|
-
/**
|
|
4475
|
-
* Dev-mode diagnostics for combinations a component accepts but cannot honour.
|
|
4476
|
-
*
|
|
4477
|
-
* Every message names what was ignored and what to do instead. Keyed: a
|
|
4478
|
-
* condition warns once per page load, not once per change detection.
|
|
4479
|
-
*
|
|
4480
|
-
* Production cost: none, PROVIDED each call site is guarded INLINE with
|
|
4481
|
-
* if (typeof ngDevMode !== 'undefined' && ngDevMode) { … }
|
|
4482
|
-
* Production builds define `ngDevMode` as false, and the minifier then drops
|
|
4483
|
-
* the whole block — messages included. A helper function returning that same
|
|
4484
|
-
* expression would NOT be folded across the call, so the check and its
|
|
4485
|
-
* strings would ship; that is why no such helper exists here.
|
|
4486
|
-
*/
|
|
4487
|
-
const warned = new Set();
|
|
4488
|
-
function strctDevWarn(key, message) {
|
|
4489
|
-
if (typeof ngDevMode === 'undefined' || !ngDevMode || warned.has(key))
|
|
4490
|
-
return;
|
|
4491
|
-
warned.add(key);
|
|
4492
|
-
console.warn(message);
|
|
4493
|
-
}
|
|
4494
|
-
/** Test hook: forget which warnings have fired. Not part of the public API. */
|
|
4495
|
-
function resetStrctDevWarnings() {
|
|
4496
|
-
warned.clear();
|
|
4497
|
-
}
|
|
4498
|
-
|
|
4499
4705
|
/**
|
|
4500
4706
|
* Refcounted body scroll-lock shared across any number of simultaneously
|
|
4501
4707
|
* open transient surfaces (modal, drawer …): the first lock hides body
|
|
@@ -8106,12 +8312,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
8106
8312
|
*/
|
|
8107
8313
|
class StrctInput {
|
|
8108
8314
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
8109
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctInput, isStandalone: true, selector: "input[strctInput], textarea[strctInput], select[strctInput]", host: { classAttribute: "strct-control" }, ngImport: i0 });
|
|
8315
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctInput, isStandalone: true, selector: "input[strctInput], textarea[strctInput], select[strctInput], input[strct-input], textarea[strct-input], select[strct-input]", host: { classAttribute: "strct-control" }, ngImport: i0 });
|
|
8110
8316
|
}
|
|
8111
8317
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctInput, decorators: [{
|
|
8112
8318
|
type: Directive,
|
|
8113
8319
|
args: [{
|
|
8114
|
-
|
|
8320
|
+
// Both spellings: `<button strct-button>` is kebab-case, so `strct-input` is
|
|
8321
|
+
// what a consumer writes by analogy — and an unstyled input is the silent
|
|
8322
|
+
// failure that follows. The alias is kinder than a warning and costs nothing.
|
|
8323
|
+
selector: 'input[strctInput], textarea[strctInput], select[strctInput], ' +
|
|
8324
|
+
'input[strct-input], textarea[strct-input], select[strct-input]',
|
|
8115
8325
|
host: { class: 'strct-control' },
|
|
8116
8326
|
}]
|
|
8117
8327
|
}] });
|
|
@@ -12183,6 +12393,22 @@ const DEFAULT_LABEL = {
|
|
|
12183
12393
|
* <strct-status-dot status="critical" size="sm" label="Node unreachable" />
|
|
12184
12394
|
*/
|
|
12185
12395
|
class StrctStatusDot {
|
|
12396
|
+
hostEl = inject(ElementRef);
|
|
12397
|
+
constructor() {
|
|
12398
|
+
// Dev-only: writing this component the way a sibling is written must not
|
|
12399
|
+
// fail silently. Guarded inline, so production drops the call — and with it
|
|
12400
|
+
// the whole diagnostics module.
|
|
12401
|
+
afterNextRender(() => {
|
|
12402
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
12403
|
+
const el = this.hostEl.nativeElement;
|
|
12404
|
+
strctCheckHostInputs(el, 'strct-status-dot', {
|
|
12405
|
+
status: 'neutral, accent, success, warning, critical',
|
|
12406
|
+
size: 'sm, md',
|
|
12407
|
+
label: 'accessible text',
|
|
12408
|
+
});
|
|
12409
|
+
}
|
|
12410
|
+
});
|
|
12411
|
+
}
|
|
12186
12412
|
/** Status tone (canonical vocabulary: OK = 'success', info = 'accent'). */
|
|
12187
12413
|
status = input('neutral', /* @ts-ignore */
|
|
12188
12414
|
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
@@ -12223,7 +12449,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
12223
12449
|
'[class.strct-dot--sm]': "size() === 'sm'",
|
|
12224
12450
|
'[class.strct-dot--pulse]': 'pulse()',
|
|
12225
12451
|
}, styles: [".strct-dot{display:inline-flex;align-items:center;flex:none;line-height:0}.strct-dot__dot{width:10px;height:10px;border-radius:50%;background:var(--t3)}.strct-dot--sm .strct-dot__dot{width:8px;height:8px}.strct-dot--accent .strct-dot__dot{background:var(--acc)}.strct-dot--success .strct-dot__dot{background:var(--success)}.strct-dot--warning .strct-dot__dot{background:var(--warning)}.strct-dot--critical .strct-dot__dot{background:var(--critical)}.strct-dot--pulse .strct-dot__dot{position:relative}.strct-dot--pulse .strct-dot__dot:after{content:\"\";position:absolute;inset:0;border-radius:50%;background:inherit;animation:strct-dot-pulse 1s ease-out infinite}@keyframes strct-dot-pulse{0%{box-shadow:0 0 0 0 currentColor;opacity:.55}to{box-shadow:0 0 0 5px transparent;opacity:0}}.strct-dot--pulse .strct-dot__dot{color:var(--t3)}.strct-dot--pulse.strct-dot--accent .strct-dot__dot{color:var(--acc)}.strct-dot--pulse.strct-dot--success .strct-dot__dot{color:var(--success)}.strct-dot--pulse.strct-dot--warning .strct-dot__dot{color:var(--warning)}.strct-dot--pulse.strct-dot--critical .strct-dot__dot{color:var(--critical)}@media(prefers-reduced-motion:reduce){.strct-dot--pulse .strct-dot__dot:after{animation:none;box-shadow:0 0 0 3px currentColor;opacity:.25}}.strct-dot__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\n"] }]
|
|
12226
|
-
}], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], pulse: [{ type: i0.Input, args: [{ isSignal: true, alias: "pulse", required: false }] }] } });
|
|
12452
|
+
}], ctorParameters: () => [], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], pulse: [{ type: i0.Input, args: [{ isSignal: true, alias: "pulse", required: false }] }] } });
|
|
12227
12453
|
|
|
12228
12454
|
/**
|
|
12229
12455
|
* Compact definition list: aligned `label : value` rows with an optional trailing
|
|
@@ -18899,6 +19125,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
18899
19125
|
|
|
18900
19126
|
/** Inline contextual banner. `<strct-alert type="warning">…</strct-alert>`. */
|
|
18901
19127
|
class StrctAlert {
|
|
19128
|
+
hostEl = inject(ElementRef);
|
|
19129
|
+
constructor() {
|
|
19130
|
+
// Dev-only: writing this component the way a sibling is written must not
|
|
19131
|
+
// fail silently. Guarded inline, so production drops the call — and with it
|
|
19132
|
+
// the whole diagnostics module.
|
|
19133
|
+
afterNextRender(() => {
|
|
19134
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
19135
|
+
const el = this.hostEl.nativeElement;
|
|
19136
|
+
strctCheckHostInputs(el, 'strct-alert', {
|
|
19137
|
+
type: 'info, success, warning, critical',
|
|
19138
|
+
icon: 'an icon name',
|
|
19139
|
+
});
|
|
19140
|
+
strctCheckHostDisplay(el, 'strct-alert', 'block');
|
|
19141
|
+
}
|
|
19142
|
+
});
|
|
19143
|
+
}
|
|
18902
19144
|
/** Visual type / variant. */
|
|
18903
19145
|
type = input('info', /* @ts-ignore */
|
|
18904
19146
|
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
@@ -18978,7 +19220,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
18978
19220
|
'[class.strct-alert--warning]': "type() === 'warning'",
|
|
18979
19221
|
'[class.strct-alert--critical]': "type() === 'critical'",
|
|
18980
19222
|
}, styles: [".strct-alert{display:block;padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);font-size:13px;color:var(--t1);background:var(--bg-1);border:1px solid var(--b2);border-inline-start:3px solid var(--acc)}.strct-alert__row{display:flex;align-items:flex-start;gap:var(--space-2)}.strct-alert strct-icon{color:var(--acc);margin-top:1px;flex-shrink:0}.strct-alert__body{flex:1;color:var(--t1)}.strct-alert__close{flex-shrink:0;display:inline-flex;padding:2px;margin-block-start:-2px;margin-inline-end:-2px;border:0;background:transparent;color:var(--t3);cursor:pointer;border-radius:var(--radius-sm)}.strct-alert__close:hover{color:var(--t1);background:var(--bg-3)}.strct-alert--success{border-inline-start-color:var(--success)}.strct-alert--success strct-icon{color:var(--success)}.strct-alert--warning{border-inline-start-color:var(--warning)}.strct-alert--warning strct-icon{color:var(--warning)}.strct-alert--critical{border-inline-start-color:var(--critical)}.strct-alert--critical strct-icon{color:var(--critical)}\n"] }]
|
|
18981
|
-
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], dismissLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissLabel", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
19223
|
+
}], ctorParameters: () => [], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], dismissLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissLabel", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
18982
19224
|
|
|
18983
19225
|
let tooltipCounter = 0;
|
|
18984
19226
|
/**
|
|
@@ -24050,6 +24292,497 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
24050
24292
|
}], 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 }] }], 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"] }] } });
|
|
24051
24293
|
let composerCounter = 0;
|
|
24052
24294
|
|
|
24295
|
+
/**
|
|
24296
|
+
* A small, dependency-free QR encoder: byte mode, versions 1–10, the four error
|
|
24297
|
+
* correction levels. Enough for an `otpauth://` URI, which is what the library
|
|
24298
|
+
* needs it for — and nothing more, so it stays readable.
|
|
24299
|
+
*
|
|
24300
|
+
* The maths is the standard one (ISO/IEC 18004): the data is split into
|
|
24301
|
+
* codewords, Reed–Solomon parity is appended per block, the result is laid into
|
|
24302
|
+
* the matrix around the function patterns, and each of the eight masks is
|
|
24303
|
+
* scored so the best one is chosen.
|
|
24304
|
+
*/
|
|
24305
|
+
/** Total codewords per version (1–10), index 0 = version 1. */
|
|
24306
|
+
const TOTAL_CODEWORDS = [26, 44, 70, 100, 134, 172, 196, 242, 292, 346];
|
|
24307
|
+
/**
|
|
24308
|
+
* Per version and level: [ec codewords per block, block count group 1,
|
|
24309
|
+
* block count group 2]. Group 2's blocks hold one more data codeword each.
|
|
24310
|
+
*/
|
|
24311
|
+
const ECC_TABLE = {
|
|
24312
|
+
L: [
|
|
24313
|
+
[7, 1, 0],
|
|
24314
|
+
[10, 1, 0],
|
|
24315
|
+
[15, 1, 0],
|
|
24316
|
+
[20, 1, 0],
|
|
24317
|
+
[26, 1, 0],
|
|
24318
|
+
[18, 2, 0],
|
|
24319
|
+
[20, 2, 0],
|
|
24320
|
+
[24, 2, 0],
|
|
24321
|
+
[30, 2, 0],
|
|
24322
|
+
[18, 2, 2],
|
|
24323
|
+
],
|
|
24324
|
+
M: [
|
|
24325
|
+
[10, 1, 0],
|
|
24326
|
+
[16, 1, 0],
|
|
24327
|
+
[26, 1, 0],
|
|
24328
|
+
[18, 2, 0],
|
|
24329
|
+
[24, 2, 0],
|
|
24330
|
+
[16, 4, 0],
|
|
24331
|
+
[18, 4, 0],
|
|
24332
|
+
[22, 2, 2],
|
|
24333
|
+
[22, 3, 2],
|
|
24334
|
+
[26, 4, 1],
|
|
24335
|
+
],
|
|
24336
|
+
Q: [
|
|
24337
|
+
[13, 1, 0],
|
|
24338
|
+
[22, 1, 0],
|
|
24339
|
+
[18, 2, 0],
|
|
24340
|
+
[26, 2, 0],
|
|
24341
|
+
[18, 2, 2],
|
|
24342
|
+
[24, 4, 0],
|
|
24343
|
+
[18, 2, 4],
|
|
24344
|
+
[22, 4, 2],
|
|
24345
|
+
[20, 4, 4],
|
|
24346
|
+
[24, 6, 2],
|
|
24347
|
+
],
|
|
24348
|
+
H: [
|
|
24349
|
+
[17, 1, 0],
|
|
24350
|
+
[28, 1, 0],
|
|
24351
|
+
[22, 2, 0],
|
|
24352
|
+
[16, 4, 0],
|
|
24353
|
+
[22, 2, 2],
|
|
24354
|
+
[28, 4, 0],
|
|
24355
|
+
[26, 4, 1],
|
|
24356
|
+
[26, 4, 2],
|
|
24357
|
+
[24, 4, 4],
|
|
24358
|
+
[28, 6, 2],
|
|
24359
|
+
],
|
|
24360
|
+
};
|
|
24361
|
+
/** Alignment-pattern centres per version (1–10). */
|
|
24362
|
+
const ALIGNMENT = [
|
|
24363
|
+
[],
|
|
24364
|
+
[6, 18],
|
|
24365
|
+
[6, 22],
|
|
24366
|
+
[6, 26],
|
|
24367
|
+
[6, 30],
|
|
24368
|
+
[6, 34],
|
|
24369
|
+
[6, 22, 38],
|
|
24370
|
+
[6, 24, 42],
|
|
24371
|
+
[6, 26, 46],
|
|
24372
|
+
[6, 28, 50],
|
|
24373
|
+
];
|
|
24374
|
+
/** Format-information bits per (level, mask), already masked per the spec. */
|
|
24375
|
+
const FORMAT_BITS = {
|
|
24376
|
+
L: [0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976],
|
|
24377
|
+
M: [0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0],
|
|
24378
|
+
Q: [0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed],
|
|
24379
|
+
H: [0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b],
|
|
24380
|
+
};
|
|
24381
|
+
// ── Galois field (2^8) with the QR primitive polynomial 0x11d ───────────────
|
|
24382
|
+
const EXP = new Uint8Array(512);
|
|
24383
|
+
const LOG = new Uint8Array(256);
|
|
24384
|
+
{
|
|
24385
|
+
let x = 1;
|
|
24386
|
+
for (let i = 0; i < 255; i++) {
|
|
24387
|
+
EXP[i] = x;
|
|
24388
|
+
LOG[x] = i;
|
|
24389
|
+
x <<= 1;
|
|
24390
|
+
if (x & 0x100)
|
|
24391
|
+
x ^= 0x11d;
|
|
24392
|
+
}
|
|
24393
|
+
for (let i = 255; i < 512; i++)
|
|
24394
|
+
EXP[i] = EXP[i - 255];
|
|
24395
|
+
}
|
|
24396
|
+
const mul = (a, b) => (a && b ? EXP[LOG[a] + LOG[b]] : 0);
|
|
24397
|
+
/** The generator polynomial for `degree` error-correction codewords. */
|
|
24398
|
+
function generator(degree) {
|
|
24399
|
+
let poly = [1];
|
|
24400
|
+
for (let i = 0; i < degree; i++) {
|
|
24401
|
+
const next = new Array(poly.length + 1).fill(0);
|
|
24402
|
+
for (let j = 0; j < poly.length; j++) {
|
|
24403
|
+
// Descending coefficients: x * poly keeps the index, α^i * poly shifts.
|
|
24404
|
+
next[j] ^= poly[j];
|
|
24405
|
+
next[j + 1] ^= mul(poly[j], EXP[i]);
|
|
24406
|
+
}
|
|
24407
|
+
poly = next;
|
|
24408
|
+
}
|
|
24409
|
+
return poly;
|
|
24410
|
+
}
|
|
24411
|
+
/** Reed–Solomon parity for one block. */
|
|
24412
|
+
function remainder(data, degree) {
|
|
24413
|
+
const gen = generator(degree);
|
|
24414
|
+
const out = new Array(degree).fill(0);
|
|
24415
|
+
for (const byte of data) {
|
|
24416
|
+
const factor = byte ^ out[0];
|
|
24417
|
+
out.shift();
|
|
24418
|
+
out.push(0);
|
|
24419
|
+
for (let i = 0; i < degree; i++)
|
|
24420
|
+
out[i] ^= mul(gen[i + 1], factor);
|
|
24421
|
+
}
|
|
24422
|
+
return out;
|
|
24423
|
+
}
|
|
24424
|
+
/** The smallest version (1–10) that holds `byteLength` bytes at `ecc`. */
|
|
24425
|
+
function chooseVersion(byteLength, ecc) {
|
|
24426
|
+
for (let version = 1; version <= 10; version++) {
|
|
24427
|
+
const [ecPerBlock, g1, g2] = ECC_TABLE[ecc][version - 1];
|
|
24428
|
+
const dataCodewords = TOTAL_CODEWORDS[version - 1] - ecPerBlock * (g1 + g2);
|
|
24429
|
+
// 4 bits of mode + 8 or 16 bits of length, rounded up to whole codewords.
|
|
24430
|
+
const headerBits = 4 + (version < 10 ? 8 : 16);
|
|
24431
|
+
if (dataCodewords * 8 >= headerBits + byteLength * 8)
|
|
24432
|
+
return version;
|
|
24433
|
+
}
|
|
24434
|
+
throw new Error('strct-qr: the value is too long (versions 1–10, byte mode)');
|
|
24435
|
+
}
|
|
24436
|
+
/** The data codewords: mode, length, the bytes, a terminator, then padding. */
|
|
24437
|
+
function dataCodewords(bytes, version, ecc) {
|
|
24438
|
+
const [ecPerBlock, g1, g2] = ECC_TABLE[ecc][version - 1];
|
|
24439
|
+
const capacity = TOTAL_CODEWORDS[version - 1] - ecPerBlock * (g1 + g2);
|
|
24440
|
+
const bits = [];
|
|
24441
|
+
const push = (value, length) => {
|
|
24442
|
+
for (let i = length - 1; i >= 0; i--)
|
|
24443
|
+
bits.push((value >> i) & 1);
|
|
24444
|
+
};
|
|
24445
|
+
push(0b0100, 4); // byte mode
|
|
24446
|
+
push(bytes.length, version < 10 ? 8 : 16);
|
|
24447
|
+
for (const b of bytes)
|
|
24448
|
+
push(b, 8);
|
|
24449
|
+
push(0, Math.min(4, capacity * 8 - bits.length)); // terminator
|
|
24450
|
+
while (bits.length % 8)
|
|
24451
|
+
bits.push(0);
|
|
24452
|
+
const words = [];
|
|
24453
|
+
for (let i = 0; i < bits.length; i += 8) {
|
|
24454
|
+
words.push(bits.slice(i, i + 8).reduce((acc, bit) => (acc << 1) | bit, 0));
|
|
24455
|
+
}
|
|
24456
|
+
// Alternating pad bytes, as the spec prescribes.
|
|
24457
|
+
for (let i = 0; words.length < capacity; i++)
|
|
24458
|
+
words.push(i % 2 === 0 ? 0xec : 0x11);
|
|
24459
|
+
return words;
|
|
24460
|
+
}
|
|
24461
|
+
/** Interleave the blocks' data and parity, as the spec lays them out. */
|
|
24462
|
+
function interleave(words, version, ecc) {
|
|
24463
|
+
const [ecPerBlock, g1, g2] = ECC_TABLE[ecc][version - 1];
|
|
24464
|
+
const blocks = g1 + g2;
|
|
24465
|
+
const shortLen = Math.floor(words.length / blocks);
|
|
24466
|
+
const data = [];
|
|
24467
|
+
const parity = [];
|
|
24468
|
+
let at = 0;
|
|
24469
|
+
for (let i = 0; i < blocks; i++) {
|
|
24470
|
+
const len = i < g1 ? shortLen : shortLen + 1;
|
|
24471
|
+
const block = words.slice(at, at + len);
|
|
24472
|
+
at += len;
|
|
24473
|
+
data.push(block);
|
|
24474
|
+
parity.push(remainder(block, ecPerBlock));
|
|
24475
|
+
}
|
|
24476
|
+
const out = [];
|
|
24477
|
+
for (let i = 0; i < shortLen + 1; i++) {
|
|
24478
|
+
for (const block of data)
|
|
24479
|
+
if (i < block.length)
|
|
24480
|
+
out.push(block[i]);
|
|
24481
|
+
}
|
|
24482
|
+
for (let i = 0; i < ecPerBlock; i++)
|
|
24483
|
+
for (const block of parity)
|
|
24484
|
+
out.push(block[i]);
|
|
24485
|
+
return out;
|
|
24486
|
+
}
|
|
24487
|
+
var Cell;
|
|
24488
|
+
(function (Cell) {
|
|
24489
|
+
Cell[Cell["Empty"] = -1] = "Empty";
|
|
24490
|
+
Cell[Cell["Light"] = 0] = "Light";
|
|
24491
|
+
Cell[Cell["Dark"] = 1] = "Dark";
|
|
24492
|
+
})(Cell || (Cell = {}));
|
|
24493
|
+
/** Draw the finder, timing and alignment patterns, and reserve the format area. */
|
|
24494
|
+
function functionPatterns(size, version) {
|
|
24495
|
+
const m = Array.from({ length: size }, () => new Array(size).fill(Cell.Empty));
|
|
24496
|
+
const finder = (r0, c0) => {
|
|
24497
|
+
for (let dr = -1; dr <= 7; dr++) {
|
|
24498
|
+
for (let dc = -1; dc <= 7; dc++) {
|
|
24499
|
+
const r = r0 + dr;
|
|
24500
|
+
const c = c0 + dc;
|
|
24501
|
+
if (r < 0 || r >= size || c < 0 || c >= size)
|
|
24502
|
+
continue;
|
|
24503
|
+
const inner = Math.max(Math.abs(dr - 3), Math.abs(dc - 3));
|
|
24504
|
+
m[r][c] = inner === 2 || inner > 3 ? Cell.Light : Cell.Dark;
|
|
24505
|
+
}
|
|
24506
|
+
}
|
|
24507
|
+
};
|
|
24508
|
+
finder(0, 0);
|
|
24509
|
+
finder(0, size - 7);
|
|
24510
|
+
finder(size - 7, 0);
|
|
24511
|
+
for (let i = 8; i < size - 8; i++) {
|
|
24512
|
+
m[6][i] = m[i][6] = i % 2 === 0 ? Cell.Dark : Cell.Light;
|
|
24513
|
+
}
|
|
24514
|
+
const centres = ALIGNMENT[version - 1];
|
|
24515
|
+
for (const r of centres) {
|
|
24516
|
+
for (const c of centres) {
|
|
24517
|
+
// Not over a finder pattern.
|
|
24518
|
+
if ((r === 6 && c === 6) || (r === 6 && c === size - 7) || (r === size - 7 && c === 6))
|
|
24519
|
+
continue;
|
|
24520
|
+
for (let dr = -2; dr <= 2; dr++) {
|
|
24521
|
+
for (let dc = -2; dc <= 2; dc++) {
|
|
24522
|
+
m[r + dr][c + dc] = Math.max(Math.abs(dr), Math.abs(dc)) === 1 ? Cell.Light : Cell.Dark;
|
|
24523
|
+
}
|
|
24524
|
+
}
|
|
24525
|
+
}
|
|
24526
|
+
}
|
|
24527
|
+
// The dark module, always set.
|
|
24528
|
+
m[size - 8][8] = Cell.Dark;
|
|
24529
|
+
// Reserve the format areas so the data does not land there.
|
|
24530
|
+
for (let i = 0; i < 9; i++) {
|
|
24531
|
+
if (m[8][i] === Cell.Empty)
|
|
24532
|
+
m[8][i] = Cell.Light;
|
|
24533
|
+
if (m[i][8] === Cell.Empty)
|
|
24534
|
+
m[i][8] = Cell.Light;
|
|
24535
|
+
}
|
|
24536
|
+
for (let i = 0; i < 8; i++) {
|
|
24537
|
+
if (m[8][size - 1 - i] === Cell.Empty)
|
|
24538
|
+
m[8][size - 1 - i] = Cell.Light;
|
|
24539
|
+
if (m[size - 1 - i][8] === Cell.Empty)
|
|
24540
|
+
m[size - 1 - i][8] = Cell.Light;
|
|
24541
|
+
}
|
|
24542
|
+
return m;
|
|
24543
|
+
}
|
|
24544
|
+
const MASKS = [
|
|
24545
|
+
(r, c) => (r + c) % 2 === 0,
|
|
24546
|
+
(r) => r % 2 === 0,
|
|
24547
|
+
(_r, c) => c % 3 === 0,
|
|
24548
|
+
(r, c) => (r + c) % 3 === 0,
|
|
24549
|
+
(r, c) => (Math.floor(r / 2) + Math.floor(c / 3)) % 2 === 0,
|
|
24550
|
+
(r, c) => ((r * c) % 2) + ((r * c) % 3) === 0,
|
|
24551
|
+
(r, c) => (((r * c) % 2) + ((r * c) % 3)) % 2 === 0,
|
|
24552
|
+
(r, c) => (((r + c) % 2) + ((r * c) % 3)) % 2 === 0,
|
|
24553
|
+
];
|
|
24554
|
+
/** The spec's penalty score — lower is better. */
|
|
24555
|
+
function penalty(m) {
|
|
24556
|
+
const size = m.length;
|
|
24557
|
+
let score = 0;
|
|
24558
|
+
const run = (line) => {
|
|
24559
|
+
let last = line[0];
|
|
24560
|
+
let length = 1;
|
|
24561
|
+
for (let i = 1; i < line.length; i++) {
|
|
24562
|
+
if (line[i] === last)
|
|
24563
|
+
length++;
|
|
24564
|
+
else {
|
|
24565
|
+
if (length >= 5)
|
|
24566
|
+
score += 3 + (length - 5);
|
|
24567
|
+
last = line[i];
|
|
24568
|
+
length = 1;
|
|
24569
|
+
}
|
|
24570
|
+
}
|
|
24571
|
+
if (length >= 5)
|
|
24572
|
+
score += 3 + (length - 5);
|
|
24573
|
+
};
|
|
24574
|
+
for (let i = 0; i < size; i++) {
|
|
24575
|
+
run(m[i]);
|
|
24576
|
+
run(m.map((row) => row[i]));
|
|
24577
|
+
}
|
|
24578
|
+
for (let r = 0; r < size - 1; r++) {
|
|
24579
|
+
for (let c = 0; c < size - 1; c++) {
|
|
24580
|
+
const v = m[r][c];
|
|
24581
|
+
if (v === m[r][c + 1] && v === m[r + 1][c] && v === m[r + 1][c + 1])
|
|
24582
|
+
score += 3;
|
|
24583
|
+
}
|
|
24584
|
+
}
|
|
24585
|
+
const pattern = [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0];
|
|
24586
|
+
const hasPattern = (line, at) => pattern.every((bit, i) => line[at + i] === bit);
|
|
24587
|
+
for (let i = 0; i < size; i++) {
|
|
24588
|
+
const row = m[i];
|
|
24589
|
+
const col = m.map((r) => r[i]);
|
|
24590
|
+
for (let j = 0; j + 11 <= size; j++) {
|
|
24591
|
+
if (hasPattern(row, j))
|
|
24592
|
+
score += 40;
|
|
24593
|
+
if (hasPattern(col, j))
|
|
24594
|
+
score += 40;
|
|
24595
|
+
const rRev = [...row].reverse();
|
|
24596
|
+
const cRev = [...col].reverse();
|
|
24597
|
+
if (hasPattern(rRev, j))
|
|
24598
|
+
score += 40;
|
|
24599
|
+
if (hasPattern(cRev, j))
|
|
24600
|
+
score += 40;
|
|
24601
|
+
}
|
|
24602
|
+
}
|
|
24603
|
+
const dark = m.flat().filter((v) => v === Cell.Dark).length;
|
|
24604
|
+
const ratio = (dark * 100) / (size * size);
|
|
24605
|
+
score += Math.floor(Math.abs(ratio - 50) / 5) * 10;
|
|
24606
|
+
return score;
|
|
24607
|
+
}
|
|
24608
|
+
/**
|
|
24609
|
+
* Encode `value` as a QR matrix of booleans (true = dark module), without the
|
|
24610
|
+
* quiet zone — the renderer adds that.
|
|
24611
|
+
*/
|
|
24612
|
+
function strctQrMatrix(value, ecc = 'M') {
|
|
24613
|
+
const bytes = new TextEncoder().encode(value);
|
|
24614
|
+
const version = chooseVersion(bytes.length, ecc);
|
|
24615
|
+
const size = version * 4 + 17;
|
|
24616
|
+
const codewords = interleave(dataCodewords(bytes, version, ecc), version, ecc);
|
|
24617
|
+
const base = functionPatterns(size, version);
|
|
24618
|
+
const reserved = base.map((row) => row.map((v) => v !== Cell.Empty));
|
|
24619
|
+
// Lay the data in the zig-zag, skipping the vertical timing column.
|
|
24620
|
+
const bits = [];
|
|
24621
|
+
for (const word of codewords)
|
|
24622
|
+
for (let i = 7; i >= 0; i--)
|
|
24623
|
+
bits.push((word >> i) & 1);
|
|
24624
|
+
let bit = 0;
|
|
24625
|
+
const matrix = base.map((row) => [...row]);
|
|
24626
|
+
for (let right = size - 1; right >= 1; right -= 2) {
|
|
24627
|
+
if (right === 6)
|
|
24628
|
+
right = 5;
|
|
24629
|
+
for (let vert = 0; vert < size; vert++) {
|
|
24630
|
+
for (let j = 0; j < 2; j++) {
|
|
24631
|
+
const c = right - j;
|
|
24632
|
+
const upward = ((right + 1) & 2) === 0;
|
|
24633
|
+
const r = upward ? size - 1 - vert : vert;
|
|
24634
|
+
if (reserved[r][c])
|
|
24635
|
+
continue;
|
|
24636
|
+
matrix[r][c] = bit < bits.length ? bits[bit++] : Cell.Light;
|
|
24637
|
+
}
|
|
24638
|
+
}
|
|
24639
|
+
}
|
|
24640
|
+
// Pick the mask with the lowest penalty, then write the format bits.
|
|
24641
|
+
let best = null;
|
|
24642
|
+
let bestMask = 0;
|
|
24643
|
+
let bestScore = Infinity;
|
|
24644
|
+
for (let mask = 0; mask < 8; mask++) {
|
|
24645
|
+
const candidate = matrix.map((row, r) => row.map((v, c) => (reserved[r][c] ? v : v ^ (MASKS[mask](r, c) ? 1 : 0))));
|
|
24646
|
+
writeFormat(candidate, ecc, mask);
|
|
24647
|
+
const score = penalty(candidate);
|
|
24648
|
+
if (score < bestScore) {
|
|
24649
|
+
bestScore = score;
|
|
24650
|
+
best = candidate;
|
|
24651
|
+
bestMask = mask;
|
|
24652
|
+
}
|
|
24653
|
+
}
|
|
24654
|
+
void bestMask;
|
|
24655
|
+
return best.map((row) => row.map((v) => v === Cell.Dark));
|
|
24656
|
+
}
|
|
24657
|
+
/** The 15 format bits, written in both of their places. */
|
|
24658
|
+
function writeFormat(m, ecc, mask) {
|
|
24659
|
+
const size = m.length;
|
|
24660
|
+
const bits = FORMAT_BITS[ecc][mask];
|
|
24661
|
+
const at = (i) => (bits >> i) & 1;
|
|
24662
|
+
for (let i = 0; i <= 5; i++)
|
|
24663
|
+
m[8][i] = at(i);
|
|
24664
|
+
m[8][7] = at(6);
|
|
24665
|
+
m[8][8] = at(7);
|
|
24666
|
+
m[7][8] = at(8);
|
|
24667
|
+
for (let i = 9; i <= 14; i++)
|
|
24668
|
+
m[14 - i][8] = at(i);
|
|
24669
|
+
for (let i = 0; i <= 6; i++)
|
|
24670
|
+
m[size - 1 - i][8] = at(i);
|
|
24671
|
+
for (let i = 7; i <= 14; i++)
|
|
24672
|
+
m[8][size - 15 + i] = at(i);
|
|
24673
|
+
m[size - 8][8] = 1; // the dark module, which is not a format bit
|
|
24674
|
+
}
|
|
24675
|
+
/** Internals, exported for the vector tests only. */
|
|
24676
|
+
const __qrInternals = { dataCodewords, remainder };
|
|
24677
|
+
|
|
24678
|
+
/**
|
|
24679
|
+
* A QR code the library draws, with the quiet zone and contrast a scanner needs
|
|
24680
|
+
* in every theme — not an image the consumer frames on white by hand.
|
|
24681
|
+
*
|
|
24682
|
+
* <strct-qr [value]="otpauthUri" label="Scan with your authenticator app" />
|
|
24683
|
+
*
|
|
24684
|
+
* **Dark modules on a light quiet zone, in every scheme.** That is a deliberate
|
|
24685
|
+
* exception to "tokens only": a themed QR code is an unscannable one. Show the
|
|
24686
|
+
* secret as text beside it, so enrolment works without a camera.
|
|
24687
|
+
*/
|
|
24688
|
+
class StrctQr {
|
|
24689
|
+
/** What the code carries — an `otpauth://` URI, a URL, any text. */
|
|
24690
|
+
value = input.required(/* @ts-ignore */
|
|
24691
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
24692
|
+
/** Rendered size in px (the code is square). */
|
|
24693
|
+
size = input(176, /* @ts-ignore */
|
|
24694
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
24695
|
+
/** The code's accessible name. */
|
|
24696
|
+
label = input('QR code', /* @ts-ignore */
|
|
24697
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
24698
|
+
/** How much of the code a scanner may lose and still read it. */
|
|
24699
|
+
errorCorrection = input('M', /* @ts-ignore */
|
|
24700
|
+
...(ngDevMode ? [{ debugName: "errorCorrection" }] : /* istanbul ignore next */ []));
|
|
24701
|
+
/** The quiet zone, in modules. Four is what the spec asks for. */
|
|
24702
|
+
quietZone = input(4, /* @ts-ignore */
|
|
24703
|
+
...(ngDevMode ? [{ debugName: "quietZone" }] : /* istanbul ignore next */ []));
|
|
24704
|
+
matrix = computed(() => strctQrMatrix(this.value(), this.errorCorrection()), /* @ts-ignore */
|
|
24705
|
+
...(ngDevMode ? [{ debugName: "matrix" }] : /* istanbul ignore next */ []));
|
|
24706
|
+
/** The whole drawing's span in modules: the code plus its quiet zone. */
|
|
24707
|
+
span = computed(() => this.matrix().length + this.quietZone() * 2, /* @ts-ignore */
|
|
24708
|
+
...(ngDevMode ? [{ debugName: "span" }] : /* istanbul ignore next */ []));
|
|
24709
|
+
viewBox = computed(() => `0 0 ${this.span()} ${this.span()}`, /* @ts-ignore */
|
|
24710
|
+
...(ngDevMode ? [{ debugName: "viewBox" }] : /* istanbul ignore next */ []));
|
|
24711
|
+
/** Dark modules merged into horizontal runs — far fewer rects to paint. */
|
|
24712
|
+
rows = computed(() => {
|
|
24713
|
+
const m = this.matrix();
|
|
24714
|
+
const pad = this.quietZone();
|
|
24715
|
+
return m.map((row, y) => {
|
|
24716
|
+
const runs = [];
|
|
24717
|
+
let start = -1;
|
|
24718
|
+
for (let x = 0; x <= row.length; x++) {
|
|
24719
|
+
if (row[x]) {
|
|
24720
|
+
if (start < 0)
|
|
24721
|
+
start = x;
|
|
24722
|
+
}
|
|
24723
|
+
else if (start >= 0) {
|
|
24724
|
+
runs.push({ x: start + pad, width: x - start });
|
|
24725
|
+
start = -1;
|
|
24726
|
+
}
|
|
24727
|
+
}
|
|
24728
|
+
return { y: y + pad, runs };
|
|
24729
|
+
});
|
|
24730
|
+
}, /* @ts-ignore */
|
|
24731
|
+
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
24732
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctQr, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
24733
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctQr, isStandalone: true, selector: "strct-qr", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, errorCorrection: { classPropertyName: "errorCorrection", publicName: "errorCorrection", isSignal: true, isRequired: false, transformFunction: null }, quietZone: { classPropertyName: "quietZone", publicName: "quietZone", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-qr" }, ngImport: i0, template: `
|
|
24734
|
+
<svg
|
|
24735
|
+
class="strct-qr__svg"
|
|
24736
|
+
[attr.viewBox]="viewBox()"
|
|
24737
|
+
[attr.width]="size()"
|
|
24738
|
+
[attr.height]="size()"
|
|
24739
|
+
role="img"
|
|
24740
|
+
[attr.aria-label]="label()"
|
|
24741
|
+
shape-rendering="crispEdges"
|
|
24742
|
+
>
|
|
24743
|
+
<rect class="strct-qr__quiet" [attr.width]="span()" [attr.height]="span()" />
|
|
24744
|
+
@for (row of rows(); track row.y) {
|
|
24745
|
+
@for (run of row.runs; track run.x) {
|
|
24746
|
+
<rect
|
|
24747
|
+
class="strct-qr__module"
|
|
24748
|
+
[attr.x]="run.x"
|
|
24749
|
+
[attr.y]="row.y"
|
|
24750
|
+
[attr.width]="run.width"
|
|
24751
|
+
height="1"
|
|
24752
|
+
/>
|
|
24753
|
+
}
|
|
24754
|
+
}
|
|
24755
|
+
</svg>
|
|
24756
|
+
`, isInline: true, styles: [".strct-qr{display:inline-flex;line-height:0}.strct-qr__svg{border-radius:var(--radius-md)}.strct-qr__quiet{fill:#fff}.strct-qr__module{fill:#000}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
24757
|
+
}
|
|
24758
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctQr, decorators: [{
|
|
24759
|
+
type: Component,
|
|
24760
|
+
args: [{ selector: 'strct-qr', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
|
|
24761
|
+
<svg
|
|
24762
|
+
class="strct-qr__svg"
|
|
24763
|
+
[attr.viewBox]="viewBox()"
|
|
24764
|
+
[attr.width]="size()"
|
|
24765
|
+
[attr.height]="size()"
|
|
24766
|
+
role="img"
|
|
24767
|
+
[attr.aria-label]="label()"
|
|
24768
|
+
shape-rendering="crispEdges"
|
|
24769
|
+
>
|
|
24770
|
+
<rect class="strct-qr__quiet" [attr.width]="span()" [attr.height]="span()" />
|
|
24771
|
+
@for (row of rows(); track row.y) {
|
|
24772
|
+
@for (run of row.runs; track run.x) {
|
|
24773
|
+
<rect
|
|
24774
|
+
class="strct-qr__module"
|
|
24775
|
+
[attr.x]="run.x"
|
|
24776
|
+
[attr.y]="row.y"
|
|
24777
|
+
[attr.width]="run.width"
|
|
24778
|
+
height="1"
|
|
24779
|
+
/>
|
|
24780
|
+
}
|
|
24781
|
+
}
|
|
24782
|
+
</svg>
|
|
24783
|
+
`, host: { class: 'strct-qr' }, styles: [".strct-qr{display:inline-flex;line-height:0}.strct-qr__svg{border-radius:var(--radius-md)}.strct-qr__quiet{fill:#fff}.strct-qr__module{fill:#000}\n"] }]
|
|
24784
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], errorCorrection: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorCorrection", required: false }] }], quietZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "quietZone", required: false }] }] } });
|
|
24785
|
+
|
|
24053
24786
|
/**
|
|
24054
24787
|
* A value change, as one phrase: "v10.27 → v10.28". The old value is muted, the
|
|
24055
24788
|
* arrow is the library's, the new one is emphasised — and assistive tech hears
|
|
@@ -25966,5 +26699,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
25966
26699
|
* Generated bundle index. Do not edit.
|
|
25967
26700
|
*/
|
|
25968
26701
|
|
|
25969
|
-
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, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, 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, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownItemAction, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFlowNodeTemplate, StrctFooter, StrctGauge, 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, 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, StrctWindowService, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
26702
|
+
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, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, 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, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownItemAction, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFlowNodeTemplate, StrctFooter, StrctGauge, 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, StrctWindowService, StrctWizard, StrctWizardAside, __qrInternals, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctCheckHostDisplay, strctCheckHostInputs, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctQrMatrix, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
25970
26703
|
//# sourceMappingURL=akcelik-strct.mjs.map
|