kanto-ds 1.7.0 → 1.9.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.
Files changed (251) hide show
  1. package/README.md +26 -14
  2. package/dist/AGENTS.md +157 -0
  3. package/dist/cdn/kanto.min.js +4743 -932
  4. package/dist/chunks/block-Cci-Kff_.js +69 -0
  5. package/dist/chunks/block-Cci-Kff_.js.map +1 -0
  6. package/dist/chunks/defaults-yhaR6U65.js +70 -0
  7. package/dist/chunks/{defaults-Cpeg13O5.js.map → defaults-yhaR6U65.js.map} +1 -1
  8. package/dist/chunks/heading-DsnZsfg-.js +21 -0
  9. package/dist/chunks/heading-DsnZsfg-.js.map +1 -0
  10. package/dist/chunks/{index-TWJzttLX.js → index-1ZFgagWW.js} +37 -12
  11. package/dist/chunks/index-1ZFgagWW.js.map +1 -0
  12. package/dist/chunks/indicator-B_Rs8F92.js +49 -0
  13. package/dist/chunks/indicator-B_Rs8F92.js.map +1 -0
  14. package/dist/chunks/{kt-calendar-CtwOby1R.js → kt-calendar-SK8eapuy.js} +3 -3
  15. package/dist/chunks/{kt-calendar-CtwOby1R.js.map → kt-calendar-SK8eapuy.js.map} +1 -1
  16. package/dist/chunks/kt-color-picker-BoezCAmx.js +365 -0
  17. package/dist/chunks/kt-color-picker-BoezCAmx.js.map +1 -0
  18. package/dist/chunks/{kt-element-T0VbIBNp.js → kt-element-DvWtPQ1Y.js} +2 -2
  19. package/dist/chunks/{kt-element-T0VbIBNp.js.map → kt-element-DvWtPQ1Y.js.map} +1 -1
  20. package/dist/chunks/motion-ChVUUO7O.js +28 -0
  21. package/dist/chunks/motion-ChVUUO7O.js.map +1 -0
  22. package/dist/chunks/numbers-QyecMiSJ.js +9 -0
  23. package/dist/chunks/numbers-QyecMiSJ.js.map +1 -0
  24. package/dist/chunks/{segmented-field-BBXR4XFL.js → segmented-field-T_Zo6lc1.js} +2 -2
  25. package/dist/chunks/{segmented-field-BBXR4XFL.js.map → segmented-field-T_Zo6lc1.js.map} +1 -1
  26. package/dist/chunks/{typed-date-CPAUNHzr.js → typed-date-CaU0kXoY.js} +2 -2
  27. package/dist/chunks/{typed-date-CPAUNHzr.js.map → typed-date-CaU0kXoY.js.map} +1 -1
  28. package/dist/components/blocks/kt-auth-form/kt-auth-form.d.ts +143 -0
  29. package/dist/components/blocks/kt-auth-form/kt-auth-form.js +368 -0
  30. package/dist/components/blocks/kt-auth-form/kt-auth-form.js.map +1 -0
  31. package/dist/components/blocks/kt-blog-post/kt-blog-post.d.ts +75 -0
  32. package/dist/components/blocks/kt-blog-post/kt-blog-post.js +285 -0
  33. package/dist/components/blocks/kt-blog-post/kt-blog-post.js.map +1 -0
  34. package/dist/components/blocks/kt-cta/kt-cta.d.ts +51 -0
  35. package/dist/components/blocks/kt-cta/kt-cta.js +126 -0
  36. package/dist/components/blocks/kt-cta/kt-cta.js.map +1 -0
  37. package/dist/components/blocks/kt-empty-page/kt-empty-page.d.ts +75 -0
  38. package/dist/components/blocks/kt-empty-page/kt-empty-page.js +245 -0
  39. package/dist/components/blocks/kt-empty-page/kt-empty-page.js.map +1 -0
  40. package/dist/components/blocks/kt-error-page/kt-error-page.d.ts +65 -0
  41. package/dist/components/blocks/kt-error-page/kt-error-page.js +177 -0
  42. package/dist/components/blocks/kt-error-page/kt-error-page.js.map +1 -0
  43. package/dist/components/blocks/kt-faq/kt-faq.d.ts +61 -0
  44. package/dist/components/blocks/kt-faq/kt-faq.js +129 -0
  45. package/dist/components/blocks/kt-faq/kt-faq.js.map +1 -0
  46. package/dist/components/blocks/kt-feature-grid/kt-feature-grid.d.ts +59 -0
  47. package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js +166 -0
  48. package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js.map +1 -0
  49. package/dist/components/blocks/kt-hero/kt-hero.d.ts +51 -0
  50. package/dist/components/blocks/kt-hero/kt-hero.js +138 -0
  51. package/dist/components/blocks/kt-hero/kt-hero.js.map +1 -0
  52. package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.d.ts +46 -0
  53. package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js +100 -0
  54. package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js.map +1 -0
  55. package/dist/components/blocks/kt-newsletter/kt-newsletter.d.ts +85 -0
  56. package/dist/components/blocks/kt-newsletter/kt-newsletter.js +247 -0
  57. package/dist/components/blocks/kt-newsletter/kt-newsletter.js.map +1 -0
  58. package/dist/components/blocks/kt-post-grid/kt-post-grid.d.ts +73 -0
  59. package/dist/components/blocks/kt-post-grid/kt-post-grid.js +249 -0
  60. package/dist/components/blocks/kt-post-grid/kt-post-grid.js.map +1 -0
  61. package/dist/components/blocks/kt-pricing-table/kt-pricing-table.d.ts +102 -0
  62. package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js +307 -0
  63. package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js.map +1 -0
  64. package/dist/components/blocks/kt-settings-section/kt-settings-section.d.ts +52 -0
  65. package/dist/components/blocks/kt-settings-section/kt-settings-section.js +158 -0
  66. package/dist/components/blocks/kt-settings-section/kt-settings-section.js.map +1 -0
  67. package/dist/components/blocks/kt-testimonials/kt-testimonials.d.ts +56 -0
  68. package/dist/components/blocks/kt-testimonials/kt-testimonials.js +161 -0
  69. package/dist/components/blocks/kt-testimonials/kt-testimonials.js.map +1 -0
  70. package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
  71. package/dist/components/core/kt-avatar-group/kt-avatar-group.d.ts +42 -0
  72. package/dist/components/core/kt-avatar-group/kt-avatar-group.js +97 -0
  73. package/dist/components/core/kt-avatar-group/kt-avatar-group.js.map +1 -0
  74. package/dist/components/core/kt-badge/kt-badge.js +2 -2
  75. package/dist/components/core/kt-button/flights.d.ts +27 -0
  76. package/dist/components/core/kt-button/kt-button.d.ts +52 -1
  77. package/dist/components/core/kt-button/kt-button.js +353 -77
  78. package/dist/components/core/kt-button/kt-button.js.map +1 -1
  79. package/dist/components/core/kt-button/morph.d.ts +27 -0
  80. package/dist/components/core/kt-card/kt-card.js +1 -1
  81. package/dist/components/core/kt-code/kt-code.d.ts +2 -1
  82. package/dist/components/core/kt-code/kt-code.js +52 -37
  83. package/dist/components/core/kt-code/kt-code.js.map +1 -1
  84. package/dist/components/core/kt-copy-button/kt-copy-button.d.ts +47 -0
  85. package/dist/components/core/kt-copy-button/kt-copy-button.js +74 -0
  86. package/dist/components/core/kt-copy-button/kt-copy-button.js.map +1 -0
  87. package/dist/components/core/kt-icon/kt-icon.js +2 -2
  88. package/dist/components/core/kt-kbd/kt-kbd.js +1 -1
  89. package/dist/components/core/kt-split-button/kt-split-button.js +2 -2
  90. package/dist/components/data/kt-chart/kt-chart.js +2 -2
  91. package/dist/components/data/kt-chat-message/kt-chat-message.d.ts +60 -0
  92. package/dist/components/data/kt-chat-message/kt-chat-message.js +204 -0
  93. package/dist/components/data/kt-chat-message/kt-chat-message.js.map +1 -0
  94. package/dist/components/data/kt-description-list/kt-description-list.d.ts +56 -0
  95. package/dist/components/data/kt-description-list/kt-description-list.js +120 -0
  96. package/dist/components/data/kt-description-list/kt-description-list.js.map +1 -0
  97. package/dist/components/data/kt-meter/kt-meter.js +8 -6
  98. package/dist/components/data/kt-meter/kt-meter.js.map +1 -1
  99. package/dist/components/data/kt-pagination/kt-pagination.js +2 -2
  100. package/dist/components/data/kt-stat/kt-stat.d.ts +3 -1
  101. package/dist/components/data/kt-stat/kt-stat.js +31 -16
  102. package/dist/components/data/kt-stat/kt-stat.js.map +1 -1
  103. package/dist/components/data/kt-table/kt-table.js +2 -2
  104. package/dist/components/data/kt-timeline/kt-timeline.js +2 -2
  105. package/dist/components/data/kt-timeline/kt-timeline.js.map +1 -1
  106. package/dist/components/data/kt-tree/kt-tree.d.ts +69 -0
  107. package/dist/components/data/kt-tree/kt-tree.js +208 -0
  108. package/dist/components/data/kt-tree/kt-tree.js.map +1 -0
  109. package/dist/components/feedback/kt-alert/kt-alert.js +2 -2
  110. package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
  111. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +1 -1
  112. package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
  113. package/dist/components/feedback/kt-toast/kt-toast.js +2 -2
  114. package/dist/components/feedback/kt-toast-container/kt-toast-container.d.ts +8 -1
  115. package/dist/components/feedback/kt-toast-container/kt-toast-container.js +65 -26
  116. package/dist/components/feedback/kt-toast-container/kt-toast-container.js.map +1 -1
  117. package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
  118. package/dist/components/forms/kt-calendar/kt-calendar.js +3 -3
  119. package/dist/components/forms/kt-checkbox/kt-checkbox.d.ts +2 -0
  120. package/dist/components/forms/kt-checkbox/kt-checkbox.js +19 -8
  121. package/dist/components/forms/kt-checkbox/kt-checkbox.js.map +1 -1
  122. package/dist/components/forms/kt-color-picker/kt-color-picker.d.ts +66 -0
  123. package/dist/components/forms/kt-color-picker/kt-color-picker.js +14 -0
  124. package/dist/components/forms/kt-color-picker/kt-color-picker.js.map +1 -0
  125. package/dist/components/forms/kt-date-input/kt-date-input.js +5 -5
  126. package/dist/components/forms/kt-date-picker/kt-date-picker.js +4 -4
  127. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +2 -2
  128. package/dist/components/forms/kt-form/kt-form.js +2 -2
  129. package/dist/components/forms/kt-input/kt-input.js +2 -2
  130. package/dist/components/forms/kt-input-menu/kt-input-menu.js +2 -2
  131. package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
  132. package/dist/components/forms/kt-multi-select/kt-multi-select.js +2 -2
  133. package/dist/components/forms/kt-number-input/kt-number-input.d.ts +92 -0
  134. package/dist/components/forms/kt-number-input/kt-number-input.js +366 -0
  135. package/dist/components/forms/kt-number-input/kt-number-input.js.map +1 -0
  136. package/dist/components/forms/kt-otp-input/kt-otp-input.d.ts +74 -0
  137. package/dist/components/forms/kt-otp-input/kt-otp-input.js +232 -0
  138. package/dist/components/forms/kt-otp-input/kt-otp-input.js.map +1 -0
  139. package/dist/components/forms/kt-prompt-input/kt-prompt-input.d.ts +74 -0
  140. package/dist/components/forms/kt-prompt-input/kt-prompt-input.js +213 -0
  141. package/dist/components/forms/kt-prompt-input/kt-prompt-input.js.map +1 -0
  142. package/dist/components/forms/kt-radio-group/kt-radio-group.js +2 -2
  143. package/dist/components/forms/kt-select/kt-select.js +2 -2
  144. package/dist/components/forms/kt-slider/kt-slider.d.ts +69 -0
  145. package/dist/components/forms/kt-slider/kt-slider.js +252 -0
  146. package/dist/components/forms/kt-slider/kt-slider.js.map +1 -0
  147. package/dist/components/forms/kt-textarea/kt-textarea.js +2 -2
  148. package/dist/components/forms/kt-time-input/kt-time-input.js +3 -3
  149. package/dist/components/forms/kt-toggle/kt-toggle.js +1 -1
  150. package/dist/components/navigation/kt-app-shell/kt-app-shell.d.ts +85 -0
  151. package/dist/components/navigation/kt-app-shell/kt-app-shell.js +220 -0
  152. package/dist/components/navigation/kt-app-shell/kt-app-shell.js.map +1 -0
  153. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +2 -2
  154. package/dist/components/navigation/kt-footer/kt-footer.d.ts +82 -0
  155. package/dist/components/navigation/kt-footer/kt-footer.js +220 -0
  156. package/dist/components/navigation/kt-footer/kt-footer.js.map +1 -0
  157. package/dist/components/navigation/kt-header/kt-header.js +2 -2
  158. package/dist/components/navigation/kt-page-header/kt-page-header.js +2 -2
  159. package/dist/components/navigation/kt-page-header/kt-page-header.js.map +1 -1
  160. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +1 -0
  161. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +81 -44
  162. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
  163. package/dist/components/navigation/kt-steps/kt-steps.d.ts +68 -0
  164. package/dist/components/navigation/kt-steps/kt-steps.js +286 -0
  165. package/dist/components/navigation/kt-steps/kt-steps.js.map +1 -0
  166. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +3 -3
  167. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -1
  168. package/dist/components/navigation/kt-tabs/kt-tabs.d.ts +1 -0
  169. package/dist/components/navigation/kt-tabs/kt-tabs.js +92 -64
  170. package/dist/components/navigation/kt-tabs/kt-tabs.js.map +1 -1
  171. package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +1 -1
  172. package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +2 -2
  173. package/dist/components/navigation/kt-user-menu/kt-user-menu.d.ts +86 -0
  174. package/dist/components/navigation/kt-user-menu/kt-user-menu.js +298 -0
  175. package/dist/components/navigation/kt-user-menu/kt-user-menu.js.map +1 -0
  176. package/dist/components/overlays/kt-accordion/kt-accordion.d.ts +47 -0
  177. package/dist/components/overlays/kt-accordion/kt-accordion.js +80 -0
  178. package/dist/components/overlays/kt-accordion/kt-accordion.js.map +1 -0
  179. package/dist/components/overlays/kt-collapsible/kt-collapsible.d.ts +17 -1
  180. package/dist/components/overlays/kt-collapsible/kt-collapsible.js +87 -32
  181. package/dist/components/overlays/kt-collapsible/kt-collapsible.js.map +1 -1
  182. package/dist/components/overlays/kt-command-palette/kt-command-palette.d.ts +87 -0
  183. package/dist/components/overlays/kt-command-palette/kt-command-palette.js +370 -0
  184. package/dist/components/overlays/kt-command-palette/kt-command-palette.js.map +1 -0
  185. package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +2 -2
  186. package/dist/components/overlays/kt-dropdown/kt-dropdown.js +2 -2
  187. package/dist/components/overlays/kt-modal/kt-modal.js +2 -2
  188. package/dist/components/overlays/kt-side-panel/kt-side-panel.js +2 -2
  189. package/dist/components/overlays/kt-tour/kt-tour.d.ts +77 -0
  190. package/dist/components/overlays/kt-tour/kt-tour.js +200 -0
  191. package/dist/components/overlays/kt-tour/kt-tour.js.map +1 -0
  192. package/dist/custom-elements.json +16427 -8061
  193. package/dist/docs/kt-accordion.md +49 -0
  194. package/dist/docs/kt-app-shell.md +89 -0
  195. package/dist/docs/kt-auth-form.md +111 -0
  196. package/dist/docs/kt-avatar-group.md +49 -0
  197. package/dist/docs/kt-blog-post.md +77 -0
  198. package/dist/docs/kt-button.md +21 -0
  199. package/dist/docs/kt-chat-message.md +68 -0
  200. package/dist/docs/kt-color-picker.md +67 -0
  201. package/dist/docs/kt-command-palette.md +99 -0
  202. package/dist/docs/kt-copy-button.md +50 -0
  203. package/dist/docs/kt-cta.md +45 -0
  204. package/dist/docs/kt-description-list.md +58 -0
  205. package/dist/docs/kt-empty-page.md +92 -0
  206. package/dist/docs/kt-error-page.md +64 -0
  207. package/dist/docs/kt-faq.md +54 -0
  208. package/dist/docs/kt-feature-grid.md +53 -0
  209. package/dist/docs/kt-footer.md +115 -0
  210. package/dist/docs/kt-hero.md +53 -0
  211. package/dist/docs/kt-logo-cloud.md +41 -0
  212. package/dist/docs/kt-newsletter.md +69 -0
  213. package/dist/docs/kt-number-input.md +77 -0
  214. package/dist/docs/kt-otp-input.md +68 -0
  215. package/dist/docs/kt-post-grid.md +66 -0
  216. package/dist/docs/kt-pricing-table.md +101 -0
  217. package/dist/docs/kt-prompt-input.md +86 -0
  218. package/dist/docs/kt-settings-section.md +65 -0
  219. package/dist/docs/kt-slider.md +76 -0
  220. package/dist/docs/kt-steps.md +79 -0
  221. package/dist/docs/kt-testimonials.md +52 -0
  222. package/dist/docs/kt-tour.md +75 -0
  223. package/dist/docs/kt-tree.md +83 -0
  224. package/dist/docs/kt-user-menu.md +77 -0
  225. package/dist/icons/defaults.d.ts +2 -0
  226. package/dist/icons/index.js +1 -1
  227. package/dist/index.d.ts +56 -0
  228. package/dist/index.js +225 -284
  229. package/dist/index.js.map +1 -1
  230. package/dist/internal/block.d.ts +23 -0
  231. package/dist/internal/command-search.d.ts +27 -0
  232. package/dist/internal/heading.d.ts +8 -0
  233. package/dist/internal/indicator.d.ts +34 -0
  234. package/dist/internal/motion.d.ts +25 -0
  235. package/dist/internal/numbers.d.ts +2 -0
  236. package/dist/internal/strings.d.ts +36 -0
  237. package/dist/react/index.d.ts +165 -0
  238. package/dist/react/index.js +420 -171
  239. package/dist/react/index.js.map +1 -1
  240. package/dist/react/jsx.d.ts +128 -1
  241. package/dist/strings/index.js +1 -1
  242. package/dist/tokens/base.css +35 -2
  243. package/dist/vscode.css-custom-data.json +165 -19
  244. package/dist/vscode.html-custom-data.json +1023 -149
  245. package/dist/vue/index.d.ts +62 -0
  246. package/dist/vue/index.js +39 -8
  247. package/dist/vue/index.js.map +1 -1
  248. package/dist/web-types.json +3238 -836
  249. package/package.json +128 -3
  250. package/dist/chunks/defaults-Cpeg13O5.js +0 -68
  251. package/dist/chunks/index-TWJzttLX.js.map +0 -1
