kanto-ds 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +56 -6
  2. package/dist/cdn/kanto.min.js +6619 -0
  3. package/dist/chunks/defaults-Cpeg13O5.js +68 -0
  4. package/dist/chunks/defaults-Cpeg13O5.js.map +1 -0
  5. package/dist/chunks/{floating-B33g-M_1.js → floating-C9RLa6cZ.js} +2 -2
  6. package/dist/chunks/floating-C9RLa6cZ.js.map +1 -0
  7. package/dist/components/core/kt-icon/kt-icon.js +1 -1
  8. package/dist/components/forms/kt-date-input/kt-date-input.js +1 -1
  9. package/dist/components/forms/kt-date-picker/kt-date-picker.js +1 -1
  10. package/dist/components/forms/kt-input/kt-input.js +1 -1
  11. package/dist/components/forms/kt-input-menu/kt-input-menu.js +1 -1
  12. package/dist/components/forms/kt-multi-select/kt-multi-select.js +1 -1
  13. package/dist/components/forms/kt-select/kt-select.js +1 -1
  14. package/dist/components/overlays/kt-dropdown/kt-dropdown.js +1 -1
  15. package/dist/docs/kt-alert.md +52 -0
  16. package/dist/docs/kt-avatar.md +46 -0
  17. package/dist/docs/kt-badge.md +104 -0
  18. package/dist/docs/kt-breadcrumb.md +53 -0
  19. package/dist/docs/kt-button.md +72 -0
  20. package/dist/docs/kt-calendar.md +98 -0
  21. package/dist/docs/kt-card.md +93 -0
  22. package/dist/docs/kt-chart.md +230 -0
  23. package/dist/docs/kt-checkbox.md +65 -0
  24. package/dist/docs/kt-code.md +88 -0
  25. package/dist/docs/kt-collapsible.md +50 -0
  26. package/dist/docs/kt-confirm-dialog.md +52 -0
  27. package/dist/docs/kt-date-input.md +97 -0
  28. package/dist/docs/kt-date-picker.md +116 -0
  29. package/dist/docs/kt-drag-drop.md +85 -0
  30. package/dist/docs/kt-dropdown.md +65 -0
  31. package/dist/docs/kt-empty-state.md +36 -0
  32. package/dist/docs/kt-form.md +93 -0
  33. package/dist/docs/kt-header.md +100 -0
  34. package/dist/docs/kt-icon.md +68 -0
  35. package/dist/docs/kt-input-menu.md +90 -0
  36. package/dist/docs/kt-input.md +137 -0
  37. package/dist/docs/kt-kbd.md +44 -0
  38. package/dist/docs/kt-label-input.md +54 -0
  39. package/dist/docs/kt-meter.md +79 -0
  40. package/dist/docs/kt-modal.md +62 -0
  41. package/dist/docs/kt-multi-select.md +115 -0
  42. package/dist/docs/kt-page-header.md +53 -0
  43. package/dist/docs/kt-pagination.md +36 -0
  44. package/dist/docs/kt-progress-bar.md +66 -0
  45. package/dist/docs/kt-radio-group.md +73 -0
  46. package/dist/docs/kt-segmented-control.md +70 -0
  47. package/dist/docs/kt-select.md +80 -0
  48. package/dist/docs/kt-side-panel.md +59 -0
  49. package/dist/docs/kt-skeleton.md +46 -0
  50. package/dist/docs/kt-split-button.md +105 -0
  51. package/dist/docs/kt-stat.md +57 -0
  52. package/dist/docs/kt-sub-menu-navigation.md +118 -0
  53. package/dist/docs/kt-table.md +179 -0
  54. package/dist/docs/kt-tabs.md +87 -0
  55. package/dist/docs/kt-textarea.md +59 -0
  56. package/dist/docs/kt-time-input.md +88 -0
  57. package/dist/docs/kt-timeline.md +63 -0
  58. package/dist/docs/kt-toast-container.md +69 -0
  59. package/dist/docs/kt-toast.md +41 -0
  60. package/dist/docs/kt-toggle-button-group.md +67 -0
  61. package/dist/docs/kt-toggle-button.md +52 -0
  62. package/dist/docs/kt-toggle.md +47 -0
  63. package/dist/docs/kt-tooltip.md +68 -0
  64. package/dist/icons/defaults.d.ts +9 -0
  65. package/dist/icons/index.js +1 -1
  66. package/dist/index.js +1 -1
  67. package/dist/internal/floating.d.ts +4 -0
  68. package/dist/tokens/colors.css +5 -2
  69. package/dist/web-types.json +1 -1
  70. package/package.json +29 -6
  71. package/dist/chunks/defaults-CFrjqae2.js +0 -59
  72. package/dist/chunks/defaults-CFrjqae2.js.map +0 -1
  73. package/dist/chunks/floating-B33g-M_1.js.map +0 -1
