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.
Files changed (90) hide show
  1. package/README.md +20 -2
  2. package/dist/chunks/form-control-CxjBTt1c.js.map +1 -1
  3. package/dist/chunks/kt-element-B_jjQDhg.js +38 -0
  4. package/dist/chunks/kt-element-B_jjQDhg.js.map +1 -0
  5. package/dist/components/core/kt-avatar/kt-avatar.js +9 -6
  6. package/dist/components/core/kt-avatar/kt-avatar.js.map +1 -1
  7. package/dist/components/core/kt-badge/kt-badge.js +17 -17
  8. package/dist/components/core/kt-badge/kt-badge.js.map +1 -1
  9. package/dist/components/core/kt-button/kt-button.d.ts +7 -0
  10. package/dist/components/core/kt-button/kt-button.js +68 -60
  11. package/dist/components/core/kt-button/kt-button.js.map +1 -1
  12. package/dist/components/core/kt-card/kt-card.js +1 -1
  13. package/dist/components/core/kt-code/kt-code.js +12 -12
  14. package/dist/components/core/kt-code/kt-code.js.map +1 -1
  15. package/dist/components/core/kt-icon/kt-icon.js +1 -1
  16. package/dist/components/core/kt-kbd/kt-kbd.js +14 -14
  17. package/dist/components/core/kt-kbd/kt-kbd.js.map +1 -1
  18. package/dist/components/core/kt-split-button/kt-split-button.js +3 -3
  19. package/dist/components/core/kt-split-button/kt-split-button.js.map +1 -1
  20. package/dist/components/data/kt-chart/kt-chart.js +1 -1
  21. package/dist/components/data/kt-meter/kt-meter.js +1 -1
  22. package/dist/components/data/kt-pagination/kt-pagination.js +1 -1
  23. package/dist/components/data/kt-stat/kt-stat.js +5 -5
  24. package/dist/components/data/kt-stat/kt-stat.js.map +1 -1
  25. package/dist/components/data/kt-table/kt-table.js +2 -2
  26. package/dist/components/data/kt-table/kt-table.js.map +1 -1
  27. package/dist/components/data/kt-timeline/kt-timeline.js +1 -1
  28. package/dist/components/feedback/kt-alert/kt-alert.js +26 -26
  29. package/dist/components/feedback/kt-alert/kt-alert.js.map +1 -1
  30. package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
  31. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +2 -2
  32. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js.map +1 -1
  33. package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
  34. package/dist/components/feedback/kt-toast/kt-toast.js +22 -22
  35. package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -1
  36. package/dist/components/feedback/kt-toast-container/kt-toast-container.js +1 -1
  37. package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
  38. package/dist/components/forms/kt-drag-drop/kt-drag-drop.d.ts +11 -1
  39. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +69 -36
  40. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -1
  41. package/dist/components/forms/kt-form/kt-form.js +1 -1
  42. package/dist/components/forms/kt-input/kt-input.js +95 -91
  43. package/dist/components/forms/kt-input/kt-input.js.map +1 -1
  44. package/dist/components/forms/kt-input-menu/kt-input-menu.d.ts +10 -1
  45. package/dist/components/forms/kt-input-menu/kt-input-menu.js +83 -53
  46. package/dist/components/forms/kt-input-menu/kt-input-menu.js.map +1 -1
  47. package/dist/components/forms/kt-label-input/kt-label-input.js +2 -2
  48. package/dist/components/forms/kt-label-input/kt-label-input.js.map +1 -1
  49. package/dist/components/forms/kt-select/kt-select.js +2 -2
  50. package/dist/components/forms/kt-select/kt-select.js.map +1 -1
  51. package/dist/components/forms/kt-textarea/kt-textarea.js +15 -13
  52. package/dist/components/forms/kt-textarea/kt-textarea.js.map +1 -1
  53. package/dist/components/forms/kt-toggle/kt-toggle.js +8 -7
  54. package/dist/components/forms/kt-toggle/kt-toggle.js.map +1 -1
  55. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +1 -1
  56. package/dist/components/navigation/kt-header/kt-header.js +1 -1
  57. package/dist/components/navigation/kt-page-header/kt-page-header.js +18 -18
  58. package/dist/components/navigation/kt-page-header/kt-page-header.js.map +1 -1
  59. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +10 -1
  60. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +88 -62
  61. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
  62. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +5 -5
  63. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -1
  64. package/dist/components/navigation/kt-tabs/kt-tabs.js +1 -1
  65. package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +3 -3
  66. package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js.map +1 -1
  67. package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +1 -1
  68. package/dist/components/overlays/kt-collapsible/kt-collapsible.js +1 -1
  69. package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +1 -1
  70. package/dist/components/overlays/kt-dropdown/kt-dropdown.d.ts +13 -0
  71. package/dist/components/overlays/kt-dropdown/kt-dropdown.js +74 -59
  72. package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
  73. package/dist/components/overlays/kt-modal/kt-modal.js +1 -1
  74. package/dist/components/overlays/kt-side-panel/kt-side-panel.js +1 -1
  75. package/dist/custom-elements.json +11791 -0
  76. package/dist/index.js +1 -1
  77. package/dist/internal/form-control.d.ts +7 -2
  78. package/dist/react/index.js.map +1 -1
  79. package/dist/react/jsx.d.ts +213 -0
  80. package/dist/react/jsx.js +2 -0
  81. package/dist/react/jsx.js.map +1 -0
  82. package/dist/tokens/README.md +7 -3
  83. package/dist/tokens/colors.css +24 -5
  84. package/dist/tokens/theme-light.css +18 -0
  85. package/dist/vscode.css-custom-data.json +154 -0
  86. package/dist/vscode.html-custom-data.json +1136 -0
  87. package/dist/web-types.json +3186 -0
  88. package/package.json +28 -9
  89. package/dist/chunks/kt-element-CcMLO5e8.js +0 -28
  90. 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 seventeen its
