kanto-ds 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/README.md +155 -0
- package/dist/assets/fonts/README.md +19 -0
- package/dist/assets/fonts/manrope/OFL.txt +93 -0
- package/dist/assets/fonts/manrope/manrope-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/manrope/manrope-cyrillic-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/manrope/manrope-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/manrope/manrope-latin-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/mulish/OFL.txt +93 -0
- package/dist/assets/fonts/mulish/mulish-cyrillic-ext-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/mulish/mulish-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/mulish/mulish-cyrillic-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/mulish/mulish-cyrillic-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/mulish/mulish-latin-ext-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/mulish/mulish-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/mulish/mulish-latin-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/mulish/mulish-latin-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/source_code_pro/OFL.txt +93 -0
- package/dist/assets/fonts/source_code_pro/SourceCodePro-Regular.woff2 +0 -0
- package/dist/chunks/dialog-CPIfFIlF.js +29 -0
- package/dist/chunks/dialog-CPIfFIlF.js.map +1 -0
- package/dist/chunks/events-Bjl5Zmmq.js +18 -0
- package/dist/chunks/events-Bjl5Zmmq.js.map +1 -0
- package/dist/chunks/form-control-CxjBTt1c.js +17 -0
- package/dist/chunks/form-control-CxjBTt1c.js.map +1 -0
- package/dist/chunks/kt-element-CcMLO5e8.js +28 -0
- package/dist/chunks/kt-element-CcMLO5e8.js.map +1 -0
- package/dist/chunks/listbox-CUXYn_3S.js +101 -0
- package/dist/chunks/listbox-CUXYn_3S.js.map +1 -0
- package/dist/chunks/registry-X4LS9J5K.js +30 -0
- package/dist/chunks/registry-X4LS9J5K.js.map +1 -0
- package/dist/chunks/slots-BPbIdxAJ.js +7 -0
- package/dist/chunks/slots-BPbIdxAJ.js.map +1 -0
- package/dist/chunks/toaster-PmdKSV5x.js +40 -0
- package/dist/chunks/toaster-PmdKSV5x.js.map +1 -0
- package/dist/components/core/kt-avatar/kt-avatar.d.ts +49 -0
- package/dist/components/core/kt-avatar/kt-avatar.js +156 -0
- package/dist/components/core/kt-avatar/kt-avatar.js.map +1 -0
- package/dist/components/core/kt-badge/kt-badge.d.ts +77 -0
- package/dist/components/core/kt-badge/kt-badge.js +254 -0
- package/dist/components/core/kt-badge/kt-badge.js.map +1 -0
- package/dist/components/core/kt-button/kt-button.d.ts +71 -0
- package/dist/components/core/kt-button/kt-button.js +271 -0
- package/dist/components/core/kt-button/kt-button.js.map +1 -0
- package/dist/components/core/kt-card/kt-card.d.ts +62 -0
- package/dist/components/core/kt-card/kt-card.js +230 -0
- package/dist/components/core/kt-card/kt-card.js.map +1 -0
- package/dist/components/core/kt-code/kt-code.d.ts +55 -0
- package/dist/components/core/kt-code/kt-code.js +155 -0
- package/dist/components/core/kt-code/kt-code.js.map +1 -0
- package/dist/components/core/kt-icon/kt-icon.d.ts +44 -0
- package/dist/components/core/kt-icon/kt-icon.js +85 -0
- package/dist/components/core/kt-icon/kt-icon.js.map +1 -0
- package/dist/components/core/kt-kbd/kt-kbd.d.ts +38 -0
- package/dist/components/core/kt-kbd/kt-kbd.js +89 -0
- package/dist/components/core/kt-kbd/kt-kbd.js.map +1 -0
- package/dist/components/data/kt-chart/kt-chart.d.ts +99 -0
- package/dist/components/data/kt-chart/kt-chart.js +406 -0
- package/dist/components/data/kt-chart/kt-chart.js.map +1 -0
- package/dist/components/data/kt-meter/kt-meter.d.ts +63 -0
- package/dist/components/data/kt-meter/kt-meter.js +177 -0
- package/dist/components/data/kt-meter/kt-meter.js.map +1 -0
- package/dist/components/data/kt-pagination/kt-pagination.d.ts +35 -0
- package/dist/components/data/kt-pagination/kt-pagination.js +88 -0
- package/dist/components/data/kt-pagination/kt-pagination.js.map +1 -0
- package/dist/components/data/kt-stat/kt-stat.d.ts +60 -0
- package/dist/components/data/kt-stat/kt-stat.js +137 -0
- package/dist/components/data/kt-stat/kt-stat.js.map +1 -0
- package/dist/components/data/kt-table/kt-table.d.ts +99 -0
- package/dist/components/data/kt-table/kt-table.js +340 -0
- package/dist/components/data/kt-table/kt-table.js.map +1 -0
- package/dist/components/data/kt-timeline/kt-timeline.d.ts +78 -0
- package/dist/components/data/kt-timeline/kt-timeline.js +252 -0
- package/dist/components/data/kt-timeline/kt-timeline.js.map +1 -0
- package/dist/components/feedback/kt-alert/kt-alert.d.ts +46 -0
- package/dist/components/feedback/kt-alert/kt-alert.js +180 -0
- package/dist/components/feedback/kt-alert/kt-alert.js.map +1 -0
- package/dist/components/feedback/kt-empty-state/kt-empty-state.d.ts +40 -0
- package/dist/components/feedback/kt-empty-state/kt-empty-state.js +100 -0
- package/dist/components/feedback/kt-empty-state/kt-empty-state.js.map +1 -0
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.d.ts +53 -0
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +212 -0
- package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js.map +1 -0
- package/dist/components/feedback/kt-skeleton/kt-skeleton.d.ts +43 -0
- package/dist/components/feedback/kt-skeleton/kt-skeleton.js +117 -0
- package/dist/components/feedback/kt-skeleton/kt-skeleton.js.map +1 -0
- package/dist/components/feedback/kt-toast/kt-toast.d.ts +57 -0
- package/dist/components/feedback/kt-toast/kt-toast.js +231 -0
- package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -0
- package/dist/components/feedback/kt-toast-container/kt-toast-container.d.ts +60 -0
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js +100 -0
- package/dist/components/feedback/kt-toast-container/kt-toast-container.js.map +1 -0
- package/dist/components/feedback/kt-toast-container/toaster.d.ts +37 -0
- package/dist/components/feedback/kt-tooltip/kt-tooltip.d.ts +57 -0
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js +138 -0
- package/dist/components/feedback/kt-tooltip/kt-tooltip.js.map +1 -0
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.d.ts +68 -0
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +287 -0
- package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -0
- package/dist/components/forms/kt-form/kt-form.d.ts +75 -0
- package/dist/components/forms/kt-form/kt-form.js +187 -0
- package/dist/components/forms/kt-form/kt-form.js.map +1 -0
- package/dist/components/forms/kt-input/kt-input.d.ts +112 -0
- package/dist/components/forms/kt-input/kt-input.js +556 -0
- package/dist/components/forms/kt-input/kt-input.js.map +1 -0
- package/dist/components/forms/kt-input-menu/kt-input-menu.d.ts +60 -0
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +313 -0
- package/dist/components/forms/kt-input-menu/kt-input-menu.js.map +1 -0
- package/dist/components/forms/kt-label-input/kt-label-input.d.ts +42 -0
- package/dist/components/forms/kt-label-input/kt-label-input.js +69 -0
- package/dist/components/forms/kt-label-input/kt-label-input.js.map +1 -0
- package/dist/components/forms/kt-select/kt-select.d.ts +80 -0
- package/dist/components/forms/kt-select/kt-select.js +334 -0
- package/dist/components/forms/kt-select/kt-select.js.map +1 -0
- package/dist/components/forms/kt-textarea/kt-textarea.d.ts +62 -0
- package/dist/components/forms/kt-textarea/kt-textarea.js +239 -0
- package/dist/components/forms/kt-textarea/kt-textarea.js.map +1 -0
- package/dist/components/forms/kt-toggle/kt-toggle.d.ts +53 -0
- package/dist/components/forms/kt-toggle/kt-toggle.js +170 -0
- package/dist/components/forms/kt-toggle/kt-toggle.js.map +1 -0
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.d.ts +45 -0
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +93 -0
- package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js.map +1 -0
- package/dist/components/navigation/kt-header/kt-header.d.ts +67 -0
- package/dist/components/navigation/kt-header/kt-header.js +195 -0
- package/dist/components/navigation/kt-header/kt-header.js.map +1 -0
- package/dist/components/navigation/kt-page-header/kt-page-header.d.ts +48 -0
- package/dist/components/navigation/kt-page-header/kt-page-header.js +111 -0
- package/dist/components/navigation/kt-page-header/kt-page-header.js.map +1 -0
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +63 -0
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +228 -0
- package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -0
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.d.ts +94 -0
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +265 -0
- package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js.map +1 -0
- package/dist/components/navigation/kt-tabs/kt-tabs.d.ts +64 -0
- package/dist/components/navigation/kt-tabs/kt-tabs.js +175 -0
- package/dist/components/navigation/kt-tabs/kt-tabs.js.map +1 -0
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.d.ts +50 -0
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +191 -0
- package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js.map +1 -0
- package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.d.ts +55 -0
- package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +128 -0
- package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js.map +1 -0
- package/dist/components/overlays/kt-collapsible/kt-collapsible.d.ts +42 -0
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js +107 -0
- package/dist/components/overlays/kt-collapsible/kt-collapsible.js.map +1 -0
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.d.ts +56 -0
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +155 -0
- package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js.map +1 -0
- package/dist/components/overlays/kt-dropdown/kt-dropdown.d.ts +64 -0
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +212 -0
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -0
- package/dist/components/overlays/kt-modal/kt-modal.d.ts +61 -0
- package/dist/components/overlays/kt-modal/kt-modal.js +207 -0
- package/dist/components/overlays/kt-modal/kt-modal.js.map +1 -0
- package/dist/components/overlays/kt-side-panel/kt-side-panel.d.ts +52 -0
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js +178 -0
- package/dist/components/overlays/kt-side-panel/kt-side-panel.js.map +1 -0
- package/dist/icons/defaults.d.ts +25 -0
- package/dist/icons/index.d.ts +3 -0
- package/dist/icons/index.js +37 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/registry.d.ts +38 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/countries.d.ts +37 -0
- package/dist/internal/dialog.d.ts +22 -0
- package/dist/internal/events.d.ts +14 -0
- package/dist/internal/form-control.d.ts +27 -0
- package/dist/internal/format.d.ts +8 -0
- package/dist/internal/kt-element.d.ts +22 -0
- package/dist/internal/listbox.d.ts +36 -0
- package/dist/internal/slots.d.ts +10 -0
- package/dist/react/index.d.ts +208 -0
- package/dist/react/index.js +314 -0
- package/dist/react/index.js.map +1 -0
- package/dist/styles.css +13 -0
- package/dist/tokens/README.md +63 -0
- package/dist/tokens/base.css +79 -0
- package/dist/tokens/colors.css +125 -0
- package/dist/tokens/fonts.css +136 -0
- package/dist/tokens/index.css +12 -0
- package/dist/tokens/responsive.css +108 -0
- package/dist/tokens/spacing.css +66 -0
- package/dist/tokens/theme-light.css +144 -0
- package/dist/tokens/typography.css +41 -0
- package/dist/vue/index.d.ts +143 -0
- package/dist/vue/index.js +56 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +296 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { KtElement } from '#internal/kt-element';
|
|
3
|
+
export type KtCardImagePosition = 'left' | 'right' | 'top' | 'bottom';
|
|
4
|
+
/**
|
|
5
|
+
* A surface for a block of related content: 12px radius, a 1px border, 24px of
|
|
6
|
+
* padding and a 20px internal gap.
|
|
7
|
+
*
|
|
8
|
+
* Set `clickable` to turn the whole card into a control. Unlike the div-with-a
|
|
9
|
+
* -click-handler this replaces, a clickable card is reachable by keyboard,
|
|
10
|
+
* announces itself as a button, and responds to Enter and Space.
|
|
11
|
+
*
|
|
12
|
+
* @element kt-card
|
|
13
|
+
*
|
|
14
|
+
* @slot - The card body.
|
|
15
|
+
* @slot header - Above the body.
|
|
16
|
+
* @slot footer - Below the body.
|
|
17
|
+
* @slot media - Replaces the `image` attribute for anything that is not a
|
|
18
|
+
* plain `<img>` — a chart, a map, a video.
|
|
19
|
+
*
|
|
20
|
+
* @csspart base - The card container.
|
|
21
|
+
* @csspart media - The image or media well.
|
|
22
|
+
* @csspart body - The header/content/footer column.
|
|
23
|
+
*
|
|
24
|
+
* @fires kt-card-click - The card was activated, by pointer or keyboard.
|
|
25
|
+
* Only fired when `clickable` is set.
|
|
26
|
+
*/
|
|
27
|
+
export declare class KtCard extends KtElement {
|
|
28
|
+
static styles: import("lit").CSSResultGroup[];
|
|
29
|
+
private hasHeader;
|
|
30
|
+
private hasFooter;
|
|
31
|
+
/** Makes the card a keyboard-reachable control. */
|
|
32
|
+
clickable: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Marks the card as chosen — one of a set of filters, a picked plan.
|
|
35
|
+
*
|
|
36
|
+
* Pairs with `clickable`: a card the user cannot toggle has no business
|
|
37
|
+
* looking toggled.
|
|
38
|
+
*/
|
|
39
|
+
selected: boolean;
|
|
40
|
+
/** Convenience image. For anything richer, use the `media` slot. */
|
|
41
|
+
image: string;
|
|
42
|
+
/** Alternative text for `image`. Empty means decorative. */
|
|
43
|
+
imageAlt: string;
|
|
44
|
+
imagePosition: KtCardImagePosition;
|
|
45
|
+
/** Width (left/right) or height (top/bottom) of the media well. */
|
|
46
|
+
imageSize: string;
|
|
47
|
+
/**
|
|
48
|
+
* The initial `slotchange` is queued as a microtask and can land after the
|
|
49
|
+
* first render has settled, so read the slots once directly as well.
|
|
50
|
+
*/
|
|
51
|
+
firstUpdated(): void;
|
|
52
|
+
private readSlots;
|
|
53
|
+
private onSlotChange;
|
|
54
|
+
private activate;
|
|
55
|
+
private onKeyDown;
|
|
56
|
+
render(): TemplateResult;
|
|
57
|
+
}
|
|
58
|
+
declare global {
|
|
59
|
+
interface HTMLElementTagNameMap {
|
|
60
|
+
'kt-card': KtCard;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { css as f, nothing as r, html as d } from "lit";
|
|
2
|
+
import { state as g, property as a } from "lit/decorators.js";
|
|
3
|
+
import { classMap as n } from "lit/directives/class-map.js";
|
|
4
|
+
import { styleMap as u } from "lit/directives/style-map.js";
|
|
5
|
+
import { K as m, d as v } from "../../../chunks/kt-element-CcMLO5e8.js";
|
|
6
|
+
import { e as b } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
7
|
+
import { h as p } from "../../../chunks/slots-BPbIdxAJ.js";
|
|
8
|
+
var y = Object.defineProperty, i = (s, e, c, k) => {
|
|
9
|
+
for (var o = void 0, l = s.length - 1, h; l >= 0; l--)
|
|
10
|
+
(h = s[l]) && (o = h(e, c, o) || o);
|
|
11
|
+
return o && y(e, c, o), o;
|
|
12
|
+
};
|
|
13
|
+
class t extends m {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments), this.hasHeader = !1, this.hasFooter = !1, this.clickable = !1, this.selected = !1, this.image = "", this.imageAlt = "", this.imagePosition = "left", this.imageSize = "120px";
|
|
16
|
+
}
|
|
17
|
+
static {
|
|
18
|
+
this.styles = [
|
|
19
|
+
m.styles,
|
|
20
|
+
f`
|
|
21
|
+
:host {
|
|
22
|
+
display: block;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* No height on the host: a grid or a flex row stretches it already, and
|
|
26
|
+
forcing 100% made a card in a flex *column* grow to the container
|
|
27
|
+
instead of to its contents. .card fills whatever the host ends up
|
|
28
|
+
being, which is what kept equal-height rows working. */
|
|
29
|
+
|
|
30
|
+
.card {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
height: 100%;
|
|
34
|
+
padding: var(--padding-card);
|
|
35
|
+
gap: var(--gap-card);
|
|
36
|
+
color: var(--text-body);
|
|
37
|
+
background-color: transparent;
|
|
38
|
+
border: var(--border-width) solid var(--border-subtle);
|
|
39
|
+
border-radius: var(--border-radius-card);
|
|
40
|
+
/* Same reason as the fields: an outline-color with nothing to start
|
|
41
|
+
from animates out of the text colour. */
|
|
42
|
+
outline: var(--border-width) solid transparent;
|
|
43
|
+
transition:
|
|
44
|
+
background-color var(--duration-instant),
|
|
45
|
+
border-color var(--duration-instant),
|
|
46
|
+
outline-color var(--duration-instant);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.clickable {
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
}
|
|
52
|
+
.clickable:hover {
|
|
53
|
+
background-color: var(--color-dark-14);
|
|
54
|
+
border-color: var(--color-dark-24);
|
|
55
|
+
outline: var(--border-width) solid var(--color-dark-24);
|
|
56
|
+
}
|
|
57
|
+
.clickable:active {
|
|
58
|
+
background-color: var(--color-dark-15);
|
|
59
|
+
border-color: var(--color-primary-base);
|
|
60
|
+
outline: var(--border-width) solid var(--color-primary-base);
|
|
61
|
+
}
|
|
62
|
+
.clickable:focus-visible {
|
|
63
|
+
outline: var(--outline-width) solid var(--color-primary-base);
|
|
64
|
+
outline-offset: 2px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Selection lives on the inner card, not the host: the radius is here,
|
|
68
|
+
and an outline only follows a radius the same element declares. */
|
|
69
|
+
.selected,
|
|
70
|
+
.selected:hover,
|
|
71
|
+
.selected:active {
|
|
72
|
+
background-color: var(--color-primary-soft);
|
|
73
|
+
border-color: var(--color-primary-base);
|
|
74
|
+
outline: var(--outline-width) solid var(--color-primary-base);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.body {
|
|
78
|
+
display: flex;
|
|
79
|
+
flex: 1;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
gap: var(--gap-card);
|
|
82
|
+
min-width: 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.content {
|
|
86
|
+
flex: 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.media {
|
|
90
|
+
display: flex;
|
|
91
|
+
flex: 0 0 auto;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
overflow: hidden;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* --media-size is set inline from the imageSize property; which axis it
|
|
98
|
+
lands on is the position class's business, not the template's. */
|
|
99
|
+
.image-left .media,
|
|
100
|
+
.image-right .media {
|
|
101
|
+
width: var(--media-size);
|
|
102
|
+
}
|
|
103
|
+
.image-top .media,
|
|
104
|
+
.image-bottom .media {
|
|
105
|
+
height: var(--media-size);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.media ::slotted(*),
|
|
109
|
+
.media img {
|
|
110
|
+
display: block;
|
|
111
|
+
width: 100%;
|
|
112
|
+
height: auto;
|
|
113
|
+
object-fit: cover;
|
|
114
|
+
border-radius: var(--border-radius);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Image position drives the flex direction of the card itself. */
|
|
118
|
+
.image-left {
|
|
119
|
+
flex-direction: row;
|
|
120
|
+
}
|
|
121
|
+
.image-right {
|
|
122
|
+
flex-direction: row-reverse;
|
|
123
|
+
}
|
|
124
|
+
.image-top {
|
|
125
|
+
flex-direction: column;
|
|
126
|
+
}
|
|
127
|
+
.image-bottom {
|
|
128
|
+
flex-direction: column-reverse;
|
|
129
|
+
}
|
|
130
|
+
.image-top .media,
|
|
131
|
+
.image-bottom .media {
|
|
132
|
+
width: 100%;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Collapsed from JS, not from :has(): a wrapper around a <slot> always
|
|
136
|
+
has one element child — the slot — so :has(*) matches even when
|
|
137
|
+
nothing was assigned, and the rule never fired. */
|
|
138
|
+
.header.empty,
|
|
139
|
+
.footer.empty {
|
|
140
|
+
display: none;
|
|
141
|
+
}
|
|
142
|
+
`
|
|
143
|
+
];
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The initial `slotchange` is queued as a microtask and can land after the
|
|
147
|
+
* first render has settled, so read the slots once directly as well.
|
|
148
|
+
*/
|
|
149
|
+
firstUpdated() {
|
|
150
|
+
this.readSlots();
|
|
151
|
+
}
|
|
152
|
+
readSlots() {
|
|
153
|
+
const e = this.shadowRoot;
|
|
154
|
+
this.hasHeader = p(e?.querySelector('slot[name="header"]')), this.hasFooter = p(e?.querySelector('slot[name="footer"]'));
|
|
155
|
+
}
|
|
156
|
+
onSlotChange() {
|
|
157
|
+
this.readSlots();
|
|
158
|
+
}
|
|
159
|
+
activate() {
|
|
160
|
+
this.clickable && b(this, "kt-card-click");
|
|
161
|
+
}
|
|
162
|
+
onKeyDown(e) {
|
|
163
|
+
this.clickable && (e.key !== "Enter" && e.key !== " " || (e.preventDefault(), this.activate()));
|
|
164
|
+
}
|
|
165
|
+
render() {
|
|
166
|
+
const e = !!this.image || this.querySelector('[slot="media"]') !== null;
|
|
167
|
+
return d`<div
|
|
168
|
+
part="base"
|
|
169
|
+
class=${n({
|
|
170
|
+
card: !0,
|
|
171
|
+
clickable: this.clickable,
|
|
172
|
+
selected: this.selected,
|
|
173
|
+
[`image-${this.imagePosition}`]: e
|
|
174
|
+
})}
|
|
175
|
+
role=${this.clickable ? "button" : r}
|
|
176
|
+
aria-pressed=${this.clickable ? String(this.selected) : r}
|
|
177
|
+
tabindex=${this.clickable ? 0 : r}
|
|
178
|
+
@click=${this.activate}
|
|
179
|
+
@keydown=${this.onKeyDown}
|
|
180
|
+
>
|
|
181
|
+
${e ? d`<div
|
|
182
|
+
part="media"
|
|
183
|
+
class="media"
|
|
184
|
+
style=${u({ "--media-size": this.imageSize })}
|
|
185
|
+
>
|
|
186
|
+
<slot name="media">
|
|
187
|
+
${this.image ? d`<img src=${this.image} alt=${this.imageAlt} />` : r}
|
|
188
|
+
</slot>
|
|
189
|
+
</div>` : r}
|
|
190
|
+
<div part="body" class="body">
|
|
191
|
+
<div class=${n({ header: !0, empty: !this.hasHeader })}>
|
|
192
|
+
<slot name="header" @slotchange=${this.onSlotChange}></slot>
|
|
193
|
+
</div>
|
|
194
|
+
<div class="content"><slot></slot></div>
|
|
195
|
+
<div class=${n({ footer: !0, empty: !this.hasFooter })}>
|
|
196
|
+
<slot name="footer" @slotchange=${this.onSlotChange}></slot>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
</div>`;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
i([
|
|
203
|
+
g()
|
|
204
|
+
], t.prototype, "hasHeader");
|
|
205
|
+
i([
|
|
206
|
+
g()
|
|
207
|
+
], t.prototype, "hasFooter");
|
|
208
|
+
i([
|
|
209
|
+
a({ type: Boolean, reflect: !0 })
|
|
210
|
+
], t.prototype, "clickable");
|
|
211
|
+
i([
|
|
212
|
+
a({ type: Boolean, reflect: !0 })
|
|
213
|
+
], t.prototype, "selected");
|
|
214
|
+
i([
|
|
215
|
+
a({ type: String })
|
|
216
|
+
], t.prototype, "image");
|
|
217
|
+
i([
|
|
218
|
+
a({ type: String, attribute: "image-alt" })
|
|
219
|
+
], t.prototype, "imageAlt");
|
|
220
|
+
i([
|
|
221
|
+
a({ type: String, attribute: "image-position" })
|
|
222
|
+
], t.prototype, "imagePosition");
|
|
223
|
+
i([
|
|
224
|
+
a({ type: String, attribute: "image-size" })
|
|
225
|
+
], t.prototype, "imageSize");
|
|
226
|
+
v("kt-card", t);
|
|
227
|
+
export {
|
|
228
|
+
t as KtCard
|
|
229
|
+
};
|
|
230
|
+
//# sourceMappingURL=kt-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kt-card.js","sources":["../../../../src/components/core/kt-card/kt-card.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 { styleMap } from 'lit/directives/style-map.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport { hasAssignedContent } from '#internal/slots';\n\nexport type KtCardImagePosition = 'left' | 'right' | 'top' | 'bottom';\n\n/**\n * A surface for a block of related content: 12px radius, a 1px border, 24px of\n * padding and a 20px internal gap.\n *\n * Set `clickable` to turn the whole card into a control. Unlike the div-with-a\n * -click-handler this replaces, a clickable card is reachable by keyboard,\n * announces itself as a button, and responds to Enter and Space.\n *\n * @element kt-card\n *\n * @slot - The card body.\n * @slot header - Above the body.\n * @slot footer - Below the body.\n * @slot media - Replaces the `image` attribute for anything that is not a\n * plain `<img>` — a chart, a map, a video.\n *\n * @csspart base - The card container.\n * @csspart media - The image or media well.\n * @csspart body - The header/content/footer column.\n *\n * @fires kt-card-click - The card was activated, by pointer or keyboard.\n * Only fired when `clickable` is set.\n */\nexport class KtCard extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n /* No height on the host: a grid or a flex row stretches it already, and\n forcing 100% made a card in a flex *column* grow to the container\n instead of to its contents. .card fills whatever the host ends up\n being, which is what kept equal-height rows working. */\n\n .card {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: var(--padding-card);\n gap: var(--gap-card);\n color: var(--text-body);\n background-color: transparent;\n border: var(--border-width) solid var(--border-subtle);\n border-radius: var(--border-radius-card);\n /* Same reason as the fields: an outline-color with nothing to start\n from animates out of the text colour. */\n outline: var(--border-width) solid transparent;\n transition:\n background-color var(--duration-instant),\n border-color var(--duration-instant),\n outline-color var(--duration-instant);\n }\n\n .clickable {\n cursor: pointer;\n }\n .clickable:hover {\n background-color: var(--color-dark-14);\n border-color: var(--color-dark-24);\n outline: var(--border-width) solid var(--color-dark-24);\n }\n .clickable:active {\n background-color: var(--color-dark-15);\n border-color: var(--color-primary-base);\n outline: var(--border-width) solid var(--color-primary-base);\n }\n .clickable:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 2px;\n }\n\n /* Selection lives on the inner card, not the host: the radius is here,\n and an outline only follows a radius the same element declares. */\n .selected,\n .selected:hover,\n .selected:active {\n background-color: var(--color-primary-soft);\n border-color: var(--color-primary-base);\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n .body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--gap-card);\n min-width: 0;\n }\n\n .content {\n flex: 1;\n }\n\n .media {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n }\n\n /* --media-size is set inline from the imageSize property; which axis it\n lands on is the position class's business, not the template's. */\n .image-left .media,\n .image-right .media {\n width: var(--media-size);\n }\n .image-top .media,\n .image-bottom .media {\n height: var(--media-size);\n }\n\n .media ::slotted(*),\n .media img {\n display: block;\n width: 100%;\n height: auto;\n object-fit: cover;\n border-radius: var(--border-radius);\n }\n\n /* Image position drives the flex direction of the card itself. */\n .image-left {\n flex-direction: row;\n }\n .image-right {\n flex-direction: row-reverse;\n }\n .image-top {\n flex-direction: column;\n }\n .image-bottom {\n flex-direction: column-reverse;\n }\n .image-top .media,\n .image-bottom .media {\n width: 100%;\n }\n\n /* Collapsed from JS, not from :has(): a wrapper around a <slot> always\n has one element child — the slot — so :has(*) matches even when\n nothing was assigned, and the rule never fired. */\n .header.empty,\n .footer.empty {\n display: none;\n }\n `,\n ];\n\n @state()\n private hasHeader = false;\n\n @state()\n private hasFooter = false;\n\n /** Makes the card a keyboard-reachable control. */\n @property({ type: Boolean, reflect: true })\n clickable = false;\n\n /**\n * Marks the card as chosen — one of a set of filters, a picked plan.\n *\n * Pairs with `clickable`: a card the user cannot toggle has no business\n * looking toggled.\n */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n /** Convenience image. For anything richer, use the `media` slot. */\n @property({ type: String })\n image = '';\n\n /** Alternative text for `image`. Empty means decorative. */\n @property({ type: String, attribute: 'image-alt' })\n imageAlt = '';\n\n @property({ type: String, attribute: 'image-position' })\n imagePosition: KtCardImagePosition = 'left';\n\n /** Width (left/right) or height (top/bottom) of the media well. */\n @property({ type: String, attribute: 'image-size' })\n imageSize = '120px';\n\n /**\n * The initial `slotchange` is queued as a microtask and can land after the\n * first render has settled, so read the slots once directly as well.\n */\n override firstUpdated(): void {\n this.readSlots();\n }\n\n private readSlots(): void {\n const root = this.shadowRoot;\n this.hasHeader = hasAssignedContent(root?.querySelector('slot[name=\"header\"]'));\n this.hasFooter = hasAssignedContent(root?.querySelector('slot[name=\"footer\"]'));\n }\n\n private onSlotChange(): void {\n this.readSlots();\n }\n\n private activate(): void {\n if (this.clickable) emit(this, 'kt-card-click');\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n if (!this.clickable) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n // Space scrolls the page unless we claim it.\n event.preventDefault();\n this.activate();\n }\n\n override render(): TemplateResult {\n const hasMedia = Boolean(this.image) || this.querySelector('[slot=\"media\"]') !== null;\n\n return html`<div\n part=\"base\"\n class=${classMap({\n card: true,\n clickable: this.clickable,\n selected: this.selected,\n [`image-${this.imagePosition}`]: hasMedia,\n })}\n role=${this.clickable ? 'button' : nothing}\n aria-pressed=${this.clickable ? String(this.selected) : nothing}\n tabindex=${this.clickable ? 0 : nothing}\n @click=${this.activate}\n @keydown=${this.onKeyDown}\n >\n ${\n hasMedia\n ? html`<div\n part=\"media\"\n class=\"media\"\n style=${styleMap({ '--media-size': this.imageSize })}\n >\n <slot name=\"media\">\n ${this.image ? html`<img src=${this.image} alt=${this.imageAlt} />` : nothing}\n </slot>\n </div>`\n : nothing\n }\n <div part=\"body\" class=\"body\">\n <div class=${classMap({ header: true, empty: !this.hasHeader })}>\n <slot name=\"header\" @slotchange=${this.onSlotChange}></slot>\n </div>\n <div class=\"content\"><slot></slot></div>\n <div class=${classMap({ footer: true, empty: !this.hasFooter })}>\n <slot name=\"footer\" @slotchange=${this.onSlotChange}></slot>\n </div>\n </div>\n </div>`;\n }\n}\n\ndefineElement('kt-card', KtCard);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-card': KtCard;\n }\n}\n"],"names":["KtCard","KtElement","css","root","hasAssignedContent","emit","event","hasMedia","html","classMap","nothing","styleMap","__decorateClass","state","property","defineElement"],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { KtElement } from '#internal/kt-element';
|
|
3
|
+
import '../kt-icon/kt-icon.js';
|
|
4
|
+
/**
|
|
5
|
+
* A block of code on a recessed surface, with its language and a copy button.
|
|
6
|
+
*
|
|
7
|
+
* The element owns the chrome — surface, label, scrolling, copy — and nothing
|
|
8
|
+
* else. **Highlighting is the caller's**: slot in whatever markup a highlighter
|
|
9
|
+
* produced, or plain text for none. A design system that bundled a syntax
|
|
10
|
+
* highlighter would be picking your bundle size and your language set for you.
|
|
11
|
+
*
|
|
12
|
+
* ```html
|
|
13
|
+
* <kt-code language="js">const total = items.length;</kt-code>
|
|
14
|
+
*
|
|
15
|
+
* <kt-code language="ts" copy>
|
|
16
|
+
* <span class="hljs-keyword">const</span> total = items.length;
|
|
17
|
+
* </kt-code>
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* For a token or an identifier inside a sentence, reach for
|
|
21
|
+
* `<kt-badge variant="code">` instead — this is for blocks.
|
|
22
|
+
*
|
|
23
|
+
* @element kt-code
|
|
24
|
+
*
|
|
25
|
+
* @slot - The code. Plain text, or a highlighter's markup.
|
|
26
|
+
*
|
|
27
|
+
* @csspart base - The container.
|
|
28
|
+
* @csspart header - The language row.
|
|
29
|
+
* @csspart pre - The scrolling `<pre>`.
|
|
30
|
+
*
|
|
31
|
+
* @fires kt-copy - The copy button was pressed. `detail: { code }`.
|
|
32
|
+
*/
|
|
33
|
+
export declare class KtCode extends KtElement {
|
|
34
|
+
static styles: import("lit").CSSResultGroup[];
|
|
35
|
+
/** How long the copy button stays in its confirmed state. */
|
|
36
|
+
private static readonly COPIED_MS;
|
|
37
|
+
private copiedTimer;
|
|
38
|
+
private copied;
|
|
39
|
+
/** Language label, shown uppercase. Purely informative. */
|
|
40
|
+
language: string;
|
|
41
|
+
/** Shows the copy button. */
|
|
42
|
+
copy: boolean;
|
|
43
|
+
/** Accessible name for the block, when the language alone is not enough. */
|
|
44
|
+
label: string;
|
|
45
|
+
disconnectedCallback(): void;
|
|
46
|
+
/** The code as plain text, whatever markup it is wrapped in. */
|
|
47
|
+
get code(): string;
|
|
48
|
+
private copyToClipboard;
|
|
49
|
+
render(): TemplateResult;
|
|
50
|
+
}
|
|
51
|
+
declare global {
|
|
52
|
+
interface HTMLElementTagNameMap {
|
|
53
|
+
'kt-code': KtCode;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { css as b, nothing as i, html as s } from "lit";
|
|
2
|
+
import { state as u, property as d } from "lit/decorators.js";
|
|
3
|
+
import { K as l, d as v } from "../../../chunks/kt-element-CcMLO5e8.js";
|
|
4
|
+
import { e as g } from "../../../chunks/events-Bjl5Zmmq.js";
|
|
5
|
+
import "../kt-icon/kt-icon.js";
|
|
6
|
+
var y = Object.defineProperty, r = (c, o, p, f) => {
|
|
7
|
+
for (var e = void 0, a = c.length - 1, n; a >= 0; a--)
|
|
8
|
+
(n = c[a]) && (e = n(o, p, e) || e);
|
|
9
|
+
return e && y(o, p, e), e;
|
|
10
|
+
};
|
|
11
|
+
const t = class h extends l {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments), this.copied = !1, this.language = "", this.copy = !1, this.label = "";
|
|
14
|
+
}
|
|
15
|
+
static {
|
|
16
|
+
this.styles = [
|
|
17
|
+
l.styles,
|
|
18
|
+
b`
|
|
19
|
+
:host {
|
|
20
|
+
display: block;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.base {
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
background: var(--surface-code);
|
|
26
|
+
border: var(--border-width) solid var(--border-code);
|
|
27
|
+
border-radius: var(--border-radius);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.header {
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: space-between;
|
|
34
|
+
gap: var(--gap-button);
|
|
35
|
+
padding: 6px 8px 6px 14px;
|
|
36
|
+
border-bottom: var(--border-width) solid var(--border-code);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.language {
|
|
40
|
+
color: var(--color-text-500);
|
|
41
|
+
font: var(--font-normal-small);
|
|
42
|
+
letter-spacing: 1px;
|
|
43
|
+
text-transform: uppercase;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.copy {
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
gap: 6px;
|
|
50
|
+
padding: 4px 8px;
|
|
51
|
+
color: var(--text-muted);
|
|
52
|
+
font: var(--font-normal-small);
|
|
53
|
+
background: transparent;
|
|
54
|
+
border: none;
|
|
55
|
+
border-radius: 5px;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
transition:
|
|
58
|
+
color var(--duration-instant),
|
|
59
|
+
background-color var(--duration-instant);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.copy:hover {
|
|
63
|
+
color: var(--text-body);
|
|
64
|
+
background: var(--surface-raised);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.copy:focus-visible {
|
|
68
|
+
outline: var(--outline-width) solid var(--color-primary-base);
|
|
69
|
+
outline-offset: 1px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.copied {
|
|
73
|
+
color: var(--color-success-base);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
pre {
|
|
77
|
+
margin: 0;
|
|
78
|
+
padding: 14px;
|
|
79
|
+
overflow-x: auto;
|
|
80
|
+
scrollbar-width: thin;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
code {
|
|
84
|
+
font: var(--font-code-regular);
|
|
85
|
+
color: var(--text-code);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* A block with no header should not leave a stray rule behind. */
|
|
89
|
+
.bare pre {
|
|
90
|
+
padding-top: 14px;
|
|
91
|
+
}
|
|
92
|
+
`
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
static {
|
|
96
|
+
this.COPIED_MS = 1600;
|
|
97
|
+
}
|
|
98
|
+
disconnectedCallback() {
|
|
99
|
+
super.disconnectedCallback(), this.copiedTimer !== void 0 && clearTimeout(this.copiedTimer);
|
|
100
|
+
}
|
|
101
|
+
/** The code as plain text, whatever markup it is wrapped in. */
|
|
102
|
+
get code() {
|
|
103
|
+
return (this.textContent ?? "").replace(/^\n+|\n+$/g, "");
|
|
104
|
+
}
|
|
105
|
+
async copyToClipboard() {
|
|
106
|
+
try {
|
|
107
|
+
await navigator.clipboard.writeText(this.code), this.copied = !0, this.copiedTimer !== void 0 && clearTimeout(this.copiedTimer), this.copiedTimer = setTimeout(() => {
|
|
108
|
+
this.copied = !1;
|
|
109
|
+
}, h.COPIED_MS);
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
112
|
+
g(this, "kt-copy", { code: this.code });
|
|
113
|
+
}
|
|
114
|
+
render() {
|
|
115
|
+
const o = !!this.language || this.copy;
|
|
116
|
+
return s`<div part="base" class=${o ? "base" : "base bare"}>
|
|
117
|
+
${o ? s`<div part="header" class="header">
|
|
118
|
+
<span class="language">${this.language}</span>
|
|
119
|
+
${this.copy ? s`<button
|
|
120
|
+
type="button"
|
|
121
|
+
class=${this.copied ? "copy copied" : "copy"}
|
|
122
|
+
aria-label=${this.copied ? "Copied" : "Copy code"}
|
|
123
|
+
@click=${this.copyToClipboard}
|
|
124
|
+
>
|
|
125
|
+
<kt-icon name=${this.copied ? "check" : "copy"} size="14"></kt-icon>
|
|
126
|
+
${this.copied ? "Copied" : "Copy"}
|
|
127
|
+
</button>` : i}
|
|
128
|
+
</div>` : i}
|
|
129
|
+
|
|
130
|
+
<pre
|
|
131
|
+
part="pre"
|
|
132
|
+
tabindex="0"
|
|
133
|
+
aria-label=${this.label || i}
|
|
134
|
+
><code><slot></slot></code></pre>
|
|
135
|
+
</div>`;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
r([
|
|
139
|
+
u()
|
|
140
|
+
], t.prototype, "copied");
|
|
141
|
+
r([
|
|
142
|
+
d({ type: String })
|
|
143
|
+
], t.prototype, "language");
|
|
144
|
+
r([
|
|
145
|
+
d({ type: Boolean })
|
|
146
|
+
], t.prototype, "copy");
|
|
147
|
+
r([
|
|
148
|
+
d({ type: String })
|
|
149
|
+
], t.prototype, "label");
|
|
150
|
+
let m = t;
|
|
151
|
+
v("kt-code", m);
|
|
152
|
+
export {
|
|
153
|
+
m as KtCode
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=kt-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kt-code.js","sources":["../../../../src/components/core/kt-code/kt-code.ts"],"sourcesContent":["import { css, html, nothing, type TemplateResult } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { KtElement, defineElement } from '#internal/kt-element';\nimport { emit } from '#internal/events';\nimport '../kt-icon/kt-icon.js';\n\n/**\n * A block of code on a recessed surface, with its language and a copy button.\n *\n * The element owns the chrome — surface, label, scrolling, copy — and nothing\n * else. **Highlighting is the caller's**: slot in whatever markup a highlighter\n * produced, or plain text for none. A design system that bundled a syntax\n * highlighter would be picking your bundle size and your language set for you.\n *\n * ```html\n * <kt-code language=\"js\">const total = items.length;</kt-code>\n *\n * <kt-code language=\"ts\" copy>\n * <span class=\"hljs-keyword\">const</span> total = items.length;\n * </kt-code>\n * ```\n *\n * For a token or an identifier inside a sentence, reach for\n * `<kt-badge variant=\"code\">` instead — this is for blocks.\n *\n * @element kt-code\n *\n * @slot - The code. Plain text, or a highlighter's markup.\n *\n * @csspart base - The container.\n * @csspart header - The language row.\n * @csspart pre - The scrolling `<pre>`.\n *\n * @fires kt-copy - The copy button was pressed. `detail: { code }`.\n */\nexport class KtCode extends KtElement {\n static override styles = [\n KtElement.styles,\n css`\n :host {\n display: block;\n }\n\n .base {\n overflow: hidden;\n background: var(--surface-code);\n border: var(--border-width) solid var(--border-code);\n border-radius: var(--border-radius);\n }\n\n .header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--gap-button);\n padding: 6px 8px 6px 14px;\n border-bottom: var(--border-width) solid var(--border-code);\n }\n\n .language {\n color: var(--color-text-500);\n font: var(--font-normal-small);\n letter-spacing: 1px;\n text-transform: uppercase;\n }\n\n .copy {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n color: var(--text-muted);\n font: var(--font-normal-small);\n background: transparent;\n border: none;\n border-radius: 5px;\n cursor: pointer;\n transition:\n color var(--duration-instant),\n background-color var(--duration-instant);\n }\n\n .copy:hover {\n color: var(--text-body);\n background: var(--surface-raised);\n }\n\n .copy:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n outline-offset: 1px;\n }\n\n .copied {\n color: var(--color-success-base);\n }\n\n pre {\n margin: 0;\n padding: 14px;\n overflow-x: auto;\n scrollbar-width: thin;\n }\n\n code {\n font: var(--font-code-regular);\n color: var(--text-code);\n }\n\n /* A block with no header should not leave a stray rule behind. */\n .bare pre {\n padding-top: 14px;\n }\n `,\n ];\n\n /** How long the copy button stays in its confirmed state. */\n private static readonly COPIED_MS = 1600;\n\n private copiedTimer: ReturnType<typeof setTimeout> | undefined;\n\n @state()\n private copied = false;\n\n /** Language label, shown uppercase. Purely informative. */\n @property({ type: String })\n language = '';\n\n /** Shows the copy button. */\n @property({ type: Boolean })\n copy = false;\n\n /** Accessible name for the block, when the language alone is not enough. */\n @property({ type: String })\n label = '';\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.copiedTimer !== undefined) clearTimeout(this.copiedTimer);\n }\n\n /** The code as plain text, whatever markup it is wrapped in. */\n get code(): string {\n return (this.textContent ?? '').replace(/^\\n+|\\n+$/g, '');\n }\n\n private async copyToClipboard(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.code);\n this.copied = true;\n\n if (this.copiedTimer !== undefined) clearTimeout(this.copiedTimer);\n this.copiedTimer = setTimeout(() => {\n this.copied = false;\n }, KtCode.COPIED_MS);\n } catch {\n // Denied permission, or an insecure origin. Nothing useful to show, and\n // failing loudly over a convenience button helps no one.\n }\n emit(this, 'kt-copy', { code: this.code });\n }\n\n override render(): TemplateResult {\n const hasHeader = Boolean(this.language) || this.copy;\n\n return html`<div part=\"base\" class=${hasHeader ? 'base' : 'base bare'}>\n ${\n hasHeader\n ? html`<div part=\"header\" class=\"header\">\n <span class=\"language\">${this.language}</span>\n ${\n this.copy\n ? html`<button\n type=\"button\"\n class=${this.copied ? 'copy copied' : 'copy'}\n aria-label=${this.copied ? 'Copied' : 'Copy code'}\n @click=${this.copyToClipboard}\n >\n <kt-icon name=${this.copied ? 'check' : 'copy'} size=\"14\"></kt-icon>\n ${this.copied ? 'Copied' : 'Copy'}\n </button>`\n : nothing\n }\n </div>`\n : nothing\n }\n\n <pre\n part=\"pre\"\n tabindex=\"0\"\n aria-label=${this.label || nothing}\n ><code><slot></slot></code></pre>\n </div>`;\n }\n}\n\ndefineElement('kt-code', KtCode);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-code': KtCode;\n }\n}\n"],"names":["_KtCode","KtElement","css","emit","hasHeader","html","nothing","__decorateClass","state","property","KtCode","defineElement"],"mappings":";;;;;;;;;;AAmCO,MAAMA,IAAN,MAAMA,UAAeC,EAAU;AAAA,EAA/B,cAAA;AAAA,UAAA,GAAA,SAAA,GAsFL,KAAQ,SAAS,IAIjB,KAAA,WAAW,IAIX,KAAA,OAAO,IAIP,KAAA,QAAQ;AAAA,EAAA;AAAA,EAjGR,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,IAAA;AAAA,EA2EF;AAAA,EAGA,OAAA;AAAA,SAAwB,YAAY;AAAA,EAAA;AAAA,EAmB3B,uBAA6B;AACpC,UAAM,qBAAA,GACF,KAAK,gBAAgB,UAAW,aAAa,KAAK,WAAW;AAAA,EACnE;AAAA;AAAA,EAGA,IAAI,OAAe;AACjB,YAAQ,KAAK,eAAe,IAAI,QAAQ,cAAc,EAAE;AAAA,EAC1D;AAAA,EAEA,MAAc,kBAAiC;AAC7C,QAAI;AACF,YAAM,UAAU,UAAU,UAAU,KAAK,IAAI,GAC7C,KAAK,SAAS,IAEV,KAAK,gBAAgB,UAAW,aAAa,KAAK,WAAW,GACjE,KAAK,cAAc,WAAW,MAAM;AAClC,aAAK,SAAS;AAAA,MAChB,GAAGF,EAAO,SAAS;AAAA,IACrB,QAAQ;AAAA,IAGR;AACA,IAAAG,EAAK,MAAM,WAAW,EAAE,MAAM,KAAK,MAAM;AAAA,EAC3C;AAAA,EAES,SAAyB;AAChC,UAAMC,IAAY,EAAQ,KAAK,YAAa,KAAK;AAEjD,WAAOC,2BAA8BD,IAAY,SAAS,WAAW;AAAA,QAEjEA,IACIC;AAAA,uCAC2B,KAAK,QAAQ;AAAA,gBAEpC,KAAK,OACDA;AAAA;AAAA,8BAEU,KAAK,SAAS,gBAAgB,MAAM;AAAA,mCAC/B,KAAK,SAAS,WAAW,WAAW;AAAA,+BACxC,KAAK,eAAe;AAAA;AAAA,sCAEb,KAAK,SAAS,UAAU,MAAM;AAAA,wBAC5C,KAAK,SAAS,WAAW,MAAM;AAAA,iCAEnCC,CACN;AAAA,sBAEFA,CACN;AAAA;AAAA;AAAA;AAAA;AAAA,qBAKe,KAAK,SAASA,CAAO;AAAA;AAAA;AAAA,EAGxC;AACF;AAxEUC,EAAA;AAAA,EADPC,EAAA;AAAM,GArFIR,EAsFH,WAAA,QAAA;AAIRO,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAzFfT,EA0FX,WAAA,UAAA;AAIAO,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GA7FhBT,EA8FX,WAAA,MAAA;AAIAO,EAAA;AAAA,EADCE,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAjGfT,EAkGX,WAAA,OAAA;AAlGK,IAAMU,IAANV;AAgKPW,EAAc,WAAWD,CAAM;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { nothing, type TemplateResult } from 'lit';
|
|
2
|
+
import { KtElement } from '#internal/kt-element';
|
|
3
|
+
import '../../../icons/defaults.js';
|
|
4
|
+
/**
|
|
5
|
+
* A Lucide icon, resolved from the registry by name.
|
|
6
|
+
*
|
|
7
|
+
* The icon inherits `currentColor`, so it is coloured by setting `color` on
|
|
8
|
+
* the element or on any ancestor — there is no colour attribute to keep in
|
|
9
|
+
* sync with the surrounding text.
|
|
10
|
+
*
|
|
11
|
+
* Unknown names render nothing but still occupy their box, so a typo shifts no
|
|
12
|
+
* layout while you find it in the console.
|
|
13
|
+
*
|
|
14
|
+
* @element kt-icon
|
|
15
|
+
*
|
|
16
|
+
* @csspart svg - The `<svg>` root.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```html
|
|
20
|
+
* <kt-icon name="search"></kt-icon>
|
|
21
|
+
* <kt-icon name="trash-2" size="16" label="Delete"></kt-icon>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class KtIcon extends KtElement {
|
|
25
|
+
static styles: import("lit").CSSResultGroup[];
|
|
26
|
+
/** Icon name, kebab-case: `chevron-down`, `circle-alert`. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Width and height in pixels. */
|
|
29
|
+
size: number;
|
|
30
|
+
/** Stroke width passed to the SVG. */
|
|
31
|
+
strokeWidth: number;
|
|
32
|
+
/**
|
|
33
|
+
* Accessible name. Set it when the icon carries meaning on its own; leave it
|
|
34
|
+
* off — the default — when adjacent text already says what this is, and the
|
|
35
|
+
* icon is hidden from assistive technology.
|
|
36
|
+
*/
|
|
37
|
+
label: string;
|
|
38
|
+
render(): TemplateResult | typeof nothing;
|
|
39
|
+
}
|
|
40
|
+
declare global {
|
|
41
|
+
interface HTMLElementTagNameMap {
|
|
42
|
+
'kt-icon': KtIcon;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { css as f, html as c, nothing as l } from "lit";
|
|
2
|
+
import { property as n } from "lit/decorators.js";
|
|
3
|
+
import { K as m, d as u } from "../../../chunks/kt-element-CcMLO5e8.js";
|
|
4
|
+
import { g as v } from "../../../chunks/registry-X4LS9J5K.js";
|
|
5
|
+
var w = Object.defineProperty, o = (i, e, r, h) => {
|
|
6
|
+
for (var t = void 0, a = i.length - 1, d; a >= 0; a--)
|
|
7
|
+
(d = i[a]) && (t = d(e, r, t) || t);
|
|
8
|
+
return t && w(e, r, t), t;
|
|
9
|
+
};
|
|
10
|
+
const g = "http://www.w3.org/2000/svg", p = /* @__PURE__ */ new Set();
|
|
11
|
+
function y([i, e]) {
|
|
12
|
+
const r = document.createElementNS(g, i);
|
|
13
|
+
for (const [h, t] of Object.entries(e))
|
|
14
|
+
t !== void 0 && r.setAttribute(h, String(t));
|
|
15
|
+
return r;
|
|
16
|
+
}
|
|
17
|
+
class s extends m {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments), this.name = "", this.size = 24, this.strokeWidth = 2, this.label = "";
|
|
20
|
+
}
|
|
21
|
+
static {
|
|
22
|
+
this.styles = [
|
|
23
|
+
m.styles,
|
|
24
|
+
f`
|
|
25
|
+
:host {
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
flex: none;
|
|
30
|
+
vertical-align: middle;
|
|
31
|
+
color: inherit;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
svg {
|
|
35
|
+
display: block;
|
|
36
|
+
}
|
|
37
|
+
`
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
render() {
|
|
41
|
+
const e = v(this.name);
|
|
42
|
+
return e ? c`<svg
|
|
43
|
+
part="svg"
|
|
44
|
+
xmlns=${g}
|
|
45
|
+
width=${this.size}
|
|
46
|
+
height=${this.size}
|
|
47
|
+
viewBox="0 0 24 24"
|
|
48
|
+
fill="none"
|
|
49
|
+
stroke="currentColor"
|
|
50
|
+
stroke-width=${this.strokeWidth}
|
|
51
|
+
stroke-linecap="round"
|
|
52
|
+
stroke-linejoin="round"
|
|
53
|
+
role=${this.label ? "img" : l}
|
|
54
|
+
aria-label=${this.label || l}
|
|
55
|
+
aria-hidden=${this.label ? l : "true"}
|
|
56
|
+
>
|
|
57
|
+
${e.map(y)}
|
|
58
|
+
</svg>` : (this.name && !p.has(this.name) && (p.add(this.name), console.warn(
|
|
59
|
+
`<kt-icon>: no icon registered as "${this.name}". Register it with registerIcons({ ... }) from "kanto-ds/icons".`
|
|
60
|
+
)), c`<svg
|
|
61
|
+
part="svg"
|
|
62
|
+
width=${this.size}
|
|
63
|
+
height=${this.size}
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
aria-hidden="true"
|
|
66
|
+
></svg>`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
o([
|
|
70
|
+
n({ type: String, reflect: !0 })
|
|
71
|
+
], s.prototype, "name");
|
|
72
|
+
o([
|
|
73
|
+
n({ type: Number, reflect: !0 })
|
|
74
|
+
], s.prototype, "size");
|
|
75
|
+
o([
|
|
76
|
+
n({ type: Number, attribute: "stroke-width" })
|
|
77
|
+
], s.prototype, "strokeWidth");
|
|
78
|
+
o([
|
|
79
|
+
n({ type: String })
|
|
80
|
+
], s.prototype, "label");
|
|
81
|
+
u("kt-icon", s);
|
|
82
|
+
export {
|
|
83
|
+
s as KtIcon
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=kt-icon.js.map
|