@sankhyatronics/sankhya-cms 0.1.16 → 0.2.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/custom-elements.json +842 -213
- package/dist/bento-grid/index.d.ts +8 -1
- package/dist/bento-grid/index.js +2 -1
- package/dist/card/index.d.ts +3 -4
- package/dist/card/index.js +1 -1
- package/dist/{chunk-LEXZKGQX.js → chunk-2DXHPEB5.js} +1 -1
- package/dist/chunk-2DXHPEB5.js.map +1 -0
- package/dist/{chunk-R5G6KFTJ.js → chunk-2FJDNJ7R.js} +1 -1
- package/dist/chunk-2FJDNJ7R.js.map +1 -0
- package/dist/{chunk-ZN4LIKVG.js → chunk-3OEEOBHB.js} +1 -1
- package/dist/chunk-3OEEOBHB.js.map +1 -0
- package/dist/{chunk-BMHMNXIA.js → chunk-4AFOKKSU.js} +1 -1
- package/dist/chunk-4AFOKKSU.js.map +1 -0
- package/dist/{chunk-76AVBQUA.js → chunk-5C6C6K5U.js} +98 -4
- package/dist/chunk-5C6C6K5U.js.map +1 -0
- package/dist/{chunk-7NLZND6Q.js → chunk-5F5PTVWR.js} +27 -2
- package/dist/chunk-5F5PTVWR.js.map +1 -0
- package/dist/chunk-5MY6OWMK.js +125 -0
- package/dist/chunk-5MY6OWMK.js.map +1 -0
- package/dist/{chunk-FLY7TNRT.js → chunk-7NIWQWTA.js} +1 -1
- package/dist/chunk-7NIWQWTA.js.map +1 -0
- package/dist/{chunk-ALI26WOB.js → chunk-EE6PAN3B.js} +33 -2
- package/dist/chunk-EE6PAN3B.js.map +1 -0
- package/dist/chunk-FML6AG2V.js +107 -0
- package/dist/chunk-FML6AG2V.js.map +1 -0
- package/dist/{chunk-VWS53WY4.js → chunk-HMUZON6I.js} +49 -4
- package/dist/chunk-HMUZON6I.js.map +1 -0
- package/dist/{chunk-G3CF7MBO.js → chunk-J6EO4R73.js} +27 -1
- package/dist/{chunk-G3CF7MBO.js.map → chunk-J6EO4R73.js.map} +1 -1
- package/dist/chunk-O4FCRKDX.js +178 -0
- package/dist/chunk-O4FCRKDX.js.map +1 -0
- package/dist/{chunk-SMLR736E.js → chunk-OELI3IWC.js} +1 -1
- package/dist/chunk-OELI3IWC.js.map +1 -0
- package/dist/{chunk-JQY2G4QK.js → chunk-OLA35A2O.js} +1 -1
- package/dist/chunk-OLA35A2O.js.map +1 -0
- package/dist/{chunk-YQ42EBK5.js → chunk-PHEGSCOM.js} +1 -1
- package/dist/chunk-PHEGSCOM.js.map +1 -0
- package/dist/{chunk-5EBWMPJS.js → chunk-QLA4BH2B.js} +5 -5
- package/dist/chunk-QLA4BH2B.js.map +1 -0
- package/dist/{chunk-JKBWZLG4.js → chunk-SQ3OZO32.js} +141 -3
- package/dist/chunk-SQ3OZO32.js.map +1 -0
- package/dist/chunk-UAIUBPDN.js +11 -0
- package/dist/chunk-UAIUBPDN.js.map +1 -0
- package/dist/{chunk-XWB4CKDU.js → chunk-XUGEXERO.js} +6 -6
- package/dist/chunk-XUGEXERO.js.map +1 -0
- package/dist/chunk-ZRC5BVDX.js +219 -0
- package/dist/chunk-ZRC5BVDX.js.map +1 -0
- package/dist/cms-theme.css +7 -0
- package/dist/content-block/index.d.ts +2 -3
- package/dist/content-block/index.js +3 -2
- package/dist/dropdown/index.d.ts +8 -11
- package/dist/dropdown/index.js +1 -1
- package/dist/feature-split/index.js +2 -1
- package/dist/features-section/index.d.ts +4 -4
- package/dist/features-section/index.js +4 -3
- package/dist/flow/index.d.ts +35 -0
- package/dist/flow/index.js +9 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/header/index.d.ts +8 -15
- package/dist/header/index.js +1 -1
- package/dist/hero/index.d.ts +18 -3
- package/dist/hero/index.js +1 -1
- package/dist/icon-button/index.d.ts +2 -4
- package/dist/icon-button/index.js +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +38 -25
- package/dist/items-accordion/index.d.ts +5 -0
- package/dist/items-accordion/index.js +2 -1
- package/dist/markdown/index.d.ts +1 -2
- package/dist/markdown/index.js +2 -1
- package/dist/mega-menu/index.d.ts +2 -2
- package/dist/mega-menu/index.js +1 -1
- package/dist/menu-grid/index.d.ts +2 -3
- package/dist/menu-grid/index.js +1 -1
- package/dist/menu-grid-item/index.d.ts +6 -8
- package/dist/menu-grid-item/index.js +1 -1
- package/dist/menu-item/index.d.ts +5 -7
- package/dist/menu-item/index.js +1 -1
- package/dist/promo-banner/index.d.ts +14 -3
- package/dist/promo-banner/index.js +1 -1
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/section/index.d.ts +3 -0
- package/dist/section/index.js +1 -1
- package/dist/steps/index.d.ts +33 -0
- package/dist/steps/index.js +10 -0
- package/dist/steps/index.js.map +1 -0
- package/dist/tag-strip/index.d.ts +26 -0
- package/dist/tag-strip/index.js +9 -0
- package/dist/tag-strip/index.js.map +1 -0
- package/dist/tooltip/index.d.ts +18 -6
- package/dist/tooltip/index.js +1 -1
- package/package.json +14 -2
- package/dist/chunk-5EBWMPJS.js.map +0 -1
- package/dist/chunk-76AVBQUA.js.map +0 -1
- package/dist/chunk-7NLZND6Q.js.map +0 -1
- package/dist/chunk-ALI26WOB.js.map +0 -1
- package/dist/chunk-BMHMNXIA.js.map +0 -1
- package/dist/chunk-FLY7TNRT.js.map +0 -1
- package/dist/chunk-JKBWZLG4.js.map +0 -1
- package/dist/chunk-JQY2G4QK.js.map +0 -1
- package/dist/chunk-LEXZKGQX.js.map +0 -1
- package/dist/chunk-R5G6KFTJ.js.map +0 -1
- package/dist/chunk-SMLR736E.js.map +0 -1
- package/dist/chunk-VWS53WY4.js.map +0 -1
- package/dist/chunk-XCA3XFFG.js +0 -74
- package/dist/chunk-XCA3XFFG.js.map +0 -1
- package/dist/chunk-XWB4CKDU.js.map +0 -1
- package/dist/chunk-YQ42EBK5.js.map +0 -1
- package/dist/chunk-ZN4LIKVG.js.map +0 -1
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import {
|
|
2
|
+
controlBaseStyles,
|
|
3
|
+
fontFamilyStyles
|
|
4
|
+
} from "./chunk-KMU6ABQF.js";
|
|
5
|
+
import {
|
|
6
|
+
__decorateClass
|
|
7
|
+
} from "./chunk-EUXUH3YW.js";
|
|
8
|
+
|
|
9
|
+
// src/flow/Flow.ts
|
|
10
|
+
import { LitElement, css, html, nothing, svg } from "lit";
|
|
11
|
+
import { customElement, property } from "lit/decorators.js";
|
|
12
|
+
var Flow = class extends LitElement {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.nodes = [];
|
|
16
|
+
this.label = "";
|
|
17
|
+
this.inverted = false;
|
|
18
|
+
}
|
|
19
|
+
arrow() {
|
|
20
|
+
return svg`<svg class="arrow" part="arrow" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
21
|
+
<path d="M5 12h13m-5-5 5 5-5 5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
|
22
|
+
</svg>`;
|
|
23
|
+
}
|
|
24
|
+
render() {
|
|
25
|
+
const last = this.nodes.length - 1;
|
|
26
|
+
return html`
|
|
27
|
+
<ol class="flow" part="flow" aria-label=${this.label || nothing}>
|
|
28
|
+
${this.nodes.map(
|
|
29
|
+
(node, index) => html`
|
|
30
|
+
<li class="step">
|
|
31
|
+
<div class="node ${node.variant ?? "solid"}" part="node">
|
|
32
|
+
<p class="label" part="label">${node.label}</p>
|
|
33
|
+
${node.caption ? html`<p class="caption" part="caption">${node.caption}</p>` : nothing}
|
|
34
|
+
</div>
|
|
35
|
+
${index < last ? this.arrow() : nothing}
|
|
36
|
+
</li>
|
|
37
|
+
`
|
|
38
|
+
)}
|
|
39
|
+
</ol>
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
Flow.styles = css`
|
|
44
|
+
${controlBaseStyles}
|
|
45
|
+
${fontFamilyStyles}
|
|
46
|
+
|
|
47
|
+
:host {
|
|
48
|
+
display: block;
|
|
49
|
+
box-sizing: border-box;
|
|
50
|
+
/* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's
|
|
51
|
+
padding; override with --st-flow-padding instead. */
|
|
52
|
+
padding: var(--st-flow-padding, var(--st-space-40) var(--st-space-24)) !important;
|
|
53
|
+
background: var(--st-color-page);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
:host([inverted]) {
|
|
57
|
+
background: var(--st-cms-band-dark-bg);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.flow {
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: stretch;
|
|
63
|
+
max-width: var(--st-cms-container-max);
|
|
64
|
+
margin: 0 auto;
|
|
65
|
+
padding: 0;
|
|
66
|
+
list-style: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.step {
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
flex: 1 1 0;
|
|
73
|
+
min-width: 0;
|
|
74
|
+
margin: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.node {
|
|
78
|
+
display: flex;
|
|
79
|
+
flex: 1 1 auto;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
justify-content: center;
|
|
82
|
+
gap: var(--st-space-4);
|
|
83
|
+
box-sizing: border-box;
|
|
84
|
+
min-width: 0;
|
|
85
|
+
min-height: 84px;
|
|
86
|
+
padding: var(--st-space-16) var(--st-space-20);
|
|
87
|
+
border: 1.5px solid transparent;
|
|
88
|
+
border-radius: var(--st-radius-lg);
|
|
89
|
+
text-align: center;
|
|
90
|
+
overflow-wrap: anywhere;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.label {
|
|
94
|
+
margin: 0;
|
|
95
|
+
font-size: var(--st-text-lg);
|
|
96
|
+
font-weight: var(--st-font-weight-bold);
|
|
97
|
+
line-height: 1.3;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.caption {
|
|
101
|
+
margin: 0;
|
|
102
|
+
font-size: var(--st-text-sm);
|
|
103
|
+
line-height: 1.5;
|
|
104
|
+
opacity: 0.85;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.node.solid {
|
|
108
|
+
background: var(--st-button-primary-bg);
|
|
109
|
+
color: var(--st-button-primary-color);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.node.outline {
|
|
113
|
+
background: var(--st-color-surface);
|
|
114
|
+
border-color: var(--st-color-accent);
|
|
115
|
+
border-style: dashed;
|
|
116
|
+
color: var(--st-color-text-strong);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.node.accent {
|
|
120
|
+
background: var(--st-cms-highlight);
|
|
121
|
+
color: var(--st-cms-navy);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.arrow {
|
|
125
|
+
flex: 0 0 auto;
|
|
126
|
+
width: 24px;
|
|
127
|
+
height: 24px;
|
|
128
|
+
margin: 0 var(--st-space-8);
|
|
129
|
+
color: var(--st-color-text-faint);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* inverted: outlined boxes take the cyan highlight so the dashed edge reads on navy. */
|
|
133
|
+
:host([inverted]) .node.outline {
|
|
134
|
+
background: transparent;
|
|
135
|
+
border-color: var(--st-cms-highlight);
|
|
136
|
+
color: var(--st-cms-band-dark-color);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:host([inverted]) .arrow {
|
|
140
|
+
color: color-mix(in oklch, var(--st-cms-band-dark-color) 60%, transparent);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@media (max-width: 600px) {
|
|
144
|
+
:host {
|
|
145
|
+
padding: var(--st-flow-padding, var(--st-space-32) var(--st-space-20)) !important;
|
|
146
|
+
}
|
|
147
|
+
.flow {
|
|
148
|
+
flex-direction: column;
|
|
149
|
+
}
|
|
150
|
+
.step {
|
|
151
|
+
flex: 0 0 auto;
|
|
152
|
+
flex-direction: column;
|
|
153
|
+
align-items: stretch;
|
|
154
|
+
}
|
|
155
|
+
.arrow {
|
|
156
|
+
align-self: center;
|
|
157
|
+
transform: rotate(90deg);
|
|
158
|
+
margin: var(--st-space-4) 0;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
`;
|
|
162
|
+
__decorateClass([
|
|
163
|
+
property({ attribute: false })
|
|
164
|
+
], Flow.prototype, "nodes", 2);
|
|
165
|
+
__decorateClass([
|
|
166
|
+
property({ type: String })
|
|
167
|
+
], Flow.prototype, "label", 2);
|
|
168
|
+
__decorateClass([
|
|
169
|
+
property({ type: Boolean, reflect: true })
|
|
170
|
+
], Flow.prototype, "inverted", 2);
|
|
171
|
+
Flow = __decorateClass([
|
|
172
|
+
customElement("st-flow")
|
|
173
|
+
], Flow);
|
|
174
|
+
|
|
175
|
+
export {
|
|
176
|
+
Flow
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=chunk-O4FCRKDX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/flow/Flow.ts"],"sourcesContent":["import { LitElement, css, html, nothing, svg } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\n\nexport interface FlowNode {\n label: string;\n caption?: string;\n /** `solid` (default, primary fill), `outline` (dashed accent border) or `accent` (cyan fill). */\n variant?: 'solid' | 'outline' | 'accent';\n}\n\n/**\n * A left-to-right process or architecture flow: boxes joined by arrows. Boxes come in three looks\n * (`solid`, `outline`, `accent`); the arrows are decorative (`aria-hidden`), and the list is exposed\n * as an ordered list. Below 600px the row stacks vertically and the arrows point down.\n * `inverted` puts the flow on the dark band (`--st-cms-band-dark-bg`).\n *\n * @cssprop --st-flow-padding - Overrides the block's padding.\n * @csspart flow - The ordered list of nodes.\n * @csspart node - Each step's box (a `li`'s child).\n * @csspart label - The box's label.\n * @csspart caption - The box's caption.\n * @csspart arrow - The arrow between two boxes.\n */\n@customElement('st-flow')\nexport class Flow extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n ${fontFamilyStyles}\n\n :host {\n display: block;\n box-sizing: border-box;\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding; override with --st-flow-padding instead. */\n padding: var(--st-flow-padding, var(--st-space-40) var(--st-space-24)) !important;\n background: var(--st-color-page);\n }\n\n :host([inverted]) {\n background: var(--st-cms-band-dark-bg);\n }\n\n .flow {\n display: flex;\n align-items: stretch;\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n padding: 0;\n list-style: none;\n }\n\n .step {\n display: flex;\n align-items: center;\n flex: 1 1 0;\n min-width: 0;\n margin: 0;\n }\n\n .node {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n justify-content: center;\n gap: var(--st-space-4);\n box-sizing: border-box;\n min-width: 0;\n min-height: 84px;\n padding: var(--st-space-16) var(--st-space-20);\n border: 1.5px solid transparent;\n border-radius: var(--st-radius-lg);\n text-align: center;\n overflow-wrap: anywhere;\n }\n\n .label {\n margin: 0;\n font-size: var(--st-text-lg);\n font-weight: var(--st-font-weight-bold);\n line-height: 1.3;\n }\n\n .caption {\n margin: 0;\n font-size: var(--st-text-sm);\n line-height: 1.5;\n opacity: 0.85;\n }\n\n .node.solid {\n background: var(--st-button-primary-bg);\n color: var(--st-button-primary-color);\n }\n\n .node.outline {\n background: var(--st-color-surface);\n border-color: var(--st-color-accent);\n border-style: dashed;\n color: var(--st-color-text-strong);\n }\n\n .node.accent {\n background: var(--st-cms-highlight);\n color: var(--st-cms-navy);\n }\n\n .arrow {\n flex: 0 0 auto;\n width: 24px;\n height: 24px;\n margin: 0 var(--st-space-8);\n color: var(--st-color-text-faint);\n }\n\n /* inverted: outlined boxes take the cyan highlight so the dashed edge reads on navy. */\n :host([inverted]) .node.outline {\n background: transparent;\n border-color: var(--st-cms-highlight);\n color: var(--st-cms-band-dark-color);\n }\n\n :host([inverted]) .arrow {\n color: color-mix(in oklch, var(--st-cms-band-dark-color) 60%, transparent);\n }\n\n @media (max-width: 600px) {\n :host {\n padding: var(--st-flow-padding, var(--st-space-32) var(--st-space-20)) !important;\n }\n .flow {\n flex-direction: column;\n }\n .step {\n flex: 0 0 auto;\n flex-direction: column;\n align-items: stretch;\n }\n .arrow {\n align-self: center;\n transform: rotate(90deg);\n margin: var(--st-space-4) 0;\n }\n }\n `;\n\n /** The boxes, in order. */\n @property({ attribute: false })\n nodes: FlowNode[] = [];\n\n /** Accessible name for the list of steps. */\n @property({ type: String })\n label = '';\n\n /** Puts the flow on the dark band (`--st-cms-band-dark-bg`), which stays dark in the dark theme. */\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n private arrow() {\n return svg`<svg class=\"arrow\" part=\"arrow\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M5 12h13m-5-5 5 5-5 5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>`;\n }\n\n render() {\n const last = this.nodes.length - 1;\n return html`\n <ol class=\"flow\" part=\"flow\" aria-label=${this.label || nothing}>\n ${this.nodes.map(\n (node, index) => html`\n <li class=\"step\">\n <div class=\"node ${node.variant ?? 'solid'}\" part=\"node\">\n <p class=\"label\" part=\"label\">${node.label}</p>\n ${node.caption ? html`<p class=\"caption\" part=\"caption\">${node.caption}</p>` : nothing}\n </div>\n ${index < last ? this.arrow() : nothing}\n </li>\n `\n )}\n </ol>\n `;\n }\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,SAAS,WAAW;AACpD,SAAS,eAAe,gBAAgB;AAyBjC,IAAM,OAAN,cAAmB,WAAW;AAAA,EAA9B;AAAA;AA2HL,iBAAoB,CAAC;AAIrB,iBAAQ;AAIR,oBAAW;AAAA;AAAA,EAEH,QAAQ;AACd,WAAO;AAAA;AAAA;AAAA,EAGT;AAAA,EAEA,SAAS;AACP,UAAM,OAAO,KAAK,MAAM,SAAS;AACjC,WAAO;AAAA,gDACqC,KAAK,SAAS,OAAO;AAAA,UAC3D,KAAK,MAAM;AAAA,MACX,CAAC,MAAM,UAAU;AAAA;AAAA,iCAEM,KAAK,WAAW,OAAO;AAAA,gDACR,KAAK,KAAK;AAAA,kBACxC,KAAK,UAAU,yCAAyC,KAAK,OAAO,SAAS,OAAO;AAAA;AAAA,gBAEtF,QAAQ,OAAO,KAAK,MAAM,IAAI,OAAO;AAAA;AAAA;AAAA,IAG7C,CAAC;AAAA;AAAA;AAAA,EAGP;AACF;AA7Ja,KACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA,MACjB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwHpB;AAAA,EADC,SAAS,EAAE,WAAW,MAAM,CAAC;AAAA,GA1HnB,KA2HX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Hf,KA+HX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlI/B,KAmIX;AAnIW,OAAN;AAAA,EADN,cAAc,SAAS;AAAA,GACX;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/menu-grid/MenuGrid.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles } from '../shared/styles';\n\n/**\n * A responsive grid of `st-menu-grid-item`s — the \"rich\" nav-menu layout (icon + title +\n * description per entry, arranged in columns), typically slotted into `st-dropdown`'s default\n * slot. Markup is `.menu-grid-container` > `.menu-grid.columns-N`; breakpoints: at 768px, 2–4\n * columns become 2; at 480px, everything becomes 1 (a 1-column grid stays 1).\n */\n@customElement('st-menu-grid')\nexport class MenuGrid extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n }\n\n .menu-grid-container {\n width: 100%;\n }\n\n .menu-grid {\n display: grid;\n gap: 12px;\n }\n\n .menu-grid.columns-1 {\n grid-template-columns: repeat(1, 1fr);\n }\n\n .menu-grid.columns-2 {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .menu-grid.columns-3 {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .menu-grid.columns-4 {\n grid-template-columns: repeat(4, 1fr);\n }\n\n @media (max-width: 768px) {\n .menu-grid.columns-2,\n .menu-grid.columns-3,\n .menu-grid.columns-4 {\n grid-template-columns: repeat(2, 1fr);\n }\n }\n\n @media (max-width: 480px) {\n .menu-grid.columns-1,\n .menu-grid.columns-2,\n .menu-grid.columns-3,\n .menu-grid.columns-4 {\n grid-template-columns: 1fr;\n }\n }\n `;\n\n /** Number of columns at full width (1–4, same as the source component's `columns-N` classes). */\n @property({ type: Number })\n columns = 3;\n\n /** Extra class(es) appended to the inner grid element — the source component's `gridClassName`.\n * Its outer `className` is the host element itself here: set a `class` attribute on `st-menu-grid`. */\n @property({ type: String, attribute: 'grid-class-name' })\n gridClassName = '';\n\n render() {\n const columns = Math.min(4, Math.max(1, Math.round(this.columns) || 1));\n return html`\n <div class=\"menu-grid-container\" part=\"container\">\n <div part=\"grid\" class=\"menu-grid columns-${columns} ${this.gridClassName}\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AAWjC,IAAM,WAAN,cAAuB,WAAW;AAAA,EAAlC;AAAA;AAqDL,mBAAU;AAKV,yBAAgB;AAAA;AAAA,EAEhB,SAAS;AACP,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,CAAC,CAAC;AACtE,WAAO;AAAA;AAAA,oDAEyC,OAAO,IAAI,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/E;AACF;AAtEa,SACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmDrB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApDf,SAqDX;AAKA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB,CAAC;AAAA,GAzD7C,SA0DX;AA1DW,WAAN;AAAA,EADN,cAAc,cAAc;AAAA,GAChB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/menu-grid-item/MenuGridItem.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport type { MenuGridItemSelectEventDetail } from './MenuGridItemEvents';\n\n/**\n * One entry in an `st-menu-grid` — icon (via `slot=\"icon\"`) + title on one line, an optional\n * description below, and an optional corner badge (\"New\", \"Popular\", ...). Effects are CSS:\n * fades up the first time it scrolls into view, scales to 1.02 on hover / 0.98 while pressed, the\n * icon tilts on hover, the badge pops in. Colors come from the suite theme rather than per-item\n * utility classes.\n *\n * An `http(s)` `href` opens in a new tab. Any other `href` fires a *cancelable*\n * `menu-grid-item-select` event (detail: `{ href }`) first: a host doing client-side routing calls\n * `event.preventDefault()` on it, which also cancels the anchor's own navigation.\n */\n@customElement('st-menu-grid-item')\nexport class MenuGridItem extends LitElement {\n /** `focus()` on the element focuses its link, so `st-dropdown` can arrow-key between items. */\n static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };\n\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n ${fontFamilyStyles}\n }\n\n @keyframes st-menu-grid-badge-pop {\n from {\n transform: scale(0);\n }\n 70% {\n transform: scale(1.12);\n }\n to {\n transform: scale(1);\n }\n }\n\n .menu-grid-item {\n display: flex;\n flex-direction: column;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n color: var(--st-color-text);\n transition:\n opacity 0.4s ease-out,\n transform 0.2s ease,\n background-color 0.2s ease;\n }\n\n .menu-grid-item.pending {\n opacity: 0;\n transform: translateY(20px);\n }\n\n .menu-grid-item.regular {\n padding: 16px;\n }\n\n .menu-grid-item.compact {\n padding: 12px;\n }\n\n /* Keyboard focus gets the same treatment as hover. */\n .menu-grid-item:hover,\n .menu-grid-item:has(.menu-grid-link:focus-visible) {\n background: var(--st-color-hover);\n transform: scale(1.02);\n }\n\n .menu-grid-item:active {\n transform: scale(0.98);\n }\n\n .menu-grid-link {\n display: flex;\n flex-direction: column;\n text-decoration: none;\n color: inherit;\n width: 100%;\n height: 100%;\n gap: 8px;\n }\n\n .menu-grid-badge {\n position: absolute;\n top: 2px;\n right: 8px;\n font-size: 0.5rem;\n padding: 2px 8px;\n border-radius: 9999px;\n font-weight: 500;\n z-index: 1;\n background-color: var(--st-color-text-strong);\n color: var(--st-color-on-solid);\n animation: st-menu-grid-badge-pop 0.35s ease-out;\n }\n\n .menu-grid-header {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n }\n\n .menu-grid-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 6px;\n transition:\n background-color 0.2s ease,\n transform 0.2s ease;\n flex-shrink: 0;\n padding: 0;\n margin-bottom: 0;\n }\n\n .menu-grid-icon:hover {\n transform: rotate(5deg) scale(1.1);\n }\n\n .menu-grid-icon[hidden] {\n display: none;\n }\n\n .menu-grid-icon ::slotted(*) {\n width: 18px;\n height: 18px;\n }\n\n .menu-grid-title {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--st-color-text-strong);\n transition: color 0.2s ease;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-bottom: 0;\n }\n\n .menu-grid-description {\n font-size: 0.75rem;\n color: var(--st-color-text-muted);\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n transition: color 0.2s ease;\n }\n\n .menu-grid-item.compact .menu-grid-header {\n gap: 8px;\n }\n\n .menu-grid-item.compact .menu-grid-icon {\n width: 24px;\n height: 24px;\n }\n\n .menu-grid-item.compact .menu-grid-icon ::slotted(*) {\n width: 14px;\n height: 14px;\n }\n\n .menu-grid-item.compact .menu-grid-title {\n font-size: 0.75rem;\n }\n\n .menu-grid-item.compact .menu-grid-description {\n font-size: 0.75rem;\n }\n\n .menu-grid-header.icon-only {\n justify-content: center;\n }\n\n @media (max-width: 480px) {\n .menu-grid-header {\n gap: 8px;\n }\n\n .menu-grid-icon {\n width: 28px;\n height: 28px;\n }\n\n .menu-grid-icon ::slotted(*) {\n width: 16px;\n height: 16px;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .menu-grid-item,\n .menu-grid-icon {\n transition: none;\n }\n\n .menu-grid-item.pending {\n opacity: 1;\n transform: none;\n }\n\n .menu-grid-badge {\n animation: none;\n }\n }\n `;\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n description = '';\n\n @property({ type: String })\n href = '';\n\n /** Small corner label, e.g. \"New\"/\"Beta\" — omit for none. */\n @property({ type: String })\n badge = '';\n\n @property({ type: Boolean, reflect: true })\n compact = false;\n\n /** Suppresses the description even when `description` is set (source: `showDescription`, default `true`). */\n @property({ type: Boolean, attribute: 'show-description' })\n showDescription = true;\n\n /** Whether `slot=\"icon\"` has content, so an omitted icon leaves no empty box. */\n @state() private hasIcon = false;\n\n /** True until the item first scrolls into view (the source's `whileInView ... once`). */\n @state() private pending = true;\n\n private observer?: IntersectionObserver;\n\n connectedCallback(): void {\n super.connectedCallback();\n if (typeof IntersectionObserver === 'undefined') {\n this.pending = false;\n return;\n }\n this.observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n this.pending = false;\n this.observer?.disconnect();\n }\n });\n this.observer.observe(this);\n }\n\n disconnectedCallback(): void {\n this.observer?.disconnect();\n super.disconnectedCallback();\n }\n\n private onIconSlotChange = (event: Event): void => {\n this.hasIcon = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;\n };\n\n private get isExternal(): boolean {\n return this.href.startsWith('http');\n }\n\n private onClick = (event: MouseEvent): void => {\n if (this.isExternal) return;\n const selectEvent = new CustomEvent<MenuGridItemSelectEventDetail>('menu-grid-item-select', {\n detail: { href: this.href },\n bubbles: true,\n composed: true,\n cancelable: true\n });\n this.dispatchEvent(selectEvent);\n if (selectEvent.defaultPrevented) event.preventDefault();\n };\n\n render() {\n const iconOnly = this.hasIcon && !this.title;\n return html`\n <div class=\"menu-grid-item ${this.compact ? 'compact' : 'regular'} ${this.pending ? 'pending' : ''}\" part=\"item\">\n <a\n part=\"link\"\n class=\"menu-grid-link\"\n href=${this.href}\n target=${this.isExternal ? '_blank' : '_self'}\n rel=${this.isExternal ? 'noopener noreferrer' : nothing}\n @click=${this.onClick}\n >\n ${this.badge ? html`<span part=\"badge\" class=\"menu-grid-badge\">${this.badge}</span>` : nothing}\n <span class=\"menu-grid-header ${iconOnly ? 'icon-only' : ''}\" part=\"header\">\n <span class=\"menu-grid-icon\" part=\"icon\" ?hidden=${!this.hasIcon}><slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot></span>\n ${this.title ? html`<span part=\"title\" class=\"menu-grid-title\">${this.title}</span>` : nothing}\n </span>\n ${this.description && this.showDescription\n ? html`<span part=\"description\" class=\"menu-grid-description\">${this.description}</span>`\n : nothing}\n </a>\n </div>\n `;\n }\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,UAAU,aAAa;AAiBxC,IAAM,eAAN,cAA2B,WAAW;AAAA,EAAtC;AAAA;AA2ML,iBAAQ;AAGR,uBAAc;AAGd,gBAAO;AAIP,iBAAQ;AAGR,mBAAU;AAIV,2BAAkB;AAGT,SAAQ,UAAU;AAGlB,SAAQ,UAAU;AAwB3B,SAAQ,mBAAmB,CAAC,UAAuB;AACjD,WAAK,UAAW,MAAM,OAA2B,cAAc,EAAE,SAAS,KAAK,CAAC,EAAE,SAAS;AAAA,IAC7F;AAMA,SAAQ,UAAU,CAAC,UAA4B;AAC7C,UAAI,KAAK,WAAY;AACrB,YAAM,cAAc,IAAI,YAA2C,yBAAyB;AAAA,QAC1F,QAAQ,EAAE,MAAM,KAAK,KAAK;AAAA,QAC1B,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,MACd,CAAC;AACD,WAAK,cAAc,WAAW;AAC9B,UAAI,YAAY,iBAAkB,OAAM,eAAe;AAAA,IACzD;AAAA;AAAA,EAtCA,oBAA0B;AACxB,UAAM,kBAAkB;AACxB,QAAI,OAAO,yBAAyB,aAAa;AAC/C,WAAK,UAAU;AACf;AAAA,IACF;AACA,SAAK,WAAW,IAAI,qBAAqB,CAAC,YAAY;AACpD,UAAI,QAAQ,KAAK,CAAC,UAAU,MAAM,cAAc,GAAG;AACjD,aAAK,UAAU;AACf,aAAK,UAAU,WAAW;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,SAAK,SAAS,QAAQ,IAAI;AAAA,EAC5B;AAAA,EAEA,uBAA6B;AAC3B,SAAK,UAAU,WAAW;AAC1B,UAAM,qBAAqB;AAAA,EAC7B;AAAA,EAMA,IAAY,aAAsB;AAChC,WAAO,KAAK,KAAK,WAAW,MAAM;AAAA,EACpC;AAAA,EAcA,SAAS;AACP,UAAM,WAAW,KAAK,WAAW,CAAC,KAAK;AACvC,WAAO;AAAA,mCACwB,KAAK,UAAU,YAAY,SAAS,IAAI,KAAK,UAAU,YAAY,EAAE;AAAA;AAAA;AAAA;AAAA,iBAIvF,KAAK,IAAI;AAAA,mBACP,KAAK,aAAa,WAAW,OAAO;AAAA,gBACvC,KAAK,aAAa,wBAAwB,OAAO;AAAA,mBAC9C,KAAK,OAAO;AAAA;AAAA,YAEnB,KAAK,QAAQ,kDAAkD,KAAK,KAAK,YAAY,OAAO;AAAA,0CAC9D,WAAW,cAAc,EAAE;AAAA,+DACN,CAAC,KAAK,OAAO,kCAAkC,KAAK,gBAAgB;AAAA,cACrH,KAAK,QAAQ,kDAAkD,KAAK,KAAK,YAAY,OAAO;AAAA;AAAA,YAE9F,KAAK,eAAe,KAAK,kBACvB,8DAA8D,KAAK,WAAW,YAC9E,OAAO;AAAA;AAAA;AAAA;AAAA,EAInB;AACF;AAAA;AAtSa,aAEJ,oBAAoB,EAAE,GAAG,WAAW,mBAAmB,gBAAgB,KAAK;AAFxE,aAIJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIf,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkMtB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA1Mf,aA2MX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA7Mf,aA8MX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAhNf,aAiNX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApNf,aAqNX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAvN/B,aAwNX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,WAAW,mBAAmB,CAAC;AAAA,GA3N/C,aA4NX;AAGiB;AAAA,EAAhB,MAAM;AAAA,GA/NI,aA+NM;AAGA;AAAA,EAAhB,MAAM;AAAA,GAlOI,aAkOM;AAlON,eAAN;AAAA,EADN,cAAc,mBAAmB;AAAA,GACrB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/icon-button/IconButton.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { buttonResetStyles, controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\n\n/**\n * A small, icon-only action button. The icon is default-slotted content (the package has no icon\n * library dependency), the same convention as `st-dropdown`/`st-menu-grid-item`'s `slot=\"icon\"`.\n *\n * Fires a plain native `click` — no custom event, since a caller just wants an ordinary button.\n */\n@customElement('st-icon-button')\nexport class IconButton extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: inline-flex;\n ${rootFontFamilyStyles}\n }\n\n button {\n ${buttonResetStyles}\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--st-size-32);\n height: var(--st-size-32);\n border-radius: var(--st-radius-sm);\n color: var(--st-color-text-muted);\n }\n\n button:hover {\n background: var(--st-color-hover);\n color: var(--st-color-text-strong);\n }\n\n :host([disabled]) button {\n color: var(--st-color-text-muted);\n cursor: not-allowed;\n pointer-events: none;\n }\n `;\n\n /** Accessible name and tooltip — matches the source component's `ariaLabel` (renamed: modern\n * browsers already expose a native `ariaLabel` reflected property on every `Element`, so reusing\n * that exact name as a Lit reactive property would shadow it). Required for a control with no\n * visible text. */\n @property({ type: String })\n label = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n render() {\n return html`\n <button part=\"button\" type=\"button\" aria-label=${this.label} title=${this.label} ?disabled=${this.disabled}>\n <slot></slot>\n </button>\n `;\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AAWjC,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC;AAAA;AAqCL,iBAAQ;AAGR,oBAAW;AAAA;AAAA,EAEX,SAAS;AACP,WAAO;AAAA,uDAC4C,KAAK,KAAK,UAAU,KAAK,KAAK,cAAc,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,EAI9G;AACF;AAjDa,WACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIf,oBAAoB;AAAA;AAAA;AAAA;AAAA,QAIpB,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BvB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApCf,WAqCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAvC/B,WAwCX;AAxCW,aAAN;AAAA,EADN,cAAc,gBAAgB;AAAA,GAClB;","names":[]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderMarkdown
|
|
3
|
+
} from "./chunk-UAIUBPDN.js";
|
|
1
4
|
import {
|
|
2
5
|
controlBaseStyles,
|
|
3
6
|
fontFamilyStyles
|
|
@@ -10,8 +13,6 @@ import {
|
|
|
10
13
|
import { LitElement, css, html, nothing } from "lit";
|
|
11
14
|
import { customElement, property, state } from "lit/decorators.js";
|
|
12
15
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
13
|
-
import DOMPurify from "dompurify";
|
|
14
|
-
import { marked } from "marked";
|
|
15
16
|
var Markdown = class extends LitElement {
|
|
16
17
|
constructor() {
|
|
17
18
|
super(...arguments);
|
|
@@ -63,8 +64,7 @@ var Markdown = class extends LitElement {
|
|
|
63
64
|
if (this.error) return html`<div part="error">Error loading content.</div>`;
|
|
64
65
|
const source = this.src ? this.fetched : this.content;
|
|
65
66
|
if (!source) return nothing;
|
|
66
|
-
|
|
67
|
-
return html`<div part="body">${unsafeHTML(rendered)}</div>`;
|
|
67
|
+
return html`<div part="body">${unsafeHTML(renderMarkdown(source))}</div>`;
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
Markdown.styles = css`
|
|
@@ -190,4 +190,4 @@ Markdown = __decorateClass([
|
|
|
190
190
|
export {
|
|
191
191
|
Markdown
|
|
192
192
|
};
|
|
193
|
-
//# sourceMappingURL=chunk-
|
|
193
|
+
//# sourceMappingURL=chunk-QLA4BH2B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/markdown/Markdown.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport { renderMarkdown } from '../shared/markdown';\nimport type { MarkdownErrorEventDetail } from './MarkdownEvents';\n\n/**\n * Renders Markdown (GFM, single newlines become `<br>`) from either an inline `content` string or\n * a `src` URL it fetches. Output is sanitized with DOMPurify. `src` wins over `content` when both are set.\n * While a fetch is pending it shows \"Loading content...\"; on failure \"Error loading content.\" and\n * a `markdown-error` event (detail: `{ error }`).\n *\n * Text color is inherited from the parent so inverted containers just work.\n */\n@customElement('st-markdown')\nexport class Markdown extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n ${fontFamilyStyles}\n line-height: 1.7;\n }\n\n :host > div > :first-child {\n margin-top: 0;\n }\n\n h1,\n h2,\n h3,\n h4 {\n color: inherit;\n font-weight: var(--st-font-weight-bold);\n line-height: 1.3;\n }\n\n h2 {\n font-size: var(--st-text-2xl);\n margin: var(--st-space-48) 0 var(--st-space-24);\n }\n\n h3 {\n font-size: var(--st-text-xl);\n font-weight: var(--st-font-weight-semibold);\n margin: var(--st-space-32) 0 var(--st-space-16);\n }\n\n p {\n margin: 0 0 var(--st-space-24);\n }\n\n ul,\n ol {\n margin: 0 0 var(--st-space-24);\n padding-left: var(--st-space-24);\n }\n\n li {\n margin-bottom: var(--st-space-8);\n }\n\n a {\n color: inherit;\n text-decoration: underline;\n text-underline-offset: 4px;\n }\n\n a:hover {\n color: var(--st-color-text-strong);\n }\n\n img {\n max-width: 100%;\n height: auto;\n border-radius: var(--st-radius-sm);\n margin: var(--st-space-32) 0;\n }\n\n blockquote {\n border-left: 4px solid var(--st-color-border);\n margin: var(--st-space-32) 0;\n padding-left: var(--st-space-24);\n font-style: italic;\n }\n\n table {\n border-collapse: collapse;\n margin: 0 0 var(--st-space-24);\n }\n\n th,\n td {\n border: 1px solid var(--st-color-border);\n padding: var(--st-space-8) var(--st-space-12);\n }\n\n pre,\n code {\n background: var(--st-color-subtle);\n border-radius: var(--st-radius-xs);\n }\n\n code {\n padding: 0 var(--st-space-4);\n }\n\n pre {\n padding: var(--st-space-16);\n overflow-x: auto;\n }\n\n pre code {\n padding: 0;\n }\n `;\n\n /** Inline Markdown source. Ignored when `src` is set. */\n @property({ type: String })\n content = '';\n\n /** URL of a Markdown file to fetch. */\n @property({ type: String })\n src = '';\n\n @state() private fetched = '';\n @state() private loading = false;\n @state() private error: Error | null = null;\n\n private abort?: AbortController;\n\n willUpdate(changed: Map<string, unknown>): void {\n if (changed.has('src')) void this.load();\n }\n\n disconnectedCallback(): void {\n this.abort?.abort();\n super.disconnectedCallback();\n }\n\n private async load(): Promise<void> {\n this.abort?.abort();\n this.fetched = '';\n this.error = null;\n if (!this.src) {\n this.loading = false;\n return;\n }\n const controller = new AbortController();\n this.abort = controller;\n this.loading = true;\n try {\n const response = await fetch(this.src, { signal: controller.signal });\n if (!response.ok) throw new Error(`Failed to fetch markdown: ${response.statusText}`);\n const text = await response.text();\n if (controller.signal.aborted) return;\n this.fetched = text;\n } catch (err) {\n if (controller.signal.aborted) return;\n this.error = err instanceof Error ? err : new Error('Unknown error fetching markdown');\n this.dispatchEvent(\n new CustomEvent<MarkdownErrorEventDetail>('markdown-error', {\n detail: { error: this.error },\n bubbles: true,\n composed: true\n })\n );\n }\n this.loading = false;\n }\n\n render() {\n if (this.loading) return html`<div part=\"loading\">Loading content...</div>`;\n if (this.error) return html`<div part=\"error\">Error loading content.</div>`;\n const source = this.src ? this.fetched : this.content;\n if (!source) return nothing;\n return html`<div part=\"body\">${unsafeHTML(renderMarkdown(source))}</div>`;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,UAAU,aAAa;AAC/C,SAAS,kBAAkB;AAepB,IAAM,WAAN,cAAuB,WAAW;AAAA,EAAlC;AAAA;AAyGL,mBAAU;AAIV,eAAM;AAEG,SAAQ,UAAU;AAClB,SAAQ,UAAU;AAClB,SAAQ,QAAsB;AAAA;AAAA,EAIvC,WAAW,SAAqC;AAC9C,QAAI,QAAQ,IAAI,KAAK,EAAG,MAAK,KAAK,KAAK;AAAA,EACzC;AAAA,EAEA,uBAA6B;AAC3B,SAAK,OAAO,MAAM;AAClB,UAAM,qBAAqB;AAAA,EAC7B;AAAA,EAEA,MAAc,OAAsB;AAClC,SAAK,OAAO,MAAM;AAClB,SAAK,UAAU;AACf,SAAK,QAAQ;AACb,QAAI,CAAC,KAAK,KAAK;AACb,WAAK,UAAU;AACf;AAAA,IACF;AACA,UAAM,aAAa,IAAI,gBAAgB;AACvC,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK,KAAK,EAAE,QAAQ,WAAW,OAAO,CAAC;AACpE,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,6BAA6B,SAAS,UAAU,EAAE;AACpF,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAI,WAAW,OAAO,QAAS;AAC/B,WAAK,UAAU;AAAA,IACjB,SAAS,KAAK;AACZ,UAAI,WAAW,OAAO,QAAS;AAC/B,WAAK,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,iCAAiC;AACrF,WAAK;AAAA,QACH,IAAI,YAAsC,kBAAkB;AAAA,UAC1D,QAAQ,EAAE,OAAO,KAAK,MAAM;AAAA,UAC5B,SAAS;AAAA,UACT,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AACA,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS;AACP,QAAI,KAAK,QAAS,QAAO;AACzB,QAAI,KAAK,MAAO,QAAO;AACvB,UAAM,SAAS,KAAK,MAAM,KAAK,UAAU,KAAK;AAC9C,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,wBAAwB,WAAW,eAAe,MAAM,CAAC,CAAC;AAAA,EACnE;AACF;AApKa,SACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIf,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmGtB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAxGf,SAyGX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA5Gf,SA6GX;AAEiB;AAAA,EAAhB,MAAM;AAAA,GA/GI,SA+GM;AACA;AAAA,EAAhB,MAAM;AAAA,GAhHI,SAgHM;AACA;AAAA,EAAhB,MAAM;AAAA,GAjHI,SAiHM;AAjHN,WAAN;AAAA,EADN,cAAc,aAAa;AAAA,GACf;","names":[]}
|
|
@@ -11,8 +11,9 @@ import {
|
|
|
11
11
|
} from "./chunk-EUXUH3YW.js";
|
|
12
12
|
|
|
13
13
|
// src/hero/Hero.ts
|
|
14
|
-
import { LitElement, css, html, nothing } from "lit";
|
|
14
|
+
import { LitElement, css, html, nothing, svg } from "lit";
|
|
15
15
|
import { customElement, property } from "lit/decorators.js";
|
|
16
|
+
var HIGHLIGHT_ICON = svg`<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M20 6 9 17l-5-5" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>`;
|
|
16
17
|
var Hero = class extends LitElement {
|
|
17
18
|
constructor() {
|
|
18
19
|
super(...arguments);
|
|
@@ -28,6 +29,10 @@ var Hero = class extends LitElement {
|
|
|
28
29
|
this.eyebrow = "";
|
|
29
30
|
this.secondaryActionLabel = "";
|
|
30
31
|
this.secondaryHref = "";
|
|
32
|
+
this.badge = "";
|
|
33
|
+
this.highlights = [];
|
|
34
|
+
this.layout = "background";
|
|
35
|
+
this.imageAlt = "";
|
|
31
36
|
this.size = "auto";
|
|
32
37
|
this.contentPosition = "center";
|
|
33
38
|
this.overlay = "even";
|
|
@@ -35,7 +40,8 @@ var Hero = class extends LitElement {
|
|
|
35
40
|
this.onSecondaryClick = (event) => this.emitAction(event, this.secondaryHref, "secondary");
|
|
36
41
|
}
|
|
37
42
|
willUpdate() {
|
|
38
|
-
|
|
43
|
+
const asBackground = this.layout !== "split";
|
|
44
|
+
this.style.backgroundImage = asBackground && this.imageSrc ? `url(${JSON.stringify(this.imageSrc)})` : "";
|
|
39
45
|
this.style.setProperty("--st-hero-position", Hero.positions[this.focalPoint] ?? Hero.positions.center);
|
|
40
46
|
}
|
|
41
47
|
emitAction(event, href, kind) {
|
|
@@ -53,6 +59,7 @@ var Hero = class extends LitElement {
|
|
|
53
59
|
<div class="overlay" part="overlay"></div>
|
|
54
60
|
<div class="content" part="content">
|
|
55
61
|
${this.eyebrow ? html`<p class="eyebrow" part="eyebrow">${this.eyebrow}</p>` : nothing}
|
|
62
|
+
${this.badge ? html`<p class="badge" part="badge">${this.badge}</p>` : nothing}
|
|
56
63
|
<h1 class="title" part="title">${this.title}</h1>
|
|
57
64
|
${this.subtitle ? html`<p class="subtitle" part="subtitle">${this.subtitle}</p>` : nothing}
|
|
58
65
|
${this.actionLabel || this.secondaryActionLabel ? html`<div class="actions" part="actions">
|
|
@@ -61,8 +68,16 @@ var Hero = class extends LitElement {
|
|
|
61
68
|
>${this.secondaryActionLabel}</a
|
|
62
69
|
>` : nothing}
|
|
63
70
|
</div>` : nothing}
|
|
71
|
+
${this.highlights.length ? html`<ul class="highlights" part="highlights">
|
|
72
|
+
${this.highlights.map(
|
|
73
|
+
(text) => html`<li class="highlight" part="highlight">${HIGHLIGHT_ICON}<span>${text}</span></li>`
|
|
74
|
+
)}
|
|
75
|
+
</ul>` : nothing}
|
|
64
76
|
<slot></slot>
|
|
65
77
|
</div>
|
|
78
|
+
${this.layout === "split" && this.imageSrc ? html`<figure class="media" part="media">
|
|
79
|
+
<img class="image" part="image" src=${this.imageSrc} alt=${this.imageAlt} />
|
|
80
|
+
</figure>` : nothing}
|
|
66
81
|
`;
|
|
67
82
|
}
|
|
68
83
|
};
|
|
@@ -273,6 +288,117 @@ Hero.styles = css`
|
|
|
273
288
|
display: none;
|
|
274
289
|
}
|
|
275
290
|
|
|
291
|
+
.badge {
|
|
292
|
+
display: inline-flex;
|
|
293
|
+
align-items: center;
|
|
294
|
+
gap: var(--st-space-8);
|
|
295
|
+
margin: 0;
|
|
296
|
+
padding: 6px 14px;
|
|
297
|
+
border: 1px solid var(--st-color-border);
|
|
298
|
+
border-radius: var(--st-radius-full);
|
|
299
|
+
background: var(--st-color-surface);
|
|
300
|
+
color: var(--st-color-text-strong);
|
|
301
|
+
font-size: var(--st-text-sm);
|
|
302
|
+
font-weight: var(--st-font-weight-bold);
|
|
303
|
+
letter-spacing: var(--st-tracking-wider);
|
|
304
|
+
line-height: 1.2;
|
|
305
|
+
text-transform: uppercase;
|
|
306
|
+
animation: st-hero-fade 0.8s 0.2s ease-out backwards;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.badge::before {
|
|
310
|
+
content: '';
|
|
311
|
+
flex: none;
|
|
312
|
+
width: 8px;
|
|
313
|
+
height: 8px;
|
|
314
|
+
border-radius: var(--st-radius-circle);
|
|
315
|
+
background: var(--st-cms-highlight);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.highlights {
|
|
319
|
+
display: flex;
|
|
320
|
+
flex-wrap: wrap;
|
|
321
|
+
justify-content: center;
|
|
322
|
+
gap: var(--st-space-12) var(--st-space-24);
|
|
323
|
+
margin: 0;
|
|
324
|
+
padding: 0;
|
|
325
|
+
list-style: none;
|
|
326
|
+
animation: st-hero-fade 0.8s 0.9s ease-out backwards;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.highlight {
|
|
330
|
+
display: inline-flex;
|
|
331
|
+
align-items: center;
|
|
332
|
+
gap: var(--st-space-8);
|
|
333
|
+
font-size: var(--st-text-md);
|
|
334
|
+
font-weight: var(--st-font-weight-semibold);
|
|
335
|
+
color: inherit;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.highlight svg {
|
|
339
|
+
flex: none;
|
|
340
|
+
width: 18px;
|
|
341
|
+
height: 18px;
|
|
342
|
+
color: var(--st-cms-highlight);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
:host([text-alignment='left']) .highlights {
|
|
346
|
+
justify-content: flex-start;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
:host([text-alignment='right']) .highlights {
|
|
350
|
+
justify-content: flex-end;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/* layout="split": a two-column block on the page surface; the image replaces the background. */
|
|
354
|
+
:host([layout='split']) {
|
|
355
|
+
display: grid;
|
|
356
|
+
grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
|
|
357
|
+
align-items: center;
|
|
358
|
+
gap: var(--st-space-48);
|
|
359
|
+
overflow: visible;
|
|
360
|
+
padding: var(--st-cms-section-padding) var(--st-space-24);
|
|
361
|
+
background-color: var(--st-color-surface);
|
|
362
|
+
background-image: none;
|
|
363
|
+
color: var(--st-color-text-strong);
|
|
364
|
+
animation: none;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
:host([layout='split']) .overlay {
|
|
368
|
+
display: none;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
:host([layout='split']) .content {
|
|
372
|
+
width: 100%;
|
|
373
|
+
margin: 0;
|
|
374
|
+
padding: 0;
|
|
375
|
+
max-width: 560px;
|
|
376
|
+
color: var(--st-hero-text-color, var(--st-color-text-strong));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
:host([layout='split'][text-alignment='left']) .actions {
|
|
380
|
+
justify-content: flex-start;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
:host([layout='split']) .highlight svg {
|
|
384
|
+
color: var(--st-color-accent);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.media {
|
|
388
|
+
margin: 0;
|
|
389
|
+
min-width: 0;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.image {
|
|
393
|
+
display: block;
|
|
394
|
+
width: 100%;
|
|
395
|
+
height: auto;
|
|
396
|
+
aspect-ratio: 4 / 3;
|
|
397
|
+
object-fit: cover;
|
|
398
|
+
border-radius: var(--st-radius-lg);
|
|
399
|
+
box-shadow: 0 24px 48px -16px var(--st-shadow-color-lg);
|
|
400
|
+
}
|
|
401
|
+
|
|
276
402
|
@media (min-width: 768px) {
|
|
277
403
|
.content { padding: var(--st-space-32); }
|
|
278
404
|
}
|
|
@@ -329,6 +455,18 @@ __decorateClass([
|
|
|
329
455
|
__decorateClass([
|
|
330
456
|
property({ type: String, attribute: "secondary-href" })
|
|
331
457
|
], Hero.prototype, "secondaryHref", 2);
|
|
458
|
+
__decorateClass([
|
|
459
|
+
property({ type: String })
|
|
460
|
+
], Hero.prototype, "badge", 2);
|
|
461
|
+
__decorateClass([
|
|
462
|
+
property({ attribute: false })
|
|
463
|
+
], Hero.prototype, "highlights", 2);
|
|
464
|
+
__decorateClass([
|
|
465
|
+
property({ type: String, reflect: true })
|
|
466
|
+
], Hero.prototype, "layout", 2);
|
|
467
|
+
__decorateClass([
|
|
468
|
+
property({ type: String, attribute: "image-alt" })
|
|
469
|
+
], Hero.prototype, "imageAlt", 2);
|
|
332
470
|
__decorateClass([
|
|
333
471
|
property({ type: String, reflect: true })
|
|
334
472
|
], Hero.prototype, "size", 2);
|
|
@@ -345,4 +483,4 @@ Hero = __decorateClass([
|
|
|
345
483
|
export {
|
|
346
484
|
Hero
|
|
347
485
|
};
|
|
348
|
-
//# sourceMappingURL=chunk-
|
|
486
|
+
//# sourceMappingURL=chunk-SQ3OZO32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hero/Hero.ts"],"sourcesContent":["import { LitElement, css, html, nothing, svg } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\nimport { ctaLinkStyles, paddingScaleStyles } from '../shared/section-styles';\nimport type { HeroActionEventDetail } from './HeroEvents';\n\nconst HIGHLIGHT_ICON = svg`<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M20 6 9 17l-5-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>`;\n\n/**\n * Full-width hero banner: background image with a darkening overlay, optional eyebrow, title,\n * optional subtitle and up to two call-to-action links. The entrance animation is CSS keyframes\n * (skipped under `prefers-reduced-motion`).\n *\n * `size`, `content-position` and `overlay=\"gradient\"` give the large editorial layout (copy on the\n * lower left over a gradient that darkens towards it) used by enterprise marketing heroes; the\n * defaults keep the original centered banner. Put several heroes in an `st-carousel` with\n * `indicator-style=\"tabs\"` for a tabbed hero carousel.\n *\n * `badge` is a pill above the title; `highlights` is a row of check-marked points under the buttons.\n * `layout=\"split\"` swaps the background for a two-column layout: copy on one side, `image-src` as an\n * `<img>` (alt from `image-alt`) on the other, on normal page colours with no overlay.\n *\n * @fires action - Cancelable, before navigating. Detail `{ href, kind }`, `kind` being `primary` or `secondary`.\n * @cssprop --st-hero-text-color - Text colour over the image.\n * @cssprop --st-hero-min-height - Minimum height when `size` is `large` (default `640px`).\n * @csspart eyebrow - The small label above the title.\n * @csspart badge - The pill above the title.\n * @csspart highlights - The row of check-marked points.\n * @csspart image - The image in `layout=\"split\"`.\n * @csspart secondary-action - The outlined second button.\n */\n@customElement('st-hero')\nexport class Hero extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n ${paddingScaleStyles}\n\n @keyframes st-hero-zoom {\n from { opacity: 0; transform: scale(1.1); }\n to { opacity: 1; transform: scale(1); }\n }\n @keyframes st-hero-rise {\n from { opacity: 0; transform: translateY(30px); }\n to { opacity: 1; transform: none; }\n }\n @keyframes st-hero-fade {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n :host {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n width: 100%;\n box-sizing: border-box;\n background-color: var(--st-color-text-strong);\n background-repeat: no-repeat;\n background-size: cover;\n background-position: var(--st-hero-position, center center);\n color: var(--st-color-on-solid);\n ${rootFontFamilyStyles}\n animation: st-hero-zoom 1.5s ease-out;\n }\n\n :host([inverted]) {\n background-color: var(--st-color-surface);\n color: var(--st-color-text-strong);\n }\n\n .overlay {\n position: absolute;\n inset: 0;\n z-index: 1;\n background: linear-gradient(\n to bottom,\n color-mix(in oklch, var(--st-color-text-strong) 40%, transparent),\n color-mix(in oklch, var(--st-color-text-strong) 20%, transparent),\n color-mix(in oklch, var(--st-color-text-strong) 40%, transparent)\n );\n }\n\n :host([inverted]) .overlay {\n display: none;\n }\n\n .content {\n display: flex;\n flex-direction: column;\n gap: var(--st-space-20);\n position: relative;\n z-index: 2;\n width: 80%;\n margin: 0 auto;\n text-align: center;\n align-items: center;\n /* Set here, not only on :host: text sits on the image/overlay, so a colour class the page puts\n on the host (e.g. a theme text colour) must not turn it dark. */\n color: var(--st-hero-text-color, var(--st-color-on-solid));\n }\n\n :host([inverted]) .content {\n color: var(--st-hero-text-color, var(--st-color-text-strong));\n }\n\n :host([text-alignment='left']) .content { text-align: left; align-items: flex-start; }\n :host([text-alignment='right']) .content { text-align: right; align-items: flex-end; }\n :host([text-alignment='justify']) .content { text-align: justify; align-items: stretch; }\n\n .title {\n font-size: var(--st-cms-text-display);\n font-weight: var(--st-font-weight-bold);\n line-height: 1.1;\n color: inherit;\n margin: 0;\n animation: st-hero-rise 0.8s 0.3s ease-out backwards;\n }\n\n .subtitle {\n font-size: var(--st-cms-text-xl);\n line-height: 1.5;\n color: inherit;\n margin: 0;\n animation: st-hero-fade 0.8s 0.5s ease-out backwards;\n }\n\n .actions {\n display: flex;\n justify-content: center;\n width: 100%;\n }\n\n .cta {\n ${ctaLinkStyles}\n background: var(--st-button-primary-bg);\n color: var(--st-button-primary-color);\n font-weight: var(--st-button-font-weight);\n font-size: var(--st-text-md);\n animation: st-hero-rise 0.6s 0.7s ease-out backwards;\n }\n\n .cta:hover {\n transform: scale(1.05);\n }\n\n .cta:active {\n transform: scale(0.98);\n }\n\n .eyebrow {\n margin: 0;\n font-size: var(--st-text-sm);\n font-weight: var(--st-font-weight-bold);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: inherit;\n opacity: 0.85;\n animation: st-hero-fade 0.8s 0.2s ease-out backwards;\n }\n\n .actions {\n flex-wrap: wrap;\n gap: var(--st-space-12);\n }\n\n .cta.secondary {\n background: transparent;\n color: inherit;\n box-shadow: inset 0 0 0 1.5px currentColor;\n }\n\n .cta.secondary:hover {\n background: color-mix(in oklch, currentColor 12%, transparent);\n }\n\n /* size=\"large\" / \"full\": a tall editorial hero. */\n :host([size='large']) {\n min-height: var(--st-hero-min-height, 640px);\n }\n\n :host([size='full']) {\n min-height: 100svh;\n }\n\n :host([size='large']) .title,\n :host([size='full']) .title {\n font-size: clamp(2.5rem, 6vw, 5rem);\n letter-spacing: -0.02em;\n line-height: 1.05;\n }\n\n /* content-position=\"bottom\": copy sits in the lower part of the hero, on the container grid. */\n :host([content-position='bottom']) {\n align-items: flex-end;\n }\n\n :host([content-position='bottom']) .content {\n width: 100%;\n max-width: var(--st-cms-container-max);\n box-sizing: border-box;\n padding: var(--st-space-48) var(--st-space-24);\n }\n\n :host([content-position='bottom']) .title,\n :host([content-position='bottom']) .subtitle {\n max-width: 18ch;\n }\n\n :host([content-position='bottom']) .subtitle {\n max-width: 48ch;\n }\n\n :host([content-position='bottom']:not([text-alignment='center']):not([text-alignment='right'])) .actions {\n justify-content: flex-start;\n }\n\n :host([content-position='bottom'][text-alignment='center']) .title,\n :host([content-position='bottom'][text-alignment='center']) .subtitle {\n margin-inline: auto;\n }\n\n /* overlay=\"gradient\": darkest behind the copy, clearing towards the far side of the image. */\n :host([overlay='gradient']) .overlay {\n background:\n linear-gradient(to top, color-mix(in oklch, var(--st-color-text-strong) 85%, transparent), transparent 70%),\n linear-gradient(to right, color-mix(in oklch, var(--st-color-text-strong) 70%, transparent), transparent 75%);\n }\n\n :host([overlay='gradient'][text-alignment='right']) .overlay {\n background:\n linear-gradient(to top, color-mix(in oklch, var(--st-color-text-strong) 85%, transparent), transparent 70%),\n linear-gradient(to left, color-mix(in oklch, var(--st-color-text-strong) 70%, transparent), transparent 75%);\n }\n\n :host([overlay='none']) .overlay {\n display: none;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n gap: var(--st-space-8);\n margin: 0;\n padding: 6px 14px;\n border: 1px solid var(--st-color-border);\n border-radius: var(--st-radius-full);\n background: var(--st-color-surface);\n color: var(--st-color-text-strong);\n font-size: var(--st-text-sm);\n font-weight: var(--st-font-weight-bold);\n letter-spacing: var(--st-tracking-wider);\n line-height: 1.2;\n text-transform: uppercase;\n animation: st-hero-fade 0.8s 0.2s ease-out backwards;\n }\n\n .badge::before {\n content: '';\n flex: none;\n width: 8px;\n height: 8px;\n border-radius: var(--st-radius-circle);\n background: var(--st-cms-highlight);\n }\n\n .highlights {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: var(--st-space-12) var(--st-space-24);\n margin: 0;\n padding: 0;\n list-style: none;\n animation: st-hero-fade 0.8s 0.9s ease-out backwards;\n }\n\n .highlight {\n display: inline-flex;\n align-items: center;\n gap: var(--st-space-8);\n font-size: var(--st-text-md);\n font-weight: var(--st-font-weight-semibold);\n color: inherit;\n }\n\n .highlight svg {\n flex: none;\n width: 18px;\n height: 18px;\n color: var(--st-cms-highlight);\n }\n\n :host([text-alignment='left']) .highlights {\n justify-content: flex-start;\n }\n\n :host([text-alignment='right']) .highlights {\n justify-content: flex-end;\n }\n\n /* layout=\"split\": a two-column block on the page surface; the image replaces the background. */\n :host([layout='split']) {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));\n align-items: center;\n gap: var(--st-space-48);\n overflow: visible;\n padding: var(--st-cms-section-padding) var(--st-space-24);\n background-color: var(--st-color-surface);\n background-image: none;\n color: var(--st-color-text-strong);\n animation: none;\n }\n\n :host([layout='split']) .overlay {\n display: none;\n }\n\n :host([layout='split']) .content {\n width: 100%;\n margin: 0;\n padding: 0;\n max-width: 560px;\n color: var(--st-hero-text-color, var(--st-color-text-strong));\n }\n\n :host([layout='split'][text-alignment='left']) .actions {\n justify-content: flex-start;\n }\n\n :host([layout='split']) .highlight svg {\n color: var(--st-color-accent);\n }\n\n .media {\n margin: 0;\n min-width: 0;\n }\n\n .image {\n display: block;\n width: 100%;\n height: auto;\n aspect-ratio: 4 / 3;\n object-fit: cover;\n border-radius: var(--st-radius-lg);\n box-shadow: 0 24px 48px -16px var(--st-shadow-color-lg);\n }\n\n @media (min-width: 768px) {\n .content { padding: var(--st-space-32); }\n }\n @media (min-width: 1024px) {\n .content { padding: var(--st-space-48); }\n :host([content-position='bottom']) .content { padding: var(--st-space-48) var(--st-space-32) 6rem; }\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host, .eyebrow, .title, .subtitle, .cta { animation: none; }\n .cta { transition: none; }\n }\n `;\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n subtitle = '';\n\n @property({ type: String, attribute: 'image-src' })\n imageSrc = '';\n\n @property({ type: String, attribute: 'action-label' })\n actionLabel = '';\n\n @property({ type: String })\n href = '';\n\n @property({ type: String, reflect: true, attribute: 'text-alignment' })\n textAlignment: 'left' | 'center' | 'right' | 'justify' = 'left';\n\n @property({ type: String, reflect: true })\n padding: 'none' | 'small' | 'medium' | 'large' = 'none';\n\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n @property({ type: String, attribute: 'focal-point' })\n focalPoint: 'top' | 'left' | 'right' | 'bottom' | 'center' = 'center';\n\n /** Small uppercase label above the title (e.g. an event or product name). */\n @property({ type: String })\n eyebrow = '';\n\n /** Label of an outlined second button next to the primary one. */\n @property({ type: String, attribute: 'secondary-action-label' })\n secondaryActionLabel = '';\n\n @property({ type: String, attribute: 'secondary-href' })\n secondaryHref = '';\n\n /** Small pill above the title (e.g. \"New\", \"Now available\"). */\n @property({ type: String })\n badge = '';\n\n /** Check-marked points shown in a row under the buttons. */\n @property({ attribute: false })\n highlights: string[] = [];\n\n /** `background` (default) puts `image-src` behind the copy; `split` puts copy and image side by side. */\n @property({ type: String, reflect: true })\n layout: 'background' | 'split' = 'background';\n\n /** Alt text of the image in `layout=\"split\"`. Empty marks it as decorative. */\n @property({ type: String, attribute: 'image-alt' })\n imageAlt = '';\n\n /** `auto` sizes to the content; `large` is a tall editorial hero (`--st-hero-min-height`); `full` fills the viewport. */\n @property({ type: String, reflect: true })\n size: 'auto' | 'large' | 'full' = 'auto';\n\n /** `center` keeps the copy in the middle; `bottom` puts it in the lower part of the hero, on the page container. */\n @property({ type: String, reflect: true, attribute: 'content-position' })\n contentPosition: 'center' | 'bottom' = 'center';\n\n /** `even` darkens the whole image; `gradient` darkens behind the copy only; `none` shows the image as is. */\n @property({ type: String, reflect: true })\n overlay: 'even' | 'gradient' | 'none' = 'even';\n\n private static positions = {\n top: 'center top',\n left: 'left center',\n right: 'right center',\n bottom: 'center bottom',\n center: 'center center'\n } as const;\n\n protected willUpdate(): void {\n const asBackground = this.layout !== 'split';\n this.style.backgroundImage = asBackground && this.imageSrc ? `url(${JSON.stringify(this.imageSrc)})` : '';\n this.style.setProperty('--st-hero-position', Hero.positions[this.focalPoint] ?? Hero.positions.center);\n }\n\n private emitAction(event: MouseEvent, href: string, kind: 'primary' | 'secondary'): void {\n const action = new CustomEvent<HeroActionEventDetail>('action', {\n detail: { href, kind },\n bubbles: true,\n composed: true,\n cancelable: true\n });\n this.dispatchEvent(action);\n if (action.defaultPrevented) event.preventDefault();\n }\n\n private onClick = (event: MouseEvent): void => this.emitAction(event, this.href, 'primary');\n\n private onSecondaryClick = (event: MouseEvent): void => this.emitAction(event, this.secondaryHref, 'secondary');\n\n render() {\n return html`\n <div class=\"overlay\" part=\"overlay\"></div>\n <div class=\"content\" part=\"content\">\n ${this.eyebrow ? html`<p class=\"eyebrow\" part=\"eyebrow\">${this.eyebrow}</p>` : nothing}\n ${this.badge ? html`<p class=\"badge\" part=\"badge\">${this.badge}</p>` : nothing}\n <h1 class=\"title\" part=\"title\">${this.title}</h1>\n ${this.subtitle ? html`<p class=\"subtitle\" part=\"subtitle\">${this.subtitle}</p>` : nothing}\n ${this.actionLabel || this.secondaryActionLabel\n ? html`<div class=\"actions\" part=\"actions\">\n ${this.actionLabel\n ? html`<a class=\"cta\" part=\"action\" href=${this.href || nothing} @click=${this.onClick}>${this.actionLabel}</a>`\n : nothing}\n ${this.secondaryActionLabel\n ? html`<a class=\"cta secondary\" part=\"secondary-action\" href=${this.secondaryHref || nothing} @click=${this.onSecondaryClick}\n >${this.secondaryActionLabel}</a\n >`\n : nothing}\n </div>`\n : nothing}\n ${this.highlights.length\n ? html`<ul class=\"highlights\" part=\"highlights\">\n ${this.highlights.map(\n (text) => html`<li class=\"highlight\" part=\"highlight\">${HIGHLIGHT_ICON}<span>${text}</span></li>`\n )}\n </ul>`\n : nothing}\n <slot></slot>\n </div>\n ${this.layout === 'split' && this.imageSrc\n ? html`<figure class=\"media\" part=\"media\">\n <img class=\"image\" part=\"image\" src=${this.imageSrc} alt=${this.imageAlt} />\n </figure>`\n : nothing}\n `;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/shared/markdown.ts
|
|
2
|
+
import DOMPurify from "dompurify";
|
|
3
|
+
import { marked } from "marked";
|
|
4
|
+
function renderMarkdown(source) {
|
|
5
|
+
return DOMPurify.sanitize(marked.parse(source, { gfm: true, breaks: true, async: false }));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
renderMarkdown
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=chunk-UAIUBPDN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/markdown.ts"],"sourcesContent":["import DOMPurify from 'dompurify';\nimport { marked } from 'marked';\n\n/**\n * Renders Markdown (GFM, single newlines become `<br>`) to HTML sanitized with DOMPurify. The one\n * place the CMS turns authored Markdown into markup; render the result with `unsafeHTML`.\n */\nexport function renderMarkdown(source: string): string {\n return DOMPurify.sanitize(marked.parse(source, { gfm: true, breaks: true, async: false }));\n}\n"],"mappings":";AAAA,OAAO,eAAe;AACtB,SAAS,cAAc;AAMhB,SAAS,eAAe,QAAwB;AACrD,SAAO,UAAU,SAAS,OAAO,MAAM,QAAQ,EAAE,KAAK,MAAM,QAAQ,MAAM,OAAO,MAAM,CAAC,CAAC;AAC3F;","names":[]}
|
|
@@ -62,7 +62,7 @@ var Header = class extends LitElement {
|
|
|
62
62
|
* own `inline` setting is left alone. */
|
|
63
63
|
this.inlinedDropdowns = /* @__PURE__ */ new Set();
|
|
64
64
|
/** While the hamburger layout is on, the dropdowns in the header open in the flow of the
|
|
65
|
-
* full-screen panel instead of floating over it (
|
|
65
|
+
* full-screen panel instead of floating over it (the touch-device layout). */
|
|
66
66
|
this.syncInlineDropdowns = () => {
|
|
67
67
|
const collapsed = this.compact || !!this.narrowQuery?.matches;
|
|
68
68
|
const dropdowns = Array.from(this.querySelectorAll("st-dropdown"));
|
|
@@ -255,8 +255,8 @@ Header.styles = css`
|
|
|
255
255
|
align-items: center;
|
|
256
256
|
/* The containing block of an st-dropdown[mega] panel, which spans the bar. */
|
|
257
257
|
position: relative;
|
|
258
|
-
/* Spacing between brand, menu and utility controls is the rows' own margins
|
|
259
|
-
|
|
258
|
+
/* Spacing between brand, menu and utility controls is the rows' own margins, not a
|
|
259
|
+
flex gap. */
|
|
260
260
|
gap: 0;
|
|
261
261
|
/* !important on the box-model properties only: a shadow host's own :host rule always loses
|
|
262
262
|
* to ANY rule the consuming page has for the same property on that element, regardless of
|
|
@@ -409,7 +409,7 @@ Header.styles = css`
|
|
|
409
409
|
display: contents;
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
-
/* Desktop layout
|
|
412
|
+
/* Desktop layout: the menu starts 4rem after the brand and takes the
|
|
413
413
|
free width; the utility controls sit after a vertical divider. Between 901px and 1200px the
|
|
414
414
|
gaps tighten so the menu still fits down to the 900px hamburger breakpoint. */
|
|
415
415
|
.menu-row {
|
|
@@ -532,7 +532,7 @@ Header.styles = css`
|
|
|
532
532
|
color: var(--st-color-accent-text);
|
|
533
533
|
}
|
|
534
534
|
|
|
535
|
-
/* Hamburger layout
|
|
535
|
+
/* Hamburger layout: a full-screen layer under the toggle, menu above
|
|
536
536
|
the utility controls, the menu's dropdowns opening in the flow (see syncInlineDropdowns). */
|
|
537
537
|
@media (max-width: ${BREAKPOINT_TABLET}px) {
|
|
538
538
|
:host {
|
|
@@ -705,4 +705,4 @@ Header = __decorateClass([
|
|
|
705
705
|
export {
|
|
706
706
|
Header
|
|
707
707
|
};
|
|
708
|
-
//# sourceMappingURL=chunk-
|
|
708
|
+
//# sourceMappingURL=chunk-XUGEXERO.js.map
|