@@ -0,0 +1,100 @@
1
+ import { css as p, nothing as c, html as d } from "lit";
2
+ import { property as a } from "lit/decorators.js";
3
+ import { K as g, d as h } from "../../../chunks/kt-element-DvWtPQ1Y.js";
4
+ import { b as f, a as u } from "../../../chunks/block-Cci-Kff_.js";
5
+ import { h as v } from "../../../chunks/heading-DsnZsfg-.js";
6
+ var y = Object.defineProperty, o = (r, l, n, m) => {
7
+ for (var t = void 0, i = r.length - 1, s; i >= 0; i--)
8
+ (s = r[i]) && (t = s(l, n, t) || t);
9
+ return t && y(l, n, t), t;
10
+ };
11
+ class e extends g {
12
+ constructor() {
13
+ super(...arguments), this.heading = "", this.align = "center", this.colour = !1, this.headingLevel = 2, this.headingId = f("kt-logo-cloud");
14
+ }
15
+ static {
16
+ this.styles = [
17
+ g.styles,
18
+ u,
19
+ p`
20
+ :host {
21
+ --kt-logo-height: 28px;
22
+ }
23
+ .block {
24
+ gap: calc(var(--gap-card) * 1.5);
25
+ }
26
+
27
+ .caption {
28
+ margin: 0;
29
+ color: var(--text-muted);
30
+ font: var(--font-normal-regular);
31
+ text-align: center;
32
+ text-wrap: balance;
33
+ }
34
+ :host([align='start']) .caption {
35
+ text-align: start;
36
+ }
37
+
38
+ .logos {
39
+ display: flex;
40
+ flex-wrap: wrap;
41
+ gap: calc(var(--gap-card) * 1.5) calc(var(--gap-card) * 3);
42
+ align-items: center;
43
+ justify-content: center;
44
+ }
45
+ :host([align='start']) .logos {
46
+ justify-content: flex-start;
47
+ }
48
+ ::slotted(*) {
49
+ display: block;
50
+ width: auto;
51
+ max-width: 160px;
52
+ height: var(--kt-logo-height);
53
+ color: var(--text-muted);
54
+ filter: grayscale(1);
55
+ opacity: 0.72;
56
+ transition:
57
+ filter var(--duration-instant),
58
+ opacity var(--duration-instant);
59
+ }
60
+ ::slotted(*:hover) {
61
+ filter: none;
62
+ opacity: 1;
63
+ }
64
+ :host([colour]) ::slotted(*) {
65
+ filter: none;
66
+ opacity: 1;
67
+ }
68
+ `
69
+ ];
70
+ }
71
+ render() {
72
+ return d`<section
73
+ part="base"
74
+ class="block"
75
+ aria-labelledby=${this.heading ? this.headingId : c}
76
+ >
77
+ ${this.heading ? d`<div id=${this.headingId}>
78
+ ${v(this.headingLevel, this.heading, "caption", 2)}
79
+ </div>` : c}
80
+ <div part="logos" class="logos"><slot></slot></div>
81
+ </section>`;
82
+ }
83
+ }
84
+ o([
85
+ a({ type: String })
86
+ ], e.prototype, "heading");
87
+ o([
88
+ a({ type: String, reflect: !0 })
89
+ ], e.prototype, "align");
90
+ o([
91
+ a({ type: Boolean, reflect: !0 })
92
+ ], e.prototype, "colour");
93
+ o([
94
+ a({ type: Number, attribute: "heading-level" })
95
+ ], e.prototype, "headingLevel");
96
+ h("kt-logo-cloud", e);
97
+ export {
98
+ e as KtLogoCloud
99
+ };
100
+ //# sourceMappingURL=kt-logo-cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kt-logo-cloud.js","sources":["../../../../src/components/blocks/kt-logo-cloud/kt-logo-cloud.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { blockId, blockStyles } from '#internal/block';\nimport { heading } from '#internal/heading';\n\n/**\n * Who uses it, in their logos: a line of marks under a caption — \"Trusted by\n * finance teams at\".\n *\n * The logos are the default slot: images or inline SVGs, each with its\n * company's name as `alt` or `aria-label`. They are drawn at one height, grey\n * until hovered, so no brand shouts over another; `colour` keeps their\n * colours.\n *\n * @element kt-logo-cloud\n *\n * @slot - The logos.\n *\n * @csspart base - The section.\n * @csspart logos - The row of logos.\n *\n * @cssproperty --kt-logo-height - The logos' height. 28px.\n *\n * @example\n * ```html\n * <kt-logo-cloud heading=\"Trusted by finance teams at\">\n * <img src=\"/logos/northwind.svg\" alt=\"Northwind\" />\n * <img src=\"/logos/kiln.svg\" alt=\"Kiln\" />\n * </kt-logo-cloud>\n * ```\n */\nexport class KtLogoCloud extends KtElement {\n static override styles = [\n KtElement.styles,\n blockStyles,\n css`\n :host {\n --kt-logo-height: 28px;\n }\n .block {\n gap: calc(var(--gap-card) * 1.5);\n }\n\n .caption {\n margin: 0;\n color: var(--text-muted);\n font: var(--font-normal-regular);\n text-align: center;\n text-wrap: balance;\n }\n :host([align='start']) .caption {\n text-align: start;\n }\n\n .logos {\n display: flex;\n flex-wrap: wrap;\n gap: calc(var(--gap-card) * 1.5) calc(var(--gap-card) * 3);\n align-items: center;\n justify-content: center;\n }\n :host([align='start']) .logos {\n justify-content: flex-start;\n }\n ::slotted(*) {\n display: block;\n width: auto;\n max-width: 160px;\n height: var(--kt-logo-height);\n color: var(--text-muted);\n filter: grayscale(1);\n opacity: 0.72;\n transition:\n filter var(--duration-instant),\n opacity var(--duration-instant);\n }\n ::slotted(*:hover) {\n filter: none;\n opacity: 1;\n }\n :host([colour]) ::slotted(*) {\n filter: none;\n opacity: 1;\n }\n `,\n ];\n\n /** The caption over the logos: \"Trusted by finance teams at\". */\n @property({ type: String })\n heading = '';\n\n /** `center` or `start`. */\n @property({ type: String, reflect: true })\n align: 'center' | 'start' = 'center';\n\n /** Keeps the logos' colours, rather than grey until hovered. */\n @property({ type: Boolean, reflect: true })\n colour = false;\n\n /** The caption's level: a heading, set small. */\n @property({ type: Number, attribute: 'heading-level' })\n headingLevel = 2;\n\n private readonly headingId = blockId('kt-logo-cloud');\n\n override render(): TemplateResult {\n return html`<section\n part=\"base\"\n class=\"block\"\n aria-labelledby=${this.heading ? this.headingId : nothing}\n >\n ${\n this.heading\n ? html`<div id=${this.headingId}>\n ${heading(this.headingLevel, this.heading, 'caption', 2)}\n </div>`\n : nothing\n }\n <div part=\"logos\" class=\"logos\"><slot></slot></div>\n </section>`;\n }\n}\n\ndefineElement('kt-logo-cloud', KtLogoCloud);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-logo-cloud': KtLogoCloud;\n }\n}\n"],"names":["KtLogoCloud","KtElement","blockId","blockStyles","css","html","nothing","heading","__decorateClass","property","defineElement"],"mappings":";;;;;;;;;;AAgCO,MAAMA,UAAoBC,EAAU;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA,GA0DL,KAAA,UAAU,IAIV,KAAA,QAA4B,UAI5B,KAAA,SAAS,IAIT,KAAA,eAAe,GAEf,KAAiB,YAAYC,EAAQ,eAAe;AAAA,EAAA;AAAA,EAvEpD,OAAA;AAAA,SAAgB,SAAS;AAAA,MACvBD,EAAU;AAAA,MACVE;AAAA,MACAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA;AAAA,EAkDF;AAAA,EAoBS,SAAyB;AAChC,WAAOC;AAAA;AAAA;AAAA,wBAGa,KAAK,UAAU,KAAK,YAAYC,CAAO;AAAA;AAAA,QAGvD,KAAK,UACDD,YAAe,KAAK,SAAS;AAAA,gBACzBE,EAAQ,KAAK,cAAc,KAAK,SAAS,WAAW,CAAC,CAAC;AAAA,sBAE1DD,CACN;AAAA;AAAA;AAAA,EAGJ;AACF;AAhCEE,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAzDfT,EA0DX,WAAA,SAAA;AAIAQ,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA7D9BT,EA8DX,WAAA,OAAA;AAIAQ,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAjE/BT,EAkEX,WAAA,QAAA;AAIAQ,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,iBAAiB;AAAA,GArE3CT,EAsEX,WAAA,cAAA;AAsBFU,EAAc,iBAAiBV,CAAW;"}
@@ -0,0 +1,85 @@
1
+ import { type TemplateResult } from 'lit';
2
+ import { KtElement } from '#internal/kt-element';
3
+ import '../../core/kt-button/kt-button.js';
4
+ import '../../core/kt-icon/kt-icon.js';
5
+ import '../../forms/kt-input/kt-input.js';
6
+ export type KtNewsletterVariant = 'panel' | 'plain';
7
+ export type KtNewsletterLayout = 'stacked' | 'inline';
8
+ /** What `kt-subscribe` carries: the address, and a way to wait for the sending. */
9
+ export interface KtSubscribeDetail {
10
+ readonly email: string;
11
+ /** Hand it the request: the button runs it; if it rejects, its message shows on the field. */
12
+ readonly wait: (sending: Promise<unknown>) => void;
13
+ }
14
+ /** Every word the block says, in English until given others. */
15
+ export interface KtNewsletterTexts {
16
+ readonly email: string;
17
+ readonly placeholder: string;
18
+ readonly subscribe: string;
19
+ readonly invalid: string;
20
+ readonly failed: string;
21
+ readonly done: string;
22
+ }
23
+ /**
24
+ * A way to hear from you again: a heading, a line, an email field and the
25
+ * button that subscribes it.
26
+ *
27
+ * It checks the address before sending, then fires `kt-subscribe` with it and
28
+ * `wait(promise)`: the button runs the request, and the block thanks the
29
+ * reader once it resolves — or shows why not on the field. Without a wait it
30
+ * thanks at once.
31
+ *
32
+ * @element kt-newsletter
33
+ *
34
+ * @slot note - Under the field: how often, and that unsubscribing is one click.
35
+ *
36
+ * @csspart base - The section.
37
+ * @csspart panel - The panel.
38
+ *
39
+ * @fires kt-subscribe - An address was sent. `detail: { email, wait(promise) }`.
40
+ *
41
+ * @example
42
+ * ```html
43
+ * <kt-newsletter heading="Notes, monthly" lead="What we shipped, and what we learned.">
44
+ * <span slot="note">One email a month. Unsubscribe in one click.</span>
45
+ * </kt-newsletter>
46
+ * <script>
47
+ * letter.addEventListener('kt-subscribe', (e) => e.detail.wait(api.subscribe(e.detail.email)));
48
+ * </script>
49
+ * ```
50
+ */
51
+ export declare class KtNewsletter extends KtElement {
52
+ static styles: import("lit").CSSResultGroup[];
53
+ heading: string;
54
+ lead: string;
55
+ /** `center` or `start`. */
56
+ align: 'center' | 'start';
57
+ /** `panel`: on a tinted panel. `plain`: on the page. */
58
+ variant: KtNewsletterVariant;
59
+ /** `stacked`: the field under the words. `inline`: beside them, where there is room. */
60
+ layout: KtNewsletterLayout;
61
+ /** The address went through: the field gives way to the thanks. */
62
+ subscribed: boolean;
63
+ /** The heading's level. */
64
+ headingLevel: number;
65
+ /** The words, English until given others. */
66
+ texts: Partial<KtNewsletterTexts>;
67
+ private hasNote;
68
+ private field;
69
+ private button;
70
+ private readonly headingId;
71
+ private get t();
72
+ firstUpdated(): void;
73
+ private readNote;
74
+ /** Sends the address, as the button does, once it is one. */
75
+ subscribe(): void;
76
+ private onSubmit;
77
+ /** Enter in the field sends, as in any form: the native field is inside the kt-input. */
78
+ private onKeyDown;
79
+ render(): TemplateResult;
80
+ }
81
+ declare global {
82
+ interface HTMLElementTagNameMap {
83
+ 'kt-newsletter': KtNewsletter;
84
+ }
85
+ }
@@ -0,0 +1,247 @@
1
+ import { css as u, nothing as h, html as p } from "lit";
2
+ import { property as r, state as f, query as m } from "lit/decorators.js";
3
+ import { K as c, d as b } from "../../../chunks/kt-element-DvWtPQ1Y.js";
4
+ import { b as y, a as g, c as v } from "../../../chunks/block-Cci-Kff_.js";
5
+ import { e as x } from "../../../chunks/events-r51msXNf.js";
6
+ import { h as k } from "../../../chunks/slots-BPbIdxAJ.js";
7
+ import "../../core/kt-button/kt-button.js";
8
+ import "../../core/kt-icon/kt-icon.js";
9
+ import "../../forms/kt-input/kt-input.js";
10
+ var w = Object.defineProperty, s = (o, t, a, l) => {
11
+ for (var e = void 0, n = o.length - 1, d; n >= 0; n--)
12
+ (d = o[n]) && (e = d(t, a, e) || e);
13
+ return e && w(t, a, e), e;
14
+ };
15
+ const $ = {
16
+ email: "Email address",
17
+ placeholder: "you@example.com",
18
+ subscribe: "Subscribe",
19
+ invalid: "Enter an email address, like name@example.com.",
20
+ failed: "That did not go through. Try again in a moment.",
21
+ done: "You are in. Check your inbox to confirm."
22
+ }, S = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
23
+ class i extends c {
24
+ constructor() {
25
+ super(...arguments), this.heading = "", this.lead = "", this.align = "center", this.variant = "panel", this.layout = "stacked", this.subscribed = !1, this.headingLevel = 2, this.texts = {}, this.hasNote = !1, this.headingId = y("kt-newsletter");
26
+ }
27
+ static {
28
+ this.styles = [
29
+ c.styles,
30
+ g,
31
+ u`
32
+ .panel {
33
+ display: grid;
34
+ gap: calc(var(--gap-card) * 1.5);
35
+ justify-items: start;
36
+ }
37
+ :host([align='center']) .panel {
38
+ justify-items: center;
39
+ text-align: center;
40
+ }
41
+ :host([variant='panel']) .panel {
42
+ padding: calc(var(--padding-card) * 2);
43
+ background-color: var(--color-primary-soft);
44
+ border: var(--border-width) solid var(--border-subtle);
45
+ border-radius: var(--border-radius-card);
46
+ }
47
+ .block-heading {
48
+ font: var(--font-title-h4);
49
+ letter-spacing: -0.01em;
50
+ }
51
+ .block-lead {
52
+ font-size: calc(16px * var(--text-scale, 1));
53
+ }
54
+
55
+ .tail {
56
+ display: grid;
57
+ gap: 10px;
58
+ width: 100%;
59
+ max-width: 460px;
60
+ justify-items: inherit;
61
+ }
62
+ form {
63
+ display: flex;
64
+ gap: var(--gap-button);
65
+ align-items: flex-start;
66
+ width: 100%;
67
+ text-align: start;
68
+ }
69
+ form kt-input {
70
+ flex: 1;
71
+ min-width: 0;
72
+ }
73
+ @container (max-width: 400px) {
74
+ form {
75
+ flex-direction: column;
76
+ align-items: stretch;
77
+ }
78
+ }
79
+
80
+ .done {
81
+ display: flex;
82
+ gap: 8px;
83
+ align-items: center;
84
+ color: var(--text-body);
85
+ font: var(--font-normal-medium);
86
+ }
87
+ /* Out of the flow while empty, but kept: a live region must be there before it speaks. */
88
+ .done.empty {
89
+ position: absolute;
90
+ width: 1px;
91
+ height: 1px;
92
+ overflow: hidden;
93
+ clip-path: inset(50%);
94
+ }
95
+ .done kt-icon {
96
+ color: var(--color-success-text);
97
+ }
98
+
99
+ .note {
100
+ color: var(--text-muted);
101
+ font: var(--font-normal-small);
102
+ }
103
+ .note.empty,
104
+ [hidden] {
105
+ display: none;
106
+ }
107
+
108
+ /* Inline: the words at the start, the field at the end, where they fit. */
109
+ @container (min-width: 760px) {
110
+ :host([layout='inline']) .panel {
111
+ grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
112
+ align-items: center;
113
+ justify-items: stretch;
114
+ text-align: start;
115
+ }
116
+ :host([layout='inline']) .block-head {
117
+ justify-items: start;
118
+ margin-inline: 0;
119
+ text-align: start;
120
+ }
121
+ :host([layout='inline']) .tail {
122
+ justify-items: start;
123
+ }
124
+ }
125
+ `
126
+ ];
127
+ }
128
+ get t() {
129
+ return { ...$, ...this.texts };
130
+ }
131
+ firstUpdated() {
132
+ this.readNote();
133
+ }
134
+ readNote() {
135
+ this.hasNote = k(this.shadowRoot?.querySelector('slot[name="note"]'));
136
+ }
137
+ /** Sends the address, as the button does, once it is one. */
138
+ subscribe() {
139
+ const t = (this.field.value ?? "").trim();
140
+ if (!S.test(t)) {
141
+ this.field.error = this.t.invalid, this.field.focus();
142
+ return;
143
+ }
144
+ this.field.error = "";
145
+ let a = null;
146
+ if (x(this, "kt-subscribe", {
147
+ email: t,
148
+ wait: (e) => {
149
+ a = e;
150
+ }
151
+ }), !a) {
152
+ this.subscribed = !0;
153
+ return;
154
+ }
155
+ const l = a;
156
+ this.button.run(() => l).then(
157
+ () => {
158
+ this.subscribed = !0;
159
+ },
160
+ (e) => {
161
+ this.field.error = e instanceof Error && e.message ? e.message : this.t.failed;
162
+ }
163
+ );
164
+ }
165
+ onSubmit(t) {
166
+ t.preventDefault(), this.subscribe();
167
+ }
168
+ /** Enter in the field sends, as in any form: the native field is inside the kt-input. */
169
+ onKeyDown(t) {
170
+ t.key !== "Enter" || t.isComposing || t.composedPath()[0].localName === "input" && (t.preventDefault(), this.subscribe());
171
+ }
172
+ render() {
173
+ const t = this.t;
174
+ return p`<section
175
+ part="base"
176
+ class="block"
177
+ aria-labelledby=${this.heading ? this.headingId : h}
178
+ >
179
+ <div part="panel" class="panel">
180
+ ${v({ title: this.heading, lead: this.lead, level: this.headingLevel, id: this.headingId })}
181
+ <div class="tail">
182
+ <form
183
+ novalidate
184
+ ?hidden=${this.subscribed}
185
+ @submit=${this.onSubmit}
186
+ @keydown=${this.onKeyDown}
187
+ >
188
+ <kt-input
189
+ name="email"
190
+ type="email"
191
+ autocomplete="email"
192
+ label=${t.email}
193
+ placeholder=${t.placeholder}
194
+ @kt-input=${() => this.field.error = ""}
195
+ ></kt-input>
196
+ <kt-button @click=${() => this.subscribe()}>${t.subscribe}</kt-button>
197
+ </form>
198
+ <p class=${this.subscribed ? "done" : "done empty"} role="status">
199
+ ${this.subscribed ? p`<kt-icon name="circle-check" size="18" aria-hidden="true"></kt-icon
200
+ >${t.done}` : h}
201
+ </p>
202
+ <div class=${this.hasNote ? "note" : "note empty"}>
203
+ <slot name="note" @slotchange=${this.readNote}></slot>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </section>`;
208
+ }
209
+ }
210
+ s([
211
+ r({ type: String })
212
+ ], i.prototype, "heading");
213
+ s([
214
+ r({ type: String })
215
+ ], i.prototype, "lead");
216
+ s([
217
+ r({ type: String, reflect: !0 })
218
+ ], i.prototype, "align");
219
+ s([
220
+ r({ type: String, reflect: !0 })
221
+ ], i.prototype, "variant");
222
+ s([
223
+ r({ type: String, reflect: !0 })
224
+ ], i.prototype, "layout");
225
+ s([
226
+ r({ type: Boolean, reflect: !0 })
227
+ ], i.prototype, "subscribed");
228
+ s([
229
+ r({ type: Number, attribute: "heading-level" })
230
+ ], i.prototype, "headingLevel");
231
+ s([
232
+ r({ attribute: !1 })
233
+ ], i.prototype, "texts");
234
+ s([
235
+ f()
236
+ ], i.prototype, "hasNote");
237
+ s([
238
+ m("kt-input")
239
+ ], i.prototype, "field");
240
+ s([
241
+ m("kt-button")
242
+ ], i.prototype, "button");
243
+ b("kt-newsletter", i);
244
+ export {
245
+ i as KtNewsletter
246
+ };
247
+ //# sourceMappingURL=kt-newsletter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kt-newsletter.js","sources":["../../../../src/components/blocks/kt-newsletter/kt-newsletter.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { blockHead, blockId, blockStyles } from '#internal/block';\nimport { emit } from '#internal/events';\nimport { hasAssignedContent } from '#internal/slots';\nimport '../../core/kt-button/kt-button.js';\nimport '../../core/kt-icon/kt-icon.js';\nimport '../../forms/kt-input/kt-input.js';\nimport type { KtButton } from '../../core/kt-button/kt-button.js';\n\nexport type KtNewsletterVariant = 'panel' | 'plain';\nexport type KtNewsletterLayout = 'stacked' | 'inline';\n\n/** What `kt-subscribe` carries: the address, and a way to wait for the sending. */\nexport interface KtSubscribeDetail {\n readonly email: string;\n /** Hand it the request: the button runs it; if it rejects, its message shows on the field. */\n readonly wait: (sending: Promise<unknown>) => void;\n}\n\n/** Every word the block says, in English until given others. */\nexport interface KtNewsletterTexts {\n readonly email: string;\n readonly placeholder: string;\n readonly subscribe: string;\n readonly invalid: string;\n readonly failed: string;\n readonly done: string;\n}\n\nconst TEXTS: KtNewsletterTexts = {\n email: 'Email address',\n placeholder: 'you@example.com',\n subscribe: 'Subscribe',\n invalid: 'Enter an email address, like name@example.com.',\n failed: 'That did not go through. Try again in a moment.',\n done: 'You are in. Check your inbox to confirm.',\n};\n\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\ntype Field = HTMLElement & { value: string; error: string };\n\n/**\n * A way to hear from you again: a heading, a line, an email field and the\n * button that subscribes it.\n *\n * It checks the address before sending, then fires `kt-subscribe` with it and\n * `wait(promise)`: the button runs the request, and the block thanks the\n * reader once it resolves — or shows why not on the field. Without a wait it\n * thanks at once.\n *\n * @element kt-newsletter\n *\n * @slot note - Under the field: how often, and that unsubscribing is one click.\n *\n * @csspart base - The section.\n * @csspart panel - The panel.\n *\n * @fires kt-subscribe - An address was sent. `detail: { email, wait(promise) }`.\n *\n * @example\n * ```html\n * <kt-newsletter heading=\"Notes, monthly\" lead=\"What we shipped, and what we learned.\">\n * <span slot=\"note\">One email a month. Unsubscribe in one click.</span>\n * </kt-newsletter>\n * <script>\n * letter.addEventListener('kt-subscribe', (e) => e.detail.wait(api.subscribe(e.detail.email)));\n * </script>\n * ```\n */\nexport class KtNewsletter extends KtElement {\n static override styles = [\n KtElement.styles,\n blockStyles,\n css`\n .panel {\n display: grid;\n gap: calc(var(--gap-card) * 1.5);\n justify-items: start;\n }\n :host([align='center']) .panel {\n justify-items: center;\n text-align: center;\n }\n :host([variant='panel']) .panel {\n padding: calc(var(--padding-card) * 2);\n background-color: var(--color-primary-soft);\n border: var(--border-width) solid var(--border-subtle);\n border-radius: var(--border-radius-card);\n }\n .block-heading {\n font: var(--font-title-h4);\n letter-spacing: -0.01em;\n }\n .block-lead {\n font-size: calc(16px * var(--text-scale, 1));\n }\n\n .tail {\n display: grid;\n gap: 10px;\n width: 100%;\n max-width: 460px;\n justify-items: inherit;\n }\n form {\n display: flex;\n gap: var(--gap-button);\n align-items: flex-start;\n width: 100%;\n text-align: start;\n }\n form kt-input {\n flex: 1;\n min-width: 0;\n }\n @container (max-width: 400px) {\n form {\n flex-direction: column;\n align-items: stretch;\n }\n }\n\n .done {\n display: flex;\n gap: 8px;\n align-items: center;\n color: var(--text-body);\n font: var(--font-normal-medium);\n }\n /* Out of the flow while empty, but kept: a live region must be there before it speaks. */\n .done.empty {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n }\n .done kt-icon {\n color: var(--color-success-text);\n }\n\n .note {\n color: var(--text-muted);\n font: var(--font-normal-small);\n }\n .note.empty,\n [hidden] {\n display: none;\n }\n\n /* Inline: the words at the start, the field at the end, where they fit. */\n @container (min-width: 760px) {\n :host([layout='inline']) .panel {\n grid-template-columns: minmax(0, 1fr) minmax(0, 420px);\n align-items: center;\n justify-items: stretch;\n text-align: start;\n }\n :host([layout='inline']) .block-head {\n justify-items: start;\n margin-inline: 0;\n text-align: start;\n }\n :host([layout='inline']) .tail {\n justify-items: start;\n }\n }\n `,\n ];\n\n @property({ type: String })\n heading = '';\n\n @property({ type: String })\n lead = '';\n\n /** `center` or `start`. */\n @property({ type: String, reflect: true })\n align: 'center' | 'start' = 'center';\n\n /** `panel`: on a tinted panel. `plain`: on the page. */\n @property({ type: String, reflect: true })\n variant: KtNewsletterVariant = 'panel';\n\n /** `stacked`: the field under the words. `inline`: beside them, where there is room. */\n @property({ type: String, reflect: true })\n layout: KtNewsletterLayout = 'stacked';\n\n /** The address went through: the field gives way to the thanks. */\n @property({ type: Boolean, reflect: true })\n subscribed = false;\n\n /** The heading's level. */\n @property({ type: Number, attribute: 'heading-level' })\n headingLevel = 2;\n\n /** The words, English until given others. */\n @property({ attribute: false })\n texts: Partial<KtNewsletterTexts> = {};\n\n @state() private hasNote = false;\n\n @query('kt-input') private field!: Field;\n @query('kt-button') private button!: KtButton;\n\n private readonly headingId = blockId('kt-newsletter');\n\n private get t(): KtNewsletterTexts {\n return { ...TEXTS, ...this.texts };\n }\n\n override firstUpdated(): void {\n this.readNote();\n }\n\n private readNote(): void {\n this.hasNote = hasAssignedContent(this.shadowRoot?.querySelector('slot[name=\"note\"]'));\n }\n\n /** Sends the address, as the button does, once it is one. */\n subscribe(): void {\n const email = (this.field.value ?? '').trim();\n if (!EMAIL.test(email)) {\n this.field.error = this.t.invalid;\n this.field.focus();\n return;\n }\n this.field.error = '';\n let sending: Promise<unknown> | null = null;\n emit<KtSubscribeDetail>(this, 'kt-subscribe', {\n email,\n wait: (promise) => {\n sending = promise;\n },\n });\n if (!sending) {\n this.subscribed = true;\n return;\n }\n const waited: Promise<unknown> = sending;\n void this.button\n .run(() => waited)\n .then(\n () => {\n this.subscribed = true;\n },\n (reason: unknown) => {\n this.field.error =\n reason instanceof Error && reason.message ? reason.message : this.t.failed;\n },\n );\n }\n\n private onSubmit(event: Event): void {\n event.preventDefault();\n this.subscribe();\n }\n\n /** Enter in the field sends, as in any form: the native field is inside the kt-input. */\n private onKeyDown(event: KeyboardEvent): void {\n if (event.key !== 'Enter' || event.isComposing) return;\n if ((event.composedPath()[0] as Element).localName !== 'input') return;\n event.preventDefault();\n this.subscribe();\n }\n\n override render(): TemplateResult {\n const t = this.t;\n return html`<section\n part=\"base\"\n class=\"block\"\n aria-labelledby=${this.heading ? this.headingId : nothing}\n >\n <div part=\"panel\" class=\"panel\">\n ${blockHead({ title: this.heading, lead: this.lead, level: this.headingLevel, id: this.headingId })}\n <div class=\"tail\">\n <form\n novalidate\n ?hidden=${this.subscribed}\n @submit=${this.onSubmit}\n @keydown=${this.onKeyDown}\n >\n <kt-input\n name=\"email\"\n type=\"email\"\n autocomplete=\"email\"\n label=${t.email}\n placeholder=${t.placeholder}\n @kt-input=${() => (this.field.error = '')}\n ></kt-input>\n <kt-button @click=${() => this.subscribe()}>${t.subscribe}</kt-button>\n </form>\n <p class=${this.subscribed ? 'done' : 'done empty'} role=\"status\">\n ${\n this.subscribed\n ? html`<kt-icon name=\"circle-check\" size=\"18\" aria-hidden=\"true\"></kt-icon\n >${t.done}`\n : nothing\n }\n </p>\n <div class=${this.hasNote ? 'note' : 'note empty'}>\n <slot name=\"note\" @slotchange=${this.readNote}></slot>\n </div>\n </div>\n </div>\n </section>`;\n }\n}\n\ndefineElement('kt-newsletter', KtNewsletter);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-newsletter': KtNewsletter;\n }\n}\n"],"names":["TEXTS","EMAIL","KtNewsletter","KtElement","blockId","blockStyles","css","hasAssignedContent","email","sending","emit","promise","waited","reason","event","html","nothing","blockHead","__decorateClass","property","state","query","defineElement"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { type TemplateResult } from 'lit';
2
+ import { KtElement } from '#internal/kt-element';
3
+ import '../../core/kt-avatar/kt-avatar.js';
4
+ export interface KtPost {
5
+ readonly title: string;
6
+ readonly href: string;
7
+ readonly excerpt?: string;
8
+ /** When it was published: `2026-09-14`. */
9
+ readonly date?: string;
10
+ /** A cover image's URL. */
11
+ readonly image?: string;
12
+ /** The cover's text alternative; empty when the title says it all. */
13
+ readonly imageAlt?: string;
14
+ readonly author?: {
15
+ readonly name: string;
16
+ readonly avatar?: string;
17
+ };
18
+ readonly tags?: readonly string[];
19
+ }
20
+ export type KtPostGridLayout = 'grid' | 'list';
21
+ /**
22
+ * The latest posts, each a card that leads to it: a cover, a title, a line,
23
+ * and who wrote it when.
24
+ *
25
+ * The posts are data: `grid.posts = [{ title, href, excerpt, date, image,
26
+ * author, tags }]`. `grid`, the default, sets them in `columns` where there is
27
+ * room; `list` puts one under another, the cover beside the words.
28
+ *
29
+ * @element kt-post-grid
30
+ *
31
+ * @slot more - Under the posts: a link to every one.
32
+ *
33
+ * @csspart base - The section.
34
+ * @csspart post - One post.
35
+ *
36
+ * @example
37
+ * ```html
38
+ * <kt-post-grid heading="From the blog">
39
+ * <a slot="more" href="/blog">Every post</a>
40
+ * </kt-post-grid>
41
+ * <script>
42
+ * grid.posts = [{ title: 'Closing the month in a day', href: '/blog/close', date: '2026-09-14' }];
43
+ * </script>
44
+ * ```
45
+ */
46
+ export declare class KtPostGrid extends KtElement {
47
+ static styles: import("lit").CSSResultGroup[];
48
+ heading: string;
49
+ lead: string;
50
+ /** `center` or `start`: the head and the more link. */
51
+ align: 'center' | 'start';
52
+ /** The posts, newest first. */
53
+ posts: readonly KtPost[];
54
+ /** Posts per row, where there is room: 2 or 3. */
55
+ columns: 2 | 3;
56
+ /** `grid`: in columns. `list`: one under another, the cover beside the words. */
57
+ layout: KtPostGridLayout;
58
+ /** The locale dates are written in; the page's language when empty. */
59
+ locale: string;
60
+ /** The heading's level; the posts' titles sit one under. */
61
+ headingLevel: number;
62
+ private hasMore;
63
+ private readonly headingId;
64
+ firstUpdated(): void;
65
+ private readMore;
66
+ private post;
67
+ render(): TemplateResult;
68
+ }
69
+ declare global {
70
+ interface HTMLElementTagNameMap {
71
+ 'kt-post-grid': KtPostGrid;
72
+ }
73
+ }