107
- own elements draw. Register what your application uses:
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/** Pushes the control's current value into the enclosing form, if there is one. */\nexport function setFormValue(internals: UsableInternals | null, value: string | null): 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;AAGO,SAASC,EAAaD,GAAmCE,GAA4B;AAC1F,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;"}
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 u, d as g } from "../../../chunks/kt-element-CcMLO5e8.js";
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 d = Array.from({ length: 8 }, (a, e) => `var(--chart-series-${e + 1})`);
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 u {
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
- u.styles,
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
- color: var(--kt-avatar-hue, var(--text-muted));
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 d[e % d.length];
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":"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"}
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":"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"}
@@ -1,13 +1,13 @@
1
- import { css as u, nothing as n, html as l } from "lit";
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 h } from "lit/directives/class-map.js";
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-CcMLO5e8.js";
6
- import { e as b } from "../../../chunks/events-Bjl5Zmmq.js";
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 = (s, r, i, f) => {
9
- for (var a = void 0, c = s.length - 1, d; c >= 0; c--)
10
- (d = s[c]) && (a = d(r, i, a) || a);
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
- u`
20
+ h`
21
21
  :host {
22
22
  display: inline-flex;
23
23
  vertical-align: middle;
24
- --kt-badge-color: var(--color-primary-hover);
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-base);
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-base);
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-base);
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-base);
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-base);
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 && b(this, "kt-badge-click");
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(), b(this, "kt-remove");
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=${h({
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":";;;;;;;;;;;;AAiDO,MAAMA,UAAgBC,EAAU;AAAA,EAAhC,cAAA;AAAA,UAAA,GAAA,SAAA,GA+JL,KAAA,UAA0B,OAI1B,KAAA,OAAoB,WAGpB,KAAA,OAAoB,UAIpB,KAAA,QAAQ,IAIR,KAAA,QAAQ,IAIR,KAAA,OAAO,IAGP,KAAA,YAAY,IAIZ,KAAA,YAAY,IAWZ,KAAA,QAAQ;AAAA,EAAA;AAAA,EAnMR,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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,EAwJF;AAAA,EA2CA,IAAY,UAAkB;AAC5B,UAAMC,IAAM,KAAK,UAAU,KAAK,eAAe,IAAI,KAAA;AACnD,QAAI,KAAK,QAAQ,OAAW,QAAOA;AAEnC,UAAMC,IAAI,OAAOD,CAAG;AACpB,WAAO,OAAO,SAASC,CAAC,KAAKA,IAAI,KAAK,MAAM,GAAG,KAAK,GAAG,MAAMD;AAAA,EAC/D;AAAA,EAEQ,WAAiB;AACvB,IAAI,KAAK,aAAWE,EAAK,MAAM,gBAAgB;AAAA,EACjD;AAAA,EAEQ,UAAUC,GAA4B;AAC5C,IAAK,KAAK,cACNA,EAAM,QAAQ,WAAWA,EAAM,QAAQ,QAC3CA,EAAM,eAAA,GACN,KAAK,SAAA;AAAA,EACP;AAAA,EAEQ,SAASA,GAAoB;AAEnC,IAAAA,EAAM,gBAAA,GACND,EAAK,MAAM,WAAW;AAAA,EACxB;AAAA,EAES,SAAyB;AAChC,UAAME,IAAO,KAAK,QAAQ,WAAW,KAAK;AAE1C,WAAOC;AAAA;AAAA,cAEGC,EAAS;AAAA,MACf,OAAO;AAAA,MACP,CAAC,KAAK,OAAO,GAAG;AAAA,MAChB,CAACF,CAAI,GAAGA,MAAS;AAAA,MACjB,OAAO,KAAK,SAAS;AAAA,MACrB,WAAW,KAAK;AAAA,IAAA,CACjB,CAAC;AAAA,cACMG,EAAS,KAAK,QAAQ,EAAE,oBAAoB,KAAK,MAAA,IAAU,EAAE,CAAC;AAAA,aAC/D,KAAK,YAAY,WAAWC,CAAO;AAAA,iBAC/B,KAAK,YAAY,IAAIA,CAAO;AAAA,eAC9B,KAAK,QAAQ;AAAA,iBACX,KAAK,SAAS;AAAA;AAAA,QAEvB,KAAK,OAAOH,kBAAqB,KAAK,IAAI,0BAA0BG,CAAO;AAAA,QAC3E,KAAK,QAAQ,SAAYH,UAAa,KAAK,KAAK,YAAY,KAAK,OAAO;AAAA,QAExE,KAAK,YACDA;AAAA;AAAA;AAAA;AAAA,2BAIe,UAAU,KAAK,WAAW,MAAM,EAAE;AAAA,uBACtC,KAAK,QAAQ;AAAA;AAAA;AAAA,yBAIxBG,CACN;AAAA;AAAA,EAEJ;AACF;AAnGEC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA9J9Bb,EA+JX,WAAA,SAAA;AAIAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAlK9Bb,EAmKX,WAAA,MAAA;AAGAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GArK9Bb,EAsKX,WAAA,MAAA;AAIAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAzKfb,EA0KX,WAAA,OAAA;AAIAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA7Kfb,EA8KX,WAAA,OAAA;AAIAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAjLfb,EAkLX,WAAA,MAAA;AAGAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GApL/Bb,EAqLX,WAAA,WAAA;AAIAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAxL/Bb,EAyLX,WAAA,WAAA;AAOAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA/Lfb,EAgMX,WAAA,KAAA;AAIAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAnM/Bb,EAoMX,WAAA,OAAA;AAgEFc,EAAc,YAAYd,CAAO;"}
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 a } from "lit/decorators.js";
3
- import { classMap as v } from "lit/directives/class-map.js";
4
- import { K as u, d as b } from "../../../chunks/kt-element-CcMLO5e8.js";
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, e = (l, r, o, y) => {
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(r, o, n) || n);
9
- return n && g(r, o, n), n;
8
+ (s = l[c]) && (n = s(t, o, n) || n);
9
+ return n && g(t, o, n), n;
10
10
  };
11
- const p = { small: 16, medium: 20, large: 24 };
12
- class t extends u {
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-base);
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-base);
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-base);
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-navigation-icon-close);
119
+ background-color: var(--color-danger-solid);
120
120
  }
