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.
- package/README.md +26 -14
- package/dist/AGENTS.md +157 -0
- package/dist/cdn/kanto.min.js +4743 -932
- package/dist/chunks/block-Cci-Kff_.js +69 -0
- package/dist/chunks/block-Cci-Kff_.js.map +1 -0
- package/dist/chunks/defaults-yhaR6U65.js +70 -0
- package/dist/chunks/{defaults-Cpeg13O5.js.map → defaults-yhaR6U65.js.map} +1 -1
- package/dist/chunks/heading-DsnZsfg-.js +21 -0
- package/dist/chunks/heading-DsnZsfg-.js.map +1 -0
- package/dist/chunks/{index-TWJzttLX.js → index-1ZFgagWW.js} +37 -12
- package/dist/chunks/index-1ZFgagWW.js.map +1 -0
- package/dist/chunks/indicator-B_Rs8F92.js +49 -0
- package/dist/chunks/indicator-B_Rs8F92.js.map +1 -0
- package/dist/chunks/{kt-calendar-CtwOby1R.js → kt-calendar-SK8eapuy.js} +3 -3
- package/dist/chunks/{kt-calendar-CtwOby1R.js.map → kt-calendar-SK8eapuy.js.map} +1 -1
- package/dist/chunks/kt-color-picker-BoezCAmx.js +365 -0
- package/dist/chunks/kt-color-picker-BoezCAmx.js.map +1 -0
- package/dist/chunks/{kt-element-T0VbIBNp.js → kt-element-DvWtPQ1Y.js} +2 -2
- package/dist/chunks/{kt-element-T0VbIBNp.js.map → kt-element-DvWtPQ1Y.js.map} +1 -1
- package/dist/chunks/motion-ChVUUO7O.js +28 -0
- package/dist/chunks/motion-ChVUUO7O.js.map +1 -0
- package/dist/chunks/numbers-QyecMiSJ.js +9 -0
- package/dist/chunks/numbers-QyecMiSJ.js.map +1 -0
- package/dist/chunks/{segmented-field-BBXR4XFL.js → segmented-field-T_Zo6lc1.js} +2 -2
- package/dist/chunks/{segmented-field-BBXR4XFL.js.map → segmented-field-T_Zo6lc1.js.map} +1 -1
- package/dist/chunks/{typed-date-CPAUNHzr.js → typed-date-CaU0kXoY.js} +2 -2
- package/dist/chunks/{typed-date-CPAUNHzr.js.map → typed-date-CaU0kXoY.js.map} +1 -1
- package/dist/components/blocks/kt-auth-form/kt-auth-form.d.ts +143 -0
- package/dist/components/blocks/kt-auth-form/kt-auth-form.js +368 -0
- package/dist/components/blocks/kt-auth-form/kt-auth-form.js.map +1 -0
- package/dist/components/blocks/kt-blog-post/kt-blog-post.d.ts +75 -0
- package/dist/components/blocks/kt-blog-post/kt-blog-post.js +285 -0
- package/dist/components/blocks/kt-blog-post/kt-blog-post.js.map +1 -0
- package/dist/components/blocks/kt-cta/kt-cta.d.ts +51 -0
- package/dist/components/blocks/kt-cta/kt-cta.js +126 -0
- package/dist/components/blocks/kt-cta/kt-cta.js.map +1 -0
- package/dist/components/blocks/kt-empty-page/kt-empty-page.d.ts +75 -0
- package/dist/components/blocks/kt-empty-page/kt-empty-page.js +245 -0
- package/dist/components/blocks/kt-empty-page/kt-empty-page.js.map +1 -0
- package/dist/components/blocks/kt-error-page/kt-error-page.d.ts +65 -0
- package/dist/components/blocks/kt-error-page/kt-error-page.js +177 -0
- package/dist/components/blocks/kt-error-page/kt-error-page.js.map +1 -0
- package/dist/components/blocks/kt-faq/kt-faq.d.ts +61 -0
- package/dist/components/blocks/kt-faq/kt-faq.js +129 -0
- package/dist/components/blocks/kt-faq/kt-faq.js.map +1 -0
- package/dist/components/blocks/kt-feature-grid/kt-feature-grid.d.ts +59 -0
- package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js +166 -0
- package/dist/components/blocks/kt-feature-grid/kt-feature-grid.js.map +1 -0
- package/dist/components/blocks/kt-hero/kt-hero.d.ts +51 -0
- package/dist/components/blocks/kt-hero/kt-hero.js +138 -0
- package/dist/components/blocks/kt-hero/kt-hero.js.map +1 -0
- package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.d.ts +46 -0
- package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js +100 -0
- package/dist/components/blocks/kt-logo-cloud/kt-logo-cloud.js.map +1 -0
- package/dist/components/blocks/kt-newsletter/kt-newsletter.d.ts +85 -0
- package/dist/components/blocks/kt-newsletter/kt-newsletter.js +247 -0
- package/dist/components/blocks/kt-newsletter/kt-newsletter.js.map +1 -0
- package/dist/components/blocks/kt-post-grid/kt-post-grid.d.ts +73 -0
- package/dist/components/blocks/kt-post-grid/kt-post-grid.js +249 -0
- package/dist/components/blocks/kt-post-grid/kt-post-grid.js.map +1 -0
- package/dist/components/blocks/kt-pricing-table/kt-pricing-table.d.ts +102 -0
- package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js +307 -0
- package/dist/components/blocks/kt-pricing-table/kt-pricing-table.js.map +1 -0
- package/dist/components/blocks/kt-settings-section/kt-settings-section.d.ts +52 -0
- package/dist/components/blocks/kt-settings-section/kt-settings-section.js +158 -0
- package/dist/components/blocks/kt-settings-section/kt-settings-section.js.map +1 -0
- package/dist/components/blocks/kt-testimonials/kt-testimonials.d.ts +56 -0
- package/dist/components/blocks/kt-testimonials/kt-testimonials.js +161 -0
- package/dist/components/blocks/kt-testimonials/kt-testimonials.js.map +1 -0
- package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
- package/dist/components/core/kt-avatar-group/kt-avatar-group.d.ts +42 -0
- package/dist/components/core/kt-avatar-group/kt-avatar-group.js +97 -0
- package/dist/components/core/kt-avatar-group/kt-avatar-group.js.map +1 -0
- package/dist/components/core/kt-badge/kt-badge.js +2 -2
- package/dist/components/core/kt-button/flights.d.ts +27 -0
- package/dist/components/core/kt-button/kt-button.d.ts +52 -1
- package/dist/components/core/kt-button/kt-button.js +353 -77
- package/dist/components/core/kt-button/kt-button.js.map +1 -1
- package/dist/components/core/kt-button/morph.d.ts +27 -0
- package/dist/components/core/kt-card/kt-card.js +1 -1
- package/dist/components/core/kt-code/kt-code.d.ts +2 -1
- package/dist/components/core/kt-code/kt-code.js +52 -37
- package/dist/components/core/kt-code/kt-code.js.map +1 -1
- package/dist/components/core/kt-copy-button/kt-copy-button.d.ts +47 -0
- package/dist/components/core/kt-copy-button/kt-copy-button.js +74 -0
- package/dist/components/core/kt-copy-button/kt-copy-button.js.map +1 -0
- package/dist/components/core/kt-icon/kt-icon.js +2 -2
- package/dist/components/core/kt-kbd/kt-kbd.js +1 -1
- package/dist/components/core/kt-split-button/kt-split-button.js +2 -2
- package/dist/components/data/kt-chart/kt-chart.js +2 -2
- package/dist/components/data/kt-chat-message/kt-chat-message.d.ts +60 -0
- package/dist/components/data/kt-chat-message/kt-chat-message.js +204 -0
- package/dist/components/data/kt-chat-message/kt-chat-message.js.map +1 -0
- package/dist/components/data/kt-description-list/kt-description-list.d.ts +56 -0
- package/dist/components/data/kt-description-list/kt-description-list.js +120 -0
- package/dist/components/data/kt-description-list/kt-description-list.js.map +1 -0
- package/dist/components/data/kt-meter/kt-meter.js +8 -6
- package/dist/components/data/kt-meter/kt-meter.js.map +1 -1
- package/dist/components/data/kt-pagination/kt-pagination.js +2 -2
- package/dist/components/data/kt-stat/kt-stat.d.ts +3 -1
- package/dist/components/data/kt-stat/kt-stat.js +31 -16
- package/dist/components/data/kt-stat/kt-stat.js.map +1 -1
- package/dist/components/data/kt-table/kt-table.js +2 -2
- package/dist/components/data/kt-timeline/kt-timeline.js +2 -2
- package/dist/components/data/kt-timeline/kt-timeline.js.map +1 -1
- package/dist/components/data/kt-tree/kt-tree.d.ts +69 -0
- package/dist/components/data/kt-tree/kt-tree.js +208 -0
- package/dist/components/data/kt-tree/kt-tree.js.map +1 -0
- package/dist/components/feedback/kt-alert/kt-alert.js +2 -2
- package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +1 -1
- package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
- package/dist/components/feedback/kt-toast/kt-toast.js +2 -2
- package/dist/components/feedback/kt-toast-container/kt-toast-container.d.ts +8 -1
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js +65 -26
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js.map +1 -1
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
- package/dist/components/forms/kt-calendar/kt-calendar.js +3 -3
- package/dist/components/forms/kt-checkbox/kt-checkbox.d.ts +2 -0
- package/dist/components/forms/kt-checkbox/kt-checkbox.js +19 -8
- package/dist/components/forms/kt-checkbox/kt-checkbox.js.map +1 -1
- package/dist/components/forms/kt-color-picker/kt-color-picker.d.ts +66 -0
- package/dist/components/forms/kt-color-picker/kt-color-picker.js +14 -0
- package/dist/components/forms/kt-color-picker/kt-color-picker.js.map +1 -0
- package/dist/components/forms/kt-date-input/kt-date-input.js +5 -5
- package/dist/components/forms/kt-date-picker/kt-date-picker.js +4 -4
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +2 -2
- package/dist/components/forms/kt-form/kt-form.js +2 -2
- package/dist/components/forms/kt-input/kt-input.js +2 -2
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +2 -2
- package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
- package/dist/components/forms/kt-multi-select/kt-multi-select.js +2 -2
- package/dist/components/forms/kt-number-input/kt-number-input.d.ts +92 -0
- package/dist/components/forms/kt-number-input/kt-number-input.js +366 -0
- package/dist/components/forms/kt-number-input/kt-number-input.js.map +1 -0
- package/dist/components/forms/kt-otp-input/kt-otp-input.d.ts +74 -0
- package/dist/components/forms/kt-otp-input/kt-otp-input.js +232 -0
- package/dist/components/forms/kt-otp-input/kt-otp-input.js.map +1 -0
- package/dist/components/forms/kt-prompt-input/kt-prompt-input.d.ts +74 -0
- package/dist/components/forms/kt-prompt-input/kt-prompt-input.js +213 -0
- package/dist/components/forms/kt-prompt-input/kt-prompt-input.js.map +1 -0
- package/dist/components/forms/kt-radio-group/kt-radio-group.js +2 -2
- package/dist/components/forms/kt-select/kt-select.js +2 -2
- package/dist/components/forms/kt-slider/kt-slider.d.ts +69 -0
- package/dist/components/forms/kt-slider/kt-slider.js +252 -0
- package/dist/components/forms/kt-slider/kt-slider.js.map +1 -0
- package/dist/components/forms/kt-textarea/kt-textarea.js +2 -2
- package/dist/components/forms/kt-time-input/kt-time-input.js +3 -3
- package/dist/components/forms/kt-toggle/kt-toggle.js +1 -1
- package/dist/components/navigation/kt-app-shell/kt-app-shell.d.ts +85 -0
- package/dist/components/navigation/kt-app-shell/kt-app-shell.js +220 -0
- package/dist/components/navigation/kt-app-shell/kt-app-shell.js.map +1 -0
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +2 -2
- package/dist/components/navigation/kt-footer/kt-footer.d.ts +82 -0
- package/dist/components/navigation/kt-footer/kt-footer.js +220 -0
- package/dist/components/navigation/kt-footer/kt-footer.js.map +1 -0
- package/dist/components/navigation/kt-header/kt-header.js +2 -2
- package/dist/components/navigation/kt-page-header/kt-page-header.js +2 -2
- package/dist/components/navigation/kt-page-header/kt-page-header.js.map +1 -1
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +1 -0
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +81 -44
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
- package/dist/components/navigation/kt-steps/kt-steps.d.ts +68 -0
- package/dist/components/navigation/kt-steps/kt-steps.js +286 -0
- package/dist/components/navigation/kt-steps/kt-steps.js.map +1 -0
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +3 -3
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -1
- package/dist/components/navigation/kt-tabs/kt-tabs.d.ts +1 -0
- package/dist/components/navigation/kt-tabs/kt-tabs.js +92 -64
- package/dist/components/navigation/kt-tabs/kt-tabs.js.map +1 -1
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +1 -1
- package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +2 -2
- package/dist/components/navigation/kt-user-menu/kt-user-menu.d.ts +86 -0
- package/dist/components/navigation/kt-user-menu/kt-user-menu.js +298 -0
- package/dist/components/navigation/kt-user-menu/kt-user-menu.js.map +1 -0
- package/dist/components/overlays/kt-accordion/kt-accordion.d.ts +47 -0
- package/dist/components/overlays/kt-accordion/kt-accordion.js +80 -0
- package/dist/components/overlays/kt-accordion/kt-accordion.js.map +1 -0
- package/dist/components/overlays/kt-collapsible/kt-collapsible.d.ts +17 -1
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js +87 -32
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js.map +1 -1
- package/dist/components/overlays/kt-command-palette/kt-command-palette.d.ts +87 -0
- package/dist/components/overlays/kt-command-palette/kt-command-palette.js +370 -0
- package/dist/components/overlays/kt-command-palette/kt-command-palette.js.map +1 -0
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +2 -2
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +2 -2
- package/dist/components/overlays/kt-modal/kt-modal.js +2 -2
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js +2 -2
- package/dist/components/overlays/kt-tour/kt-tour.d.ts +77 -0
- package/dist/components/overlays/kt-tour/kt-tour.js +200 -0
- package/dist/components/overlays/kt-tour/kt-tour.js.map +1 -0
- package/dist/custom-elements.json +16427 -8061
- package/dist/docs/kt-accordion.md +49 -0
- package/dist/docs/kt-app-shell.md +89 -0
- package/dist/docs/kt-auth-form.md +111 -0
- package/dist/docs/kt-avatar-group.md +49 -0
- package/dist/docs/kt-blog-post.md +77 -0
- package/dist/docs/kt-button.md +21 -0
- package/dist/docs/kt-chat-message.md +68 -0
- package/dist/docs/kt-color-picker.md +67 -0
- package/dist/docs/kt-command-palette.md +99 -0
- package/dist/docs/kt-copy-button.md +50 -0
- package/dist/docs/kt-cta.md +45 -0
- package/dist/docs/kt-description-list.md +58 -0
- package/dist/docs/kt-empty-page.md +92 -0
- package/dist/docs/kt-error-page.md +64 -0
- package/dist/docs/kt-faq.md +54 -0
- package/dist/docs/kt-feature-grid.md +53 -0
- package/dist/docs/kt-footer.md +115 -0
- package/dist/docs/kt-hero.md +53 -0
- package/dist/docs/kt-logo-cloud.md +41 -0
- package/dist/docs/kt-newsletter.md +69 -0
- package/dist/docs/kt-number-input.md +77 -0
- package/dist/docs/kt-otp-input.md +68 -0
- package/dist/docs/kt-post-grid.md +66 -0
- package/dist/docs/kt-pricing-table.md +101 -0
- package/dist/docs/kt-prompt-input.md +86 -0
- package/dist/docs/kt-settings-section.md +65 -0
- package/dist/docs/kt-slider.md +76 -0
- package/dist/docs/kt-steps.md +79 -0
- package/dist/docs/kt-testimonials.md +52 -0
- package/dist/docs/kt-tour.md +75 -0
- package/dist/docs/kt-tree.md +83 -0
- package/dist/docs/kt-user-menu.md +77 -0
- package/dist/icons/defaults.d.ts +2 -0
- package/dist/icons/index.js +1 -1
- package/dist/index.d.ts +56 -0
- package/dist/index.js +225 -284
- package/dist/index.js.map +1 -1
- package/dist/internal/block.d.ts +23 -0
- package/dist/internal/command-search.d.ts +27 -0
- package/dist/internal/heading.d.ts +8 -0
- package/dist/internal/indicator.d.ts +34 -0
- package/dist/internal/motion.d.ts +25 -0
- package/dist/internal/numbers.d.ts +2 -0
- package/dist/internal/strings.d.ts +36 -0
- package/dist/react/index.d.ts +165 -0
- package/dist/react/index.js +420 -171
- package/dist/react/index.js.map +1 -1
- package/dist/react/jsx.d.ts +128 -1
- package/dist/strings/index.js +1 -1
- package/dist/tokens/base.css +35 -2
- package/dist/vscode.css-custom-data.json +165 -19
- package/dist/vscode.html-custom-data.json +1023 -149
- package/dist/vue/index.d.ts +62 -0
- package/dist/vue/index.js +39 -8
- package/dist/vue/index.js.map +1 -1
- package/dist/web-types.json +3238 -836
- package/package.json +128 -3
- package/dist/chunks/defaults-Cpeg13O5.js +0 -68
- package/dist/chunks/index-TWJzttLX.js.map +0 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# `<kt-accordion>`
|
|
2
|
+
|
|
3
|
+
A set of `kt-collapsible` sections that open one at a time: opening one folds
|
|
4
|
+
the one that was open, so the page stays the length of one answer.
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<kt-accordion>
|
|
8
|
+
<kt-collapsible heading="Shipping">Three to five days, tracked.</kt-collapsible>
|
|
9
|
+
<kt-collapsible heading="Returns">Thirty days, no questions.</kt-collapsible>
|
|
10
|
+
<kt-collapsible heading="Warranty">Two years, parts and labour.</kt-collapsible>
|
|
11
|
+
</kt-accordion>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## One at a time, or each on its own
|
|
15
|
+
|
|
16
|
+
By default one section is open at most: opening another folds it, with the
|
|
17
|
+
collapsible's own animation. Of several opened in the markup, the first stays
|
|
18
|
+
open. `multiple` lets each section open and close on its own — the accordion
|
|
19
|
+
then only adds the keyboard.
|
|
20
|
+
|
|
21
|
+
`kt-change` reports the indexes of the open sections after each change.
|
|
22
|
+
|
|
23
|
+
## Keyboard
|
|
24
|
+
|
|
25
|
+
From a section's summary, the arrows move to the next or previous summary,
|
|
26
|
+
wrapping at the ends, and Home and End to the first and last — the WAI-ARIA
|
|
27
|
+
accordion pattern. Enter and Space open and close, as on any summary. Keys
|
|
28
|
+
inside a section's content are left to it.
|
|
29
|
+
|
|
30
|
+
## Accessibility
|
|
31
|
+
|
|
32
|
+
The sections stay `<details>`: each summary is a real control, announced as
|
|
33
|
+
expanded or collapsed, and find-in-page still opens a section to show a match.
|
|
34
|
+
The accordion adds the arrows; it adds no role, since a group of details needs
|
|
35
|
+
none.
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
| Property | Attribute | Type | Default |
|
|
40
|
+
| ---------- | ---------- | --------- | ------- |
|
|
41
|
+
| `multiple` | `multiple` | `boolean` | `false` |
|
|
42
|
+
|
|
43
|
+
| Getter | Description |
|
|
44
|
+
| ---------- | ---------------------------------------- |
|
|
45
|
+
| `sections` | The `kt-collapsible` children, in order. |
|
|
46
|
+
|
|
47
|
+
| Event | Detail |
|
|
48
|
+
| ----------- | -------------------- |
|
|
49
|
+
| `kt-change` | `{ open: number[] }` |
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# `<kt-app-shell>`
|
|
2
|
+
|
|
3
|
+
The frame of an application: a header along the top, a sidebar down the side,
|
|
4
|
+
and the content, which scrolls on its own.
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<kt-app-shell style="height: 100dvh">
|
|
8
|
+
<a slot="header" href="/">Northwind</a>
|
|
9
|
+
<kt-sub-menu-navigation slot="sidebar"></kt-sub-menu-navigation>
|
|
10
|
+
|
|
11
|
+
<h1>Overview</h1>
|
|
12
|
+
</kt-app-shell>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The shell fills its container's height: give the container one —
|
|
16
|
+
`height: 100dvh` on a page, a fixed height in a preview. The header and the
|
|
17
|
+
sidebar stay put while the content scrolls.
|
|
18
|
+
|
|
19
|
+
## The sidebar
|
|
20
|
+
|
|
21
|
+
Wide, the sidebar sits beside the content, and the toggle at the start of the
|
|
22
|
+
header narrows it to a rail: `collapsed` is reflected, so the sidebar's content
|
|
23
|
+
can follow it.
|
|
24
|
+
|
|
25
|
+
```css
|
|
26
|
+
kt-app-shell[collapsed] .nav-label {
|
|
27
|
+
display: none;
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Narrower than `breakpoint` — 900px of the **shell's own width**, not the
|
|
32
|
+
viewport's — the sidebar leaves the layout. The toggle opens it as a drawer over
|
|
33
|
+
the content, behind a backdrop; Escape or a click on the backdrop closes it. The
|
|
34
|
+
drawer takes the focus as it opens and gives it back to the toggle as it
|
|
35
|
+
closes, and a closed drawer is inert, so Tab never wanders into a panel that is
|
|
36
|
+
not there. `narrow` is reflected while it applies.
|
|
37
|
+
|
|
38
|
+
`toggleSidebar()` does what the toggle does; `kt-sidebar-toggle` reports it,
|
|
39
|
+
with `detail.open`. Set `no-toggle` when the header brings its own control, and
|
|
40
|
+
call `toggleSidebar()` from it.
|
|
41
|
+
|
|
42
|
+
## Inside a page
|
|
43
|
+
|
|
44
|
+
A shell shown inside a page that has its own landmarks — a preview, a demo, a
|
|
45
|
+
screenshot of the product on its marketing page — would put a second `<main>`
|
|
46
|
+
inside the first. `no-landmarks` draws the sidebar and the content as plain
|
|
47
|
+
boxes instead; everything else is the same.
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<kt-app-shell no-landmarks style="height: 420px">…</kt-app-shell>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Sizes
|
|
54
|
+
|
|
55
|
+
| CSS property | Default |
|
|
56
|
+
| ------------------------------ | ------- |
|
|
57
|
+
| `--kt-app-shell-sidebar-width` | `240px` |
|
|
58
|
+
| `--kt-app-shell-rail-width` | `64px` |
|
|
59
|
+
| `--kt-app-shell-header-height` | `56px` |
|
|
60
|
+
|
|
61
|
+
## Accessibility
|
|
62
|
+
|
|
63
|
+
The sidebar is an `<aside>` named by `label` — "Sidebar" by default, translated
|
|
64
|
+
through `setStrings` — and the content a `<main>`, so a page built on the shell
|
|
65
|
+
has its landmarks without writing them. The toggle is named after the sidebar
|
|
66
|
+
it controls, with `aria-controls` and `aria-expanded`, so it reads as "Sidebar,
|
|
67
|
+
expanded" or "collapsed" rather than as a picture of a panel.
|
|
68
|
+
|
|
69
|
+
## API
|
|
70
|
+
|
|
71
|
+
| Property | Attribute | Type | Default |
|
|
72
|
+
| ------------- | -------------- | --------- | ------- |
|
|
73
|
+
| `collapsed` | `collapsed` | `boolean` | `false` |
|
|
74
|
+
| `sidebarOpen` | `sidebar-open` | `boolean` | `false` |
|
|
75
|
+
| `breakpoint` | `breakpoint` | `number` | `900` |
|
|
76
|
+
| `noToggle` | `no-toggle` | `boolean` | `false` |
|
|
77
|
+
| `noLandmarks` | `no-landmarks` | `boolean` | `false` |
|
|
78
|
+
| `label` | `label` | `string` | `''` |
|
|
79
|
+
|
|
80
|
+
| Event | Detail |
|
|
81
|
+
| ------------------- | ------------------- |
|
|
82
|
+
| `kt-sidebar-toggle` | `{ open: boolean }` |
|
|
83
|
+
|
|
84
|
+
| Part | Description |
|
|
85
|
+
| --------- | -------------------- |
|
|
86
|
+
| `header` | The top bar |
|
|
87
|
+
| `sidebar` | The `<aside>` |
|
|
88
|
+
| `main` | The `<main>` |
|
|
89
|
+
| `toggle` | The sidebar's toggle |
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# `<kt-auth-form>`
|
|
2
|
+
|
|
3
|
+
The way into a product: signing in, creating an account, resetting a password,
|
|
4
|
+
entering a code — one block, four modes.
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<kt-auth-form remember>
|
|
8
|
+
<img slot="logo" src="/logo.svg" alt="Northwind" height="32" />
|
|
9
|
+
<span slot="footer">By continuing you agree to the <a href="/terms">terms</a>.</span>
|
|
10
|
+
</kt-auth-form>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
const form = document.querySelector('kt-auth-form');
|
|
14
|
+
form.addEventListener('kt-submit', (event) => {
|
|
15
|
+
const { mode, values, wait } = event.detail;
|
|
16
|
+
if (mode === 'sign-in') wait(auth.signIn(values.email, values.password));
|
|
17
|
+
if (mode === 'sign-up') wait(auth.signUp(values));
|
|
18
|
+
if (mode === 'forgot') wait(auth.sendReset(values.email));
|
|
19
|
+
if (mode === 'code') wait(auth.verify(values.code));
|
|
20
|
+
});
|
|
21
|
+
</script>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Modes
|
|
25
|
+
|
|
26
|
+
| `mode` | Asks for | Button |
|
|
27
|
+
| --------- | ---------------------------------------------------- | -------------- |
|
|
28
|
+
| `sign-in` | Email, password; "Keep me signed in" with `remember` | Sign in |
|
|
29
|
+
| `sign-up` | Name, email, a new password | Create account |
|
|
30
|
+
| `forgot` | Email | Send the link |
|
|
31
|
+
| `code` | A one-time code, sent as soon as it is whole | Verify |
|
|
32
|
+
|
|
33
|
+
The links between them — "Forgot password?", "Create an account", "Sign in" —
|
|
34
|
+
move the form itself and fire `kt-mode`; `goTo(mode)` does the same from
|
|
35
|
+
script. Each field has the `autocomplete` a password manager looks for.
|
|
36
|
+
|
|
37
|
+
## Sending
|
|
38
|
+
|
|
39
|
+
Before anything is sent the form checks what it can: an email that is one, a
|
|
40
|
+
password, a name, a new password at least `password-min` long (8), a whole
|
|
41
|
+
code. A field found wanting says why and takes the focus; nothing is sent.
|
|
42
|
+
|
|
43
|
+
Then `kt-submit` carries the `mode`, the `values` and `wait(promise)`. Hand it
|
|
44
|
+
the request: the button runs it — busy, then a tick — and if it rejects, its
|
|
45
|
+
error's message is shown above the fields (`error` sets one by hand). A
|
|
46
|
+
`forgot` that succeeds says the link is on its way. Enter in a field sends, as
|
|
47
|
+
in any form; `submit()` does from script.
|
|
48
|
+
|
|
49
|
+
## Providers
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
form.providers = [
|
|
53
|
+
{ id: 'github', label: 'Continue with GitHub', icon: 'github' },
|
|
54
|
+
{ id: 'google', label: 'Continue with Google' },
|
|
55
|
+
];
|
|
56
|
+
form.addEventListener('kt-provider', (event) => auth.redirect(event.detail.id));
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
They sit above the fields when signing in or up, set apart by "or". Their icons
|
|
60
|
+
are the page's to register.
|
|
61
|
+
|
|
62
|
+
## Words
|
|
63
|
+
|
|
64
|
+
Every word is in `texts`, English until given others — headings, leads, labels,
|
|
65
|
+
buttons, links and messages:
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
form.texts = {
|
|
69
|
+
signInHeading: 'Connexion',
|
|
70
|
+
email: 'Adresse e-mail',
|
|
71
|
+
passwordShort: (least) => `Au moins ${least} caractères.`,
|
|
72
|
+
};
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`heading-level` sets the heading's level — 1 by default, since the form is
|
|
76
|
+
usually the page — and `plain` drops the card around it.
|
|
77
|
+
|
|
78
|
+
## Accessibility
|
|
79
|
+
|
|
80
|
+
A real `<form>`; each field labelled, its error announced with it; the error
|
|
81
|
+
from a failed sending shown in an alert. The links between modes are buttons,
|
|
82
|
+
since they change the form rather than the page.
|
|
83
|
+
|
|
84
|
+
## API
|
|
85
|
+
|
|
86
|
+
| Property | Attribute | Type | Default |
|
|
87
|
+
| -------------- | --------------- | ---------------------- | ----------- |
|
|
88
|
+
| `mode` | `mode` | `KtAuthMode` | `'sign-in'` |
|
|
89
|
+
| `providers` | — | `KtAuthProvider[]` | `[]` |
|
|
90
|
+
| `remember` | `remember` | `boolean` | `false` |
|
|
91
|
+
| `passwordMin` | `password-min` | `number` | `8` |
|
|
92
|
+
| `headingLevel` | `heading-level` | `number` | `1` |
|
|
93
|
+
| `plain` | `plain` | `boolean` | `false` |
|
|
94
|
+
| `error` | — | `string` | `''` |
|
|
95
|
+
| `texts` | — | `Partial<KtAuthTexts>` | `{}` |
|
|
96
|
+
|
|
97
|
+
| Method | Description |
|
|
98
|
+
| ------------ | ------------------------------------- |
|
|
99
|
+
| `submit()` | Checks and sends, as the button does. |
|
|
100
|
+
| `goTo(mode)` | Moves the form to another mode. |
|
|
101
|
+
|
|
102
|
+
| Event | Detail |
|
|
103
|
+
| ------------- | --------------------------------- |
|
|
104
|
+
| `kt-submit` | `{ mode, values, wait(promise) }` |
|
|
105
|
+
| `kt-mode` | `{ mode }` |
|
|
106
|
+
| `kt-provider` | `{ id }` |
|
|
107
|
+
|
|
108
|
+
| Slot | Where |
|
|
109
|
+
| -------- | ------------------------------ |
|
|
110
|
+
| `logo` | Above the heading |
|
|
111
|
+
| `footer` | Under the form: terms, privacy |
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# `<kt-avatar-group>`
|
|
2
|
+
|
|
3
|
+
The people on something — a project's members, a document's editors — as
|
|
4
|
+
avatars overlapping in a row, the rest summed up as "+N".
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<kt-avatar-group label="Project members" max="3"></kt-avatar-group>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
document.querySelector('kt-avatar-group').people = [
|
|
11
|
+
{ name: 'Dana Whitfield' },
|
|
12
|
+
{ name: 'Hank Scorpio', src: '/hank.png' },
|
|
13
|
+
{ name: 'Bill Lumbergh' },
|
|
14
|
+
{ name: 'Gavin Belson' },
|
|
15
|
+
{ name: 'Alice Abernathy' },
|
|
16
|
+
];
|
|
17
|
+
</script>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## People
|
|
21
|
+
|
|
22
|
+
`people` is a list of `{ name, src? }`. Each becomes a `kt-avatar` — the
|
|
23
|
+
picture when there is one, the name's initials otherwise — overlapping the last
|
|
24
|
+
by a third, ringed in the page's colour so the stack reads as one.
|
|
25
|
+
|
|
26
|
+
`max` (4 by default) is how many are shown; the rest are summed up at the end
|
|
27
|
+
as "+N". `size` — `small`, `medium`, `large` — sizes them all, the sum
|
|
28
|
+
included.
|
|
29
|
+
|
|
30
|
+
## Accessibility
|
|
31
|
+
|
|
32
|
+
A list named by `label`, each avatar named by its person. The sum is said as
|
|
33
|
+
"2 more", not "plus two", and is translated through `setStrings` as
|
|
34
|
+
`moreCount`. When the people matter one by one, list them somewhere a person
|
|
35
|
+
can read every name — a tooltip on the group, or the members page it links to.
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
| Property | Attribute | Type | Default |
|
|
40
|
+
| -------- | --------- | -------------------------------- | ---------- |
|
|
41
|
+
| `people` | — | `KtAvatarGroupPerson[]` | `[]` |
|
|
42
|
+
| `max` | `max` | `number` | `4` |
|
|
43
|
+
| `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
|
|
44
|
+
| `label` | `label` | `string` | `''` |
|
|
45
|
+
|
|
46
|
+
| Part | Description |
|
|
47
|
+
| ------ | ------------------- |
|
|
48
|
+
| `list` | The `<ul>` |
|
|
49
|
+
| `more` | The "+N" at the end |
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# `<kt-blog-post>`
|
|
2
|
+
|
|
3
|
+
A post, set to be read: its title, who wrote it and when, a cover, and the
|
|
4
|
+
body in a measure an eye can follow.
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<kt-blog-post
|
|
8
|
+
heading="Closing the month in a day"
|
|
9
|
+
lead="What changed when the bank feed matched itself."
|
|
10
|
+
author="Ada Park"
|
|
11
|
+
author-role="CFO, Northwind"
|
|
12
|
+
date="2026-09-14"
|
|
13
|
+
back-href="/blog"
|
|
14
|
+
>
|
|
15
|
+
<img slot="cover" src="/covers/close.jpg" alt="" />
|
|
16
|
+
<p>For years, the first week of every month was the close.</p>
|
|
17
|
+
<h2>What we changed</h2>
|
|
18
|
+
<p>…</p>
|
|
19
|
+
<div slot="end">
|
|
20
|
+
Filed under Finance. <a href="/blog/reminders">Next: reminders that get paid</a>
|
|
21
|
+
</div>
|
|
22
|
+
</kt-blog-post>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## The body
|
|
26
|
+
|
|
27
|
+
The body is the default slot, and its elements are set as prose: paragraphs,
|
|
28
|
+
`<h2>` and `<h3>`, lists, quotes, `<pre>` and `<kt-code>`, images, figures and
|
|
29
|
+
rules — in a column `--kt-post-measure` wide — 700px, about 70 characters, shared
|
|
30
|
+
with the header so the two line up. What
|
|
31
|
+
is inside them — links, emphasis, code — takes the page's own styles.
|
|
32
|
+
|
|
33
|
+
## Who and when
|
|
34
|
+
|
|
35
|
+
`author`, `author-role` and `avatar` say who wrote it; `date` when, written
|
|
36
|
+
for people in `locale` — Sep 14, 2026 — and kept for machines in a
|
|
37
|
+
`<time datetime>`. The reading time is counted from the body, at 230 words a
|
|
38
|
+
minute, unless `reading-time` gives one. `tags` sit over the title;
|
|
39
|
+
`back-href` adds a link to every post.
|
|
40
|
+
|
|
41
|
+
## Slots
|
|
42
|
+
|
|
43
|
+
| Slot | What goes in it |
|
|
44
|
+
| --------- | ---------------------------------------------------------- |
|
|
45
|
+
| (default) | The body. |
|
|
46
|
+
| `cover` | Under the header, wider than the body: an image, a figure. |
|
|
47
|
+
| `end` | After the body, over a rule: tags, sharing, the next post. |
|
|
48
|
+
|
|
49
|
+
## Words
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
post.texts = { back: 'Tous les articles', minRead: (minutes) => `${minutes} min de lecture` };
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Accessibility
|
|
56
|
+
|
|
57
|
+
An `<article>` named by its title — an `<h1>`, since the post is the page;
|
|
58
|
+
`heading-level` changes it. Headings in the body should start at `<h2>`. The
|
|
59
|
+
avatar repeats the author's name, so it is hidden from assistive tech; a
|
|
60
|
+
cover that only illustrates takes `alt=""`.
|
|
61
|
+
|
|
62
|
+
## API
|
|
63
|
+
|
|
64
|
+
| Property | Attribute | Type | Default |
|
|
65
|
+
| -------------- | --------------- | -------------------------- | ------- |
|
|
66
|
+
| `heading` | `heading` | `string` | `''` |
|
|
67
|
+
| `lead` | `lead` | `string` | `''` |
|
|
68
|
+
| `date` | `date` | `string` | `''` |
|
|
69
|
+
| `author` | `author` | `string` | `''` |
|
|
70
|
+
| `authorRole` | `author-role` | `string` | `''` |
|
|
71
|
+
| `avatar` | `avatar` | `string` | `''` |
|
|
72
|
+
| `readingTime` | `reading-time` | `number` | `0` |
|
|
73
|
+
| `tags` | — | `string[]` | `[]` |
|
|
74
|
+
| `backHref` | `back-href` | `string` | `''` |
|
|
75
|
+
| `locale` | `locale` | `string` | `''` |
|
|
76
|
+
| `headingLevel` | `heading-level` | `number` | `1` |
|
|
77
|
+
| `texts` | — | `Partial<KtBlogPostTexts>` | `{}` |
|
package/dist/docs/kt-button.md
CHANGED
|
@@ -31,6 +31,27 @@ accessible name of its own, so `label` is required:
|
|
|
31
31
|
<kt-button icon="x" label="Close" variant="secondary-no-bg"></kt-button>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## Running an action
|
|
35
|
+
|
|
36
|
+
`run()` takes an async action and shows how it went: busy while it runs —
|
|
37
|
+
clicks ignored, the focus kept — then a tick, or a shake and an alert if it
|
|
38
|
+
throws. Two seconds later the button is back at rest. `done-label` and
|
|
39
|
+
`failed-label` replace the label meanwhile, and are announced.
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<kt-button id="send" icon="send" done-label="Sent" failed-label="Not sent">Send</kt-button>
|
|
43
|
+
<script>
|
|
44
|
+
send.addEventListener('click', () => send.run(() => api.send(message)));
|
|
45
|
+
</script>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
It resolves with what the action resolved with and rejects with what it threw,
|
|
49
|
+
so the caller still handles the error. A second call while one runs gets the
|
|
50
|
+
same promise. A `send` plane turns into the spinner itself while it waits —
|
|
51
|
+
its outline drawn round into a turning arc — and back into the plane, which
|
|
52
|
+
flies off to the top right; other icons give way to a spinner, and fade. Under
|
|
53
|
+
reduced motion only the label and icon change.
|
|
54
|
+
|
|
34
55
|
## Forms
|
|
35
56
|
|
|
36
57
|
A button inside a shadow root is invisible to the enclosing form, so
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# `<kt-chat-message>`
|
|
2
|
+
|
|
3
|
+
One message of a conversation with an assistant.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-chat-message from="user" name="Dana">What changed this week?</kt-chat-message>
|
|
7
|
+
|
|
8
|
+
<kt-chat-message name="Northwind AI" time="09:41" datetime="2026-10-04T09:41">
|
|
9
|
+
<p>Revenue rose 12%, led by three new Team plans.</p>
|
|
10
|
+
<kt-button slot="actions" size="small" variant="text" icon="copy">Copy</kt-button>
|
|
11
|
+
</kt-chat-message>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Who wrote it
|
|
15
|
+
|
|
16
|
+
`from="assistant"`, the default, sets the reply beside its avatar as text on
|
|
17
|
+
the page: a reply is often long, and a bubble around paragraphs, lists and code
|
|
18
|
+
only crowds them. `from="user"` puts a person's message in a bubble on the far
|
|
19
|
+
side, short and clearly theirs.
|
|
20
|
+
|
|
21
|
+
`name` names the message for a screen reader and draws the avatar's initials;
|
|
22
|
+
`avatar` gives it a picture, and the `avatar` slot replaces it altogether — an
|
|
23
|
+
icon, a logo.
|
|
24
|
+
|
|
25
|
+
## Thinking and streaming
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<kt-chat-message name="Northwind AI" thinking></kt-chat-message>
|
|
29
|
+
<kt-chat-message name="Northwind AI" streaming>Revenue rose</kt-chat-message>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`thinking` shows three dots — and says "Thinking…" to a screen reader — in
|
|
33
|
+
place of the content, until the reply has a word of its own. `streaming` marks
|
|
34
|
+
the end of a reply still arriving with a caret. Both set `aria-busy` on the
|
|
35
|
+
message, and both hold still under reduced motion.
|
|
36
|
+
|
|
37
|
+
## Content
|
|
38
|
+
|
|
39
|
+
The message is the default slot. Render markdown into it as you would anywhere
|
|
40
|
+
else; the first and last child lose their outer margins so a paragraph sits
|
|
41
|
+
flush in the bubble.
|
|
42
|
+
|
|
43
|
+
## Accessibility
|
|
44
|
+
|
|
45
|
+
An `<article>` named by `name`. The time is a `<time>`, with `datetime` for the
|
|
46
|
+
machine-readable moment. Actions in the `actions` slot stay visible: a control
|
|
47
|
+
that appears only on hover cannot be reached by touch, and is hard to find from
|
|
48
|
+
the keyboard. Put the messages in a list or a log, and announce new ones from
|
|
49
|
+
there — a message cannot know it is the newest.
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
| Property | Attribute | Type | Default |
|
|
54
|
+
| ----------- | ----------- | ----------------------- | ------------- |
|
|
55
|
+
| `from` | `from` | `'assistant' \| 'user'` | `'assistant'` |
|
|
56
|
+
| `name` | `name` | `string` | `''` |
|
|
57
|
+
| `avatar` | `avatar` | `string` | `''` |
|
|
58
|
+
| `time` | `time` | `string` | `''` |
|
|
59
|
+
| `datetime` | `datetime` | `string` | `''` |
|
|
60
|
+
| `thinking` | `thinking` | `boolean` | `false` |
|
|
61
|
+
| `streaming` | `streaming` | `boolean` | `false` |
|
|
62
|
+
|
|
63
|
+
| Part | Description |
|
|
64
|
+
| --------- | ------------------- |
|
|
65
|
+
| `base` | The `<article>` |
|
|
66
|
+
| `bubble` | A person's bubble |
|
|
67
|
+
| `content` | The message |
|
|
68
|
+
| `meta` | The author and time |
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# `<kt-color-picker>`
|
|
2
|
+
|
|
3
|
+
A colour, chosen from swatches or set freely: a label's colour, a theme's
|
|
4
|
+
accent, a chart series.
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<kt-color-picker label="Label colour" name="colour" value="#1f6feb"></kt-color-picker>
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Swatches
|
|
11
|
+
|
|
12
|
+
The swatches are Kanto's accents until `swatches` gives others — a list of
|
|
13
|
+
`{ value, label? }`, each a hex colour and the name a screen reader says for it:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
picker.swatches = [
|
|
17
|
+
{ value: '#e11d48', label: 'Rose' },
|
|
18
|
+
{ value: '#f59e0b', label: 'Amber' },
|
|
19
|
+
{ value: '#10b981', label: 'Emerald' },
|
|
20
|
+
];
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
They are a radio group: a click picks one, the arrows move and pick, wrapping,
|
|
24
|
+
and the chosen one wears a ring in its own colour.
|
|
25
|
+
|
|
26
|
+
## Any colour
|
|
27
|
+
|
|
28
|
+
Beside the swatches, the free colour: a swatch that opens the system's own
|
|
29
|
+
picker, and a hex field that takes a colour once it is a whole one — `#e11d48`,
|
|
30
|
+
`e11d48` or `#e14`, all read as `#ee1144`'s spelling, `#rrggbb` in lower case.
|
|
31
|
+
The free swatch takes the colour when it is none of the presets.
|
|
32
|
+
`no-custom` keeps to the swatches.
|
|
33
|
+
|
|
34
|
+
## Forms
|
|
35
|
+
|
|
36
|
+
A form control, submitted as `#rrggbb` under `name`, reset to its first
|
|
37
|
+
`value` with the form, disabled with a disabled fieldset. `kt-change` fires as
|
|
38
|
+
the colour changes, from a swatch, the picker or the field.
|
|
39
|
+
|
|
40
|
+
## Accessibility
|
|
41
|
+
|
|
42
|
+
A radio group named by `label`, each swatch named by its colour's `label` — a
|
|
43
|
+
person who cannot tell the swatches apart by sight hears "Blue, radio button,
|
|
44
|
+
checked". The system picker and the hex field are named "Custom colour" and
|
|
45
|
+
"Hex code", translated through `setStrings` as `customColour` and `hexColour`.
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
| Property | Attribute | Type | Default |
|
|
50
|
+
| ---------- | ----------- | ----------------- | --------------- |
|
|
51
|
+
| `value` | `value` | `string` | `''` |
|
|
52
|
+
| `swatches` | — | `KtColorSwatch[]` | Kanto's accents |
|
|
53
|
+
| `label` | `label` | `string` | `''` |
|
|
54
|
+
| `name` | `name` | `string` | `''` |
|
|
55
|
+
| `disabled` | `disabled` | `boolean` | `false` |
|
|
56
|
+
| `noCustom` | `no-custom` | `boolean` | `false` |
|
|
57
|
+
|
|
58
|
+
| Event | Detail |
|
|
59
|
+
| ----------- | ------------------- |
|
|
60
|
+
| `kt-change` | `{ value: string }` |
|
|
61
|
+
|
|
62
|
+
| Part | Description |
|
|
63
|
+
| ---------- | ------------------------ |
|
|
64
|
+
| `swatches` | The radio group |
|
|
65
|
+
| `swatch` | One swatch |
|
|
66
|
+
| `custom` | The free colour's swatch |
|
|
67
|
+
| `hex` | The hex field |
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# `<kt-command-palette>`
|
|
2
|
+
|
|
3
|
+
The palette a product opens on Cmd+K: every action and page, a few keystrokes away.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-command-palette></kt-command-palette>
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
palette.commands = [
|
|
11
|
+
{ id: 'new-invoice', label: 'New invoice', group: 'Create', shortcut: 'mod i' },
|
|
12
|
+
{ id: 'new-customer', label: 'New customer', group: 'Create', keywords: ['client'] },
|
|
13
|
+
{ id: 'settings', label: 'Open settings', group: 'Navigate', icon: 'settings' },
|
|
14
|
+
{ id: 'export', label: 'Export as CSV', group: 'Actions', disabled: true },
|
|
15
|
+
];
|
|
16
|
+
palette.addEventListener('kt-select', (e) => run(e.detail.id));
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Opening it
|
|
20
|
+
|
|
21
|
+
Cmd+K on a Mac, Ctrl+K elsewhere, opens and closes it from anywhere on the
|
|
22
|
+
page — inside a field too, as people expect. `hotkey` sets another letter;
|
|
23
|
+
`hotkey=""` turns the shortcut off, for a page that opens it from a button of
|
|
24
|
+
its own (`palette.open = true`). Each opening starts from an empty search.
|
|
25
|
+
|
|
26
|
+
## Finding a command
|
|
27
|
+
|
|
28
|
+
Typing narrows the list. Every word typed must appear, in any order, in the
|
|
29
|
+
command's label, one of its `keywords` or its `group`, ignoring case and
|
|
30
|
+
accents — "client" finds New customer, "preferences" finds Préférences. What
|
|
31
|
+
remains ranks by how it matched:
|
|
32
|
+
|
|
33
|
+
1. a label that starts with the search;
|
|
34
|
+
2. a label in which each word starts a word;
|
|
35
|
+
3. a label that holds the search anywhere;
|
|
36
|
+
4. a match on a keyword or the group only.
|
|
37
|
+
|
|
38
|
+
Commands that tie keep the order you gave them, so the list reads the way you
|
|
39
|
+
wrote it. A disabled command stays listed — its absence would be a mystery —
|
|
40
|
+
and cannot be run.
|
|
41
|
+
|
|
42
|
+
## Keyboard
|
|
43
|
+
|
|
44
|
+
| Key | Does |
|
|
45
|
+
| ------------ | -------------------------------------------------------------- |
|
|
46
|
+
| `↑` / `↓` | the previous or next command, skipping disabled ones, wrapping |
|
|
47
|
+
| `Home`/`End` | the first or last command |
|
|
48
|
+
| `Enter` | runs the active command, and closes |
|
|
49
|
+
| `Escape` | closes, and gives the focus back to where it was |
|
|
50
|
+
|
|
51
|
+
A click runs a command too; a click outside the panel closes it.
|
|
52
|
+
|
|
53
|
+
## Commands
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
interface KtCommand {
|
|
57
|
+
id: string;
|
|
58
|
+
label: string;
|
|
59
|
+
group?: string; // the heading it is listed under
|
|
60
|
+
icon?: string; // a Lucide name
|
|
61
|
+
keywords?: string[]; // other words it answers to
|
|
62
|
+
shortcut?: string; // keys shown beside it, as <kt-kbd keys> takes them
|
|
63
|
+
disabled?: boolean;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Groups appear in the order their first command does. A shortcut is only shown:
|
|
68
|
+
binding it is the application's work.
|
|
69
|
+
|
|
70
|
+
## API
|
|
71
|
+
|
|
72
|
+
| Property | Attribute | Type | Default |
|
|
73
|
+
| ------------- | ------------- | ------------- | ----------------- |
|
|
74
|
+
| `commands` | — | `KtCommand[]` | `[]` |
|
|
75
|
+
| `open` | `open` | `boolean` | `false` |
|
|
76
|
+
| `hotkey` | `hotkey` | `string` | `'k'` |
|
|
77
|
+
| `placeholder` | `placeholder` | `string` | from `setStrings` |
|
|
78
|
+
|
|
79
|
+
| Event | Detail |
|
|
80
|
+
| ----------- | ------------------------------------ |
|
|
81
|
+
| `kt-select` | `{ id: string, command: KtCommand }` |
|
|
82
|
+
| `kt-open` | — |
|
|
83
|
+
| `kt-close` | — |
|
|
84
|
+
|
|
85
|
+
| Part | Description |
|
|
86
|
+
| -------- | ------------------ |
|
|
87
|
+
| `dialog` | The `<dialog>` |
|
|
88
|
+
| `input` | The search field |
|
|
89
|
+
| `list` | The scrolling list |
|
|
90
|
+
| `footer` | The keyboard hints |
|
|
91
|
+
|
|
92
|
+
## Accessibility
|
|
93
|
+
|
|
94
|
+
Built on the native `<dialog>`: the top layer, focus containment and the inert
|
|
95
|
+
page come from the platform. The field is a `combobox` over a `listbox`; the
|
|
96
|
+
active command is its `aria-activedescendant`, so a screen reader reads each
|
|
97
|
+
command as the arrows reach it, and each group is a `group` named by its
|
|
98
|
+
heading. The focus goes to the field on opening and back to where it was on
|
|
99
|
+
closing.
|