@@ -0,0 +1,52 @@
1
+ # `<kt-toggle-button>`
2
+
3
+ A button that stays pressed.
4
+
5
+ ```html
6
+ <kt-toggle-button icon="bold" label="Bold"></kt-toggle-button>
7
+ <kt-toggle-button variant="outline" value="draft">Draft</kt-toggle-button>
8
+ ```
9
+
10
+ `aria-pressed`, not `aria-checked`: this is a control holding a state, not one
11
+ option among several. When they _are_ options among several and only one may be
12
+ active, reach for [`<kt-segmented-control>`](./kt-segmented-control.md)
13
+ or [`<kt-tabs>`](./kt-tabs.md) — they carry the right semantics and the
14
+ right keyboard model.
15
+
16
+ To draw several as one bar, wrap them in
17
+ [`<kt-toggle-button-group>`](./kt-toggle-button-group.md).
18
+ Inside a group the button becomes controlled: it stops flipping itself and stops
19
+ emitting, and the group drives it.
20
+
21
+ ## Variants
22
+
23
+ | Variant | Resting |
24
+ | ----------- | ------------------------------------------ |
25
+ | `primary` | Raised surface; solid indigo when pressed |
26
+ | `secondary` | Flat; soft indigo tint when pressed |
27
+ | `outline` | Bordered, transparent; tinted when pressed |
28
+
29
+ ## API
30
+
31
+ | Property | Attribute | Type | Default |
32
+ | -------------- | --------------- | --------------------------------------- | ----------- |
33
+ | `selected` | `selected` | `boolean` | `false` |
34
+ | `disabled` | `disabled` | `boolean` | `false` |
35
+ | `variant` | `variant` | `'primary' \| 'secondary' \| 'outline'` | `'primary'` |
36
+ | `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
37
+ | `value` | `value` | `string` | `''` |
38
+ | `icon` | `icon` | `string` | `''` |
39
+ | `iconPosition` | `icon-position` | `'left' \| 'right'` | `'left'` |
40
+ | `label` | `label` | `string` | `''` |
41
+
42
+ | Event | Detail |
43
+ | ----------- | ------------------------------------------------ |
44
+ | `kt-change` | `{ selected, value }` — not fired inside a group |
45
+
46
+ | Slot | Description |
47
+ | --------- | ---------------- |
48
+ | _default_ | The button label |
49
+
50
+ | Part | Description |
51
+ | -------- | --------------------- |
52
+ | `button` | The native `<button>` |
@@ -0,0 +1,47 @@
1
+ # `<kt-toggle>`
2
+
3
+ An on/off switch.
4
+
5
+ ```html
6
+ <kt-toggle checked>Notifications</kt-toggle>
7
+ <kt-toggle size="small" label="Dark mode"></kt-toggle>
8
+ <kt-toggle disabled></kt-toggle>
9
+ ```
10
+
11
+ ## Sizing
12
+
13
+ The switch is derived from the field height rather than given fixed pixels:
14
+ the track is 1.8× `--switch-height`, and the thumb is inset by 12% of it. So a
15
+ toggle lines up with the inputs and buttons next to it, at every size and every
16
+ breakpoint, and overriding `--button-height` moves all of them together.
17
+
18
+ ## Switch, not checkbox
19
+
20
+ `role="switch"` with `aria-checked`, which screen readers announce as "on"/"off"
21
+ rather than "checked". Use it for a setting that takes effect immediately. For
22
+ something that only applies when a form is submitted, a checkbox is the honest
23
+ control.
24
+
25
+ In a form, an unchecked toggle contributes **nothing** to the submission and a
26
+ checked one contributes its `value` — the same rule as a native checkbox.
27
+
28
+ ## API
29
+
30
+ | Property | Attribute | Type | Default |
31
+ | ---------- | ---------- | -------------------------------- | ---------- |
32
+ | `checked` | `checked` | `boolean` | `false` |
33
+ | `disabled` | `disabled` | `boolean` | `false` |
34
+ | `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
35
+ | `name` | `name` | `string` | `''` |
36
+ | `value` | `value` | `string` | `'on'` |
37
+ | `label` | `label` | `string` | `''` |
38
+
39
+ | Event | Detail |
40
+ | ----------- | ---------------------- |
41
+ | `kt-change` | `{ checked: boolean }` |
42
+
43
+ | Part | Description |
44
+ | ------- | -------------------------- |
45
+ | `base` | The `role="switch"` button |
46
+ | `track` | The track |
47
+ | `thumb` | The sliding thumb |
@@ -0,0 +1,68 @@
1
+ # `<kt-tooltip>`
2
+
3
+ A short label that appears on hover or focus. Wrap what it describes:
4
+
5
+ ```html
6
+ <kt-tooltip text="Refresh the data">
7
+ <kt-button icon="refresh-cw" label="Refresh"></kt-button>
8
+ </kt-tooltip>
9
+ ```
10
+
11
+ ## A tooltip is a description, not a name
12
+
13
+ Note the `label` on the button above. A tooltip supplements a control; it must
14
+ never be the only thing naming it. A tooltip that has to be hovered to be read
15
+ leaves touch users and screen-reader users with an unlabelled button.
16
+
17
+ The rule: if the trigger has no visible text, it needs its own accessible name,
18
+ and the tooltip adds detail on top.
19
+
20
+ ## How the description reaches the trigger
21
+
22
+ `aria-describedby` cannot cross a shadow boundary — an id inside this element's
23
+ shadow root is invisible to a trigger sitting in the light DOM.
24
+
25
+ So `<kt-tooltip>` also puts the text in a light-DOM node, addressed to a slot
26
+ that does not exist. That keeps it out of the rendered output while leaving it
27
+ referenceable: an explicit `aria-describedby` target is read even when it is not
28
+ displayed.
29
+
30
+ ## Where the bubble goes
31
+
32
+ The bubble is a popover in the top layer, placed from the trigger in viewport
33
+ coordinates. No ancestor's `overflow: hidden` can clip it, and it takes no room
34
+ in the page.
35
+
36
+ `placement` is a preference. When that side has no room — `top` on an icon at
37
+ the top of the page — the bubble takes the opposite side, and it slides along
38
+ its side to stay inside the screen. Scrolling or resizing hides it, since a
39
+ bubble fixed to the viewport would drift away from its trigger.
40
+
41
+ ## Holding it open
42
+
43
+ `open` shows the bubble whatever the pointer does. It is for a trigger that
44
+ cannot take focus itself: `<kt-input>` holds its error icon's tooltip open while
45
+ the field has focus, so a keyboard user sees the message a mouse user gets on
46
+ hover.
47
+
48
+ ## Dismissal
49
+
50
+ Escape hides the tooltip while the trigger keeps focus, as WCAG 1.4.13 requires
51
+ of any content shown on hover or focus.
52
+
53
+ ## API
54
+
55
+ | Property | Attribute | Type | Default |
56
+ | ----------- | ----------- | ---------------------------------------- | ------- |
57
+ | `text` | `text` | `string` | `''` |
58
+ | `placement` | `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` |
59
+ | `disabled` | `disabled` | `boolean` | `false` |
60
+ | `open` | `open` | `boolean` | `false` |
61
+
62
+ | Slot | Description |
63
+ | --------- | ----------- |
64
+ | _default_ | The trigger |
65
+
66
+ | Part | Description |
67
+ | -------- | ------------------ |
68
+ | `bubble` | The tooltip bubble |
@@ -11,17 +11,26 @@ export declare const defaultIcons: {
11
11
  CircleAlert: import("lucide").IconNode;
12
12
  CircleCheck: import("lucide").IconNode;
13
13
  Copy: import("lucide").IconNode;
14
+ Download: import("lucide").IconNode;
15
+ Ellipsis: import("lucide").IconNode;
16
+ ExternalLink: import("lucide").IconNode;
14
17
  Eye: import("lucide").IconNode;
15
18
  EyeOff: import("lucide").IconNode;
16
19
  File: import("lucide").IconNode;
17
20
  FileUp: import("lucide").IconNode;
21
+ Filter: import("lucide").IconNode;
18
22
  Info: import("lucide").IconNode;
19
23
  LoaderCircle: import("lucide").IconNode;
20
24
  Menu: import("lucide").IconNode;
21
25
  Minus: import("lucide").IconNode;
26
+ Pencil: import("lucide").IconNode;
27
+ Plus: import("lucide").IconNode;
28
+ RefreshCw: import("lucide").IconNode;
22
29
  Search: import("lucide").IconNode;
30
+ Settings: import("lucide").IconNode;
23
31
  Trash2: import("lucide").IconNode;
24
32
  TriangleAlert: import("lucide").IconNode;
33
+ Upload: import("lucide").IconNode;
25
34
  User: import("lucide").IconNode;
26
35
  X: import("lucide").IconNode;
27
36
  };