121
121
  .delete:hover {
122
- background-color: var(--color-danger-base);
122
+ background-color: var(--color-danger-solid-hover);
123
123
  }
124
124
 
125
125
  .warning {
126
- color: var(--color-warning-base);
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-base);
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-base);
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-base);
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(r) {
190
- this.shadowRoot?.querySelector("button")?.focus(r);
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 r = this.closest("form");
206
- if (!r) return;
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), r.append(o), o.click(), o.remove();
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(r) {
210
+ onClick(t) {
211
211
  if (this.disabled) {
212
- r.preventDefault(), r.stopPropagation();
212
+ t.preventDefault(), t.stopPropagation();
213
213
  return;
214
214
  }
215
215
  this.type !== "button" && this.submitEnclosingForm();
216
216
  }
217
217
  render() {
218
- const r = !!this.icon && !this.hasLabelText, o = this.icon ? d`<kt-icon part="icon" name=${this.icon} size=${p[this.size]}></kt-icon>` : i;
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=${v({
221
+ class=${p({
222
222
  [this.variant]: !0,
223
223
  [this.size]: !0,
224
- "icon-only": r
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
- e([
238
- a({ type: String, reflect: !0 })
239
- ], t.prototype, "variant");
240
- e([
241
- a({ type: String, reflect: !0 })
242
- ], t.prototype, "size");
243
- e([
244
- a({ type: Boolean, reflect: !0 })
245
- ], t.prototype, "disabled");
246
- e([
247
- a({ type: String })
248
- ], t.prototype, "type");
249
- e([
250
- a({ type: String })
251
- ], t.prototype, "icon");
252
- e([
253
- a({ type: String, attribute: "icon-position" })
254
- ], t.prototype, "iconPosition");
255
- e([
256
- a({ type: String })
257
- ], t.prototype, "label");
258
- e([
259
- a({ type: Boolean, reflect: !0, attribute: "full-width" })
260
- ], t.prototype, "fullWidth");
261
- e([
262
- a({ type: String })
263
- ], t.prototype, "name");
264
- e([
265
- a({ type: String })
266
- ], t.prototype, "value");
267
- b("kt-button", t);
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
- t as KtButton
277
+ r as KtButton
270
278
  };
271
279
  //# sourceMappingURL=kt-button.js.map