kanto-ds 1.6.1 → 1.7.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 +52 -4
- package/dist/cdn/kanto.min.js +6619 -0
- package/dist/chunks/{floating-B33g-M_1.js → floating-C9RLa6cZ.js} +2 -2
- package/dist/chunks/floating-C9RLa6cZ.js.map +1 -0
- package/dist/components/forms/kt-date-input/kt-date-input.js +1 -1
- package/dist/components/forms/kt-date-picker/kt-date-picker.js +1 -1
- package/dist/components/forms/kt-input/kt-input.js +1 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +1 -1
- package/dist/components/forms/kt-multi-select/kt-multi-select.js +1 -1
- package/dist/components/forms/kt-select/kt-select.js +1 -1
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +1 -1
- package/dist/docs/kt-alert.md +52 -0
- package/dist/docs/kt-avatar.md +46 -0
- package/dist/docs/kt-badge.md +104 -0
- package/dist/docs/kt-breadcrumb.md +53 -0
- package/dist/docs/kt-button.md +72 -0
- package/dist/docs/kt-calendar.md +98 -0
- package/dist/docs/kt-card.md +93 -0
- package/dist/docs/kt-chart.md +230 -0
- package/dist/docs/kt-checkbox.md +65 -0
- package/dist/docs/kt-code.md +88 -0
- package/dist/docs/kt-collapsible.md +50 -0
- package/dist/docs/kt-confirm-dialog.md +52 -0
- package/dist/docs/kt-date-input.md +97 -0
- package/dist/docs/kt-date-picker.md +116 -0
- package/dist/docs/kt-drag-drop.md +85 -0
- package/dist/docs/kt-dropdown.md +65 -0
- package/dist/docs/kt-empty-state.md +36 -0
- package/dist/docs/kt-form.md +93 -0
- package/dist/docs/kt-header.md +100 -0
- package/dist/docs/kt-icon.md +68 -0
- package/dist/docs/kt-input-menu.md +90 -0
- package/dist/docs/kt-input.md +137 -0
- package/dist/docs/kt-kbd.md +44 -0
- package/dist/docs/kt-label-input.md +54 -0
- package/dist/docs/kt-meter.md +79 -0
- package/dist/docs/kt-modal.md +62 -0
- package/dist/docs/kt-multi-select.md +115 -0
- package/dist/docs/kt-page-header.md +53 -0
- package/dist/docs/kt-pagination.md +36 -0
- package/dist/docs/kt-progress-bar.md +66 -0
- package/dist/docs/kt-radio-group.md +73 -0
- package/dist/docs/kt-segmented-control.md +70 -0
- package/dist/docs/kt-select.md +80 -0
- package/dist/docs/kt-side-panel.md +59 -0
- package/dist/docs/kt-skeleton.md +46 -0
- package/dist/docs/kt-split-button.md +105 -0
- package/dist/docs/kt-stat.md +57 -0
- package/dist/docs/kt-sub-menu-navigation.md +118 -0
- package/dist/docs/kt-table.md +179 -0
- package/dist/docs/kt-tabs.md +87 -0
- package/dist/docs/kt-textarea.md +59 -0
- package/dist/docs/kt-time-input.md +88 -0
- package/dist/docs/kt-timeline.md +63 -0
- package/dist/docs/kt-toast-container.md +69 -0
- package/dist/docs/kt-toast.md +41 -0
- package/dist/docs/kt-toggle-button-group.md +67 -0
- package/dist/docs/kt-toggle-button.md +52 -0
- package/dist/docs/kt-toggle.md +47 -0
- package/dist/docs/kt-tooltip.md +68 -0
- package/dist/internal/floating.d.ts +4 -0
- package/dist/tokens/colors.css +5 -2
- package/dist/web-types.json +1 -1
- package/package.json +23 -5
- package/dist/chunks/floating-B33g-M_1.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { p as r } from "./position-Cx_ZH5zh.js";
|
|
|
3
3
|
const p = n`
|
|
4
4
|
.floating {
|
|
5
5
|
position: fixed;
|
|
6
|
-
inset: auto;
|
|
6
|
+
inset: 0 auto auto 0;
|
|
7
7
|
display: block;
|
|
8
8
|
/* As wide as what it holds, wherever it is placed: a box sized from its
|
|
9
9
|
position would change size when moved, and be moved again. */
|
|
@@ -60,4 +60,4 @@ export {
|
|
|
60
60
|
d as F,
|
|
61
61
|
p as f
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=floating-
|
|
63
|
+
//# sourceMappingURL=floating-C9RLa6cZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating-C9RLa6cZ.js","sources":["../../src/internal/floating.ts"],"sourcesContent":["import { css, type ReactiveController, type ReactiveControllerHost } from 'lit';\nimport { placeFloating, type Align, type Side } from './position.js';\n\n/**\n * A panel that opens from a trigger — a select's list, a date picker's\n * calendar, a menu — drawn in the top layer and placed from the trigger.\n *\n * A panel positioned inside its element was cut off by any ancestor with\n * `overflow: hidden`: a table cell, a side panel, an app's scrolling main\n * area. In the top layer, nothing clips it. It opens on the side asked for, or\n * the other one when that has no room, and follows the trigger as the page\n * scrolls.\n */\n\nexport interface FloatingOptions {\n /** The panel, which carries `popover=\"manual\"` and the `floating` class. */\n readonly panel: () => HTMLElement | null | undefined;\n /** What the panel opens from. */\n readonly anchor: () => Element | null | undefined;\n /** The side it prefers. */\n readonly side?: () => Side;\n /** Which edge of the anchor it lines up with; its start by default. */\n readonly align?: () => Align;\n /** Sizes the panel to the anchor's width — a list under its field. */\n readonly matchWidth?: boolean;\n /** Told the side it opened on, for the direction of its entrance. */\n readonly onPlace?: (side: Side) => void;\n}\n\n/**\n * The panel's own styles. Closed, it keeps the display and the hidden,\n * animatable state its element gives it, so it can fade out after it leaves\n * the top layer: `display` here only undoes the popover's `display: none`, and\n * a panel's own `display` still wins.\n *\n * Until it is first placed it sits top left. With auto insets a closed panel\n * sat where the flow put it — beside a right-hand trigger, past the edge of\n * the page, which then scrolled sideways.\n */\nexport const floatingStyles = css`\n .floating {\n position: fixed;\n inset: 0 auto auto 0;\n display: block;\n /* As wide as what it holds, wherever it is placed: a box sized from its\n position would change size when moved, and be moved again. */\n width: max-content;\n margin: 0;\n color: inherit;\n /* Set apart from the page by the theme: a lighter surface in the dark,\n an edge and a soft shadow in the light. */\n border: var(--border-width) solid var(--border-popover);\n box-shadow: var(--shadow-popover);\n }\n`;\n\nexport class FloatingController implements ReactiveController {\n private open = false;\n private frame = 0;\n /** Places the panel again when its size changes — content drawn after it opened. */\n private resizeObserver: ResizeObserver | undefined;\n\n constructor(\n host: ReactiveControllerHost,\n private readonly options: FloatingOptions,\n ) {\n host.addController(this);\n }\n\n /**\n * Call from the host's `updated()` with whether the panel is open. While it\n * is, every update re-places it: its content — a filtered list — can change\n * its size.\n */\n sync(open: boolean): void {\n // First, and whatever the panel: one rendered only while open is already\n // gone when it closes, and its listeners must go with it.\n if (open !== this.open) {\n this.open = open;\n const method = open ? 'addEventListener' : 'removeEventListener';\n window[method]('scroll', this.follow, { capture: true, passive: true });\n window[method]('resize', this.follow);\n }\n\n const panel = this.options.panel();\n // Where popovers are missing — a test DOM — the panel stays where it is.\n if (!panel || typeof panel.showPopover !== 'function') return;\n\n if (open) {\n if (!panel.matches(':popover-open')) panel.showPopover();\n this.place();\n // A panel measured at opening may grow once what it holds has drawn —\n // a calendar is an element of its own — and must be placed again.\n if (!this.resizeObserver && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(this.follow);\n this.resizeObserver.observe(panel);\n }\n } else {\n this.unobserve();\n if (panel.matches(':popover-open')) panel.hidePopover();\n }\n }\n\n private unobserve(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n\n hostDisconnected(): void {\n this.sync(false);\n this.unobserve();\n cancelAnimationFrame(this.frame);\n }\n\n private follow = (): void => {\n cancelAnimationFrame(this.frame);\n this.frame = requestAnimationFrame(() => this.place());\n };\n\n private place(): void {\n const panel = this.options.panel();\n const anchor = this.options.anchor()?.getBoundingClientRect();\n if (!panel || !anchor) return;\n\n if (this.options.matchWidth) panel.style.width = `${anchor.width}px`;\n // Untransformed size: the entrance animation scales and slides the panel.\n const { x, y, placement } = placeFloating(\n anchor,\n { width: panel.offsetWidth, height: panel.offsetHeight },\n { width: window.innerWidth, height: window.innerHeight },\n this.options.side?.() ?? 'bottom',\n this.options.align?.() ?? 'start',\n );\n panel.style.left = `${x}px`;\n panel.style.top = `${y}px`;\n this.options.onPlace?.(placement);\n }\n}\n"],"names":["floatingStyles","css","FloatingController","host","options","open","method","panel","anchor","x","y","placement","placeFloating"],"mappings":";;AAuCO,MAAMA,IAAiBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBvB,MAAMC,EAAiD;AAAA,EAM5D,YACEC,GACiBC,GACjB;AADiB,SAAA,UAAAA,GAPnB,KAAQ,OAAO,IACf,KAAQ,QAAQ,GAwDhB,KAAQ,SAAS,MAAY;AAC3B,2BAAqB,KAAK,KAAK,GAC/B,KAAK,QAAQ,sBAAsB,MAAM,KAAK,OAAO;AAAA,IACvD,GAnDED,EAAK,cAAc,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAKE,GAAqB;AAGxB,QAAIA,MAAS,KAAK,MAAM;AACtB,WAAK,OAAOA;AACZ,YAAMC,IAASD,IAAO,qBAAqB;AAC3C,aAAOC,CAAM,EAAE,UAAU,KAAK,QAAQ,EAAE,SAAS,IAAM,SAAS,IAAM,GACtE,OAAOA,CAAM,EAAE,UAAU,KAAK,MAAM;AAAA,IACtC;AAEA,UAAMC,IAAQ,KAAK,QAAQ,MAAA;AAE3B,IAAI,CAACA,KAAS,OAAOA,EAAM,eAAgB,eAEvCF,KACGE,EAAM,QAAQ,eAAe,OAAS,YAAA,GAC3C,KAAK,MAAA,GAGD,CAAC,KAAK,kBAAkB,OAAO,iBAAmB,QACpD,KAAK,iBAAiB,IAAI,eAAe,KAAK,MAAM,GACpD,KAAK,eAAe,QAAQA,CAAK,OAGnC,KAAK,UAAA,GACDA,EAAM,QAAQ,eAAe,OAAS,YAAA;AAAA,EAE9C;AAAA,EAEQ,YAAkB;AACxB,SAAK,gBAAgB,WAAA,GACrB,KAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,mBAAyB;AACvB,SAAK,KAAK,EAAK,GACf,KAAK,UAAA,GACL,qBAAqB,KAAK,KAAK;AAAA,EACjC;AAAA,EAOQ,QAAc;AACpB,UAAMA,IAAQ,KAAK,QAAQ,MAAA,GACrBC,IAAS,KAAK,QAAQ,OAAA,GAAU,sBAAA;AACtC,QAAI,CAACD,KAAS,CAACC,EAAQ;AAEvB,IAAI,KAAK,QAAQ,eAAYD,EAAM,MAAM,QAAQ,GAAGC,EAAO,KAAK;AAEhE,UAAM,EAAE,GAAAC,GAAG,GAAAC,GAAG,WAAAC,EAAA,IAAcC;AAAA,MAC1BJ;AAAA,MACA,EAAE,OAAOD,EAAM,aAAa,QAAQA,EAAM,aAAA;AAAA,MAC1C,EAAE,OAAO,OAAO,YAAY,QAAQ,OAAO,YAAA;AAAA,MAC3C,KAAK,QAAQ,OAAA,KAAY;AAAA,MACzB,KAAK,QAAQ,aAAa;AAAA,IAAA;AAE5B,IAAAA,EAAM,MAAM,OAAO,GAAGE,CAAC,MACvBF,EAAM,MAAM,MAAM,GAAGG,CAAC,MACtB,KAAK,QAAQ,UAAUC,CAAS;AAAA,EAClC;AACF;"}
|
|
@@ -3,7 +3,7 @@ import { property as w, state as x, query as $ } from "lit/decorators.js";
|
|
|
3
3
|
import { classMap as C } from "lit/directives/class-map.js";
|
|
4
4
|
import { d as P } from "../../../chunks/kt-element-T0VbIBNp.js";
|
|
5
5
|
import { u as S, t as I } from "../../../chunks/events-r51msXNf.js";
|
|
6
|
-
import { F as q, f as E } from "../../../chunks/floating-
|
|
6
|
+
import { F as q, f as E } from "../../../chunks/floating-C9RLa6cZ.js";
|
|
7
7
|
import { K as f } from "../../../chunks/segmented-field-BBXR4XFL.js";
|
|
8
8
|
import { d as y, p as u, t as v, c as b, f as Y } from "../../../chunks/kt-calendar-CtwOby1R.js";
|
|
9
9
|
import { d as K, e as L, t as M } from "../../../chunks/typed-date-CPAUNHzr.js";
|
|
@@ -5,7 +5,7 @@ import { live as O } from "lit/directives/live.js";
|
|
|
5
5
|
import { K as D, d as R } from "../../../chunks/kt-element-T0VbIBNp.js";
|
|
6
6
|
import { u as q, t as E, e as v } from "../../../chunks/events-r51msXNf.js";
|
|
7
7
|
import { a as B, s as F, b as L } from "../../../chunks/form-control-B74_EHtG.js";
|
|
8
|
-
import { F as z, f as K } from "../../../chunks/floating-
|
|
8
|
+
import { F as z, f as K } from "../../../chunks/floating-C9RLa6cZ.js";
|
|
9
9
|
import { r as M, d as _ } from "../../../chunks/locale-C5xLkGx5.js";
|
|
10
10
|
import { s as f } from "../../../chunks/index-TWJzttLX.js";
|
|
11
11
|
import { a as P, p as u, c as g, b as w, t as m, e as k, f as C, g as V, h as I, d as W } from "../../../chunks/kt-calendar-CtwOby1R.js";
|
|
@@ -5,7 +5,7 @@ import { live as w } from "lit/directives/live.js";
|
|
|
5
5
|
import { K as g, d as $ } from "../../../chunks/kt-element-T0VbIBNp.js";
|
|
6
6
|
import { t as C, e as c } from "../../../chunks/events-r51msXNf.js";
|
|
7
7
|
import { a as S, s as b, b as E } from "../../../chunks/form-control-B74_EHtG.js";
|
|
8
|
-
import { F as O, f as z } from "../../../chunks/floating-
|
|
8
|
+
import { F as O, f as z } from "../../../chunks/floating-C9RLa6cZ.js";
|
|
9
9
|
import { s as u } from "../../../chunks/index-TWJzttLX.js";
|
|
10
10
|
import "../../core/kt-icon/kt-icon.js";
|
|
11
11
|
import "../../feedback/kt-tooltip/kt-tooltip.js";
|
|
@@ -6,7 +6,7 @@ import { K as m, d as $ } from "../../../chunks/kt-element-T0VbIBNp.js";
|
|
|
6
6
|
import { u as I, t as y, e as f } from "../../../chunks/events-r51msXNf.js";
|
|
7
7
|
import { a as D, s as q, b as O } from "../../../chunks/form-control-B74_EHtG.js";
|
|
8
8
|
import { a as S, b as C, o as g, f as v, l as P, n as E } from "../../../chunks/listbox-LsUEyGhQ.js";
|
|
9
|
-
import { F as L, f as A } from "../../../chunks/floating-
|
|
9
|
+
import { F as L, f as A } from "../../../chunks/floating-C9RLa6cZ.js";
|
|
10
10
|
import { s as l } from "../../../chunks/index-TWJzttLX.js";
|
|
11
11
|
import "../../core/kt-icon/kt-icon.js";
|
|
12
12
|
var V = Object.defineProperty, i = (u, t, o, r) => {
|
|
@@ -6,7 +6,7 @@ import { K as $, d as P } from "../../../chunks/kt-element-T0VbIBNp.js";
|
|
|
6
6
|
import { u as C, t as I, e as D } from "../../../chunks/events-r51msXNf.js";
|
|
7
7
|
import { a as L, s as z, b as B } from "../../../chunks/form-control-B74_EHtG.js";
|
|
8
8
|
import { a as T, b as F, f as y, l as V, n as _, o as w } from "../../../chunks/listbox-LsUEyGhQ.js";
|
|
9
|
-
import { F as A, f as W } from "../../../chunks/floating-
|
|
9
|
+
import { F as A, f as W } from "../../../chunks/floating-C9RLa6cZ.js";
|
|
10
10
|
import { s as p } from "../../../chunks/index-TWJzttLX.js";
|
|
11
11
|
import "../../core/kt-icon/kt-icon.js";
|
|
12
12
|
var K = Object.defineProperty, r = (m, t, i, e) => {
|
|
@@ -5,7 +5,7 @@ import { K as v, d as w } from "../../../chunks/kt-element-T0VbIBNp.js";
|
|
|
5
5
|
import { u as k, t as g, e as m } from "../../../chunks/events-r51msXNf.js";
|
|
6
6
|
import { a as $, s as I, b as D } from "../../../chunks/form-control-B74_EHtG.js";
|
|
7
7
|
import { a as S, f as b, l as L, n as C, o as y } from "../../../chunks/listbox-LsUEyGhQ.js";
|
|
8
|
-
import { F as E, f as P } from "../../../chunks/floating-
|
|
8
|
+
import { F as E, f as P } from "../../../chunks/floating-C9RLa6cZ.js";
|
|
9
9
|
import { s as l } from "../../../chunks/index-TWJzttLX.js";
|
|
10
10
|
import "../../core/kt-icon/kt-icon.js";
|
|
11
11
|
var q = Object.defineProperty, i = (c, e, o, a) => {
|
|
@@ -4,7 +4,7 @@ import { classMap as u } from "lit/directives/class-map.js";
|
|
|
4
4
|
import { K as c, d as b } from "../../../chunks/kt-element-T0VbIBNp.js";
|
|
5
5
|
import { t as m, e as d } from "../../../chunks/events-r51msXNf.js";
|
|
6
6
|
import { o as x } from "../../../chunks/listbox-LsUEyGhQ.js";
|
|
7
|
-
import { F as w, f as k } from "../../../chunks/floating-
|
|
7
|
+
import { F as w, f as k } from "../../../chunks/floating-C9RLa6cZ.js";
|
|
8
8
|
import { s as $ } from "../../../chunks/index-TWJzttLX.js";
|
|
9
9
|
var P = Object.defineProperty, r = (i, t, s, a) => {
|
|
10
10
|
for (var o = void 0, l = i.length - 1, g; l >= 0; l--)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# `<kt-alert>`
|
|
2
|
+
|
|
3
|
+
A message that stays on the page.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-alert
|
|
7
|
+
variant="warning"
|
|
8
|
+
heading="Storage almost full"
|
|
9
|
+
description="You are using 88% of your quota."
|
|
10
|
+
dismissible
|
|
11
|
+
>
|
|
12
|
+
<kt-button slot="actions" size="small" variant="warning">Upgrade</kt-button>
|
|
13
|
+
</kt-alert>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Against a toast
|
|
17
|
+
|
|
18
|
+
A **toast** is transient and interrupts; it belongs to the moment. An **alert**
|
|
19
|
+
sits in the layout and waits; it belongs to the page.
|
|
20
|
+
|
|
21
|
+
A form that failed to save, a trial about to expire, a consent notice — all
|
|
22
|
+
alerts. "Saved", "Copied", "3 rows deleted" — all toasts. Getting this backwards
|
|
23
|
+
is how important messages disappear after four seconds.
|
|
24
|
+
|
|
25
|
+
## Colour and urgency
|
|
26
|
+
|
|
27
|
+
The whole block takes the variant's tint and border, so the message's
|
|
28
|
+
temperature is legible before a word is read. `danger` is `aria-live="assertive"`
|
|
29
|
+
and interrupts the screen reader; everything else is polite and waits its turn.
|
|
30
|
+
|
|
31
|
+
`dismissible` adds the button and fires `kt-close` — **removing the alert is
|
|
32
|
+
yours**, because only the caller knows whether it should come back.
|
|
33
|
+
|
|
34
|
+
## API
|
|
35
|
+
|
|
36
|
+
| Property | Attribute | Type | Default |
|
|
37
|
+
| ------------- | ------------- | ----------------------------------------------------------- | -------- |
|
|
38
|
+
| `variant` | `variant` | `'info' \| 'success' \| 'warning' \| 'danger' \| 'neutral'` | `'info'` |
|
|
39
|
+
| `heading` | `heading` | `string` | `''` |
|
|
40
|
+
| `description` | `description` | `string` | `''` |
|
|
41
|
+
| `dismissible` | `dismissible` | `boolean` | `false` |
|
|
42
|
+
| `noIcon` | `no-icon` | `boolean` | `false` |
|
|
43
|
+
| `icon` | `icon` | `string` | `''` |
|
|
44
|
+
|
|
45
|
+
| Slot | Description |
|
|
46
|
+
| --------- | ------------------------------------ |
|
|
47
|
+
| _default_ | Body, when `description` is not used |
|
|
48
|
+
| `actions` | Buttons, at the end |
|
|
49
|
+
|
|
50
|
+
| Event | Description |
|
|
51
|
+
| ---------- | ------------------------------ |
|
|
52
|
+
| `kt-close` | The dismiss button was pressed |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# `<kt-avatar>`
|
|
2
|
+
|
|
3
|
+
A person or an organisation, as a picture or as their initials.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-avatar name="Benjamin Canac"></kt-avatar>
|
|
7
|
+
<kt-avatar name="Emma Davis" src="/emma.jpg" status="online"></kt-avatar>
|
|
8
|
+
<kt-avatar name="Kanto Studio" square size="large"></kt-avatar>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## The fallback is the main path
|
|
12
|
+
|
|
13
|
+
Most rows in most products have no photo, so the initials are what actually
|
|
14
|
+
renders. They are derived from the name — first and last word, or the first two
|
|
15
|
+
letters of a single word — and an email address is read as one, so
|
|
16
|
+
`emma.davis@example.com` becomes `ED`.
|
|
17
|
+
|
|
18
|
+
The colour is picked from the name, which means **the same person is the same
|
|
19
|
+
colour on every screen**. That is not decoration: it lets the eye find a row
|
|
20
|
+
before it has read it. Override it with `color` when the entity has a brand of
|
|
21
|
+
its own.
|
|
22
|
+
|
|
23
|
+
A photo that fails to load falls back to the initials rather than to a broken
|
|
24
|
+
image. Changing `src` clears that failure, so a retry is a property assignment.
|
|
25
|
+
|
|
26
|
+
## API
|
|
27
|
+
|
|
28
|
+
| Property | Attribute | Type | Default |
|
|
29
|
+
| -------- | --------- | ------------------------------------------- | ---------- |
|
|
30
|
+
| `name` | `name` | `string` | `''` |
|
|
31
|
+
| `src` | `src` | `string` | `''` |
|
|
32
|
+
| `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
|
|
33
|
+
| `square` | `square` | `boolean` | `false` |
|
|
34
|
+
| `status` | `status` | `'online' \| 'away' \| 'busy' \| 'offline'` | — |
|
|
35
|
+
| `color` | `color` | `string` | `''` |
|
|
36
|
+
|
|
37
|
+
Sizes are 24 / 32 / 48px, and everything inside scales from
|
|
38
|
+
`--kt-avatar-size`, so overriding that one property resizes the whole thing.
|
|
39
|
+
|
|
40
|
+
| Part | Description |
|
|
41
|
+
| ------- | ----------- |
|
|
42
|
+
| `base` | The circle |
|
|
43
|
+
| `image` | The `<img>` |
|
|
44
|
+
|
|
45
|
+
`initialsOf(name)` is exported too, for the cases where you need the same
|
|
46
|
+
letters somewhere else.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# `<kt-badge>`
|
|
2
|
+
|
|
3
|
+
A compact label: a pill `tag`, a monospaced `code` token, a `category` tinted
|
|
4
|
+
with a colour of your choosing, or a `count`.
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<kt-badge>Design systems</kt-badge>
|
|
8
|
+
<kt-badge tone="success">Active</kt-badge>
|
|
9
|
+
<kt-badge variant="code">--surface-card</kt-badge>
|
|
10
|
+
<kt-badge variant="category" color="#3987e5">Infrastructure</kt-badge>
|
|
11
|
+
<kt-badge variant="count" tone="danger" max="99">128</kt-badge>
|
|
12
|
+
<kt-badge icon="user" removable>Assigned to me</kt-badge>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Shape and colour are separate
|
|
16
|
+
|
|
17
|
+
`variant` is the **shape** — what kind of thing this is. `tone` is the
|
|
18
|
+
**colour** — what it means. They are separate properties because they answer
|
|
19
|
+
different questions: a tag can be neutral or dangerous, and so can a count.
|
|
20
|
+
Folding them into one list would give you nine variants and still no way to say
|
|
21
|
+
"a tag, but this one is a warning".
|
|
22
|
+
|
|
23
|
+
| `variant` | What it is |
|
|
24
|
+
| ---------- | ---------------------------------------------------- |
|
|
25
|
+
| `tag` | The default. A pill: a label, a filter, a topic. |
|
|
26
|
+
| `code` | A monospaced token — a property name, a flag, a key. |
|
|
27
|
+
| `category` | Tinted with `color`, for a palette the data owns. |
|
|
28
|
+
| `count` | A number pinned to something else. |
|
|
29
|
+
|
|
30
|
+
`count` is the one shape with no border. A number on a nav item is a mark on
|
|
31
|
+
the thing it counts, not a label with an outline of its own — and at that size
|
|
32
|
+
a border is most of what you see.
|
|
33
|
+
|
|
34
|
+
`tone` uses the system's tinted pair throughout: the colour behind at low
|
|
35
|
+
opacity, the colour itself as the ink. The same pair a secondary button, a
|
|
36
|
+
danger button and an avatar wear, so a badge beside any of them reads as one
|
|
37
|
+
family.
|
|
38
|
+
|
|
39
|
+
## Categories
|
|
40
|
+
|
|
41
|
+
`category` takes any CSS colour and fills at 20% of it:
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<kt-badge variant="category" color="var(--color-success-base)">Delivered</kt-badge>
|
|
45
|
+
<kt-badge variant="category" color="rgb(57, 135, 229)">Infrastructure</kt-badge>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The mixing is `color-mix`, which is honest for every notation. The build this
|
|
49
|
+
replaced concatenated a `"33"` onto the string and produced garbage for
|
|
50
|
+
`rgb()` and for named colours.
|
|
51
|
+
|
|
52
|
+
Reach for `tone` when the meaning is one of the system's six states, and
|
|
53
|
+
`category` when the palette belongs to the data — a project colour, a label the
|
|
54
|
+
user picked.
|
|
55
|
+
|
|
56
|
+
## Counting
|
|
57
|
+
|
|
58
|
+
`max` caps a numeric label: `max="99"` on `128` shows `99+`. A non-numeric
|
|
59
|
+
label is left alone, so `max` is safe to set from a template that does not know
|
|
60
|
+
what it will be given.
|
|
61
|
+
|
|
62
|
+
## Interaction
|
|
63
|
+
|
|
64
|
+
Neither `clickable` nor `removable` is on by default, because most badges are
|
|
65
|
+
labels and a label that looks pressable is a lie.
|
|
66
|
+
|
|
67
|
+
`clickable` makes it a real control — `role="button"`, a tab stop, Enter and
|
|
68
|
+
Space — and fires `kt-badge-click`. `removable` adds a remove button that fires
|
|
69
|
+
a cancelable `kt-remove`; cancel it and remove the badge yourself once the
|
|
70
|
+
server agrees. A badge that is both does not report the click when the remove
|
|
71
|
+
button is what was pressed.
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
| Property | Attribute | Type | Default |
|
|
76
|
+
| ----------- | ----------- | ------------------------------------------------------------------------ | ----------- |
|
|
77
|
+
| `variant` | `variant` | `'tag' \| 'code' \| 'category' \| 'count'` | `'tag'` |
|
|
78
|
+
| `tone` | `tone` | `'neutral' \| 'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | `'neutral'` |
|
|
79
|
+
| `size` | `size` | `'small' \| 'medium'` | `'medium'` |
|
|
80
|
+
| `label` | `label` | `string` | `''` |
|
|
81
|
+
| `color` | `color` | `string` — any CSS colour, for `category` | `''` |
|
|
82
|
+
| `icon` | `icon` | `string` — lucide name, before the text | `''` |
|
|
83
|
+
| `clickable` | `clickable` | `boolean` | `false` |
|
|
84
|
+
| `removable` | `removable` | `boolean` | `false` |
|
|
85
|
+
| `max` | `max` | `number` | — |
|
|
86
|
+
| `error` | `error` | `boolean` — shorthand for `tone="danger"` | `false` |
|
|
87
|
+
|
|
88
|
+
| Event | Detail |
|
|
89
|
+
| ---------------- | ------------ |
|
|
90
|
+
| `kt-badge-click` | — cancelable |
|
|
91
|
+
| `kt-remove` | — cancelable |
|
|
92
|
+
|
|
93
|
+
| Slot | Description |
|
|
94
|
+
| --------- | -------------------------------- |
|
|
95
|
+
| _default_ | The text. Falls back to `label`. |
|
|
96
|
+
|
|
97
|
+
| CSS property | Description |
|
|
98
|
+
| ------------------ | ------------------------------------ |
|
|
99
|
+
| `--kt-badge-color` | Category hue; the fill is it at 20%. |
|
|
100
|
+
|
|
101
|
+
| Part | Description |
|
|
102
|
+
| -------- | ----------------------------------- |
|
|
103
|
+
| `base` | The container |
|
|
104
|
+
| `remove` | The remove button, when `removable` |
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# `<kt-breadcrumb>`
|
|
2
|
+
|
|
3
|
+
A trail showing where the current page sits.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
trail.items = [
|
|
7
|
+
{ label: 'Home', href: '/' },
|
|
8
|
+
{ label: 'Entities', href: '/entites' },
|
|
9
|
+
{ label: 'Entity 4812' },
|
|
10
|
+
];
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The last entry is the current page: rendered as text with `aria-current="page"`,
|
|
14
|
+
not as a link. A breadcrumb whose final item links to the page you are already
|
|
15
|
+
on is a dead control.
|
|
16
|
+
|
|
17
|
+
## Client-side routing
|
|
18
|
+
|
|
19
|
+
`kt-navigate` is cancelable. Cancel it and the browser will not follow the
|
|
20
|
+
href; leave it alone and the link behaves like a link.
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
trail.addEventListener('kt-navigate', (e) => {
|
|
24
|
+
e.preventDefault();
|
|
25
|
+
router.push(e.detail.item.href);
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Modified clicks — ⌘, Ctrl, Shift, middle button — are never intercepted. The
|
|
30
|
+
user is asking the browser for a new tab, and the element stays out of it.
|
|
31
|
+
|
|
32
|
+
## API
|
|
33
|
+
|
|
34
|
+
| Property | Attribute | Type | Default |
|
|
35
|
+
| -------- | --------- | -------------------- | -------------- |
|
|
36
|
+
| `items` | — | `KtBreadcrumbItem[]` | `[]` |
|
|
37
|
+
| `label` | `label` | `string` | `"Breadcrumb"` |
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
interface KtBreadcrumbItem {
|
|
41
|
+
label: string;
|
|
42
|
+
href?: string;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
| Event | Detail |
|
|
47
|
+
| ------------- | ------------------------------ |
|
|
48
|
+
| `kt-navigate` | `{ item, index }` — cancelable |
|
|
49
|
+
|
|
50
|
+
| Part | Description |
|
|
51
|
+
| ------ | ------------- |
|
|
52
|
+
| `nav` | The `<nav>` |
|
|
53
|
+
| `item` | A trail entry |
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# `<kt-button>`
|
|
2
|
+
|
|
3
|
+
The Kanto action button. Ten variants, three sizes, an optional Lucide icon.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-button icon="plus">New entity</kt-button>
|
|
7
|
+
<kt-button variant="secondary" icon="refresh-cw">Refresh</kt-button>
|
|
8
|
+
<kt-button variant="danger">Delete</kt-button>
|
|
9
|
+
<kt-button variant="text">View full history</kt-button>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Choosing a variant
|
|
13
|
+
|
|
14
|
+
| Variant | Use for |
|
|
15
|
+
| -------------------------- | --------------------------------------------------------------- |
|
|
16
|
+
| `primary` | The one action a screen is about. At most one per view. |
|
|
17
|
+
| `secondary` | Supporting actions. Soft indigo tint. |
|
|
18
|
+
| `secondary-no-bg` | The same, with no resting background — for toolbars. |
|
|
19
|
+
| `dark` | Neutral actions that must not compete for attention. |
|
|
20
|
+
| `danger` | Destructive, but recoverable. Tinted red. |
|
|
21
|
+
| `delete` | Irreversible. The only solid red in the system — use sparingly. |
|
|
22
|
+
| `warning` `info` `success` | Status-carrying actions inside a matching context. |
|
|
23
|
+
| `text` | Inline, link-like. No padding, no height. |
|
|
24
|
+
|
|
25
|
+
## Icon-only
|
|
26
|
+
|
|
27
|
+
An `icon` with no slotted text collapses the button to a square. It then has no
|
|
28
|
+
accessible name of its own, so `label` is required:
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<kt-button icon="x" label="Close" variant="secondary-no-bg"></kt-button>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Forms
|
|
35
|
+
|
|
36
|
+
A button inside a shadow root is invisible to the enclosing form, so
|
|
37
|
+
`type="submit"` would normally do nothing. `<kt-button>` bridges that: it runs
|
|
38
|
+
the form's constraint validation, fires a real `submit` event, and carries
|
|
39
|
+
`name` / `value` into the submission.
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<form>
|
|
43
|
+
<kt-input name="email" type="email" required></kt-input>
|
|
44
|
+
<kt-button type="submit">Send</kt-button>
|
|
45
|
+
</form>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
| Property | Attribute | Type | Default |
|
|
51
|
+
| -------------- | --------------- | --------------------------------- | ----------- |
|
|
52
|
+
| `variant` | `variant` | see table above | `'primary'` |
|
|
53
|
+
| `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
|
|
54
|
+
| `disabled` | `disabled` | `boolean` | `false` |
|
|
55
|
+
| `type` | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` |
|
|
56
|
+
| `icon` | `icon` | `string` | `''` |
|
|
57
|
+
| `iconPosition` | `icon-position` | `'left' \| 'right'` | `'left'` |
|
|
58
|
+
| `label` | `label` | `string` | `''` |
|
|
59
|
+
| `fullWidth` | `full-width` | `boolean` | `false` |
|
|
60
|
+
| `name` | `name` | `string` | `''` |
|
|
61
|
+
| `value` | `value` | `string` | `''` |
|
|
62
|
+
|
|
63
|
+
| Slot | Description |
|
|
64
|
+
| --------- | ---------------- |
|
|
65
|
+
| _default_ | The button label |
|
|
66
|
+
|
|
67
|
+
| Part | Description |
|
|
68
|
+
| -------- | --------------------- |
|
|
69
|
+
| `button` | The native `<button>` |
|
|
70
|
+
| `icon` | The icon, when set |
|
|
71
|
+
|
|
72
|
+
Emits no custom events — listen for `click` as on any button.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# `<kt-calendar>`
|
|
2
|
+
|
|
3
|
+
A month calendar to pick a day or a period from, shown in the page.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-calendar value="2026-09-25"></kt-calendar>
|
|
7
|
+
<kt-calendar range value="2026-09-07/2026-09-18" min="2026-01-01"></kt-calendar>
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
It is the calendar `<kt-date-picker>` opens in its popup. Use it on its own
|
|
11
|
+
when the calendar _is_ the interface — a booking page, a dashboard's date
|
|
12
|
+
filter, a planning view — and `<kt-date-picker>` when it is only a way to fill
|
|
13
|
+
a field.
|
|
14
|
+
|
|
15
|
+
## A month and a year in two clicks
|
|
16
|
+
|
|
17
|
+
The title — "September 2026" — opens one panel: a scrolling list of years
|
|
18
|
+
beside the twelve months of the one chosen. Pick the year, then the month, and
|
|
19
|
+
the days are back, the day of the month kept: from 25 September, choosing March
|
|
20
|
+
1987 lands on 25 March 1987. The list opens on the chosen year, centred, and
|
|
21
|
+
reaches from `min` to `max` — or, without them, 120 years back and 50 ahead,
|
|
22
|
+
birthdays to plans. Typing four digits in the list jumps to that year. Months
|
|
23
|
+
wholly outside `min`/`max` are disabled.
|
|
24
|
+
|
|
25
|
+
The arrows beside the title page a month at a time; they are the only thing
|
|
26
|
+
that does.
|
|
27
|
+
|
|
28
|
+
## Two months
|
|
29
|
+
|
|
30
|
+
`months="2"` shows two months side by side — what `<kt-date-picker range>`
|
|
31
|
+
does, so a period across a month's end is two clicks. Each grid holds its own
|
|
32
|
+
days only, so none shows twice, and the keyboard moves across both, paging
|
|
33
|
+
only once it leaves the second.
|
|
34
|
+
|
|
35
|
+
## Keyboard
|
|
36
|
+
|
|
37
|
+
In the days, the WAI-ARIA date grid pattern:
|
|
38
|
+
|
|
39
|
+
| Key | Does |
|
|
40
|
+
| ---------------------------- | ------------------------------- |
|
|
41
|
+
| `←` / `→` | Previous / next day |
|
|
42
|
+
| `↑` / `↓` | Same day, previous / next week |
|
|
43
|
+
| `Home` / `End` | First / last day of the week |
|
|
44
|
+
| `Page Up` / `Page Down` | Same day, previous / next month |
|
|
45
|
+
| `Shift` + `Page Up` / `Down` | Same day, previous / next year |
|
|
46
|
+
| `Enter` / `Space` | Choose the day in focus |
|
|
47
|
+
|
|
48
|
+
In the year list:
|
|
49
|
+
|
|
50
|
+
| Key | Does |
|
|
51
|
+
| ----------------------- | -------------------------------------------------------------------- |
|
|
52
|
+
| `↑` / `↓` | Previous / next year |
|
|
53
|
+
| `Page Up` / `Page Down` | Ten years back / ahead |
|
|
54
|
+
| `Home` / `End` | First / last year offered |
|
|
55
|
+
| Four digits | That year |
|
|
56
|
+
| `Enter`, `Tab` | On to the months |
|
|
57
|
+
| `Escape` | Back to the days — and no further, so an enclosing dialog stays open |
|
|
58
|
+
|
|
59
|
+
In the months: the arrows, three to a row; `Page Up`/`Page Down` by year;
|
|
60
|
+
`Enter` to choose; `Escape` back to the days.
|
|
61
|
+
|
|
62
|
+
Focus follows every switch, so the keys keep working without a click in
|
|
63
|
+
between.
|
|
64
|
+
|
|
65
|
+
## ISO values and locales
|
|
66
|
+
|
|
67
|
+
As for `<kt-date-picker>`: the value is ISO 8601 text — `2026-09-25`, or
|
|
68
|
+
`2026-09-07/2026-09-18` with `range` — and names, the first day of the week
|
|
69
|
+
and every accessible label follow `locale`, else the page's `lang`, else the
|
|
70
|
+
browser's language. A period takes two picks in either order and fires
|
|
71
|
+
`kt-change` once, with the whole period.
|
|
72
|
+
|
|
73
|
+
`<kt-calendar>` is not a form control; inside a form, use `<kt-date-picker>`.
|
|
74
|
+
|
|
75
|
+
## API
|
|
76
|
+
|
|
77
|
+
| Property | Attribute | Type | Default |
|
|
78
|
+
| -------- | --------- | ---------------- | ------------------ |
|
|
79
|
+
| `value` | `value` | `string \| null` | `null` |
|
|
80
|
+
| `range` | `range` | `boolean` | `false` |
|
|
81
|
+
| `min` | `min` | `string` | `''` |
|
|
82
|
+
| `max` | `max` | `string` | `''` |
|
|
83
|
+
| `months` | `months` | `1 \| 2` | `1` |
|
|
84
|
+
| `locale` | `locale` | `string` | page, then browser |
|
|
85
|
+
| `label` | `label` | `string` | from `setStrings` |
|
|
86
|
+
|
|
87
|
+
| Method | Description |
|
|
88
|
+
| --------- | ------------------------------------------ |
|
|
89
|
+
| `focus()` | Focuses the current day — chosen, or today |
|
|
90
|
+
|
|
91
|
+
| Event | Detail |
|
|
92
|
+
| ----------- | ------------------------------------------ |
|
|
93
|
+
| `kt-change` | `{ value: string }` — ISO date or interval |
|
|
94
|
+
|
|
95
|
+
| Part | Description |
|
|
96
|
+
| ------ | ------------ |
|
|
97
|
+
| `base` | The calendar |
|
|
98
|
+
| `day` | A day cell |
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# `<kt-card>`
|
|
2
|
+
|
|
3
|
+
The system's content surface: 12px radius, a 1px `--border-subtle` border, 24px
|
|
4
|
+
of padding, 20px between its rows. Transparent at rest — a card reads as a
|
|
5
|
+
grouping, not as an elevation.
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<kt-card>
|
|
9
|
+
<h6 slot="header">Recent transactions</h6>
|
|
10
|
+
<kt-table></kt-table>
|
|
11
|
+
<kt-button slot="footer" variant="text">View full history</kt-button>
|
|
12
|
+
</kt-card>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Empty `header` and `footer` slots collapse, so an omitted footer costs no gap.
|
|
16
|
+
|
|
17
|
+
## Clickable cards
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<kt-card clickable>Entity 4812</kt-card>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`clickable` gives the card `role="button"`, a tab stop, hover and active
|
|
24
|
+
states, and Enter/Space activation, then fires `kt-card-click`. The
|
|
25
|
+
div-with-a-click-handler it replaces did none of that.
|
|
26
|
+
|
|
27
|
+
Do not nest interactive elements inside a clickable card — a button inside a
|
|
28
|
+
button is invalid, and the two hit targets fight. Either the card is the
|
|
29
|
+
control, or the things inside it are.
|
|
30
|
+
|
|
31
|
+
## Selected cards
|
|
32
|
+
|
|
33
|
+
`selected` marks a card as chosen — one filter of several, a picked plan:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<kt-card clickable selected>Pending</kt-card>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
It tints the card, outlines it in the primary colour and sets `aria-pressed`,
|
|
40
|
+
so the state is announced and not merely drawn.
|
|
41
|
+
|
|
42
|
+
Pair it with `clickable`. A card the user cannot toggle has no business looking
|
|
43
|
+
toggled, so a `selected` card that is not `clickable` gets the styling but no
|
|
44
|
+
`aria-pressed` — there is nothing to press, and claiming otherwise would be a
|
|
45
|
+
lie to a screen reader.
|
|
46
|
+
|
|
47
|
+
The outline lives on the card's own box rather than on the host element. An
|
|
48
|
+
outline only follows a `border-radius` declared on the same element, and the
|
|
49
|
+
host has none — put one on the host and you get sharp corners around a rounded
|
|
50
|
+
card.
|
|
51
|
+
|
|
52
|
+
## Media
|
|
53
|
+
|
|
54
|
+
`image` is the convenience path; the `media` slot takes anything else.
|
|
55
|
+
|
|
56
|
+
```html
|
|
57
|
+
<kt-card image="/preview.png" image-alt="Preview" image-position="top" image-size="160px"></kt-card>
|
|
58
|
+
|
|
59
|
+
<kt-card image-position="right" image-size="200px">
|
|
60
|
+
<canvas slot="media"></canvas>
|
|
61
|
+
Monthly breakdown
|
|
62
|
+
</kt-card>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`image-size` sets the width for `left`/`right` and the height for `top`/`bottom`.
|
|
66
|
+
|
|
67
|
+
## API
|
|
68
|
+
|
|
69
|
+
| Property | Attribute | Type | Default |
|
|
70
|
+
| --------------- | ---------------- | ---------------------------------------- | --------- |
|
|
71
|
+
| `clickable` | `clickable` | `boolean` | `false` |
|
|
72
|
+
| `selected` | `selected` | `boolean` | `false` |
|
|
73
|
+
| `image` | `image` | `string` | `''` |
|
|
74
|
+
| `imageAlt` | `image-alt` | `string` | `''` |
|
|
75
|
+
| `imagePosition` | `image-position` | `'left' \| 'right' \| 'top' \| 'bottom'` | `'left'` |
|
|
76
|
+
| `imageSize` | `image-size` | `string` | `'120px'` |
|
|
77
|
+
|
|
78
|
+
| Slot | Description |
|
|
79
|
+
| --------- | ------------------------------ |
|
|
80
|
+
| _default_ | Card body |
|
|
81
|
+
| `header` | Above the body |
|
|
82
|
+
| `footer` | Below the body |
|
|
83
|
+
| `media` | Replaces the `image` attribute |
|
|
84
|
+
|
|
85
|
+
| Event | Detail | Fired when |
|
|
86
|
+
| --------------- | ------ | -------------------------------------------- |
|
|
87
|
+
| `kt-card-click` | — | A `clickable` card is activated. Cancelable. |
|
|
88
|
+
|
|
89
|
+
| Part | Description |
|
|
90
|
+
| ------- | ---------------------------- |
|
|
91
|
+
| `base` | The card container |
|
|
92
|
+
| `media` | The image or media well |
|
|
93
|
+
| `body` | Header/content/footer column |
|