kanto-ds 1.4.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/chunks/{defaults-BwgjMcww.js → defaults-CFrjqae2.js} +22 -21
- package/dist/chunks/{defaults-BwgjMcww.js.map → defaults-CFrjqae2.js.map} +1 -1
- package/dist/chunks/events-r51msXNf.js +22 -0
- package/dist/chunks/{events-Bjl5Zmmq.js.map → events-r51msXNf.js.map} +1 -1
- package/dist/chunks/floating-B7_Dahpn.js +54 -0
- package/dist/chunks/floating-B7_Dahpn.js.map +1 -0
- package/dist/chunks/{form-control-CxjBTt1c.js → form-control-B74_EHtG.js} +7 -7
- package/dist/chunks/form-control-B74_EHtG.js.map +1 -0
- package/dist/chunks/{index-DSSLJirw.js → index-STEEvEP7.js} +24 -12
- package/dist/chunks/index-STEEvEP7.js.map +1 -0
- package/dist/chunks/kt-calendar-B_hFdD9V.js +640 -0
- package/dist/chunks/kt-calendar-B_hFdD9V.js.map +1 -0
- package/dist/chunks/{kt-element-E-tfJpGQ.js → kt-element-Djx2JcGl.js} +2 -2
- package/dist/chunks/{kt-element-E-tfJpGQ.js.map → kt-element-Djx2JcGl.js.map} +1 -1
- package/dist/chunks/{listbox-Sm3nvsC6.js → listbox-llcUu_V-.js} +18 -14
- package/dist/chunks/{listbox-Sm3nvsC6.js.map → listbox-llcUu_V-.js.map} +1 -1
- package/dist/chunks/locale-C5xLkGx5.js +14 -0
- package/dist/chunks/locale-C5xLkGx5.js.map +1 -0
- package/dist/chunks/position-Cx_ZH5zh.js +39 -0
- package/dist/chunks/position-Cx_ZH5zh.js.map +1 -0
- package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
- package/dist/components/core/kt-badge/kt-badge.js +3 -3
- package/dist/components/core/kt-button/kt-button.js +1 -1
- package/dist/components/core/kt-card/kt-card.js +2 -2
- package/dist/components/core/kt-code/kt-code.js +3 -3
- package/dist/components/core/kt-icon/kt-icon.js +2 -2
- package/dist/components/core/kt-kbd/kt-kbd.js +1 -1
- package/dist/components/core/kt-split-button/kt-split-button.js +4 -4
- package/dist/components/data/kt-chart/kt-chart.js +3 -3
- package/dist/components/data/kt-meter/kt-meter.js +1 -1
- package/dist/components/data/kt-pagination/kt-pagination.js +3 -3
- package/dist/components/data/kt-stat/kt-stat.js +1 -1
- package/dist/components/data/kt-table/kt-table.d.ts +53 -3
- package/dist/components/data/kt-table/kt-table.js +286 -131
- package/dist/components/data/kt-table/kt-table.js.map +1 -1
- package/dist/components/data/kt-table/window.d.ts +19 -0
- package/dist/components/data/kt-timeline/kt-timeline.js +1 -1
- package/dist/components/feedback/kt-alert/kt-alert.js +3 -3
- package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +10 -10
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js.map +1 -1
- package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
- package/dist/components/feedback/kt-toast/kt-toast.js +58 -42
- package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -1
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js +1 -1
- package/dist/components/feedback/kt-tooltip/kt-tooltip.d.ts +20 -0
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js +95 -51
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js.map +1 -1
- package/dist/components/forms/kt-calendar/kt-calendar.d.ts +96 -0
- package/dist/components/forms/kt-calendar/kt-calendar.js +13 -0
- package/dist/components/forms/kt-calendar/kt-calendar.js.map +1 -0
- package/dist/components/forms/kt-checkbox/kt-checkbox.d.ts +9 -0
- package/dist/components/forms/kt-checkbox/kt-checkbox.js +34 -20
- package/dist/components/forms/kt-checkbox/kt-checkbox.js.map +1 -1
- package/dist/components/forms/kt-date-picker/kt-date-picker.d.ts +105 -0
- package/dist/components/forms/kt-date-picker/kt-date-picker.js +382 -0
- package/dist/components/forms/kt-date-picker/kt-date-picker.js.map +1 -0
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.d.ts +9 -0
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +36 -22
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -1
- package/dist/components/forms/kt-form/kt-form.js +2 -2
- package/dist/components/forms/kt-input/kt-input.d.ts +37 -1
- package/dist/components/forms/kt-input/kt-input.js +380 -194
- package/dist/components/forms/kt-input/kt-input.js.map +1 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.d.ts +13 -0
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +73 -42
- package/dist/components/forms/kt-input-menu/kt-input-menu.js.map +1 -1
- package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
- package/dist/components/forms/kt-radio-group/kt-radio-group.d.ts +9 -0
- package/dist/components/forms/kt-radio-group/kt-radio-group.js +67 -53
- package/dist/components/forms/kt-radio-group/kt-radio-group.js.map +1 -1
- package/dist/components/forms/kt-select/kt-select.d.ts +13 -0
- package/dist/components/forms/kt-select/kt-select.js +87 -56
- package/dist/components/forms/kt-select/kt-select.js.map +1 -1
- package/dist/components/forms/kt-textarea/kt-textarea.d.ts +9 -0
- package/dist/components/forms/kt-textarea/kt-textarea.js +28 -14
- package/dist/components/forms/kt-textarea/kt-textarea.js.map +1 -1
- package/dist/components/forms/kt-toggle/kt-toggle.d.ts +9 -0
- package/dist/components/forms/kt-toggle/kt-toggle.js +43 -29
- package/dist/components/forms/kt-toggle/kt-toggle.js.map +1 -1
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +3 -3
- package/dist/components/navigation/kt-header/kt-header.js +3 -3
- package/dist/components/navigation/kt-page-header/kt-page-header.js +1 -1
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +9 -0
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +40 -22
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +3 -3
- package/dist/components/navigation/kt-tabs/kt-tabs.js +2 -2
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +2 -2
- package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +3 -3
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js +2 -2
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +3 -3
- package/dist/components/overlays/kt-dropdown/kt-dropdown.d.ts +7 -5
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +67 -57
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
- package/dist/components/overlays/kt-modal/kt-modal.js +3 -3
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js +3 -3
- package/dist/custom-elements.json +2110 -124
- package/dist/icons/defaults.d.ts +1 -0
- package/dist/icons/index.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +91 -87
- package/dist/index.js.map +1 -1
- package/dist/internal/countries.d.ts +24 -9
- package/dist/internal/date.d.ts +53 -0
- package/dist/internal/events.d.ts +5 -0
- package/dist/internal/floating.d.ts +48 -0
- package/dist/internal/form-control.d.ts +5 -1
- package/dist/internal/locale.d.ts +15 -0
- package/dist/internal/position.d.ts +27 -0
- package/dist/internal/strings.d.ts +15 -0
- package/dist/react/index.d.ts +12 -0
- package/dist/react/index.js +180 -166
- package/dist/react/index.js.map +1 -1
- package/dist/react/jsx.d.ts +11 -1
- package/dist/strings/index.js +1 -1
- package/dist/tokens/base.css +2 -0
- package/dist/tokens/responsive.css +1 -0
- package/dist/tokens/spacing.css +1 -0
- package/dist/vscode.css-custom-data.json +8 -0
- package/dist/vscode.html-custom-data.json +138 -11
- package/dist/vue/index.d.ts +4 -0
- package/dist/vue/index.js +9 -7
- package/dist/vue/index.js.map +1 -1
- package/dist/web-types.json +292 -14
- package/package.json +10 -1
- package/dist/chunks/events-Bjl5Zmmq.js +0 -18
- package/dist/chunks/form-control-CxjBTt1c.js.map +0 -1
- package/dist/chunks/index-DSSLJirw.js.map +0 -1
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import { css as h, html as
|
|
2
|
-
import { state as
|
|
1
|
+
import { css as h, html as c } from "lit";
|
|
2
|
+
import { state as b, query as u, property as n } from "lit/decorators.js";
|
|
3
3
|
import { classMap as v } from "lit/directives/class-map.js";
|
|
4
|
-
import { K as
|
|
5
|
-
import { u as
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
import { K as l, d as f } from "../../../chunks/kt-element-Djx2JcGl.js";
|
|
5
|
+
import { u as m } from "../../../chunks/events-r51msXNf.js";
|
|
6
|
+
import { p as w } from "../../../chunks/position-Cx_ZH5zh.js";
|
|
7
|
+
var y = Object.defineProperty, o = (r, e, s, d) => {
|
|
8
|
+
for (var t = void 0, a = r.length - 1, p; a >= 0; a--)
|
|
9
|
+
(p = r[a]) && (t = p(e, s, t) || t);
|
|
10
|
+
return t && y(e, s, t), t;
|
|
10
11
|
};
|
|
11
|
-
const
|
|
12
|
-
class i extends
|
|
12
|
+
const g = "kt-tooltip-description";
|
|
13
|
+
class i extends l {
|
|
13
14
|
constructor() {
|
|
14
|
-
super(...arguments), this.descriptionId =
|
|
15
|
+
super(...arguments), this.descriptionId = m("kt-tooltip"), this.visible = !1, this.text = "", this.placement = "top", this.open = !1, this.disabled = !1, this.show = () => {
|
|
15
16
|
!this.disabled && this.text && (this.visible = !0);
|
|
16
17
|
}, this.hide = () => {
|
|
17
18
|
this.visible = !1;
|
|
18
|
-
}, this.onKeyDown = (
|
|
19
|
-
|
|
19
|
+
}, this.onKeyDown = (e) => {
|
|
20
|
+
e.key === "Escape" && this.visible && (e.stopPropagation(), this.visible = !1);
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
static {
|
|
23
24
|
this.styles = [
|
|
24
|
-
|
|
25
|
+
l.styles,
|
|
25
26
|
h`
|
|
26
27
|
:host {
|
|
27
28
|
position: relative;
|
|
@@ -30,47 +31,54 @@ class i extends d {
|
|
|
30
31
|
justify-content: center;
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
/* A popover in the top layer, placed in viewport coordinates from
|
|
35
|
+
the trigger: no ancestor's overflow can clip it, and it takes no
|
|
36
|
+
room in the page — a bubble by the right edge used to widen the
|
|
37
|
+
document. */
|
|
33
38
|
.bubble {
|
|
34
|
-
position:
|
|
39
|
+
position: fixed;
|
|
40
|
+
inset: auto;
|
|
35
41
|
z-index: var(--z-tooltip);
|
|
36
42
|
max-width: 260px;
|
|
43
|
+
margin: 0;
|
|
37
44
|
padding: var(--padding-chip);
|
|
45
|
+
overflow: visible;
|
|
38
46
|
/* Inverted against the page, so the bubble reads as floating in
|
|
39
47
|
both themes — the raw ramp step this used to name is pure white
|
|
40
48
|
under data-theme="light". */
|
|
41
49
|
color: var(--text-inverted);
|
|
42
50
|
font: var(--font-code-regular);
|
|
43
|
-
|
|
51
|
+
/* As wide as a short label, and wrapped at max-width for a sentence:
|
|
52
|
+
a positioned box beside a small trigger would otherwise shrink to
|
|
53
|
+
one word per line. */
|
|
54
|
+
width: max-content;
|
|
55
|
+
overflow-wrap: anywhere;
|
|
44
56
|
background: var(--surface-inverted);
|
|
57
|
+
border: none;
|
|
45
58
|
border-radius: var(--radius-input);
|
|
59
|
+
display: none;
|
|
46
60
|
opacity: 0;
|
|
47
61
|
pointer-events: none;
|
|
48
|
-
|
|
62
|
+
/* The discrete display and overlay transitions keep the fade-out
|
|
63
|
+
once the popover closes. */
|
|
64
|
+
transition:
|
|
65
|
+
opacity var(--duration-fast) var(--easing-standard),
|
|
66
|
+
display var(--duration-fast) allow-discrete,
|
|
67
|
+
overlay var(--duration-fast) allow-discrete;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.bubble:popover-open {
|
|
71
|
+
display: block;
|
|
49
72
|
}
|
|
50
73
|
|
|
51
74
|
.bubble.visible {
|
|
52
75
|
opacity: 1;
|
|
53
76
|
}
|
|
54
77
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
.bottom {
|
|
61
|
-
top: calc(100% + 6px);
|
|
62
|
-
left: 50%;
|
|
63
|
-
transform: translateX(-50%);
|
|
64
|
-
}
|
|
65
|
-
.left {
|
|
66
|
-
top: 50%;
|
|
67
|
-
right: calc(100% + 6px);
|
|
68
|
-
transform: translateY(-50%);
|
|
69
|
-
}
|
|
70
|
-
.right {
|
|
71
|
-
top: 50%;
|
|
72
|
-
left: calc(100% + 6px);
|
|
73
|
-
transform: translateY(-50%);
|
|
78
|
+
@starting-style {
|
|
79
|
+
.bubble.visible {
|
|
80
|
+
opacity: 0;
|
|
81
|
+
}
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -85,10 +93,39 @@ class i extends d {
|
|
|
85
93
|
super.connectedCallback(), this.addEventListener("pointerenter", this.show), this.addEventListener("pointerleave", this.hide), this.addEventListener("focusin", this.show), this.addEventListener("focusout", this.hide), this.addEventListener("keydown", this.onKeyDown);
|
|
86
94
|
}
|
|
87
95
|
disconnectedCallback() {
|
|
88
|
-
super.disconnectedCallback(), this.removeEventListener("pointerenter", this.show), this.removeEventListener("pointerleave", this.hide), this.removeEventListener("focusin", this.show), this.removeEventListener("focusout", this.hide), this.removeEventListener("keydown", this.onKeyDown), this.description?.remove();
|
|
96
|
+
super.disconnectedCallback(), this.removeEventListener("pointerenter", this.show), this.removeEventListener("pointerleave", this.hide), this.removeEventListener("focusin", this.show), this.removeEventListener("focusout", this.hide), this.removeEventListener("keydown", this.onKeyDown), this.description?.remove(), this.visible = !1, this.closeBubble();
|
|
97
|
+
}
|
|
98
|
+
willUpdate(e) {
|
|
99
|
+
e.has("text") && this.syncDescription();
|
|
89
100
|
}
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
/** Hovered, focused or held open — and something to say. */
|
|
102
|
+
get shown() {
|
|
103
|
+
return (this.visible || this.open) && !this.disabled && !!this.text;
|
|
104
|
+
}
|
|
105
|
+
// Untyped: `visible` is private, so not among the keys PropertyValues<this> knows.
|
|
106
|
+
updated(e) {
|
|
107
|
+
["visible", "open", "text", "disabled"].some((s) => e.has(s)) && (this.shown ? this.openBubble() : this.closeBubble());
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Opens the bubble in the top layer, then places it: it has to be open to be
|
|
111
|
+
* measured. Where popovers are missing — a test DOM — it stays in place.
|
|
112
|
+
*/
|
|
113
|
+
openBubble() {
|
|
114
|
+
const e = this.bubble;
|
|
115
|
+
if (typeof e.showPopover != "function") return;
|
|
116
|
+
e.matches(":popover-open") || e.showPopover();
|
|
117
|
+
const s = this.getBoundingClientRect(), { x: d, y: t } = w(
|
|
118
|
+
s,
|
|
119
|
+
e.getBoundingClientRect(),
|
|
120
|
+
{ width: window.innerWidth, height: window.innerHeight },
|
|
121
|
+
this.placement
|
|
122
|
+
);
|
|
123
|
+
e.style.left = `${d}px`, e.style.top = `${t}px`, window.addEventListener("scroll", this.hide, { capture: !0, passive: !0 }), window.addEventListener("resize", this.hide);
|
|
124
|
+
}
|
|
125
|
+
closeBubble() {
|
|
126
|
+
window.removeEventListener("scroll", this.hide, { capture: !0 }), window.removeEventListener("resize", this.hide);
|
|
127
|
+
const e = this.bubble;
|
|
128
|
+
typeof e?.hidePopover == "function" && e.matches(":popover-open") && e.hidePopover();
|
|
92
129
|
}
|
|
93
130
|
/**
|
|
94
131
|
* `aria-describedby` cannot reach across a shadow boundary: an id inside this
|
|
@@ -104,34 +141,41 @@ class i extends d {
|
|
|
104
141
|
this.description?.remove(), this.description = void 0;
|
|
105
142
|
return;
|
|
106
143
|
}
|
|
107
|
-
this.description || (this.description = document.createElement("span"), this.description.id = this.descriptionId, this.description.slot =
|
|
108
|
-
for (const
|
|
109
|
-
|
|
144
|
+
this.description || (this.description = document.createElement("span"), this.description.id = this.descriptionId, this.description.slot = g, this.append(this.description)), this.description.textContent = this.text;
|
|
145
|
+
for (const e of this.children)
|
|
146
|
+
e !== this.description && e.setAttribute("aria-describedby", this.descriptionId);
|
|
110
147
|
}
|
|
111
148
|
render() {
|
|
112
|
-
return
|
|
149
|
+
return c`<slot @slotchange=${this.syncDescription}></slot>
|
|
113
150
|
<span
|
|
114
151
|
part="bubble"
|
|
115
|
-
|
|
152
|
+
popover="manual"
|
|
153
|
+
class=${v({ bubble: !0, visible: this.shown })}
|
|
116
154
|
role="tooltip"
|
|
117
|
-
aria-hidden=${this.
|
|
155
|
+
aria-hidden=${this.shown ? "false" : "true"}
|
|
118
156
|
>${this.text}</span
|
|
119
157
|
>`;
|
|
120
158
|
}
|
|
121
159
|
}
|
|
122
|
-
|
|
123
|
-
|
|
160
|
+
o([
|
|
161
|
+
b()
|
|
124
162
|
], i.prototype, "visible");
|
|
125
|
-
|
|
163
|
+
o([
|
|
164
|
+
u(".bubble")
|
|
165
|
+
], i.prototype, "bubble");
|
|
166
|
+
o([
|
|
126
167
|
n({ type: String })
|
|
127
168
|
], i.prototype, "text");
|
|
128
|
-
|
|
169
|
+
o([
|
|
129
170
|
n({ type: String, reflect: !0 })
|
|
130
171
|
], i.prototype, "placement");
|
|
131
|
-
|
|
172
|
+
o([
|
|
173
|
+
n({ type: Boolean, reflect: !0 })
|
|
174
|
+
], i.prototype, "open");
|
|
175
|
+
o([
|
|
132
176
|
n({ type: Boolean, reflect: !0 })
|
|
133
177
|
], i.prototype, "disabled");
|
|
134
|
-
|
|
178
|
+
f("kt-tooltip", i);
|
|
135
179
|
export {
|
|
136
180
|
i as KtTooltip
|
|
137
181
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-tooltip.js","sources":["../../../../src/components/feedback/kt-tooltip/kt-tooltip.ts"],"sourcesContent":["import { css, html, type PropertyValues, 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 { uniqueId } from '#internal/events';\n\nexport type KtTooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\n/** Marks the description node so it is never assigned to the default slot. */\nconst DESCRIPTION_SLOT = 'kt-tooltip-description';\n\n/**\n * A short label that appears on hover or focus.\n *\n * Wrap the thing it describes:\n *\n * ```html\n * <kt-tooltip text=\"Refresh the data\">\n * <kt-button icon=\"refresh-cw\" label=\"Refresh\"></kt-button>\n * </kt-tooltip>\n * ```\n *\n * A tooltip is a *description*, never the only name of a control. If the\n * trigger has no visible text, give it its own `label` too — a tooltip that has\n * to be hovered to be read leaves touch and screen-reader users with nothing.\n *\n * @element kt-tooltip\n *\n * @slot - The trigger.\n *\n * @csspart bubble - The tooltip bubble.\n */\nexport class KtTooltip extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n .bubble {\n position: absolute;\n z-index: var(--z-tooltip);\n max-width: 260px;\n padding: var(--padding-chip);\n /* Inverted against the page, so the bubble reads as floating in\n both themes — the raw ramp step this used to name is pure white\n under data-theme=\"light\". */\n color: var(--text-inverted);\n font: var(--font-code-regular);\n white-space: nowrap;\n background: var(--surface-inverted);\n border-radius: var(--radius-input);\n opacity: 0;\n pointer-events: none;\n transition: opacity 150ms var(--easing-standard);\n }\n\n .bubble.visible {\n opacity: 1;\n }\n\n .top {\n bottom: calc(100% + 6px);\n left: 50%;\n transform: translateX(-50%);\n }\n .bottom {\n top: calc(100% + 6px);\n left: 50%;\n transform: translateX(-50%);\n }\n .left {\n top: 50%;\n right: calc(100% + 6px);\n transform: translateY(-50%);\n }\n .right {\n top: 50%;\n left: calc(100% + 6px);\n transform: translateY(-50%);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .bubble {\n transition: none;\n }\n }\n `,\n ];\n\n private readonly descriptionId = uniqueId('kt-tooltip');\n private description: HTMLElement | undefined;\n\n @state()\n private visible = false;\n\n @property({ type: String })\n text = '';\n\n @property({ type: String, reflect: true })\n placement: KtTooltipPlacement = 'top';\n\n /** Suppresses the tooltip without removing it from the markup. */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('pointerenter', this.show);\n this.addEventListener('pointerleave', this.hide);\n this.addEventListener('focusin', this.show);\n this.addEventListener('focusout', this.hide);\n this.addEventListener('keydown', this.onKeyDown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('pointerenter', this.show);\n this.removeEventListener('pointerleave', this.hide);\n this.removeEventListener('focusin', this.show);\n this.removeEventListener('focusout', this.hide);\n this.removeEventListener('keydown', this.onKeyDown);\n this.description?.remove();\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('text')) this.syncDescription();\n }\n\n /**\n * `aria-describedby` cannot reach across a shadow boundary: an id inside this\n * element's shadow root is invisible to a trigger sitting in the light DOM.\n *\n * So the description also exists as a light-DOM node, addressed to a slot\n * that does not exist — which keeps it out of the rendered output while\n * leaving it referenceable, since an explicit aria-describedby target is read\n * even when it is not displayed.\n */\n private syncDescription(): void {\n if (!this.text) {\n this.description?.remove();\n this.description = undefined;\n return;\n }\n\n if (!this.description) {\n this.description = document.createElement('span');\n this.description.id = this.descriptionId;\n this.description.slot = DESCRIPTION_SLOT;\n this.append(this.description);\n }\n this.description.textContent = this.text;\n\n for (const trigger of this.children) {\n if (trigger !== this.description)\n trigger.setAttribute('aria-describedby', this.descriptionId);\n }\n }\n\n private show = (): void => {\n if (!this.disabled && this.text) this.visible = true;\n };\n\n private hide = (): void => {\n this.visible = false;\n };\n\n /** WCAG 1.4.13: a pointer-triggered overlay must be dismissible from the keyboard. */\n private onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape' && this.visible) {\n event.stopPropagation();\n this.visible = false;\n }\n };\n\n override render(): TemplateResult {\n return html`<slot @slotchange=${this.syncDescription}></slot>\n <span\n part=\"bubble\"\n class=${classMap({ bubble: true, [this.placement]: true, visible: this.visible })}\n role=\"tooltip\"\n aria-hidden=${this.visible ? 'false' : 'true'}\n >${this.text}</span\n >`;\n }\n}\n\ndefineElement('kt-tooltip', KtTooltip);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-tooltip': KtTooltip;\n }\n}\n"],"names":["DESCRIPTION_SLOT","KtTooltip","KtElement","uniqueId","event","css","changed","trigger","html","classMap","__decorateClass","state","property","defineElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kt-tooltip.js","sources":["../../../../src/components/feedback/kt-tooltip/kt-tooltip.ts"],"sourcesContent":["import { css, html, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { uniqueId } from '#internal/events';\nimport { placeFloating } from '#internal/position';\n\nexport type KtTooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\n/** Marks the description node so it is never assigned to the default slot. */\nconst DESCRIPTION_SLOT = 'kt-tooltip-description';\n\n/**\n * A short label that appears on hover or focus.\n *\n * Wrap the thing it describes:\n *\n * ```html\n * <kt-tooltip text=\"Refresh the data\">\n * <kt-button icon=\"refresh-cw\" label=\"Refresh\"></kt-button>\n * </kt-tooltip>\n * ```\n *\n * A tooltip is a *description*, never the only name of a control. If the\n * trigger has no visible text, give it its own `label` too — a tooltip that has\n * to be hovered to be read leaves touch and screen-reader users with nothing.\n *\n * @element kt-tooltip\n *\n * @slot - The trigger.\n *\n * @csspart bubble - The tooltip bubble.\n */\nexport class KtTooltip extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n /* A popover in the top layer, placed in viewport coordinates from\n the trigger: no ancestor's overflow can clip it, and it takes no\n room in the page — a bubble by the right edge used to widen the\n document. */\n .bubble {\n position: fixed;\n inset: auto;\n z-index: var(--z-tooltip);\n max-width: 260px;\n margin: 0;\n padding: var(--padding-chip);\n overflow: visible;\n /* Inverted against the page, so the bubble reads as floating in\n both themes — the raw ramp step this used to name is pure white\n under data-theme=\"light\". */\n color: var(--text-inverted);\n font: var(--font-code-regular);\n /* As wide as a short label, and wrapped at max-width for a sentence:\n a positioned box beside a small trigger would otherwise shrink to\n one word per line. */\n width: max-content;\n overflow-wrap: anywhere;\n background: var(--surface-inverted);\n border: none;\n border-radius: var(--radius-input);\n display: none;\n opacity: 0;\n pointer-events: none;\n /* The discrete display and overlay transitions keep the fade-out\n once the popover closes. */\n transition:\n opacity var(--duration-fast) var(--easing-standard),\n display var(--duration-fast) allow-discrete,\n overlay var(--duration-fast) allow-discrete;\n }\n\n .bubble:popover-open {\n display: block;\n }\n\n .bubble.visible {\n opacity: 1;\n }\n\n @starting-style {\n .bubble.visible {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .bubble {\n transition: none;\n }\n }\n `,\n ];\n\n private readonly descriptionId = uniqueId('kt-tooltip');\n private description: HTMLElement | undefined;\n\n @state()\n private visible = false;\n\n @query('.bubble')\n private bubble!: HTMLElement;\n\n @property({ type: String })\n text = '';\n\n /**\n * The side the bubble prefers. It takes the opposite one when this one has\n * no room — \"top\" on a trigger at the top of the page shows below it.\n */\n @property({ type: String, reflect: true })\n placement: KtTooltipPlacement = 'top';\n\n /**\n * Shows the bubble whatever the pointer and focus do — for a trigger that\n * cannot take focus itself, like an icon beside a field, whose owner shows\n * it while the field is focused.\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /** Suppresses the tooltip without removing it from the markup. */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('pointerenter', this.show);\n this.addEventListener('pointerleave', this.hide);\n this.addEventListener('focusin', this.show);\n this.addEventListener('focusout', this.hide);\n this.addEventListener('keydown', this.onKeyDown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('pointerenter', this.show);\n this.removeEventListener('pointerleave', this.hide);\n this.removeEventListener('focusin', this.show);\n this.removeEventListener('focusout', this.hide);\n this.removeEventListener('keydown', this.onKeyDown);\n this.description?.remove();\n this.visible = false;\n this.closeBubble();\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('text')) this.syncDescription();\n }\n\n /** Hovered, focused or held open — and something to say. */\n private get shown(): boolean {\n return (this.visible || this.open) && !this.disabled && Boolean(this.text);\n }\n\n // Untyped: `visible` is private, so not among the keys PropertyValues<this> knows.\n override updated(changed: PropertyValues): void {\n if (!['visible', 'open', 'text', 'disabled'].some((key) => changed.has(key))) return;\n if (this.shown) this.openBubble();\n else this.closeBubble();\n }\n\n /**\n * Opens the bubble in the top layer, then places it: it has to be open to be\n * measured. Where popovers are missing — a test DOM — it stays in place.\n */\n private openBubble(): void {\n const bubble = this.bubble;\n if (typeof bubble.showPopover !== 'function') return;\n if (!bubble.matches(':popover-open')) bubble.showPopover();\n\n const anchor = this.getBoundingClientRect();\n const { x, y } = placeFloating(\n anchor,\n bubble.getBoundingClientRect(),\n { width: window.innerWidth, height: window.innerHeight },\n this.placement,\n );\n bubble.style.left = `${x}px`;\n bubble.style.top = `${y}px`;\n // Fixed to the viewport, the bubble would drift from its trigger.\n window.addEventListener('scroll', this.hide, { capture: true, passive: true });\n window.addEventListener('resize', this.hide);\n }\n\n private closeBubble(): void {\n window.removeEventListener('scroll', this.hide, { capture: true });\n window.removeEventListener('resize', this.hide);\n const bubble = this.bubble;\n if (typeof bubble?.hidePopover === 'function' && bubble.matches(':popover-open')) {\n bubble.hidePopover();\n }\n }\n\n /**\n * `aria-describedby` cannot reach across a shadow boundary: an id inside this\n * element's shadow root is invisible to a trigger sitting in the light DOM.\n *\n * So the description also exists as a light-DOM node, addressed to a slot\n * that does not exist — which keeps it out of the rendered output while\n * leaving it referenceable, since an explicit aria-describedby target is read\n * even when it is not displayed.\n */\n private syncDescription(): void {\n if (!this.text) {\n this.description?.remove();\n this.description = undefined;\n return;\n }\n\n if (!this.description) {\n this.description = document.createElement('span');\n this.description.id = this.descriptionId;\n this.description.slot = DESCRIPTION_SLOT;\n this.append(this.description);\n }\n this.description.textContent = this.text;\n\n for (const trigger of this.children) {\n if (trigger !== this.description)\n trigger.setAttribute('aria-describedby', this.descriptionId);\n }\n }\n\n private show = (): void => {\n if (!this.disabled && this.text) this.visible = true;\n };\n\n private hide = (): void => {\n this.visible = false;\n };\n\n /** WCAG 1.4.13: a pointer-triggered overlay must be dismissible from the keyboard. */\n private onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape' && this.visible) {\n event.stopPropagation();\n this.visible = false;\n }\n };\n\n override render(): TemplateResult {\n return html`<slot @slotchange=${this.syncDescription}></slot>\n <span\n part=\"bubble\"\n popover=\"manual\"\n class=${classMap({ bubble: true, visible: this.shown })}\n role=\"tooltip\"\n aria-hidden=${this.shown ? 'false' : 'true'}\n >${this.text}</span\n >`;\n }\n}\n\ndefineElement('kt-tooltip', KtTooltip);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-tooltip': KtTooltip;\n }\n}\n"],"names":["DESCRIPTION_SLOT","KtTooltip","KtElement","uniqueId","event","css","changed","key","bubble","anchor","x","y","placeFloating","trigger","html","classMap","__decorateClass","state","query","property","defineElement"],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { KtElement } from '#internal/kt-element';
|
|
3
|
+
import '../../core/kt-icon/kt-icon.js';
|
|
4
|
+
export type KtCalendarView = 'day' | 'month' | 'year';
|
|
5
|
+
/**
|
|
6
|
+
* A month calendar to pick a day or a period from, shown in the page.
|
|
7
|
+
*
|
|
8
|
+
* The same calendar `<kt-date-picker>` opens in its popup, for when the
|
|
9
|
+
* calendar is the interface rather than a way to fill a field: a booking
|
|
10
|
+
* page, a dashboard's date filter, a planning view.
|
|
11
|
+
*
|
|
12
|
+
* The header's month and year are buttons. The month opens a grid of the
|
|
13
|
+
* twelve months, the year a grid of twelve years, so reaching a date years
|
|
14
|
+
* away takes three clicks rather than paging month by month.
|
|
15
|
+
*
|
|
16
|
+
* Keyboard, in the day grid (the WAI-ARIA date grid pattern): arrows by day
|
|
17
|
+
* and week, Home/End to the week's ends, Page Up/Down by month and with Shift
|
|
18
|
+
* by year, Enter to choose. In the month and year grids: arrows, Page Up/Down
|
|
19
|
+
* by year or by twelve years, Enter to choose, Escape back to the days.
|
|
20
|
+
*
|
|
21
|
+
* @element kt-calendar
|
|
22
|
+
*
|
|
23
|
+
* @csspart base - The calendar.
|
|
24
|
+
* @csspart day - A day cell.
|
|
25
|
+
*
|
|
26
|
+
* @fires kt-change - A day, or a whole period, was chosen. `detail: { value }`.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```html
|
|
30
|
+
* <kt-calendar value="2026-09-25"></kt-calendar>
|
|
31
|
+
* <kt-calendar range value="2026-09-01/2026-09-25" min="2026-01-01"></kt-calendar>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class KtCalendar extends KtElement {
|
|
35
|
+
static styles: import("lit").CSSResultGroup[];
|
|
36
|
+
private readonly liveId;
|
|
37
|
+
private focusCell;
|
|
38
|
+
/** Set while the calendar writes its own value, which should not move it. */
|
|
39
|
+
private committing;
|
|
40
|
+
private view;
|
|
41
|
+
/** First day of the month the day view shows. */
|
|
42
|
+
private month;
|
|
43
|
+
/** The day, month or year holding the grid's one tab stop. */
|
|
44
|
+
private focused;
|
|
45
|
+
/** In a period: the first end chosen, while the second is pending. */
|
|
46
|
+
private anchor;
|
|
47
|
+
/** ISO date, or `start/end` interval with `range`. `null` when empty. */
|
|
48
|
+
value: string | null;
|
|
49
|
+
/** Choose a period — two dates — instead of one day. */
|
|
50
|
+
range: boolean;
|
|
51
|
+
/** Earliest date that can be chosen, ISO. */
|
|
52
|
+
min: string;
|
|
53
|
+
/** Latest date that can be chosen, ISO. */
|
|
54
|
+
max: string;
|
|
55
|
+
/**
|
|
56
|
+
* BCP 47 language tag for names and the first day of the week. Empty: the
|
|
57
|
+
* page's `lang`, then the browser's language.
|
|
58
|
+
*/
|
|
59
|
+
locale: string;
|
|
60
|
+
/** Accessible name of the calendar. Defaults to the strings registry. */
|
|
61
|
+
label: string;
|
|
62
|
+
connectedCallback(): void;
|
|
63
|
+
willUpdate(changed: PropertyValues<this>): void;
|
|
64
|
+
updated(): void;
|
|
65
|
+
/** Focuses the grid's current cell — the chosen day, or today. */
|
|
66
|
+
focus(): void;
|
|
67
|
+
private get resolvedLocale();
|
|
68
|
+
private get selection();
|
|
69
|
+
private get bounds();
|
|
70
|
+
private clamp;
|
|
71
|
+
private isOutOfBounds;
|
|
72
|
+
/** A month or a year is unavailable only when every day of it is. */
|
|
73
|
+
private isSpanOutOfBounds;
|
|
74
|
+
private format;
|
|
75
|
+
/** Moves the tab stop, and the day view with it when it leaves the month. */
|
|
76
|
+
private jumpTo;
|
|
77
|
+
private setView;
|
|
78
|
+
private chooseDay;
|
|
79
|
+
private commit;
|
|
80
|
+
private chooseMonth;
|
|
81
|
+
private chooseYear;
|
|
82
|
+
private onDayKeyDown;
|
|
83
|
+
/** Months and years share one model: a list of cells, three to a row. */
|
|
84
|
+
private onPickerKeyDown;
|
|
85
|
+
private renderHeader;
|
|
86
|
+
private renderDay;
|
|
87
|
+
private renderDays;
|
|
88
|
+
/** The month or year grid: twelve cells, three to a row. */
|
|
89
|
+
private renderPicker;
|
|
90
|
+
render(): TemplateResult;
|
|
91
|
+
}
|
|
92
|
+
declare global {
|
|
93
|
+
interface HTMLElementTagNameMap {
|
|
94
|
+
'kt-calendar': KtCalendar;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "lit";
|
|
2
|
+
import "lit/decorators.js";
|
|
3
|
+
import "lit/directives/class-map.js";
|
|
4
|
+
import "../../../chunks/kt-element-Djx2JcGl.js";
|
|
5
|
+
import "../../../chunks/events-r51msXNf.js";
|
|
6
|
+
import "../../../chunks/locale-C5xLkGx5.js";
|
|
7
|
+
import "../../../chunks/index-STEEvEP7.js";
|
|
8
|
+
import { K as f } from "../../../chunks/kt-calendar-B_hFdD9V.js";
|
|
9
|
+
import "../../core/kt-icon/kt-icon.js";
|
|
10
|
+
export {
|
|
11
|
+
f as KtCalendar
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=kt-calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kt-calendar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
|
|
@@ -42,6 +42,10 @@ export declare class KtCheckbox extends KtElement {
|
|
|
42
42
|
*/
|
|
43
43
|
indeterminate: boolean;
|
|
44
44
|
disabled: boolean;
|
|
45
|
+
/** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */
|
|
46
|
+
private formDisabled;
|
|
47
|
+
/** Whether the control is off, by its own `disabled` or by its form. */
|
|
48
|
+
private get inactive();
|
|
45
49
|
required: boolean;
|
|
46
50
|
size: KtCheckboxSize;
|
|
47
51
|
name: string;
|
|
@@ -54,6 +58,11 @@ export declare class KtCheckbox extends KtElement {
|
|
|
54
58
|
connectedCallback(): void;
|
|
55
59
|
willUpdate(changed: PropertyValues<this>): void;
|
|
56
60
|
formResetCallback(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Called by the platform when the control's disabled state changes — its
|
|
63
|
+
* own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.
|
|
64
|
+
*/
|
|
65
|
+
formDisabledCallback(disabled: boolean): void;
|
|
57
66
|
formStateRestoreCallback(state: string | null): void;
|
|
58
67
|
focus(options?: FocusOptions): void;
|
|
59
68
|
private onChange;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { css as p, nothing as a, html as c } from "lit";
|
|
2
|
-
import { query as
|
|
3
|
-
import { live as
|
|
4
|
-
import { K as d, d as
|
|
5
|
-
import { e as
|
|
6
|
-
import { a as
|
|
7
|
-
import { s as
|
|
2
|
+
import { query as b, property as i, state as u } from "lit/decorators.js";
|
|
3
|
+
import { live as m } from "lit/directives/live.js";
|
|
4
|
+
import { K as d, d as f } from "../../../chunks/kt-element-Djx2JcGl.js";
|
|
5
|
+
import { e as k } from "../../../chunks/events-r51msXNf.js";
|
|
6
|
+
import { a as v, s as g, b as y } from "../../../chunks/form-control-B74_EHtG.js";
|
|
7
|
+
import { s as x } from "../../../chunks/index-STEEvEP7.js";
|
|
8
8
|
import "../../core/kt-icon/kt-icon.js";
|
|
9
|
-
var
|
|
9
|
+
var C = Object.defineProperty, r = (l, e, o, $) => {
|
|
10
10
|
for (var s = void 0, n = l.length - 1, h; n >= 0; n--)
|
|
11
11
|
(h = l[n]) && (s = h(e, o, s) || s);
|
|
12
|
-
return s &&
|
|
12
|
+
return s && C(e, o, s), s;
|
|
13
13
|
};
|
|
14
14
|
class t extends d {
|
|
15
15
|
constructor() {
|
|
16
|
-
super(...arguments), this.internals = null, this.defaultChecked = !1, this.checked = !1, this.indeterminate = !1, this.disabled = !1, this.required = !1, this.size = "medium", this.name = "", this.value = "on", this.label = "", this.error = "";
|
|
16
|
+
super(...arguments), this.internals = null, this.defaultChecked = !1, this.checked = !1, this.indeterminate = !1, this.disabled = !1, this.formDisabled = !1, this.required = !1, this.size = "medium", this.name = "", this.value = "on", this.label = "", this.error = "";
|
|
17
17
|
}
|
|
18
18
|
static {
|
|
19
19
|
this.formAssociated = !0;
|
|
@@ -98,11 +98,11 @@ class t extends d {
|
|
|
98
98
|
border-color: var(--color-danger-base);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
:host(
|
|
101
|
+
:host(:disabled) label {
|
|
102
102
|
color: var(--text-disabled);
|
|
103
103
|
cursor: not-allowed;
|
|
104
104
|
}
|
|
105
|
-
:host(
|
|
105
|
+
:host(:disabled) .box {
|
|
106
106
|
background-color: var(--color-dark-22);
|
|
107
107
|
border-color: var(--color-dark-24);
|
|
108
108
|
color: var(--text-disabled);
|
|
@@ -110,23 +110,34 @@ class t extends d {
|
|
|
110
110
|
`
|
|
111
111
|
];
|
|
112
112
|
}
|
|
113
|
+
/** Whether the control is off, by its own `disabled` or by its form. */
|
|
114
|
+
get inactive() {
|
|
115
|
+
return this.disabled || this.formDisabled;
|
|
116
|
+
}
|
|
113
117
|
connectedCallback() {
|
|
114
|
-
super.connectedCallback(), this.internals ??=
|
|
118
|
+
super.connectedCallback(), this.internals ??= v(this), this.defaultChecked = this.checked;
|
|
115
119
|
}
|
|
116
120
|
willUpdate(e) {
|
|
117
121
|
if (e.has("checked") || e.has("value") || e.has("required") || e.has("error") || this.stringsChanged(e)) {
|
|
118
|
-
|
|
122
|
+
g(this.internals, this.checked ? this.value : null);
|
|
119
123
|
const o = this.required && !this.checked;
|
|
120
|
-
|
|
124
|
+
y(
|
|
121
125
|
this.internals,
|
|
122
126
|
{ valueMissing: o, customError: !!this.error },
|
|
123
|
-
this.error || (o ?
|
|
127
|
+
this.error || (o ? x().checkRequired : "")
|
|
124
128
|
);
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
131
|
formResetCallback() {
|
|
128
132
|
this.checked = this.defaultChecked, this.indeterminate = !1;
|
|
129
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Called by the platform when the control's disabled state changes — its
|
|
136
|
+
* own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.
|
|
137
|
+
*/
|
|
138
|
+
formDisabledCallback(e) {
|
|
139
|
+
this.formDisabled = e;
|
|
140
|
+
}
|
|
130
141
|
formStateRestoreCallback(e) {
|
|
131
142
|
this.checked = e === this.value;
|
|
132
143
|
}
|
|
@@ -135,7 +146,7 @@ class t extends d {
|
|
|
135
146
|
}
|
|
136
147
|
onChange(e) {
|
|
137
148
|
const o = e.target;
|
|
138
|
-
this.checked = o.checked, this.indeterminate = !1,
|
|
149
|
+
this.checked = o.checked, this.indeterminate = !1, k(this, "kt-change", { checked: this.checked });
|
|
139
150
|
}
|
|
140
151
|
render() {
|
|
141
152
|
const e = this.indeterminate ? "minus" : this.checked ? "check" : "";
|
|
@@ -144,9 +155,9 @@ class t extends d {
|
|
|
144
155
|
<input
|
|
145
156
|
part="input"
|
|
146
157
|
type="checkbox"
|
|
147
|
-
.checked=${
|
|
158
|
+
.checked=${m(this.checked)}
|
|
148
159
|
.indeterminate=${this.indeterminate}
|
|
149
|
-
?disabled=${this.
|
|
160
|
+
?disabled=${this.inactive}
|
|
150
161
|
?required=${this.required}
|
|
151
162
|
aria-label=${this.label || a}
|
|
152
163
|
aria-invalid=${this.error ? "true" : a}
|
|
@@ -162,7 +173,7 @@ class t extends d {
|
|
|
162
173
|
}
|
|
163
174
|
}
|
|
164
175
|
r([
|
|
165
|
-
|
|
176
|
+
b("input")
|
|
166
177
|
], t.prototype, "input");
|
|
167
178
|
r([
|
|
168
179
|
i({ type: Boolean, reflect: !0 })
|
|
@@ -173,6 +184,9 @@ r([
|
|
|
173
184
|
r([
|
|
174
185
|
i({ type: Boolean, reflect: !0 })
|
|
175
186
|
], t.prototype, "disabled");
|
|
187
|
+
r([
|
|
188
|
+
u()
|
|
189
|
+
], t.prototype, "formDisabled");
|
|
176
190
|
r([
|
|
177
191
|
i({ type: Boolean, reflect: !0 })
|
|
178
192
|
], t.prototype, "required");
|
|
@@ -191,7 +205,7 @@ r([
|
|
|
191
205
|
r([
|
|
192
206
|
i({ type: String, reflect: !0 })
|
|
193
207
|
], t.prototype, "error");
|
|
194
|
-
|
|
208
|
+
f("kt-checkbox", t);
|
|
195
209
|
export {
|
|
196
210
|
t as KtCheckbox
|
|
197
211
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kt-checkbox.js","sources":["../../../../src/components/forms/kt-checkbox/kt-checkbox.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport type KtCheckboxSize = 'small' | 'medium' | 'large';\n\n/**\n * A checkbox: a choice that applies when the form is submitted.\n *\n * Built on a real `<input type=\"checkbox\">`, laid invisibly over the drawn\n * box, so the keyboard, the label click, the indeterminate state and what a\n * screen reader announces all come from the platform rather than a\n * reimplementation of it.\n *\n * For a setting that takes effect the moment it is flipped, use\n * `<kt-toggle>`; for one choice among several, `<kt-radio-group>`.\n *\n * @element kt-checkbox\n *\n * @slot - The label, clickable.\n *\n * @csspart base - The `<label>` around box and text.\n * @csspart input - The native checkbox.\n * @csspart box - The drawn box.\n *\n * @fires kt-change - The box was checked or unchecked. `detail: { checked }`.\n *\n * @example\n * ```html\n * <kt-checkbox name=\"terms\" required>I accept the terms</kt-checkbox>\n * <kt-checkbox indeterminate>Select all</kt-checkbox>\n * ```\n */\nexport class KtCheckbox extends KtElement {\n static readonly formAssociated = true;\n\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n /* Sized off the button heights, like the toggle, so a checkbox lines\n up with the fields and buttons beside it. */\n --checkbox-size: calc(var(--button-height) * 0.45);\n }\n :host([size='small']) {\n --checkbox-size: calc(var(--button-height-small) * 0.45);\n }\n :host([size='large']) {\n --checkbox-size: calc(var(--button-height-large) * 0.45);\n }\n\n label {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--gap-button);\n color: var(--text-body);\n font: var(--font-normal-regular);\n cursor: pointer;\n }\n\n .control {\n position: relative;\n flex: none;\n width: var(--checkbox-size);\n height: var(--checkbox-size);\n /* Centre the box on the first line of text, not the whole block. */\n margin-top: calc((1lh - var(--checkbox-size)) / 2);\n }\n\n input {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n opacity: 0;\n cursor: inherit;\n }\n\n .box {\n display: grid;\n place-items: center;\n width: 100%;\n height: 100%;\n color: var(--color-white);\n background-color: var(--surface-field);\n border: var(--border-width) solid var(--border-field);\n border-radius: var(--radius-sub-menu);\n transition:\n background-color var(--duration-instant),\n border-color var(--duration-instant);\n pointer-events: none;\n }\n\n label:hover .box {\n border-color: var(--text-muted);\n }\n\n input:focus-visible + .box {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n }\n\n input:checked + .box,\n input:indeterminate + .box {\n background-color: var(--color-primary-base);\n border-color: var(--color-primary-base);\n }\n\n .error .box {\n border-color: var(--color-danger-base);\n }\n\n :host([disabled]) label {\n color: var(--text-disabled);\n cursor: not-allowed;\n }\n :host([disabled]) .box {\n background-color: var(--color-dark-22);\n border-color: var(--color-dark-24);\n color: var(--text-disabled);\n }\n `,\n ];\n\n @query('input')\n private input?: HTMLInputElement;\n\n private internals: UsableInternals | null = null;\n private defaultChecked = false;\n\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * Neither checked nor unchecked — for a \"select all\" over a partial\n * selection. Cleared as soon as the user clicks, as on a native checkbox.\n */\n @property({ type: Boolean, reflect: true })\n indeterminate = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n @property({ type: String, reflect: true })\n size: KtCheckboxSize = 'medium';\n\n @property({ type: String })\n name = '';\n\n /** Submitted when checked, as for a native checkbox. */\n @property({ type: String })\n value = 'on';\n\n /** Accessible name, when nothing is slotted. */\n @property({ type: String })\n label = '';\n\n /** Error message. A non-empty value puts the box in its error state. */\n @property({ type: String, reflect: true })\n error = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.internals ??= attachFormInternals(this);\n this.defaultChecked = this.checked;\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('checked') ||\n changed.has('value') ||\n changed.has('required') ||\n changed.has('error') ||\n this.stringsChanged(changed)\n ) {\n // Unchecked contributes nothing to the submission, not an empty string.\n setFormValue(this.internals, this.checked ? this.value : null);\n\n const missing = this.required && !this.checked;\n setValidity(\n this.internals,\n { valueMissing: missing, customError: Boolean(this.error) },\n this.error || (missing ? strings().checkRequired : ''),\n );\n }\n }\n\n formResetCallback(): void {\n this.checked = this.defaultChecked;\n this.indeterminate = false;\n }\n\n formStateRestoreCallback(state: string | null): void {\n this.checked = state === this.value;\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options);\n }\n\n private onChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.checked = input.checked;\n this.indeterminate = false;\n emit(this, 'kt-change', { checked: this.checked });\n }\n\n override render(): TemplateResult {\n const icon = this.indeterminate ? 'minus' : this.checked ? 'check' : '';\n\n // The message sits outside the <label>: inside it, it would become part of\n // the checkbox's name instead of its description.\n return html`${\n this.error\n ? html`<span id=\"error-message\" class=\"visually-hidden\">${this.error}</span>`\n : nothing\n }<label part=\"base\" class=${this.error ? 'error' : ''}>\n <span class=\"control\">\n <input\n part=\"input\"\n type=\"checkbox\"\n .checked=${live(this.checked)}\n .indeterminate=${this.indeterminate}\n ?disabled=${this.disabled}\n ?required=${this.required}\n aria-label=${this.label || nothing}\n aria-invalid=${this.error ? 'true' : nothing}\n aria-describedby=${this.error ? 'error-message' : nothing}\n @change=${this.onChange}\n />\n <span part=\"box\" class=\"box\">\n ${icon ? html`<kt-icon name=${icon} size=\"14\"></kt-icon>` : nothing}\n </span>\n </span>\n <span class=\"text\"><slot></slot></span>\n </label>`;\n }\n}\n\ndefineElement('kt-checkbox', KtCheckbox);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-checkbox': KtCheckbox;\n }\n}\n"],"names":["KtCheckbox","KtElement","css","attachFormInternals","changed","setFormValue","missing","setValidity","strings","state","options","event","input","emit","icon","html","nothing","live","__decorateClass","query","property","defineElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kt-checkbox.js","sources":["../../../../src/components/forms/kt-checkbox/kt-checkbox.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport {\n attachFormInternals,\n setFormValue,\n setValidity,\n type UsableInternals,\n} from '#internal/form-control';\nimport { strings } from '#internal/strings';\nimport '../../core/kt-icon/kt-icon.js';\n\nexport type KtCheckboxSize = 'small' | 'medium' | 'large';\n\n/**\n * A checkbox: a choice that applies when the form is submitted.\n *\n * Built on a real `<input type=\"checkbox\">`, laid invisibly over the drawn\n * box, so the keyboard, the label click, the indeterminate state and what a\n * screen reader announces all come from the platform rather than a\n * reimplementation of it.\n *\n * For a setting that takes effect the moment it is flipped, use\n * `<kt-toggle>`; for one choice among several, `<kt-radio-group>`.\n *\n * @element kt-checkbox\n *\n * @slot - The label, clickable.\n *\n * @csspart base - The `<label>` around box and text.\n * @csspart input - The native checkbox.\n * @csspart box - The drawn box.\n *\n * @fires kt-change - The box was checked or unchecked. `detail: { checked }`.\n *\n * @example\n * ```html\n * <kt-checkbox name=\"terms\" required>I accept the terms</kt-checkbox>\n * <kt-checkbox indeterminate>Select all</kt-checkbox>\n * ```\n */\nexport class KtCheckbox extends KtElement {\n static readonly formAssociated = true;\n\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n /* Sized off the button heights, like the toggle, so a checkbox lines\n up with the fields and buttons beside it. */\n --checkbox-size: calc(var(--button-height) * 0.45);\n }\n :host([size='small']) {\n --checkbox-size: calc(var(--button-height-small) * 0.45);\n }\n :host([size='large']) {\n --checkbox-size: calc(var(--button-height-large) * 0.45);\n }\n\n label {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--gap-button);\n color: var(--text-body);\n font: var(--font-normal-regular);\n cursor: pointer;\n }\n\n .control {\n position: relative;\n flex: none;\n width: var(--checkbox-size);\n height: var(--checkbox-size);\n /* Centre the box on the first line of text, not the whole block. */\n margin-top: calc((1lh - var(--checkbox-size)) / 2);\n }\n\n input {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n opacity: 0;\n cursor: inherit;\n }\n\n .box {\n display: grid;\n place-items: center;\n width: 100%;\n height: 100%;\n color: var(--color-white);\n background-color: var(--surface-field);\n border: var(--border-width) solid var(--border-field);\n border-radius: var(--radius-sub-menu);\n transition:\n background-color var(--duration-instant),\n border-color var(--duration-instant);\n pointer-events: none;\n }\n\n label:hover .box {\n border-color: var(--text-muted);\n }\n\n input:focus-visible + .box {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n }\n\n input:checked + .box,\n input:indeterminate + .box {\n background-color: var(--color-primary-base);\n border-color: var(--color-primary-base);\n }\n\n .error .box {\n border-color: var(--color-danger-base);\n }\n\n :host(:disabled) label {\n color: var(--text-disabled);\n cursor: not-allowed;\n }\n :host(:disabled) .box {\n background-color: var(--color-dark-22);\n border-color: var(--color-dark-24);\n color: var(--text-disabled);\n }\n `,\n ];\n\n @query('input')\n private input?: HTMLInputElement;\n\n private internals: UsableInternals | null = null;\n private defaultChecked = false;\n\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * Neither checked nor unchecked — for a \"select all\" over a partial\n * selection. Cleared as soon as the user clicks, as on a native checkbox.\n */\n @property({ type: Boolean, reflect: true })\n indeterminate = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Disabled by an enclosing `<fieldset>`, which leaves `disabled` alone. */\n @state()\n private formDisabled = false;\n\n /** Whether the control is off, by its own `disabled` or by its form. */\n private get inactive(): boolean {\n return this.disabled || this.formDisabled;\n }\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n @property({ type: String, reflect: true })\n size: KtCheckboxSize = 'medium';\n\n @property({ type: String })\n name = '';\n\n /** Submitted when checked, as for a native checkbox. */\n @property({ type: String })\n value = 'on';\n\n /** Accessible name, when nothing is slotted. */\n @property({ type: String })\n label = '';\n\n /** Error message. A non-empty value puts the box in its error state. */\n @property({ type: String, reflect: true })\n error = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.internals ??= attachFormInternals(this);\n this.defaultChecked = this.checked;\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (\n changed.has('checked') ||\n changed.has('value') ||\n changed.has('required') ||\n changed.has('error') ||\n this.stringsChanged(changed)\n ) {\n // Unchecked contributes nothing to the submission, not an empty string.\n setFormValue(this.internals, this.checked ? this.value : null);\n\n const missing = this.required && !this.checked;\n setValidity(\n this.internals,\n { valueMissing: missing, customError: Boolean(this.error) },\n this.error || (missing ? strings().checkRequired : ''),\n );\n }\n }\n\n formResetCallback(): void {\n this.checked = this.defaultChecked;\n this.indeterminate = false;\n }\n\n /**\n * Called by the platform when the control's disabled state changes — its\n * own `disabled`, or an ancestor `<fieldset disabled>` it cannot see.\n */\n formDisabledCallback(disabled: boolean): void {\n this.formDisabled = disabled;\n }\n\n formStateRestoreCallback(state: string | null): void {\n this.checked = state === this.value;\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options);\n }\n\n private onChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.checked = input.checked;\n this.indeterminate = false;\n emit(this, 'kt-change', { checked: this.checked });\n }\n\n override render(): TemplateResult {\n const icon = this.indeterminate ? 'minus' : this.checked ? 'check' : '';\n\n // The message sits outside the <label>: inside it, it would become part of\n // the checkbox's name instead of its description.\n return html`${\n this.error\n ? html`<span id=\"error-message\" class=\"visually-hidden\">${this.error}</span>`\n : nothing\n }<label part=\"base\" class=${this.error ? 'error' : ''}>\n <span class=\"control\">\n <input\n part=\"input\"\n type=\"checkbox\"\n .checked=${live(this.checked)}\n .indeterminate=${this.indeterminate}\n ?disabled=${this.inactive}\n ?required=${this.required}\n aria-label=${this.label || nothing}\n aria-invalid=${this.error ? 'true' : nothing}\n aria-describedby=${this.error ? 'error-message' : nothing}\n @change=${this.onChange}\n />\n <span part=\"box\" class=\"box\">\n ${icon ? html`<kt-icon name=${icon} size=\"14\"></kt-icon>` : nothing}\n </span>\n </span>\n <span class=\"text\"><slot></slot></span>\n </label>`;\n }\n}\n\ndefineElement('kt-checkbox', KtCheckbox);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-checkbox': KtCheckbox;\n }\n}\n"],"names":["KtCheckbox","KtElement","css","attachFormInternals","changed","setFormValue","missing","setValidity","strings","disabled","state","options","event","input","emit","icon","html","nothing","live","__decorateClass","query","property","defineElement"],"mappings":"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"}
|