@@ -1,4 +1,4 @@
1
- import { d as a, g as r, r as o, a as t, b as c, t as g } from "../chunks/defaults-CFrjqae2.js";
1
+ import { d as a, g as r, r as o, a as t, b as c, t as g } from "../chunks/defaults-Cpeg13O5.js";
2
2
  export {
3
3
  a as defaultIcons,
4
4
  r as getIcon,
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ import { KtPagination as He } from "./components/data/kt-pagination/kt-paginatio
48
48
  import { KtStat as je } from "./components/data/kt-stat/kt-stat.js";
49
49
  import { KtTable as ze } from "./components/data/kt-table/kt-table.js";
50
50
  import { KtTimeline as Xe, KtTimelineItem as We } from "./components/data/kt-timeline/kt-timeline.js";
51
- import { g as Ze, r as qe, a as Je, b as Qe } from "./chunks/defaults-CFrjqae2.js";
51
+ import { g as Ze, r as qe, a as Je, b as Qe } from "./chunks/defaults-Cpeg13O5.js";
52
52
  import { d as eo, s as oo, r as ro, a as no } from "./chunks/index-TWJzttLX.js";
53
53
  import { K as so, d as co } from "./chunks/kt-element-T0VbIBNp.js";
54
54
  const C = (t) => {
@@ -29,6 +29,10 @@ export interface FloatingOptions {
29
29
  * animatable state its element gives it, so it can fade out after it leaves
30
30
  * the top layer: `display` here only undoes the popover's `display: none`, and
31
31
  * a panel's own `display` still wins.
32
+ *
33
+ * Until it is first placed it sits top left. With auto insets a closed panel
34
+ * sat where the flow put it — beside a right-hand trigger, past the edge of
35
+ * the page, which then scrolled sideways.
32
36
  */
33
37
  export declare const floatingStyles: import("lit").CSSResult;
34
38
  export declare class FloatingController implements ReactiveController {
@@ -56,9 +56,12 @@
56
56
  --color-success-soft: rgba(53, 221, 131, 0.12);
57
57
 
58
58
  /* === TEXT STEPS OF THE BRAND AND SEMANTIC COLOURS === */
59
+ /* Info and danger are a shade lighter than the rest need: an alert's action
60
+ button lays its tint on the alert's, and on a card that double tint is the
61
+ lightest ground these text steps meet. */
59
62
  --color-primary-text: var(--accent-text-dark, #8e97ff);
60
- --color-danger-text: #ff727f;
61
- --color-info-text: #06b0fc;
63
+ --color-danger-text: #ff7984;
64
+ --color-info-text: #43bbff;
62
65
  --color-warning-text: #fca80d;
63
66
  --color-success-text: #01df7e;
64
67
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
3
3
  "name": "kanto-ds",
4
- "version": "1.6.0",
4
+ "version": "1.7.0",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
package/package.json CHANGED
@@ -1,14 +1,29 @@
1
1
  {
2
2
  "name": "kanto-ds",
3
- "version": "1.6.0",
4
- "description": "Framework-agnostic design system for data-dense product interfaces.",
3
+ "version": "1.7.0",
4
+ "description": "Forty-nine accessible web components for dashboards, admin tools and forms — themeable in one line, in React, Vue, Angular, Svelte or plain HTML.",
5
5
  "keywords": [
6
6
  "design-system",
7
7
  "web-components",
8
8
  "custom-elements",
9
9
  "lit",
10
10
  "ui",
11
- "dark-theme"
11
+ "ui-kit",
12
+ "components",
13
+ "dashboard",
14
+ "admin",
15
+ "forms",
16
+ "data-table",
17
+ "date-picker",
18
+ "react",
19
+ "vue",
20
+ "angular",
21
+ "svelte",
22
+ "accessible",
23
+ "a11y",
24
+ "theming",
25
+ "dark-theme",
26
+ "dark-mode"
12
27
  ],
13
28
  "homepage": "https://kanto.arnaudmichel.fr",
14
29
  "bugs": {
@@ -23,6 +38,10 @@
23
38
  "type": "module",
24
39
  "sideEffects": [
25
40
  "*.css",
41
+ "./dist/index.js",
42
+ "./dist/vue/index.js",
43
+ "./src/index.ts",
44
+ "./src/vue/index.ts",
26
45
  "./dist/components/**",
27
46
  "./dist/icons/defaults.js",
28
47
  "./src/components/**",
@@ -33,6 +52,8 @@
33
52
  },
34
53
  "main": "./dist/index.js",
35
54
  "module": "./dist/index.js",
55
+ "unpkg": "./dist/cdn/kanto.min.js",
56
+ "jsdelivr": "./dist/cdn/kanto.min.js",
36
57
  "types": "./dist/index.d.ts",
37
58
  "customElements": "./dist/custom-elements.json",
38
59
  "web-types": "./dist/web-types.json",
@@ -282,10 +303,11 @@
282
303
  ],
283
304
  "scripts": {
284
305
  "dev": "vite --config demo/vite.config.ts",
285
- "build": "npm run build:js && npm run build:types && npm run build:static && npm run build:manifest",
306
+ "build": "npm run build:js && npm run build:cdn && npm run build:types && npm run build:static && npm run build:manifest",
307
+ "build:cdn": "node scripts/build-cdn.js",
286
308
  "build:js": "vite build",
287
309
  "build:types": "tsc -p tsconfig.build.json",
288
- "build:static": "node scripts/copy-static.js",
310
+ "build:static": "node scripts/copy-static.js && node scripts/llms.js --docs",
289
311
  "build:manifest": "cem analyze --config custom-elements-manifest.config.js",
290
312
  "build:demo": "vite build --config demo/vite.config.ts",
291
313
  "test": "vitest run",
@@ -298,8 +320,9 @@
298
320
  "format:check": "prettier --check .",
299
321
  "clean": "node -e \"fs.rmSync(dist,{recursive:true,force:true})\"",
300
322
  "check:exports": "node scripts/check-exports.js",
323
+ "check:consumer": "node scripts/check-consumer.js",
301
324
  "check:size": "node scripts/check-size.js",
302
- "verify": "npm run format:check && npm run lint && npm run typecheck && npm run test && npm run build && npm run check:exports && npm run check:size && npm run build:demo",
325
+ "verify": "npm run format:check && npm run lint && npm run typecheck && npm run test && npm run build && npm run check:exports && npm run check:consumer && npm run check:size && npm run build:demo",
303
326
  "release": "node scripts/release.js",
304
327
  "release:dry": "node scripts/release.js --dry-run",
305
328
  "prepublishOnly": "npm run verify"
@@ -1,59 +0,0 @@
1
- import { X as s, User as a, TriangleAlert as c, Trash2 as i, Search as f, Minus as g, Menu as p, LoaderCircle as u, Info as C, FileUp as l, File as y, EyeOff as A, Eye as I, Copy as h, CircleCheck as w, CircleAlert as $, ChevronUp as b, ChevronRight as d, ChevronLeft as v, ChevronDown as U, Check as Z, Calendar as k, ArrowUp as m, ArrowDown as z } from "lucide";
2
- const n = /* @__PURE__ */ new Map();
3
- function t(e) {
4
- return e.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-zA-Z])(\d)/g, "$1-$2").replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
5
- }
6
- function L(e, r) {
7
- n.set(t(e), r);
8
- }
9
- function M(e) {
10
- for (const [r, o] of Object.entries(e))
11
- j(o) && L(r, o);
12
- }
13
- function F(e) {
14
- return n.get(t(e));
15
- }
16
- function O() {
17
- return [...n.keys()].sort();
18
- }
19
- function j(e) {
20
- return Array.isArray(e) && e.every(
21
- (r) => Array.isArray(r) && typeof r[0] == "string" && typeof r[1] == "object" && r[1] !== null
22
- );
23
- }
24
- const D = {
25
- ArrowDown: z,
26
- ArrowUp: m,
27
- Calendar: k,
28
- Check: Z,
29
- ChevronDown: U,
30
- ChevronLeft: v,
31
- ChevronRight: d,
32
- ChevronUp: b,
33
- CircleAlert: $,
34
- CircleCheck: w,
35
- Copy: h,
36
- Eye: I,
37
- EyeOff: A,
38
- File: y,
39
- FileUp: l,
40
- Info: C,
41
- LoaderCircle: u,
42
- Menu: p,
43
- Minus: g,
44
- Search: f,
45
- Trash2: i,
46
- TriangleAlert: c,
47
- User: a,
48
- X: s
49
- };
50
- M(D);
51
- export {
52
- M as a,
53
- O as b,
54
- D as d,
55
- F as g,
56
- L as r,
57
- t
58
- };
59
- //# sourceMappingURL=defaults-CFrjqae2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults-CFrjqae2.js","sources":["../../src/icons/registry.ts","../../src/icons/defaults.ts"],"sourcesContent":["/**\n * The icon registry.\n *\n * `<kt-icon>` looks icons up by name at render time, which means the set of\n * icons cannot be statically analysed and a bundler cannot tree-shake it. So\n * Kanto does not bundle all two thousand Lucide icons: the elements register\n * the handful they need themselves, and an application registers whatever else\n * it uses.\n *\n * import { Rocket, Wallet } from 'lucide';\n * import { registerIcons } from 'kanto-ds/icons';\n *\n * registerIcons({ Rocket, Wallet });\n *\n * Names are normalised to kebab-case, so `Rocket`, `rocket` and\n * `ChevronDown` / `chevron-down` all resolve.\n */\n\n/** A Lucide icon: a flat list of SVG children, each `[tag, attributes]`. */\nexport type IconNode = [tag: string, attrs: Record<string, string | number | undefined>][];\n\nconst registry = new Map<string, IconNode>();\n\n/**\n * `ChevronDown` → `chevron-down`, `Trash2` → `trash-2`, `AArrowDown` →\n * `a-arrow-down`.\n *\n * The digit boundary matters: Lucide names that icon `trash-2`, so a rule that\n * only splits on case produces `trash2` and the lookup quietly misses.\n */\nexport function toKebabCase(name: string): string {\n return name\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2') // acronym run before a word\n .replace(/([a-zA-Z])(\\d)/g, '$1-$2') // letter before a digit\n .replace(/([a-z])([A-Z])/g, '$1-$2') // ordinary camel boundary\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/** Registers a single icon under `name`. */\nexport function registerIcon(name: string, node: IconNode): void {\n registry.set(toKebabCase(name), node);\n}\n\n/**\n * Registers a map of icons. Accepts a Lucide namespace import directly:\n * every non-icon export (`createElement`, `createIcons`, …) is skipped.\n */\nexport function registerIcons(icons: Record<string, unknown>): void {\n for (const [name, node] of Object.entries(icons)) {\n if (isIconNode(node)) registerIcon(name, node);\n }\n}\n\n/** Returns the icon registered under `name`, or `undefined`. */\nexport function getIcon(name: string): IconNode | undefined {\n return registry.get(toKebabCase(name));\n}\n\n/** Every registered name, kebab-cased and sorted. Useful for docs and tests. */\nexport function registeredIcons(): string[] {\n return [...registry.keys()].sort();\n}\n\nfunction isIconNode(value: unknown): value is IconNode {\n return (\n Array.isArray(value) &&\n value.every(\n (child) =>\n Array.isArray(child) &&\n typeof child[0] === 'string' &&\n typeof child[1] === 'object' &&\n child[1] !== null,\n )\n );\n}\n","/**\n * The icons the design system uses in its own elements.\n *\n * Importing any Kanto element pulls this set in — roughly 2 kB of path data,\n * the price of `<kt-select>` being able to draw its own chevron. Application\n * icons are registered separately through `registerIcons`.\n */\nimport {\n ArrowDown,\n ArrowUp,\n Calendar,\n Check,\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n ChevronUp,\n CircleAlert,\n CircleCheck,\n Copy,\n Eye,\n EyeOff,\n File,\n FileUp,\n Info,\n LoaderCircle,\n Menu,\n Minus,\n Search,\n Trash2,\n TriangleAlert,\n User,\n X,\n} from 'lucide';\n// The sibling registry, not the `kanto-ds` barrel: the barrel pulls in every\n// element, and one of them pulls in this file — a cycle that leaves\n// `registerIcons` undefined by the time the call below runs.\nimport { registerIcons } from './registry.js';\n\n/** Icons referenced by Kanto elements, keyed by their Lucide name. */\nexport const defaultIcons = {\n ArrowDown,\n ArrowUp,\n Calendar,\n Check,\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n ChevronUp,\n CircleAlert,\n CircleCheck,\n Copy,\n Eye,\n EyeOff,\n File,\n FileUp,\n Info,\n LoaderCircle,\n Menu,\n Minus,\n Search,\n Trash2,\n TriangleAlert,\n User,\n X,\n};\n\nregisterIcons(defaultIcons);\n"],"names":["registry","toKebabCase","name","registerIcon","node","registerIcons","icons","isIconNode","getIcon","registeredIcons","value","child","defaultIcons","ArrowDown","ArrowUp","Calendar","Check","ChevronDown","ChevronLeft","ChevronRight","ChevronUp","CircleAlert","CircleCheck","Copy","Eye","EyeOff","File","FileUp","Info","LoaderCircle","Menu","Minus","Search","Trash2","TriangleAlert","User","X"],"mappings":";AAqBA,MAAMA,wBAAe,IAAA;AASd,SAASC,EAAYC,GAAsB;AAChD,SAAOA,EACJ,QAAQ,yBAAyB,OAAO,EACxC,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,WAAW,GAAG,EACtB,YAAA;AACL;AAGO,SAASC,EAAaD,GAAcE,GAAsB;AAC/D,EAAAJ,EAAS,IAAIC,EAAYC,CAAI,GAAGE,CAAI;AACtC;AAMO,SAASC,EAAcC,GAAsC;AAClE,aAAW,CAACJ,GAAME,CAAI,KAAK,OAAO,QAAQE,CAAK;AAC7C,IAAIC,EAAWH,CAAI,KAAGD,EAAaD,GAAME,CAAI;AAEjD;AAGO,SAASI,EAAQN,GAAoC;AAC1D,SAAOF,EAAS,IAAIC,EAAYC,CAAI,CAAC;AACvC;AAGO,SAASO,IAA4B;AAC1C,SAAO,CAAC,GAAGT,EAAS,KAAA,CAAM,EAAE,KAAA;AAC9B;AAEA,SAASO,EAAWG,GAAmC;AACrD,SACE,MAAM,QAAQA,CAAK,KACnBA,EAAM;AAAA,IACJ,CAACC,MACC,MAAM,QAAQA,CAAK,KACnB,OAAOA,EAAM,CAAC,KAAM,YACpB,OAAOA,EAAM,CAAC,KAAM,YACpBA,EAAM,CAAC,MAAM;AAAA,EAAA;AAGrB;ACpCO,MAAMC,IAAe;AAAA,EAC1B,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,KAAAC;AAAA,EACA,QAAAC;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,MAAAC;AAAA,EACA,cAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,eAAAC;AAAA,EACA,MAAAC;AAAA,EACA,GAAAC;AACF;AAEA/B,EAAcO,CAAY;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"floating-B33g-M_1.js","sources":["../../src/internal/floating.ts"],"sourcesContent":["import { css, type ReactiveController, type ReactiveControllerHost } from 'lit';\nimport { placeFloating, type Align, type Side } from './position.js';\n\n/**\n * A panel that opens from a trigger — a select's list, a date picker's\n * calendar, a menu — drawn in the top layer and placed from the trigger.\n *\n * A panel positioned inside its element was cut off by any ancestor with\n * `overflow: hidden`: a table cell, a side panel, an app's scrolling main\n * area. In the top layer, nothing clips it. It opens on the side asked for, or\n * the other one when that has no room, and follows the trigger as the page\n * scrolls.\n */\n\nexport interface FloatingOptions {\n /** The panel, which carries `popover=\"manual\"` and the `floating` class. */\n readonly panel: () => HTMLElement | null | undefined;\n /** What the panel opens from. */\n readonly anchor: () => Element | null | undefined;\n /** The side it prefers. */\n readonly side?: () => Side;\n /** Which edge of the anchor it lines up with; its start by default. */\n readonly align?: () => Align;\n /** Sizes the panel to the anchor's width — a list under its field. */\n readonly matchWidth?: boolean;\n /** Told the side it opened on, for the direction of its entrance. */\n readonly onPlace?: (side: Side) => void;\n}\n\n/**\n * The panel's own styles. Closed, it keeps the display and the hidden,\n * animatable state its element gives it, so it can fade out after it leaves\n * the top layer: `display` here only undoes the popover's `display: none`, and\n * a panel's own `display` still wins.\n */\nexport const floatingStyles = css`\n .floating {\n position: fixed;\n inset: auto;\n display: block;\n /* As wide as what it holds, wherever it is placed: a box sized from its\n position would change size when moved, and be moved again. */\n width: max-content;\n margin: 0;\n color: inherit;\n /* Set apart from the page by the theme: a lighter surface in the dark,\n an edge and a soft shadow in the light. */\n border: var(--border-width) solid var(--border-popover);\n box-shadow: var(--shadow-popover);\n }\n`;\n\nexport class FloatingController implements ReactiveController {\n private open = false;\n private frame = 0;\n /** Places the panel again when its size changes — content drawn after it opened. */\n private resizeObserver: ResizeObserver | undefined;\n\n constructor(\n host: ReactiveControllerHost,\n private readonly options: FloatingOptions,\n ) {\n host.addController(this);\n }\n\n /**\n * Call from the host's `updated()` with whether the panel is open. While it\n * is, every update re-places it: its content — a filtered list — can change\n * its size.\n */\n sync(open: boolean): void {\n // First, and whatever the panel: one rendered only while open is already\n // gone when it closes, and its listeners must go with it.\n if (open !== this.open) {\n this.open = open;\n const method = open ? 'addEventListener' : 'removeEventListener';\n window[method]('scroll', this.follow, { capture: true, passive: true });\n window[method]('resize', this.follow);\n }\n\n const panel = this.options.panel();\n // Where popovers are missing — a test DOM — the panel stays where it is.\n if (!panel || typeof panel.showPopover !== 'function') return;\n\n if (open) {\n if (!panel.matches(':popover-open')) panel.showPopover();\n this.place();\n // A panel measured at opening may grow once what it holds has drawn —\n // a calendar is an element of its own — and must be placed again.\n if (!this.resizeObserver && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(this.follow);\n this.resizeObserver.observe(panel);\n }\n } else {\n this.unobserve();\n if (panel.matches(':popover-open')) panel.hidePopover();\n }\n }\n\n private unobserve(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n\n hostDisconnected(): void {\n this.sync(false);\n this.unobserve();\n cancelAnimationFrame(this.frame);\n }\n\n private follow = (): void => {\n cancelAnimationFrame(this.frame);\n this.frame = requestAnimationFrame(() => this.place());\n };\n\n private place(): void {\n const panel = this.options.panel();\n const anchor = this.options.anchor()?.getBoundingClientRect();\n if (!panel || !anchor) return;\n\n if (this.options.matchWidth) panel.style.width = `${anchor.width}px`;\n // Untransformed size: the entrance animation scales and slides the panel.\n const { x, y, placement } = placeFloating(\n anchor,\n { width: panel.offsetWidth, height: panel.offsetHeight },\n { width: window.innerWidth, height: window.innerHeight },\n this.options.side?.() ?? 'bottom',\n this.options.align?.() ?? 'start',\n );\n panel.style.left = `${x}px`;\n panel.style.top = `${y}px`;\n this.options.onPlace?.(placement);\n }\n}\n"],"names":["floatingStyles","css","FloatingController","host","options","open","method","panel","anchor","x","y","placement","placeFloating"],"mappings":";;AAmCO,MAAMA,IAAiBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBvB,MAAMC,EAAiD;AAAA,EAM5D,YACEC,GACiBC,GACjB;AADiB,SAAA,UAAAA,GAPnB,KAAQ,OAAO,IACf,KAAQ,QAAQ,GAwDhB,KAAQ,SAAS,MAAY;AAC3B,2BAAqB,KAAK,KAAK,GAC/B,KAAK,QAAQ,sBAAsB,MAAM,KAAK,OAAO;AAAA,IACvD,GAnDED,EAAK,cAAc,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAKE,GAAqB;AAGxB,QAAIA,MAAS,KAAK,MAAM;AACtB,WAAK,OAAOA;AACZ,YAAMC,IAASD,IAAO,qBAAqB;AAC3C,aAAOC,CAAM,EAAE,UAAU,KAAK,QAAQ,EAAE,SAAS,IAAM,SAAS,IAAM,GACtE,OAAOA,CAAM,EAAE,UAAU,KAAK,MAAM;AAAA,IACtC;AAEA,UAAMC,IAAQ,KAAK,QAAQ,MAAA;AAE3B,IAAI,CAACA,KAAS,OAAOA,EAAM,eAAgB,eAEvCF,KACGE,EAAM,QAAQ,eAAe,OAAS,YAAA,GAC3C,KAAK,MAAA,GAGD,CAAC,KAAK,kBAAkB,OAAO,iBAAmB,QACpD,KAAK,iBAAiB,IAAI,eAAe,KAAK,MAAM,GACpD,KAAK,eAAe,QAAQA,CAAK,OAGnC,KAAK,UAAA,GACDA,EAAM,QAAQ,eAAe,OAAS,YAAA;AAAA,EAE9C;AAAA,EAEQ,YAAkB;AACxB,SAAK,gBAAgB,WAAA,GACrB,KAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,mBAAyB;AACvB,SAAK,KAAK,EAAK,GACf,KAAK,UAAA,GACL,qBAAqB,KAAK,KAAK;AAAA,EACjC;AAAA,EAOQ,QAAc;AACpB,UAAMA,IAAQ,KAAK,QAAQ,MAAA,GACrBC,IAAS,KAAK,QAAQ,OAAA,GAAU,sBAAA;AACtC,QAAI,CAACD,KAAS,CAACC,EAAQ;AAEvB,IAAI,KAAK,QAAQ,eAAYD,EAAM,MAAM,QAAQ,GAAGC,EAAO,KAAK;AAEhE,UAAM,EAAE,GAAAC,GAAG,GAAAC,GAAG,WAAAC,EAAA,IAAcC;AAAA,MAC1BJ;AAAA,MACA,EAAE,OAAOD,EAAM,aAAa,QAAQA,EAAM,aAAA;AAAA,MAC1C,EAAE,OAAO,OAAO,YAAY,QAAQ,OAAO,YAAA;AAAA,MAC3C,KAAK,QAAQ,OAAA,KAAY;AAAA,MACzB,KAAK,QAAQ,aAAa;AAAA,IAAA;AAE5B,IAAAA,EAAM,MAAM,OAAO,GAAGE,CAAC,MACvBF,EAAM,MAAM,MAAM,GAAGG,CAAC,MACtB,KAAK,QAAQ,UAAUC,CAAS;AAAA,EAClC;AACF;"}