kanto-ds 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/dist/chunks/form-control-CxjBTt1c.js.map +1 -1
- package/dist/chunks/kt-element-B_jjQDhg.js +38 -0
- package/dist/chunks/kt-element-B_jjQDhg.js.map +1 -0
- package/dist/components/core/kt-avatar/kt-avatar.js +9 -6
- package/dist/components/core/kt-avatar/kt-avatar.js.map +1 -1
- package/dist/components/core/kt-badge/kt-badge.js +17 -17
- package/dist/components/core/kt-badge/kt-badge.js.map +1 -1
- package/dist/components/core/kt-button/kt-button.d.ts +7 -0
- package/dist/components/core/kt-button/kt-button.js +68 -60
- package/dist/components/core/kt-button/kt-button.js.map +1 -1
- package/dist/components/core/kt-card/kt-card.js +1 -1
- package/dist/components/core/kt-code/kt-code.js +12 -12
- package/dist/components/core/kt-code/kt-code.js.map +1 -1
- package/dist/components/core/kt-icon/kt-icon.js +1 -1
- package/dist/components/core/kt-kbd/kt-kbd.js +14 -14
- package/dist/components/core/kt-kbd/kt-kbd.js.map +1 -1
- package/dist/components/core/kt-split-button/kt-split-button.js +3 -3
- package/dist/components/core/kt-split-button/kt-split-button.js.map +1 -1
- package/dist/components/data/kt-chart/kt-chart.js +1 -1
- package/dist/components/data/kt-meter/kt-meter.js +1 -1
- package/dist/components/data/kt-pagination/kt-pagination.js +1 -1
- package/dist/components/data/kt-stat/kt-stat.js +5 -5
- 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-table/kt-table.js.map +1 -1
- package/dist/components/data/kt-timeline/kt-timeline.js +1 -1
- package/dist/components/feedback/kt-alert/kt-alert.js +26 -26
- package/dist/components/feedback/kt-alert/kt-alert.js.map +1 -1
- package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +2 -2
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js.map +1 -1
- package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
- package/dist/components/feedback/kt-toast/kt-toast.js +22 -22
- package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -1
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js +1 -1
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.d.ts +11 -1
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +69 -36
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -1
- package/dist/components/forms/kt-form/kt-form.js +1 -1
- package/dist/components/forms/kt-input/kt-input.js +95 -91
- package/dist/components/forms/kt-input/kt-input.js.map +1 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.d.ts +10 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +83 -53
- package/dist/components/forms/kt-input-menu/kt-input-menu.js.map +1 -1
- package/dist/components/forms/kt-label-input/kt-label-input.js +2 -2
- package/dist/components/forms/kt-label-input/kt-label-input.js.map +1 -1
- package/dist/components/forms/kt-select/kt-select.js +2 -2
- package/dist/components/forms/kt-select/kt-select.js.map +1 -1
- package/dist/components/forms/kt-textarea/kt-textarea.js +15 -13
- package/dist/components/forms/kt-textarea/kt-textarea.js.map +1 -1
- package/dist/components/forms/kt-toggle/kt-toggle.js +8 -7
- package/dist/components/forms/kt-toggle/kt-toggle.js.map +1 -1
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +1 -1
- package/dist/components/navigation/kt-header/kt-header.js +1 -1
- package/dist/components/navigation/kt-page-header/kt-page-header.js +18 -18
- 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 +10 -1
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +88 -62
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +5 -5
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -1
- package/dist/components/navigation/kt-tabs/kt-tabs.js +1 -1
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +3 -3
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js.map +1 -1
- package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +1 -1
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js +1 -1
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +1 -1
- package/dist/components/overlays/kt-dropdown/kt-dropdown.d.ts +13 -0
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +74 -59
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
- package/dist/components/overlays/kt-modal/kt-modal.js +1 -1
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js +1 -1
- package/dist/custom-elements.json +11791 -0
- package/dist/index.js +1 -1
- package/dist/internal/form-control.d.ts +7 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/jsx.d.ts +213 -0
- package/dist/react/jsx.js +2 -0
- package/dist/react/jsx.js.map +1 -0
- package/dist/tokens/README.md +7 -3
- package/dist/tokens/colors.css +24 -5
- package/dist/tokens/theme-light.css +18 -0
- package/dist/vscode.css-custom-data.json +154 -0
- package/dist/vscode.html-custom-data.json +1136 -0
- package/dist/web-types.json +3186 -0
- package/package.json +28 -9
- package/dist/chunks/kt-element-CcMLO5e8.js +0 -28
- package/dist/chunks/kt-element-CcMLO5e8.js.map +0 -1
package/README.md
CHANGED
|
@@ -103,8 +103,8 @@ import 'kanto-ds/components/core/kt-button'; // just this one
|
|
|
103
103
|
## Icons
|
|
104
104
|
|
|
105
105
|
`<kt-icon>` resolves [Lucide](https://lucide.dev) icons by name at render time,
|
|
106
|
-
which means the set cannot be tree-shaken. So Kanto ships only the
|
|
107
|
-
|
|
106
|
+
which means the set cannot be tree-shaken. So Kanto ships only the 22 its own
|
|
107
|
+
elements draw. Register what your application uses:
|
|
108
108
|
|
|
109
109
|
```js
|
|
110
110
|
import { Rocket, Wallet } from 'lucide';
|
|
@@ -128,6 +128,24 @@ input — no hidden mirror inputs, no manual wiring.
|
|
|
128
128
|
</form>
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
+
## Editor support
|
|
132
|
+
|
|
133
|
+
The package ships a [Custom Elements Manifest](https://custom-elements-manifest.open-wc.org/)
|
|
134
|
+
— every element's attributes, properties, events, slots and CSS parts — and
|
|
135
|
+
editor data generated from it, so plain HTML gets completion and hover docs:
|
|
136
|
+
|
|
137
|
+
- **WebStorm / JetBrains** read `web-types.json` from the package on their own.
|
|
138
|
+
- **VS Code** needs pointing at it once, in `.vscode/settings.json`:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"html.customData": ["./node_modules/kanto-ds/dist/vscode.html-custom-data.json"],
|
|
143
|
+
"css.customData": ["./node_modules/kanto-ds/dist/vscode.css-custom-data.json"]
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- **Storybook** and API-docs generators take `kanto-ds/custom-elements.json`.
|
|
148
|
+
|
|
131
149
|
## Accessibility
|
|
132
150
|
|
|
133
151
|
Not a phase at the end; it is why several of these components exist in this
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-control-CxjBTt1c.js","sources":["../../src/internal/form-control.ts"],"sourcesContent":["/**\n * Form participation for Kanto's input elements.\n *\n * A control inside a shadow root is invisible to the form around it. The\n * platform's answer is `ElementInternals`: the element declares\n * `static formAssociated = true`, calls `attachInternals()` and pushes its\n * value in with `setFormValue`, which makes it a first-class form control —\n * serialised into `FormData`, reset by `form.reset()`, validated by\n * `form.checkValidity()`.\n *\n * Every browser Kanto targets supports this. Test environments do not: neither\n * happy-dom nor jsdom implements it, and jsdom stubs `attachInternals` with an\n * object that has no `setFormValue`. So each call is guarded, and an element\n * still works — minus form serialisation — where the API is missing.\n */\n\n/** An `ElementInternals` implementation complete enough to be worth calling. */\nexport type UsableInternals = ElementInternals;\n\nexport function attachFormInternals(host: HTMLElement): UsableInternals | null {\n if (typeof host.attachInternals !== 'function') return null;\n\n const internals = host.attachInternals();\n if (typeof internals.setFormValue !== 'function') return null;\n\n return internals;\n}\n\n
|
|
1
|
+
{"version":3,"file":"form-control-CxjBTt1c.js","sources":["../../src/internal/form-control.ts"],"sourcesContent":["/**\n * Form participation for Kanto's input elements.\n *\n * A control inside a shadow root is invisible to the form around it. The\n * platform's answer is `ElementInternals`: the element declares\n * `static formAssociated = true`, calls `attachInternals()` and pushes its\n * value in with `setFormValue`, which makes it a first-class form control —\n * serialised into `FormData`, reset by `form.reset()`, validated by\n * `form.checkValidity()`.\n *\n * Every browser Kanto targets supports this. Test environments do not: neither\n * happy-dom nor jsdom implements it, and jsdom stubs `attachInternals` with an\n * object that has no `setFormValue`. So each call is guarded, and an element\n * still works — minus form serialisation — where the API is missing.\n */\n\n/** An `ElementInternals` implementation complete enough to be worth calling. */\nexport type UsableInternals = ElementInternals;\n\nexport function attachFormInternals(host: HTMLElement): UsableInternals | null {\n if (typeof host.attachInternals !== 'function') return null;\n\n const internals = host.attachInternals();\n if (typeof internals.setFormValue !== 'function') return null;\n\n return internals;\n}\n\n/**\n * Pushes the control's current value into the enclosing form, if there is one.\n *\n * A `FormData` submits each of its entries as they are named in it — which is\n * how one control contributes several files under one name.\n */\nexport function setFormValue(\n internals: UsableInternals | null,\n value: string | FormData | null,\n): void {\n internals?.setFormValue(value);\n}\n\n/**\n * Mirrors a control's validity onto the host element.\n *\n * `anchor` is the element a browser scrolls to and anchors the native bubble\n * against when the form is submitted invalid.\n */\nexport function setValidity(\n internals: UsableInternals | null,\n flags: ValidityStateFlags,\n message: string,\n anchor?: HTMLElement,\n): void {\n if (!internals || typeof internals.setValidity !== 'function') return;\n if (Object.values(flags).some(Boolean)) internals.setValidity(flags, message, anchor);\n else internals.setValidity({});\n}\n"],"names":["attachFormInternals","host","internals","setFormValue","value","setValidity","flags","message","anchor"],"mappings":"AAmBO,SAASA,EAAoBC,GAA2C;AAC7E,MAAI,OAAOA,EAAK,mBAAoB,WAAY,QAAO;AAEvD,QAAMC,IAAYD,EAAK,gBAAA;AACvB,SAAI,OAAOC,EAAU,gBAAiB,aAAmB,OAElDA;AACT;AAQO,SAASC,EACdD,GACAE,GACM;AACN,EAAAF,GAAW,aAAaE,CAAK;AAC/B;AAQO,SAASC,EACdH,GACAI,GACAC,GACAC,GACM;AACN,EAAI,CAACN,KAAa,OAAOA,EAAU,eAAgB,eAC/C,OAAO,OAAOI,CAAK,EAAE,KAAK,OAAO,IAAGJ,EAAU,YAAYI,GAAOC,GAASC,CAAM,IAC/EN,EAAU,YAAY,EAAE;AAC/B;"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LitElement as i, css as s } from "lit";
|
|
2
|
+
class o extends i {
|
|
3
|
+
static {
|
|
4
|
+
this.styles = s`
|
|
5
|
+
:host {
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:host([hidden]) {
|
|
10
|
+
display: none !important;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
*,
|
|
14
|
+
*::before,
|
|
15
|
+
*::after {
|
|
16
|
+
box-sizing: inherit;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Read by assistive technology, never drawn. */
|
|
20
|
+
.visually-hidden {
|
|
21
|
+
position: absolute;
|
|
22
|
+
width: 1px;
|
|
23
|
+
height: 1px;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
clip-path: inset(50%);
|
|
26
|
+
white-space: nowrap;
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function d(e, t) {
|
|
32
|
+
customElements.get(e) || customElements.define(e, t);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
o as K,
|
|
36
|
+
d
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=kt-element-B_jjQDhg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kt-element-B_jjQDhg.js","sources":["../../src/internal/kt-element.ts"],"sourcesContent":["import { LitElement, css, type CSSResultGroup } from 'lit';\n\n/**\n * Base class for every Kanto element.\n *\n * It exists for two reasons. First, `box-sizing: border-box` does not cross a\n * shadow boundary, so each root has to re-establish it. Second, `[hidden]`\n * loses to a `:host { display: flex }` rule inside the shadow root, and every\n * element in this system sets its own display — without the override here,\n * hiding a Kanto element from the outside silently does nothing.\n */\nexport class KtElement extends LitElement {\n static override styles: CSSResultGroup = css`\n :host {\n box-sizing: border-box;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n *,\n *::before,\n *::after {\n box-sizing: inherit;\n }\n\n /* Read by assistive technology, never drawn. */\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n `;\n}\n\n/**\n * Registers a custom element, tolerating a repeat call.\n *\n * A design system gets loaded twice more often than you would like — two\n * versions in one dependency tree, a dev-server hot reload, a micro-frontend\n * mounting a second copy. `customElements.define` throws on a duplicate tag\n * and would take the whole page down with it.\n */\nexport function defineElement(tag: string, ctor: CustomElementConstructor): void {\n if (customElements.get(tag)) return;\n customElements.define(tag, ctor);\n}\n"],"names":["KtElement","LitElement","css","defineElement","tag","ctor"],"mappings":";AAWO,MAAMA,UAAkBC,EAAW;AAAA,EACxC,OAAA;AAAA,SAAgB,SAAyBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA;AAyB3C;AAUO,SAASC,EAAcC,GAAaC,GAAsC;AAC/E,EAAI,eAAe,IAAID,CAAG,KAC1B,eAAe,OAAOA,GAAKC,CAAI;AACjC;"}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { css as p, nothing as f, html as n } from "lit";
|
|
2
2
|
import { state as v, property as o } from "lit/decorators.js";
|
|
3
3
|
import { classMap as c } from "lit/directives/class-map.js";
|
|
4
|
-
import { K as
|
|
4
|
+
import { K as d, d as g } from "../../../chunks/kt-element-B_jjQDhg.js";
|
|
5
5
|
import "../kt-icon/kt-icon.js";
|
|
6
6
|
var m = Object.defineProperty, s = (a, e, t, b) => {
|
|
7
7
|
for (var i = void 0, l = a.length - 1, h; l >= 0; l--)
|
|
8
8
|
(h = a[l]) && (i = h(e, t, i) || i);
|
|
9
9
|
return i && m(e, t, i), i;
|
|
10
10
|
};
|
|
11
|
-
const
|
|
11
|
+
const u = Array.from({ length: 8 }, (a, e) => `var(--chart-series-${e + 1})`);
|
|
12
12
|
function y(a) {
|
|
13
13
|
const t = (a.includes("@") ? a.split("@")[0] ?? "" : a).split(/[\s._-]+/).filter(Boolean);
|
|
14
14
|
return t.length === 0 ? "" : t.length === 1 ? (t[0] ?? "").slice(0, 2).toUpperCase() : `${t[0][0]}${t[t.length - 1][0]}`.toUpperCase();
|
|
15
15
|
}
|
|
16
|
-
class r extends
|
|
16
|
+
class r extends d {
|
|
17
17
|
constructor() {
|
|
18
18
|
super(...arguments), this.failed = !1, this.name = "", this.src = "", this.size = "medium", this.square = !1, this.color = "";
|
|
19
19
|
}
|
|
20
20
|
static {
|
|
21
21
|
this.styles = [
|
|
22
|
-
|
|
22
|
+
d.styles,
|
|
23
23
|
p`
|
|
24
24
|
:host {
|
|
25
25
|
display: inline-flex;
|
|
@@ -48,7 +48,10 @@ class r extends u {
|
|
|
48
48
|
width: var(--kt-avatar-size);
|
|
49
49
|
height: var(--kt-avatar-size);
|
|
50
50
|
overflow: hidden;
|
|
51
|
-
|
|
51
|
+
/* The hue alone is too faint on its own 12% tint. Pulled towards the
|
|
52
|
+
body text — lighter in dark, darker in light — it keeps its identity
|
|
53
|
+
and clears 4.5:1 for all eight hues in both themes. */
|
|
54
|
+
color: color-mix(in srgb, var(--kt-avatar-hue, var(--text-muted)) 45%, var(--text-body));
|
|
52
55
|
font: 600 calc(var(--kt-avatar-size) * 0.36) / 1 var(--font-family-body);
|
|
53
56
|
background: color-mix(in srgb, var(--kt-avatar-hue, transparent) 12%, transparent);
|
|
54
57
|
border-radius: var(--radius-full);
|
|
@@ -104,7 +107,7 @@ class r extends u {
|
|
|
104
107
|
if (this.color) return this.color;
|
|
105
108
|
let e = 0;
|
|
106
109
|
for (const t of this.name) e += t.charCodeAt(0);
|
|
107
|
-
return
|
|
110
|
+
return u[e % u.length];
|
|
108
111
|
}
|
|
109
112
|
render() {
|
|
110
113
|
const e = y(this.name), t = !!this.src && !this.failed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-avatar.js","sources":["../../../../src/components/core/kt-avatar/kt-avatar.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport '../kt-icon/kt-icon.js';\n\nexport type KtAvatarSize = 'small' | 'medium' | 'large';\nexport type KtAvatarStatus = 'online' | 'away' | 'busy' | 'offline';\n\n/**\n * Deterministic hue per name, so a person keeps their colour everywhere.\n *\n * From the chart palette, not the semantic one: status colours are reserved,\n * and a person filled with `--color-danger-base` reads as an error rather than\n * as a person. These eight are the same slots a chart uses, in the same fixed\n * order, so an avatar never impersonates a state.\n */\nconst HUES = Array.from({ length: 8 }, (_, i) => `var(--chart-series-${i + 1})`);\n\n/** \"Benjamin Canac\" → \"BC\", \"emma.davis@example.com\" → \"ED\". */\nexport function initialsOf(name: string): string {\n const cleaned = name.includes('@') ? (name.split('@')[0] ?? '') : name;\n const parts = cleaned.split(/[\\s._-]+/).filter(Boolean);\n\n if (parts.length === 0) return '';\n if (parts.length === 1) return (parts[0] ?? '').slice(0, 2).toUpperCase();\n return `${parts[0]![0]}${parts[parts.length - 1]![0]}`.toUpperCase();\n}\n\n/**\n * A person or an organisation, as a picture or as their initials.\n *\n * The fallback is not decoration: most rows in most products have no photo, so\n * the initials path is the one that renders. It picks a colour from the name,\n * which means the same person is the same colour on every screen and the eye\n * can use it.\n *\n * @element kt-avatar\n *\n * @csspart base - The avatar circle.\n * @csspart image - The `<img>`, when `src` is set and loads.\n *\n * @example\n * ```html\n * <kt-avatar name=\"Benjamin Canac\"></kt-avatar>\n * <kt-avatar name=\"Emma Davis\" src=\"/emma.jpg\" status=\"online\"></kt-avatar>\n * ```\n */\nexport class KtAvatar extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-flex;\n --kt-avatar-size: 32px;\n }\n\n :host([size='small']) {\n --kt-avatar-size: 24px;\n }\n :host([size='large']) {\n --kt-avatar-size: 48px;\n }\n\n /* The identity hue is worn exactly the way every other tinted thing in\n Kanto wears one: the colour at 12% behind, the colour itself as the\n ink, and no border — the same pair as a secondary button, a danger\n button or a badge tone. A saturated fill with white initials is a\n different system's idea, and beside those it looks like one. */\n .avatar {\n position: relative;\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--kt-avatar-size);\n height: var(--kt-avatar-size);\n overflow: hidden;\n color: var(--kt-avatar-hue, var(--text-muted));\n font: 600 calc(var(--kt-avatar-size) * 0.36) / 1 var(--font-family-body);\n background: color-mix(in srgb, var(--kt-avatar-hue, transparent) 12%, transparent);\n border-radius: var(--radius-full);\n user-select: none;\n }\n\n /* No hue to tint with, and a photograph that fills the circle anyway. */\n .avatar.has-image,\n .avatar.anonymous {\n background: var(--surface-raised);\n }\n\n :host([square]) .avatar {\n border-radius: var(--border-radius);\n }\n\n img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n /* The dot sits outside the clipped circle, so it needs its own box. */\n .status {\n position: absolute;\n right: 0;\n bottom: 0;\n width: calc(var(--kt-avatar-size) * 0.28);\n height: calc(var(--kt-avatar-size) * 0.28);\n border: 2px solid var(--surface-page);\n border-radius: var(--radius-full);\n }\n\n .online {\n background: var(--color-success-base);\n }\n .away {\n background: var(--color-warning-base);\n }\n .busy {\n background: var(--color-danger-base);\n }\n .offline {\n background: var(--color-text-500);\n }\n `,\n ];\n\n @state()\n private failed = false;\n\n /** The person's name. Drives the initials, the colour and the label. */\n @property({ type: String })\n name = '';\n\n /** Photo. Falls back to initials if it is missing or fails to load. */\n @property({ type: String })\n src = '';\n\n @property({ type: String, reflect: true })\n size: KtAvatarSize = 'medium';\n\n /** Rounds to the card radius instead of a circle — for organisations. */\n @property({ type: Boolean, reflect: true })\n square = false;\n\n /** Presence dot. Omit for none. */\n @property({ type: String, reflect: true })\n status?: KtAvatarStatus;\n\n /** Overrides the colour picked from the name. */\n @property({ type: String })\n color = '';\n\n override willUpdate(changed: Map<string, unknown>): void {\n // A new source deserves a fresh attempt; without this a single failure\n // would stick for the element's lifetime.\n if (changed.has('src')) this.failed = false;\n }\n\n private get hue(): string {\n if (this.color) return this.color;\n\n let sum = 0;\n for (const char of this.name) sum += char.charCodeAt(0);\n return HUES[sum % HUES.length]!;\n }\n\n override render(): TemplateResult {\n const initials = initialsOf(this.name);\n const showImage = Boolean(this.src) && !this.failed;\n\n return html`<span\n part=\"base\"\n class=${classMap({ avatar: true, 'has-image': showImage, anonymous: !this.name })}\n style=${showImage ? '' : `--kt-avatar-hue:${this.hue}`}\n role=\"img\"\n aria-label=${this.name || 'Avatar'}\n >\n ${\n showImage\n ? html`<img\n part=\"image\"\n src=${this.src}\n alt=\"\"\n @error=${() => {\n this.failed = true;\n }}\n />`\n : initials || html`<kt-icon name=\"user\" size=\"16\"></kt-icon>`\n }\n ${\n this.status\n ? html`<span class=${classMap({ status: true, [this.status]: true })}></span>`\n : nothing\n }\n </span>`;\n }\n}\n\ndefineElement('kt-avatar', KtAvatar);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-avatar': KtAvatar;\n }\n}\n"],"names":["HUES","_","i","initialsOf","name","parts","KtAvatar","KtElement","css","changed","sum","char","initials","showImage","html","classMap","nothing","__decorateClass","state","property","defineElement"],"mappings":";;;;;;;;;;AAiBA,MAAMA,IAAO,MAAM,KAAK,EAAE,QAAQ,EAAA,GAAK,CAACC,GAAGC,MAAM,sBAAsBA,IAAI,CAAC,GAAG;AAGxE,SAASC,EAAWC,GAAsB;AAE/C,QAAMC,KADUD,EAAK,SAAS,GAAG,IAAKA,EAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAMA,GAC5C,MAAM,UAAU,EAAE,OAAO,OAAO;AAEtD,SAAIC,EAAM,WAAW,IAAU,KAC3BA,EAAM,WAAW,KAAWA,EAAM,CAAC,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,YAAA,IACrD,GAAGA,EAAM,CAAC,EAAG,CAAC,CAAC,GAAGA,EAAMA,EAAM,SAAS,CAAC,EAAG,CAAC,CAAC,GAAG,YAAA;AACzD;AAqBO,MAAMC,UAAiBC,EAAU;AAAA,EAAjC,cAAA;AAAA,UAAA,GAAA,SAAA,
|
|
1
|
+
{"version":3,"file":"kt-avatar.js","sources":["../../../../src/components/core/kt-avatar/kt-avatar.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport '../kt-icon/kt-icon.js';\n\nexport type KtAvatarSize = 'small' | 'medium' | 'large';\nexport type KtAvatarStatus = 'online' | 'away' | 'busy' | 'offline';\n\n/**\n * Deterministic hue per name, so a person keeps their colour everywhere.\n *\n * From the chart palette, not the semantic one: status colours are reserved,\n * and a person filled with `--color-danger-base` reads as an error rather than\n * as a person. These eight are the same slots a chart uses, in the same fixed\n * order, so an avatar never impersonates a state.\n */\nconst HUES = Array.from({ length: 8 }, (_, i) => `var(--chart-series-${i + 1})`);\n\n/** \"Benjamin Canac\" → \"BC\", \"emma.davis@example.com\" → \"ED\". */\nexport function initialsOf(name: string): string {\n const cleaned = name.includes('@') ? (name.split('@')[0] ?? '') : name;\n const parts = cleaned.split(/[\\s._-]+/).filter(Boolean);\n\n if (parts.length === 0) return '';\n if (parts.length === 1) return (parts[0] ?? '').slice(0, 2).toUpperCase();\n return `${parts[0]![0]}${parts[parts.length - 1]![0]}`.toUpperCase();\n}\n\n/**\n * A person or an organisation, as a picture or as their initials.\n *\n * The fallback is not decoration: most rows in most products have no photo, so\n * the initials path is the one that renders. It picks a colour from the name,\n * which means the same person is the same colour on every screen and the eye\n * can use it.\n *\n * @element kt-avatar\n *\n * @csspart base - The avatar circle.\n * @csspart image - The `<img>`, when `src` is set and loads.\n *\n * @example\n * ```html\n * <kt-avatar name=\"Benjamin Canac\"></kt-avatar>\n * <kt-avatar name=\"Emma Davis\" src=\"/emma.jpg\" status=\"online\"></kt-avatar>\n * ```\n */\nexport class KtAvatar extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-flex;\n --kt-avatar-size: 32px;\n }\n\n :host([size='small']) {\n --kt-avatar-size: 24px;\n }\n :host([size='large']) {\n --kt-avatar-size: 48px;\n }\n\n /* The identity hue is worn exactly the way every other tinted thing in\n Kanto wears one: the colour at 12% behind, the colour itself as the\n ink, and no border — the same pair as a secondary button, a danger\n button or a badge tone. A saturated fill with white initials is a\n different system's idea, and beside those it looks like one. */\n .avatar {\n position: relative;\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--kt-avatar-size);\n height: var(--kt-avatar-size);\n overflow: hidden;\n /* The hue alone is too faint on its own 12% tint. Pulled towards the\n body text — lighter in dark, darker in light — it keeps its identity\n and clears 4.5:1 for all eight hues in both themes. */\n color: color-mix(in srgb, var(--kt-avatar-hue, var(--text-muted)) 45%, var(--text-body));\n font: 600 calc(var(--kt-avatar-size) * 0.36) / 1 var(--font-family-body);\n background: color-mix(in srgb, var(--kt-avatar-hue, transparent) 12%, transparent);\n border-radius: var(--radius-full);\n user-select: none;\n }\n\n /* No hue to tint with, and a photograph that fills the circle anyway. */\n .avatar.has-image,\n .avatar.anonymous {\n background: var(--surface-raised);\n }\n\n :host([square]) .avatar {\n border-radius: var(--border-radius);\n }\n\n img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n /* The dot sits outside the clipped circle, so it needs its own box. */\n .status {\n position: absolute;\n right: 0;\n bottom: 0;\n width: calc(var(--kt-avatar-size) * 0.28);\n height: calc(var(--kt-avatar-size) * 0.28);\n border: 2px solid var(--surface-page);\n border-radius: var(--radius-full);\n }\n\n .online {\n background: var(--color-success-base);\n }\n .away {\n background: var(--color-warning-base);\n }\n .busy {\n background: var(--color-danger-base);\n }\n .offline {\n background: var(--color-text-500);\n }\n `,\n ];\n\n @state()\n private failed = false;\n\n /** The person's name. Drives the initials, the colour and the label. */\n @property({ type: String })\n name = '';\n\n /** Photo. Falls back to initials if it is missing or fails to load. */\n @property({ type: String })\n src = '';\n\n @property({ type: String, reflect: true })\n size: KtAvatarSize = 'medium';\n\n /** Rounds to the card radius instead of a circle — for organisations. */\n @property({ type: Boolean, reflect: true })\n square = false;\n\n /** Presence dot. Omit for none. */\n @property({ type: String, reflect: true })\n status?: KtAvatarStatus;\n\n /** Overrides the colour picked from the name. */\n @property({ type: String })\n color = '';\n\n override willUpdate(changed: Map<string, unknown>): void {\n // A new source deserves a fresh attempt; without this a single failure\n // would stick for the element's lifetime.\n if (changed.has('src')) this.failed = false;\n }\n\n private get hue(): string {\n if (this.color) return this.color;\n\n let sum = 0;\n for (const char of this.name) sum += char.charCodeAt(0);\n return HUES[sum % HUES.length]!;\n }\n\n override render(): TemplateResult {\n const initials = initialsOf(this.name);\n const showImage = Boolean(this.src) && !this.failed;\n\n return html`<span\n part=\"base\"\n class=${classMap({ avatar: true, 'has-image': showImage, anonymous: !this.name })}\n style=${showImage ? '' : `--kt-avatar-hue:${this.hue}`}\n role=\"img\"\n aria-label=${this.name || 'Avatar'}\n >\n ${\n showImage\n ? html`<img\n part=\"image\"\n src=${this.src}\n alt=\"\"\n @error=${() => {\n this.failed = true;\n }}\n />`\n : initials || html`<kt-icon name=\"user\" size=\"16\"></kt-icon>`\n }\n ${\n this.status\n ? html`<span class=${classMap({ status: true, [this.status]: true })}></span>`\n : nothing\n }\n </span>`;\n }\n}\n\ndefineElement('kt-avatar', KtAvatar);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-avatar': KtAvatar;\n }\n}\n"],"names":["HUES","_","i","initialsOf","name","parts","KtAvatar","KtElement","css","changed","sum","char","initials","showImage","html","classMap","nothing","__decorateClass","state","property","defineElement"],"mappings":";;;;;;;;;;AAiBA,MAAMA,IAAO,MAAM,KAAK,EAAE,QAAQ,EAAA,GAAK,CAACC,GAAGC,MAAM,sBAAsBA,IAAI,CAAC,GAAG;AAGxE,SAASC,EAAWC,GAAsB;AAE/C,QAAMC,KADUD,EAAK,SAAS,GAAG,IAAKA,EAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAMA,GAC5C,MAAM,UAAU,EAAE,OAAO,OAAO;AAEtD,SAAIC,EAAM,WAAW,IAAU,KAC3BA,EAAM,WAAW,KAAWA,EAAM,CAAC,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,YAAA,IACrD,GAAGA,EAAM,CAAC,EAAG,CAAC,CAAC,GAAGA,EAAMA,EAAM,SAAS,CAAC,EAAG,CAAC,CAAC,GAAG,YAAA;AACzD;AAqBO,MAAMC,UAAiBC,EAAU;AAAA,EAAjC,cAAA;AAAA,UAAA,GAAA,SAAA,GAoFL,KAAQ,SAAS,IAIjB,KAAA,OAAO,IAIP,KAAA,MAAM,IAGN,KAAA,OAAqB,UAIrB,KAAA,SAAS,IAQT,KAAA,QAAQ;AAAA,EAAA;AAAA,EA1GR,OAAA;AAAA,SAAgB,SAAS;AAAA,MACvBA,EAAU;AAAA,MACVC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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,EA8EF;AAAA,EA4BS,WAAWC,GAAqC;AAGvD,IAAIA,EAAQ,IAAI,KAAK,WAAQ,SAAS;AAAA,EACxC;AAAA,EAEA,IAAY,MAAc;AACxB,QAAI,KAAK,MAAO,QAAO,KAAK;AAE5B,QAAIC,IAAM;AACV,eAAWC,KAAQ,KAAK,KAAM,CAAAD,KAAOC,EAAK,WAAW,CAAC;AACtD,WAAOX,EAAKU,IAAMV,EAAK,MAAM;AAAA,EAC/B;AAAA,EAES,SAAyB;AAChC,UAAMY,IAAWT,EAAW,KAAK,IAAI,GAC/BU,IAAY,EAAQ,KAAK,OAAQ,CAAC,KAAK;AAE7C,WAAOC;AAAA;AAAA,cAEGC,EAAS,EAAE,QAAQ,IAAM,aAAaF,GAAW,WAAW,CAAC,KAAK,MAAM,CAAC;AAAA,cACzEA,IAAY,KAAK,mBAAmB,KAAK,GAAG,EAAE;AAAA;AAAA,mBAEzC,KAAK,QAAQ,QAAQ;AAAA;AAAA,QAGhCA,IACIC;AAAA;AAAA,oBAEQ,KAAK,GAAG;AAAA;AAAA,uBAEL,MAAM;AACb,WAAK,SAAS;AAAA,IAChB,CAAC;AAAA,kBAEHF,KAAYE,4CAClB;AAAA,QAEE,KAAK,SACDA,gBAAmBC,EAAS,EAAE,QAAQ,IAAM,CAAC,KAAK,MAAM,GAAG,GAAA,CAAM,CAAC,aAClEC,CACN;AAAA;AAAA,EAEJ;AACF;AArEUC,EAAA;AAAA,EADPC,EAAA;AAAM,GAnFIZ,EAoFH,WAAA,QAAA;AAIRW,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAvFfb,EAwFX,WAAA,MAAA;AAIAW,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA3Ffb,EA4FX,WAAA,KAAA;AAGAW,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA9F9Bb,EA+FX,WAAA,MAAA;AAIAW,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAlG/Bb,EAmGX,WAAA,QAAA;AAIAW,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAtG9Bb,EAuGX,WAAA,QAAA;AAIAW,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA1Gfb,EA2GX,WAAA,OAAA;AAgDFc,EAAc,aAAad,CAAQ;"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { css as
|
|
1
|
+
import { css as h, nothing as n, html as l } from "lit";
|
|
2
2
|
import { property as e } from "lit/decorators.js";
|
|
3
|
-
import { classMap as
|
|
3
|
+
import { classMap as b } from "lit/directives/class-map.js";
|
|
4
4
|
import { styleMap as m } from "lit/directives/style-map.js";
|
|
5
|
-
import { K as p, d as v } from "../../../chunks/kt-element-
|
|
6
|
-
import { e as
|
|
5
|
+
import { K as p, d as v } from "../../../chunks/kt-element-B_jjQDhg.js";
|
|
6
|
+
import { e as u } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
7
7
|
import "../kt-icon/kt-icon.js";
|
|
8
|
-
var g = Object.defineProperty, t = (
|
|
9
|
-
for (var a = void 0,
|
|
10
|
-
(d = s
|
|
8
|
+
var g = Object.defineProperty, t = (c, r, i, f) => {
|
|
9
|
+
for (var a = void 0, s = c.length - 1, d; s >= 0; s--)
|
|
10
|
+
(d = c[s]) && (a = d(r, i, a) || a);
|
|
11
11
|
return a && g(r, i, a), a;
|
|
12
12
|
};
|
|
13
13
|
class o extends p {
|
|
@@ -17,11 +17,11 @@ class o extends p {
|
|
|
17
17
|
static {
|
|
18
18
|
this.styles = [
|
|
19
19
|
p.styles,
|
|
20
|
-
|
|
20
|
+
h`
|
|
21
21
|
:host {
|
|
22
22
|
display: inline-flex;
|
|
23
23
|
vertical-align: middle;
|
|
24
|
-
--kt-badge-color: var(--color-primary-
|
|
24
|
+
--kt-badge-color: var(--color-primary-text);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.badge {
|
|
@@ -92,27 +92,27 @@ class o extends p {
|
|
|
92
92
|
colour itself as the ink. The border follows on the bordered shapes
|
|
93
93
|
and is simply absent on the count shape. */
|
|
94
94
|
.primary {
|
|
95
|
-
color: var(--color-primary-
|
|
95
|
+
color: var(--color-primary-text);
|
|
96
96
|
background-color: var(--color-primary-soft);
|
|
97
97
|
border-color: var(--color-primary-base);
|
|
98
98
|
}
|
|
99
99
|
.success {
|
|
100
|
-
color: var(--color-success-
|
|
100
|
+
color: var(--color-success-text);
|
|
101
101
|
background-color: var(--color-success-soft);
|
|
102
102
|
border-color: var(--color-success-base);
|
|
103
103
|
}
|
|
104
104
|
.warning {
|
|
105
|
-
color: var(--color-warning-
|
|
105
|
+
color: var(--color-warning-text);
|
|
106
106
|
background-color: var(--color-warning-soft);
|
|
107
107
|
border-color: var(--color-warning-base);
|
|
108
108
|
}
|
|
109
109
|
.danger {
|
|
110
|
-
color: var(--color-danger-
|
|
110
|
+
color: var(--color-danger-text);
|
|
111
111
|
background-color: var(--color-danger-soft);
|
|
112
112
|
border-color: var(--color-danger-base);
|
|
113
113
|
}
|
|
114
114
|
.info {
|
|
115
|
-
color: var(--color-info-
|
|
115
|
+
color: var(--color-info-text);
|
|
116
116
|
background-color: var(--color-info-soft);
|
|
117
117
|
border-color: var(--color-info-base);
|
|
118
118
|
}
|
|
@@ -178,19 +178,19 @@ class o extends p {
|
|
|
178
178
|
return Number.isFinite(i) && i > this.max ? `${this.max}+` : r;
|
|
179
179
|
}
|
|
180
180
|
activate() {
|
|
181
|
-
this.clickable &&
|
|
181
|
+
this.clickable && u(this, "kt-badge-click");
|
|
182
182
|
}
|
|
183
183
|
onKeyDown(r) {
|
|
184
184
|
this.clickable && (r.key !== "Enter" && r.key !== " " || (r.preventDefault(), this.activate()));
|
|
185
185
|
}
|
|
186
186
|
onRemove(r) {
|
|
187
|
-
r.stopPropagation(),
|
|
187
|
+
r.stopPropagation(), u(this, "kt-remove");
|
|
188
188
|
}
|
|
189
189
|
render() {
|
|
190
190
|
const r = this.error ? "danger" : this.tone;
|
|
191
191
|
return l`<span
|
|
192
192
|
part="base"
|
|
193
|
-
class=${
|
|
193
|
+
class=${b({
|
|
194
194
|
badge: !0,
|
|
195
195
|
[this.variant]: !0,
|
|
196
196
|
[r]: r !== "neutral",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-badge.js","sources":["../../../../src/components/core/kt-badge/kt-badge.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport '../kt-icon/kt-icon.js';\n\nexport type KtBadgeVariant = 'tag' | 'code' | 'category' | 'count';\nexport type KtBadgeTone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info';\nexport type KtBadgeSize = 'small' | 'medium';\n\n/**\n * A compact label: a pill `tag`, a monospaced `code` token, a `category`\n * tinted with a colour of your choosing, or a `count`.\n *\n * Two independent axes, because they answer different questions. `variant` is\n * the **shape** — what kind of thing this is. `tone` is the **colour** — what\n * it means. A tag can be neutral or dangerous; so can a count. Folding them\n * into one list would give you nine variants and no way to say \"a tag, but\n * this one is a warning\".\n *\n * `count` is the exception that carries no border, because a number pinned to\n * a nav item is not a label with an outline — it is a mark on the thing it\n * counts.\n *\n * @element kt-badge\n *\n * @slot - The text. Falls back to the `label` attribute.\n *\n * @csspart base - The container.\n * @csspart remove - The remove button, when `removable`.\n *\n * @cssproperty --kt-badge-color - Category hue. The fill is this colour at 20%.\n *\n * @fires kt-badge-click - A `clickable` badge was activated. Cancelable.\n * @fires kt-remove - The remove button was pressed. Cancelable: cancel it and\n * remove the badge yourself once the server agrees.\n *\n * @example\n * ```html\n * <kt-badge>Design systems</kt-badge>\n * <kt-badge tone=\"success\">Active</kt-badge>\n * <kt-badge variant=\"code\">--surface-card</kt-badge>\n * <kt-badge variant=\"category\" color=\"#3987e5\">Infrastructure</kt-badge>\n * <kt-badge variant=\"count\" tone=\"danger\" max=\"99\">128</kt-badge>\n * <kt-badge icon=\"user\" removable>Assigned to me</kt-badge>\n * ```\n */\nexport class KtBadge extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n --kt-badge-color: var(--color-primary-hover);\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n gap: var(--gap-element);\n width: fit-content;\n margin: 0;\n padding: var(--padding-chip);\n color: var(--text-body);\n font: var(--font-normal-regular);\n background-color: var(--color-dark-20);\n border: var(--border-width) solid var(--color-text-600);\n border-radius: var(--radius-input);\n white-space: normal;\n }\n\n .small {\n padding: 2px 8px;\n font: var(--font-normal-small);\n }\n\n /* === TAG === */\n .tag {\n border-radius: var(--radius-pill);\n }\n\n /* === CODE ===\n Uses the semantic code surface rather than a ramp step: --color-dark-8\n is the darkest surface in the dark theme and pure white in the light\n one, which made this badge white-on-white. */\n .code {\n color: var(--text-code);\n font: var(--font-code-regular);\n background-color: var(--surface-code);\n border-color: var(--border-code);\n }\n\n /* === CATEGORY ===\n color-mix keeps the 20% fill honest for any colour notation the host\n hands us; concatenating a \"33\" onto a hex string produces garbage\n for rgb() and named colours. */\n .category {\n color: var(--kt-badge-color);\n background-color: color-mix(in srgb, var(--kt-badge-color) 20%, transparent);\n border-color: var(--kt-badge-color);\n }\n\n /* === COUNT ===\n No border: a number pinned to a nav item is a mark on the thing it\n counts, not a label with an outline of its own. */\n .count {\n min-width: 20px;\n padding: 2px 6px;\n justify-content: center;\n color: var(--text-muted);\n font: var(--font-normal-small);\n font-variant-numeric: tabular-nums;\n line-height: 1.4;\n white-space: nowrap;\n background: var(--surface-raised);\n border: none;\n border-radius: var(--radius-pill);\n }\n\n /* === TONES ===\n The system's tinted pair everywhere: the colour at 12% behind, the\n colour itself as the ink. The border follows on the bordered shapes\n and is simply absent on the count shape. */\n .primary {\n color: var(--color-primary-base);\n background-color: var(--color-primary-soft);\n border-color: var(--color-primary-base);\n }\n .success {\n color: var(--color-success-base);\n background-color: var(--color-success-soft);\n border-color: var(--color-success-base);\n }\n .warning {\n color: var(--color-warning-base);\n background-color: var(--color-warning-soft);\n border-color: var(--color-warning-base);\n }\n .danger {\n color: var(--color-danger-base);\n background-color: var(--color-danger-soft);\n border-color: var(--color-danger-base);\n }\n .info {\n color: var(--color-info-base);\n background-color: var(--color-info-soft);\n border-color: var(--color-info-base);\n }\n\n .count.primary,\n .count.success,\n .count.warning,\n .count.danger,\n .count.info {\n border: none;\n }\n\n /* === CLICKABLE === */\n .clickable {\n cursor: pointer;\n }\n .clickable:hover {\n outline: var(--outline-width) solid var(--text-muted);\n }\n .clickable:active {\n color: var(--color-white);\n background-color: var(--color-primary-base);\n border-color: transparent;\n }\n .clickable:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n }\n\n .remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: -4px;\n padding: 0;\n color: inherit;\n background: none;\n border: none;\n border-radius: var(--radius-pill);\n cursor: pointer;\n opacity: 0.65;\n }\n\n .remove:hover {\n opacity: 1;\n }\n\n .remove:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 1px;\n }\n\n kt-icon {\n flex: none;\n }\n `,\n ];\n\n /** The shape: what kind of thing this is. */\n @property({ type: String, reflect: true })\n variant: KtBadgeVariant = 'tag';\n\n /** The colour: what it means. Independent of `variant`. */\n @property({ type: String, reflect: true })\n tone: KtBadgeTone = 'neutral';\n\n @property({ type: String, reflect: true })\n size: KtBadgeSize = 'medium';\n\n /** Badge text. The default slot wins when both are present. */\n @property({ type: String })\n label = '';\n\n /** Category hue: any CSS colour. The fill is this colour at 20%. */\n @property({ type: String })\n color = '';\n\n /** Lucide icon name, before the text. */\n @property({ type: String })\n icon = '';\n\n @property({ type: Boolean, reflect: true })\n clickable = false;\n\n /** Adds a remove button. Fires a cancelable `kt-remove`. */\n @property({ type: Boolean, reflect: true })\n removable = false;\n\n /**\n * Caps a numeric label: `max=\"99\"` shows `99+`.\n * Ignored when the content is not a number.\n */\n @property({ type: Number })\n max?: number;\n\n /** Shorthand for `tone=\"danger\"`, kept from the field components. */\n @property({ type: Boolean, reflect: true })\n error = false;\n\n private get display(): string {\n const raw = this.label || (this.textContent ?? '').trim();\n if (this.max === undefined) return raw;\n\n const n = Number(raw);\n return Number.isFinite(n) && n > this.max ? `${this.max}+` : raw;\n }\n\n private activate(): void {\n if (this.clickable) emit(this, 'kt-badge-click');\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n if (!this.clickable) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n this.activate();\n }\n\n private onRemove(event: Event): void {\n // Otherwise a removable clickable badge reports both at once.\n event.stopPropagation();\n emit(this, 'kt-remove');\n }\n\n override render(): TemplateResult {\n const tone = this.error ? 'danger' : this.tone;\n\n return html`<span\n part=\"base\"\n class=${classMap({\n badge: true,\n [this.variant]: true,\n [tone]: tone !== 'neutral',\n small: this.size === 'small',\n clickable: this.clickable,\n })}\n style=${styleMap(this.color ? { '--kt-badge-color': this.color } : {})}\n role=${this.clickable ? 'button' : nothing}\n tabindex=${this.clickable ? 0 : nothing}\n @click=${this.activate}\n @keydown=${this.onKeyDown}\n >\n ${this.icon ? html`<kt-icon name=${this.icon} size=\"14\"></kt-icon>` : nothing}\n ${this.max === undefined ? html`<slot>${this.label}</slot>` : this.display}\n ${\n this.removable\n ? html`<button\n part=\"remove\"\n type=\"button\"\n class=\"remove\"\n aria-label=${`Remove ${this.display || 'this'}`}\n @click=${this.onRemove}\n >\n <kt-icon name=\"x\" size=\"12\"></kt-icon>\n </button>`\n : nothing\n }\n </span>`;\n }\n}\n\ndefineElement('kt-badge', KtBadge);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-badge': KtBadge;\n }\n}\n"],"names":["KtBadge","KtElement","css","raw","n","emit","event","tone","html","classMap","styleMap","nothing","__decorateClass","property","defineElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kt-badge.js","sources":["../../../../src/components/core/kt-badge/kt-badge.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport '../kt-icon/kt-icon.js';\n\nexport type KtBadgeVariant = 'tag' | 'code' | 'category' | 'count';\nexport type KtBadgeTone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info';\nexport type KtBadgeSize = 'small' | 'medium';\n\n/**\n * A compact label: a pill `tag`, a monospaced `code` token, a `category`\n * tinted with a colour of your choosing, or a `count`.\n *\n * Two independent axes, because they answer different questions. `variant` is\n * the **shape** — what kind of thing this is. `tone` is the **colour** — what\n * it means. A tag can be neutral or dangerous; so can a count. Folding them\n * into one list would give you nine variants and no way to say \"a tag, but\n * this one is a warning\".\n *\n * `count` is the exception that carries no border, because a number pinned to\n * a nav item is not a label with an outline — it is a mark on the thing it\n * counts.\n *\n * @element kt-badge\n *\n * @slot - The text. Falls back to the `label` attribute.\n *\n * @csspart base - The container.\n * @csspart remove - The remove button, when `removable`.\n *\n * @cssproperty --kt-badge-color - Category hue. The fill is this colour at 20%.\n *\n * @fires kt-badge-click - A `clickable` badge was activated. Cancelable.\n * @fires kt-remove - The remove button was pressed. Cancelable: cancel it and\n * remove the badge yourself once the server agrees.\n *\n * @example\n * ```html\n * <kt-badge>Design systems</kt-badge>\n * <kt-badge tone=\"success\">Active</kt-badge>\n * <kt-badge variant=\"code\">--surface-card</kt-badge>\n * <kt-badge variant=\"category\" color=\"#3987e5\">Infrastructure</kt-badge>\n * <kt-badge variant=\"count\" tone=\"danger\" max=\"99\">128</kt-badge>\n * <kt-badge icon=\"user\" removable>Assigned to me</kt-badge>\n * ```\n */\nexport class KtBadge extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n --kt-badge-color: var(--color-primary-text);\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n gap: var(--gap-element);\n width: fit-content;\n margin: 0;\n padding: var(--padding-chip);\n color: var(--text-body);\n font: var(--font-normal-regular);\n background-color: var(--color-dark-20);\n border: var(--border-width) solid var(--color-text-600);\n border-radius: var(--radius-input);\n white-space: normal;\n }\n\n .small {\n padding: 2px 8px;\n font: var(--font-normal-small);\n }\n\n /* === TAG === */\n .tag {\n border-radius: var(--radius-pill);\n }\n\n /* === CODE ===\n Uses the semantic code surface rather than a ramp step: --color-dark-8\n is the darkest surface in the dark theme and pure white in the light\n one, which made this badge white-on-white. */\n .code {\n color: var(--text-code);\n font: var(--font-code-regular);\n background-color: var(--surface-code);\n border-color: var(--border-code);\n }\n\n /* === CATEGORY ===\n color-mix keeps the 20% fill honest for any colour notation the host\n hands us; concatenating a \"33\" onto a hex string produces garbage\n for rgb() and named colours. */\n .category {\n color: var(--kt-badge-color);\n background-color: color-mix(in srgb, var(--kt-badge-color) 20%, transparent);\n border-color: var(--kt-badge-color);\n }\n\n /* === COUNT ===\n No border: a number pinned to a nav item is a mark on the thing it\n counts, not a label with an outline of its own. */\n .count {\n min-width: 20px;\n padding: 2px 6px;\n justify-content: center;\n color: var(--text-muted);\n font: var(--font-normal-small);\n font-variant-numeric: tabular-nums;\n line-height: 1.4;\n white-space: nowrap;\n background: var(--surface-raised);\n border: none;\n border-radius: var(--radius-pill);\n }\n\n /* === TONES ===\n The system's tinted pair everywhere: the colour at 12% behind, the\n colour itself as the ink. The border follows on the bordered shapes\n and is simply absent on the count shape. */\n .primary {\n color: var(--color-primary-text);\n background-color: var(--color-primary-soft);\n border-color: var(--color-primary-base);\n }\n .success {\n color: var(--color-success-text);\n background-color: var(--color-success-soft);\n border-color: var(--color-success-base);\n }\n .warning {\n color: var(--color-warning-text);\n background-color: var(--color-warning-soft);\n border-color: var(--color-warning-base);\n }\n .danger {\n color: var(--color-danger-text);\n background-color: var(--color-danger-soft);\n border-color: var(--color-danger-base);\n }\n .info {\n color: var(--color-info-text);\n background-color: var(--color-info-soft);\n border-color: var(--color-info-base);\n }\n\n .count.primary,\n .count.success,\n .count.warning,\n .count.danger,\n .count.info {\n border: none;\n }\n\n /* === CLICKABLE === */\n .clickable {\n cursor: pointer;\n }\n .clickable:hover {\n outline: var(--outline-width) solid var(--text-muted);\n }\n .clickable:active {\n color: var(--color-white);\n background-color: var(--color-primary-base);\n border-color: transparent;\n }\n .clickable:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n }\n\n .remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: -4px;\n padding: 0;\n color: inherit;\n background: none;\n border: none;\n border-radius: var(--radius-pill);\n cursor: pointer;\n opacity: 0.65;\n }\n\n .remove:hover {\n opacity: 1;\n }\n\n .remove:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 1px;\n }\n\n kt-icon {\n flex: none;\n }\n `,\n ];\n\n /** The shape: what kind of thing this is. */\n @property({ type: String, reflect: true })\n variant: KtBadgeVariant = 'tag';\n\n /** The colour: what it means. Independent of `variant`. */\n @property({ type: String, reflect: true })\n tone: KtBadgeTone = 'neutral';\n\n @property({ type: String, reflect: true })\n size: KtBadgeSize = 'medium';\n\n /** Badge text. The default slot wins when both are present. */\n @property({ type: String })\n label = '';\n\n /** Category hue: any CSS colour. The fill is this colour at 20%. */\n @property({ type: String })\n color = '';\n\n /** Lucide icon name, before the text. */\n @property({ type: String })\n icon = '';\n\n @property({ type: Boolean, reflect: true })\n clickable = false;\n\n /** Adds a remove button. Fires a cancelable `kt-remove`. */\n @property({ type: Boolean, reflect: true })\n removable = false;\n\n /**\n * Caps a numeric label: `max=\"99\"` shows `99+`.\n * Ignored when the content is not a number.\n */\n @property({ type: Number })\n max?: number;\n\n /** Shorthand for `tone=\"danger\"`, kept from the field components. */\n @property({ type: Boolean, reflect: true })\n error = false;\n\n private get display(): string {\n const raw = this.label || (this.textContent ?? '').trim();\n if (this.max === undefined) return raw;\n\n const n = Number(raw);\n return Number.isFinite(n) && n > this.max ? `${this.max}+` : raw;\n }\n\n private activate(): void {\n if (this.clickable) emit(this, 'kt-badge-click');\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n if (!this.clickable) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n this.activate();\n }\n\n private onRemove(event: Event): void {\n // Otherwise a removable clickable badge reports both at once.\n event.stopPropagation();\n emit(this, 'kt-remove');\n }\n\n override render(): TemplateResult {\n const tone = this.error ? 'danger' : this.tone;\n\n return html`<span\n part=\"base\"\n class=${classMap({\n badge: true,\n [this.variant]: true,\n [tone]: tone !== 'neutral',\n small: this.size === 'small',\n clickable: this.clickable,\n })}\n style=${styleMap(this.color ? { '--kt-badge-color': this.color } : {})}\n role=${this.clickable ? 'button' : nothing}\n tabindex=${this.clickable ? 0 : nothing}\n @click=${this.activate}\n @keydown=${this.onKeyDown}\n >\n ${this.icon ? html`<kt-icon name=${this.icon} size=\"14\"></kt-icon>` : nothing}\n ${this.max === undefined ? html`<slot>${this.label}</slot>` : this.display}\n ${\n this.removable\n ? html`<button\n part=\"remove\"\n type=\"button\"\n class=\"remove\"\n aria-label=${`Remove ${this.display || 'this'}`}\n @click=${this.onRemove}\n >\n <kt-icon name=\"x\" size=\"12\"></kt-icon>\n </button>`\n : nothing\n }\n </span>`;\n }\n}\n\ndefineElement('kt-badge', KtBadge);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-badge': KtBadge;\n }\n}\n"],"names":["KtBadge","KtElement","css","raw","n","emit","event","tone","html","classMap","styleMap","nothing","__decorateClass","property","defineElement"],"mappings":"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"}
|
|
@@ -44,6 +44,13 @@ export declare class KtButton extends KtElement {
|
|
|
44
44
|
iconPosition: 'left' | 'right';
|
|
45
45
|
/** Accessible name. Required for an icon-only button. */
|
|
46
46
|
label: string;
|
|
47
|
+
/**
|
|
48
|
+
* The kind of popup this button opens, as `aria-haspopup` on the inner
|
|
49
|
+
* button. Set by `<kt-dropdown>` on its trigger; rarely by hand.
|
|
50
|
+
*/
|
|
51
|
+
popup: 'menu' | 'listbox' | 'dialog' | undefined;
|
|
52
|
+
/** Whether the popup or region this button controls is open, as `aria-expanded`. */
|
|
53
|
+
expanded: boolean | undefined;
|
|
47
54
|
/** Stretches the button to the width of its container. */
|
|
48
55
|
fullWidth: boolean;
|
|
49
56
|
/** Submitted with the form, as on a native button. */
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { css as h, html as d, nothing as i } from "lit";
|
|
2
|
-
import { property as
|
|
3
|
-
import { classMap as
|
|
4
|
-
import { K as u, d as
|
|
2
|
+
import { property as e } from "lit/decorators.js";
|
|
3
|
+
import { classMap as p } from "lit/directives/class-map.js";
|
|
4
|
+
import { K as u, d as v } from "../../../chunks/kt-element-B_jjQDhg.js";
|
|
5
5
|
import "../kt-icon/kt-icon.js";
|
|
6
|
-
var g = Object.defineProperty,
|
|
6
|
+
var g = Object.defineProperty, a = (l, t, o, y) => {
|
|
7
7
|
for (var n = void 0, c = l.length - 1, s; c >= 0; c--)
|
|
8
|
-
(s = l[c]) && (n = s(
|
|
9
|
-
return n && g(
|
|
8
|
+
(s = l[c]) && (n = s(t, o, n) || n);
|
|
9
|
+
return n && g(t, o, n), n;
|
|
10
10
|
};
|
|
11
|
-
const
|
|
12
|
-
class
|
|
11
|
+
const b = { small: 16, medium: 20, large: 24 };
|
|
12
|
+
class r extends u {
|
|
13
13
|
constructor() {
|
|
14
|
-
super(...arguments), this.variant = "primary", this.size = "medium", this.disabled = !1, this.type = "button", this.icon = "", this.iconPosition = "left", this.label = "", this.fullWidth = !1, this.name = "", this.value = "";
|
|
14
|
+
super(...arguments), this.variant = "primary", this.size = "medium", this.disabled = !1, this.type = "button", this.icon = "", this.iconPosition = "left", this.label = "", this.popup = void 0, this.expanded = void 0, this.fullWidth = !1, this.name = "", this.value = "";
|
|
15
15
|
}
|
|
16
16
|
static {
|
|
17
17
|
this.styles = [
|
|
@@ -71,7 +71,7 @@ class t extends u {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
.secondary {
|
|
74
|
-
color: var(--color-primary-
|
|
74
|
+
color: var(--color-primary-text);
|
|
75
75
|
background-color: var(--color-primary-soft);
|
|
76
76
|
}
|
|
77
77
|
.secondary:hover {
|
|
@@ -82,7 +82,7 @@ class t extends u {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
.secondary-no-bg {
|
|
85
|
-
color: var(--color-primary-
|
|
85
|
+
color: var(--color-primary-text);
|
|
86
86
|
background: none;
|
|
87
87
|
}
|
|
88
88
|
.secondary-no-bg:hover {
|
|
@@ -104,7 +104,7 @@ class t extends u {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
.danger {
|
|
107
|
-
color: var(--color-danger-
|
|
107
|
+
color: var(--color-danger-text);
|
|
108
108
|
background-color: var(--color-danger-soft);
|
|
109
109
|
}
|
|
110
110
|
.danger:hover {
|
|
@@ -116,14 +116,14 @@ class t extends u {
|
|
|
116
116
|
|
|
117
117
|
.delete {
|
|
118
118
|
color: var(--color-white);
|
|
119
|
-
background-color: var(--color-
|
|
119
|
+
background-color: var(--color-danger-solid);
|
|
120
120
|
}
|
|
121
121
|
.delete:hover {
|
|
122
|
-
background-color: var(--color-danger-
|
|
122
|
+
background-color: var(--color-danger-solid-hover);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
.warning {
|
|
126
|
-
color: var(--color-warning-
|
|
126
|
+
color: var(--color-warning-text);
|
|
127
127
|
background-color: var(--color-warning-soft);
|
|
128
128
|
}
|
|
129
129
|
.warning:hover {
|
|
@@ -131,7 +131,7 @@ class t extends u {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
.info {
|
|
134
|
-
color: var(--color-info-
|
|
134
|
+
color: var(--color-info-text);
|
|
135
135
|
background-color: var(--color-info-soft);
|
|
136
136
|
}
|
|
137
137
|
.info:hover {
|
|
@@ -139,7 +139,7 @@ class t extends u {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
.success {
|
|
142
|
-
color: var(--color-success-
|
|
142
|
+
color: var(--color-success-text);
|
|
143
143
|
background-color: var(--color-success-soft);
|
|
144
144
|
}
|
|
145
145
|
.success:hover {
|
|
@@ -149,7 +149,7 @@ class t extends u {
|
|
|
149
149
|
.text {
|
|
150
150
|
height: auto;
|
|
151
151
|
padding: 0;
|
|
152
|
-
color: var(--color-primary-
|
|
152
|
+
color: var(--color-primary-text);
|
|
153
153
|
background: none;
|
|
154
154
|
}
|
|
155
155
|
.text:active {
|
|
@@ -186,8 +186,8 @@ class t extends u {
|
|
|
186
186
|
];
|
|
187
187
|
}
|
|
188
188
|
/** Moves focus to the button. */
|
|
189
|
-
focus(
|
|
190
|
-
this.shadowRoot?.querySelector("button")?.focus(
|
|
189
|
+
focus(t) {
|
|
190
|
+
this.shadowRoot?.querySelector("button")?.focus(t);
|
|
191
191
|
}
|
|
192
192
|
blur() {
|
|
193
193
|
this.shadowRoot?.querySelector("button")?.blur();
|
|
@@ -202,30 +202,32 @@ class t extends u {
|
|
|
202
202
|
* `name`/`value` into the submission the way an author expects.
|
|
203
203
|
*/
|
|
204
204
|
submitEnclosingForm() {
|
|
205
|
-
const
|
|
206
|
-
if (!
|
|
205
|
+
const t = this.closest("form");
|
|
206
|
+
if (!t) return;
|
|
207
207
|
const o = document.createElement("button");
|
|
208
|
-
o.type = this.type, o.hidden = !0, this.name && (o.name = this.name), this.value && (o.value = this.value),
|
|
208
|
+
o.type = this.type, o.hidden = !0, this.name && (o.name = this.name), this.value && (o.value = this.value), t.append(o), o.click(), o.remove();
|
|
209
209
|
}
|
|
210
|
-
onClick(
|
|
210
|
+
onClick(t) {
|
|
211
211
|
if (this.disabled) {
|
|
212
|
-
|
|
212
|
+
t.preventDefault(), t.stopPropagation();
|
|
213
213
|
return;
|
|
214
214
|
}
|
|
215
215
|
this.type !== "button" && this.submitEnclosingForm();
|
|
216
216
|
}
|
|
217
217
|
render() {
|
|
218
|
-
const
|
|
218
|
+
const t = !!this.icon && !this.hasLabelText, o = this.icon ? d`<kt-icon part="icon" name=${this.icon} size=${b[this.size]}></kt-icon>` : i;
|
|
219
219
|
return d`<button
|
|
220
220
|
part="button"
|
|
221
|
-
class=${
|
|
221
|
+
class=${p({
|
|
222
222
|
[this.variant]: !0,
|
|
223
223
|
[this.size]: !0,
|
|
224
|
-
"icon-only":
|
|
224
|
+
"icon-only": t
|
|
225
225
|
})}
|
|
226
226
|
type=${this.type}
|
|
227
227
|
?disabled=${this.disabled}
|
|
228
228
|
aria-label=${this.label || i}
|
|
229
|
+
aria-haspopup=${this.popup ?? i}
|
|
230
|
+
aria-expanded=${this.expanded === void 0 ? i : String(this.expanded)}
|
|
229
231
|
@click=${this.onClick}
|
|
230
232
|
>
|
|
231
233
|
${this.iconPosition === "left" ? o : i}
|
|
@@ -234,38 +236,44 @@ class t extends u {
|
|
|
234
236
|
</button>`;
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
],
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
],
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
],
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
],
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
],
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
],
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
],
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
],
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
],
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
],
|
|
267
|
-
|
|
239
|
+
a([
|
|
240
|
+
e({ type: String, reflect: !0 })
|
|
241
|
+
], r.prototype, "variant");
|
|
242
|
+
a([
|
|
243
|
+
e({ type: String, reflect: !0 })
|
|
244
|
+
], r.prototype, "size");
|
|
245
|
+
a([
|
|
246
|
+
e({ type: Boolean, reflect: !0 })
|
|
247
|
+
], r.prototype, "disabled");
|
|
248
|
+
a([
|
|
249
|
+
e({ type: String })
|
|
250
|
+
], r.prototype, "type");
|
|
251
|
+
a([
|
|
252
|
+
e({ type: String })
|
|
253
|
+
], r.prototype, "icon");
|
|
254
|
+
a([
|
|
255
|
+
e({ type: String, attribute: "icon-position" })
|
|
256
|
+
], r.prototype, "iconPosition");
|
|
257
|
+
a([
|
|
258
|
+
e({ type: String })
|
|
259
|
+
], r.prototype, "label");
|
|
260
|
+
a([
|
|
261
|
+
e({ attribute: !1 })
|
|
262
|
+
], r.prototype, "popup");
|
|
263
|
+
a([
|
|
264
|
+
e({ attribute: !1 })
|
|
265
|
+
], r.prototype, "expanded");
|
|
266
|
+
a([
|
|
267
|
+
e({ type: Boolean, reflect: !0, attribute: "full-width" })
|
|
268
|
+
], r.prototype, "fullWidth");
|
|
269
|
+
a([
|
|
270
|
+
e({ type: String })
|
|
271
|
+
], r.prototype, "name");
|
|
272
|
+
a([
|
|
273
|
+
e({ type: String })
|
|
274
|
+
], r.prototype, "value");
|
|
275
|
+
v("kt-button", r);
|
|
268
276
|
export {
|
|
269
|
-
|
|
277
|
+
r as KtButton
|
|
270
278
|
};
|
|
271
279
|
//# sourceMappingURL=kt-button.js.map
|