@sankhyatronics/sankhya-cms 0.1.10 → 0.1.12

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.
@@ -0,0 +1,93 @@
1
+ import {
2
+ fontFamilyStyles
3
+ } from "./chunk-KMU6ABQF.js";
4
+ import {
5
+ __decorateClass
6
+ } from "./chunk-EUXUH3YW.js";
7
+
8
+ // src/chip/Chip.ts
9
+ import { LitElement, css, html } from "lit";
10
+ import { customElement, property } from "lit/decorators.js";
11
+ var Chip = class extends LitElement {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.tone = "neutral";
15
+ this.size = "md";
16
+ this.dot = false;
17
+ }
18
+ render() {
19
+ return html`<span class="dot" part="dot" aria-hidden="true"></span><slot></slot>`;
20
+ }
21
+ };
22
+ Chip.styles = css`
23
+ ${fontFamilyStyles}
24
+
25
+ :host {
26
+ display: inline-flex;
27
+ align-items: center;
28
+ gap: var(--st-space-6);
29
+ padding: var(--st-space-2) var(--st-space-10);
30
+ border-radius: var(--st-radius-full);
31
+ font-size: var(--st-text-sm);
32
+ font-weight: var(--st-font-weight-medium);
33
+ line-height: 1.4;
34
+ white-space: nowrap;
35
+ background: var(--st-color-subtle);
36
+ color: var(--st-color-text-secondary);
37
+ font-variant-numeric: tabular-nums;
38
+ }
39
+
40
+ :host([size='sm']) {
41
+ padding: 0 var(--st-space-8);
42
+ font-size: var(--st-text-xs);
43
+ }
44
+
45
+ :host([tone='accent']) {
46
+ background: var(--st-color-accent-subtle);
47
+ color: var(--st-color-accent-text);
48
+ }
49
+
50
+ :host([tone='success']) {
51
+ background: var(--st-color-success-subtle);
52
+ color: var(--st-color-success-text);
53
+ }
54
+
55
+ :host([tone='warning']) {
56
+ background: var(--st-color-warning-subtle);
57
+ color: var(--st-color-warning-text);
58
+ }
59
+
60
+ :host([tone='danger']) {
61
+ background: var(--st-color-danger-subtle);
62
+ color: var(--st-color-danger-text);
63
+ }
64
+
65
+ .dot {
66
+ width: 6px;
67
+ height: 6px;
68
+ border-radius: var(--st-radius-circle);
69
+ background: currentColor;
70
+ flex: none;
71
+ }
72
+
73
+ :host(:not([dot])) .dot {
74
+ display: none;
75
+ }
76
+ `;
77
+ __decorateClass([
78
+ property({ type: String, reflect: true })
79
+ ], Chip.prototype, "tone", 2);
80
+ __decorateClass([
81
+ property({ type: String, reflect: true })
82
+ ], Chip.prototype, "size", 2);
83
+ __decorateClass([
84
+ property({ type: Boolean, reflect: true })
85
+ ], Chip.prototype, "dot", 2);
86
+ Chip = __decorateClass([
87
+ customElement("st-chip")
88
+ ], Chip);
89
+
90
+ export {
91
+ Chip
92
+ };
93
+ //# sourceMappingURL=chunk-LGGLQNSU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chip/Chip.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { fontFamilyStyles } from '../shared/styles';\n\n/**\n * A small rounded status pill: text in the default slot, with an optional leading dot. Tones map\n * to the theme's status tokens (soft background, text colour on that background), so a chip reads\n * the same in every theme. Use `neutral` for plain labels, `accent` for the brand tint, and the\n * status tones for meaning only (success = done, warning = due soon, danger = overdue).\n */\n@customElement('st-chip')\nexport class Chip extends LitElement {\n static styles = css`\n ${fontFamilyStyles}\n\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--st-space-6);\n padding: var(--st-space-2) var(--st-space-10);\n border-radius: var(--st-radius-full);\n font-size: var(--st-text-sm);\n font-weight: var(--st-font-weight-medium);\n line-height: 1.4;\n white-space: nowrap;\n background: var(--st-color-subtle);\n color: var(--st-color-text-secondary);\n font-variant-numeric: tabular-nums;\n }\n\n :host([size='sm']) {\n padding: 0 var(--st-space-8);\n font-size: var(--st-text-xs);\n }\n\n :host([tone='accent']) {\n background: var(--st-color-accent-subtle);\n color: var(--st-color-accent-text);\n }\n\n :host([tone='success']) {\n background: var(--st-color-success-subtle);\n color: var(--st-color-success-text);\n }\n\n :host([tone='warning']) {\n background: var(--st-color-warning-subtle);\n color: var(--st-color-warning-text);\n }\n\n :host([tone='danger']) {\n background: var(--st-color-danger-subtle);\n color: var(--st-color-danger-text);\n }\n\n .dot {\n width: 6px;\n height: 6px;\n border-radius: var(--st-radius-circle);\n background: currentColor;\n flex: none;\n }\n\n :host(:not([dot])) .dot {\n display: none;\n }\n `;\n\n /** Colour treatment: a soft tint of the matching theme token. */\n @property({ type: String, reflect: true })\n tone: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' = 'neutral';\n\n /** `sm` for dense lists and table cells. */\n @property({ type: String, reflect: true })\n size: 'md' | 'sm' = 'md';\n\n /** Shows a leading dot in the chip's text colour. */\n @property({ type: Boolean, reflect: true })\n dot = false;\n\n render() {\n return html`<span class=\"dot\" part=\"dot\" aria-hidden=\"true\"></span><slot></slot>`;\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AAWjC,IAAM,OAAN,cAAmB,WAAW;AAAA,EAA9B;AAAA;AA2DL,gBAAgE;AAIhE,gBAAoB;AAIpB,eAAM;AAAA;AAAA,EAEN,SAAS;AACP,WAAO;AAAA,EACT;AACF;AAxEa,KACJ,SAAS;AAAA,MACZ,gBAAgB;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;AAyDpB;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA1D9B,KA2DX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA9D9B,KA+DX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlE/B,KAmEX;AAnEW,OAAN;AAAA,EADN,cAAc,SAAS;AAAA,GACX;","names":[]}
@@ -0,0 +1,122 @@
1
+ import {
2
+ fontFamilyStyles
3
+ } from "./chunk-KMU6ABQF.js";
4
+ import {
5
+ __decorateClass
6
+ } from "./chunk-EUXUH3YW.js";
7
+
8
+ // src/segmented-control/SegmentedControl.ts
9
+ import { LitElement, css, html, nothing } from "lit";
10
+ import { customElement, property } from "lit/decorators.js";
11
+ var SegmentedControl = class extends LitElement {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.options = [];
15
+ this.value = "";
16
+ this.groupLabel = "";
17
+ }
18
+ select(next) {
19
+ if (next === this.value) return;
20
+ this.value = next;
21
+ this.dispatchEvent(
22
+ new CustomEvent("segment-change", {
23
+ detail: { value: next },
24
+ bubbles: true,
25
+ composed: true
26
+ })
27
+ );
28
+ }
29
+ onKeydown(event) {
30
+ const enabled = this.options;
31
+ if (!enabled.length) return;
32
+ const index = enabled.findIndex((option) => option.value === this.value);
33
+ let next = null;
34
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") next = (index + 1) % enabled.length;
35
+ if (event.key === "ArrowLeft" || event.key === "ArrowUp") next = (index - 1 + enabled.length) % enabled.length;
36
+ if (event.key === "Home") next = 0;
37
+ if (event.key === "End") next = enabled.length - 1;
38
+ if (next === null) return;
39
+ event.preventDefault();
40
+ this.select(enabled[next].value);
41
+ this.renderRoot.querySelector(`button[data-value="${enabled[next].value}"]`)?.focus();
42
+ }
43
+ render() {
44
+ return html`<div class="track" role="radiogroup" aria-label=${this.groupLabel || nothing} @keydown=${this.onKeydown}>
45
+ ${this.options.map(
46
+ (option) => html`<button
47
+ type="button"
48
+ role="radio"
49
+ data-value=${option.value}
50
+ aria-checked=${option.value === this.value ? "true" : "false"}
51
+ tabindex=${option.value === this.value ? 0 : -1}
52
+ @click=${() => this.select(option.value)}
53
+ >${option.label}</button>`
54
+ )}
55
+ </div>`;
56
+ }
57
+ };
58
+ SegmentedControl.styles = css`
59
+ ${fontFamilyStyles}
60
+
61
+ :host {
62
+ display: inline-flex;
63
+ max-width: 100%;
64
+ }
65
+
66
+ .track {
67
+ display: flex;
68
+ gap: var(--st-space-2);
69
+ padding: var(--st-space-3);
70
+ border-radius: var(--st-radius-md);
71
+ background: var(--st-color-subtle);
72
+ max-width: 100%;
73
+ }
74
+
75
+ button {
76
+ appearance: none;
77
+ border: 0;
78
+ border-radius: var(--st-radius-sm);
79
+ padding: var(--st-space-6) var(--st-space-14);
80
+ background: transparent;
81
+ color: var(--st-color-text-secondary);
82
+ font: inherit;
83
+ font-size: var(--st-text-base);
84
+ font-weight: var(--st-font-weight-medium);
85
+ white-space: nowrap;
86
+ cursor: pointer;
87
+ }
88
+
89
+ button[aria-checked='true'] {
90
+ background: var(--st-color-surface);
91
+ color: var(--st-color-text-strong);
92
+ font-weight: var(--st-font-weight-semibold);
93
+ box-shadow: 0 1px 2px rgba(20, 23, 31, 0.08);
94
+ }
95
+
96
+ button:focus-visible {
97
+ outline: 2px solid var(--st-color-accent);
98
+ outline-offset: 1px;
99
+ }
100
+
101
+ button:disabled {
102
+ opacity: 0.5;
103
+ cursor: not-allowed;
104
+ }
105
+ `;
106
+ __decorateClass([
107
+ property({ attribute: false })
108
+ ], SegmentedControl.prototype, "options", 2);
109
+ __decorateClass([
110
+ property({ type: String, reflect: true })
111
+ ], SegmentedControl.prototype, "value", 2);
112
+ __decorateClass([
113
+ property({ type: String, attribute: "group-label" })
114
+ ], SegmentedControl.prototype, "groupLabel", 2);
115
+ SegmentedControl = __decorateClass([
116
+ customElement("st-segmented-control")
117
+ ], SegmentedControl);
118
+
119
+ export {
120
+ SegmentedControl
121
+ };
122
+ //# sourceMappingURL=chunk-MG2VTZA4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/segmented-control/SegmentedControl.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { fontFamilyStyles } from '../shared/styles';\n\nexport interface SegmentedOption {\n value: string;\n label: string;\n}\n\n/** Fired when a segment is chosen. `detail.value` is the chosen option's `value`. */\nexport interface SegmentChangeEventDetail {\n value: string;\n}\n\n/**\n * A row of mutually exclusive segments in a grey track, one of them lifted as white. Pass the\n * segments as `options` and the chosen one as `value`; a `segment-change` event fires on choice.\n * Keyboard: arrows move between segments, Home and End jump to the ends.\n */\n@customElement('st-segmented-control')\nexport class SegmentedControl extends LitElement {\n static styles = css`\n ${fontFamilyStyles}\n\n :host {\n display: inline-flex;\n max-width: 100%;\n }\n\n .track {\n display: flex;\n gap: var(--st-space-2);\n padding: var(--st-space-3);\n border-radius: var(--st-radius-md);\n background: var(--st-color-subtle);\n max-width: 100%;\n }\n\n button {\n appearance: none;\n border: 0;\n border-radius: var(--st-radius-sm);\n padding: var(--st-space-6) var(--st-space-14);\n background: transparent;\n color: var(--st-color-text-secondary);\n font: inherit;\n font-size: var(--st-text-base);\n font-weight: var(--st-font-weight-medium);\n white-space: nowrap;\n cursor: pointer;\n }\n\n button[aria-checked='true'] {\n background: var(--st-color-surface);\n color: var(--st-color-text-strong);\n font-weight: var(--st-font-weight-semibold);\n box-shadow: 0 1px 2px rgba(20, 23, 31, 0.08);\n }\n\n button:focus-visible {\n outline: 2px solid var(--st-color-accent);\n outline-offset: 1px;\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `;\n\n /** The segments, in order. */\n @property({ attribute: false })\n options: SegmentedOption[] = [];\n\n /** The chosen segment's `value`. */\n @property({ type: String, reflect: true })\n value = '';\n\n /** Names the group for assistive technology. */\n @property({ type: String, attribute: 'group-label' })\n groupLabel = '';\n\n private select(next: string) {\n if (next === this.value) return;\n this.value = next;\n this.dispatchEvent(\n new CustomEvent<SegmentChangeEventDetail>('segment-change', {\n detail: { value: next },\n bubbles: true,\n composed: true\n })\n );\n }\n\n private onKeydown(event: KeyboardEvent) {\n const enabled = this.options;\n if (!enabled.length) return;\n const index = enabled.findIndex(option => option.value === this.value);\n let next: number | null = null;\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') next = (index + 1) % enabled.length;\n if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') next = (index - 1 + enabled.length) % enabled.length;\n if (event.key === 'Home') next = 0;\n if (event.key === 'End') next = enabled.length - 1;\n if (next === null) return;\n event.preventDefault();\n this.select(enabled[next].value);\n this.renderRoot.querySelector<HTMLButtonElement>(`button[data-value=\"${enabled[next].value}\"]`)?.focus();\n }\n\n render() {\n return html`<div class=\"track\" role=\"radiogroup\" aria-label=${this.groupLabel || nothing} @keydown=${this.onKeydown}>\n ${this.options.map(\n option => html`<button\n type=\"button\"\n role=\"radio\"\n data-value=${option.value}\n aria-checked=${option.value === this.value ? 'true' : 'false'}\n tabindex=${option.value === this.value ? 0 : -1}\n @click=${() => this.select(option.value)}\n >${option.label}</button>`\n )}\n </div>`;\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,gBAAgB;AAoBjC,IAAM,mBAAN,cAA+B,WAAW;AAAA,EAA1C;AAAA;AAoDL,mBAA6B,CAAC;AAI9B,iBAAQ;AAIR,sBAAa;AAAA;AAAA,EAEL,OAAO,MAAc;AAC3B,QAAI,SAAS,KAAK,MAAO;AACzB,SAAK,QAAQ;AACb,SAAK;AAAA,MACH,IAAI,YAAsC,kBAAkB;AAAA,QAC1D,QAAQ,EAAE,OAAO,KAAK;AAAA,QACtB,SAAS;AAAA,QACT,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,UAAU,OAAsB;AACtC,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,QAAQ,OAAQ;AACrB,UAAM,QAAQ,QAAQ,UAAU,YAAU,OAAO,UAAU,KAAK,KAAK;AACrE,QAAI,OAAsB;AAC1B,QAAI,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,YAAa,SAAQ,QAAQ,KAAK,QAAQ;AAC1F,QAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,UAAW,SAAQ,QAAQ,IAAI,QAAQ,UAAU,QAAQ;AACxG,QAAI,MAAM,QAAQ,OAAQ,QAAO;AACjC,QAAI,MAAM,QAAQ,MAAO,QAAO,QAAQ,SAAS;AACjD,QAAI,SAAS,KAAM;AACnB,UAAM,eAAe;AACrB,SAAK,OAAO,QAAQ,IAAI,EAAE,KAAK;AAC/B,SAAK,WAAW,cAAiC,sBAAsB,QAAQ,IAAI,EAAE,KAAK,IAAI,GAAG,MAAM;AAAA,EACzG;AAAA,EAEA,SAAS;AACP,WAAO,uDAAuD,KAAK,cAAc,OAAO,aAAa,KAAK,SAAS;AAAA,QAC/G,KAAK,QAAQ;AAAA,MACb,YAAU;AAAA;AAAA;AAAA,uBAGK,OAAO,KAAK;AAAA,yBACV,OAAO,UAAU,KAAK,QAAQ,SAAS,OAAO;AAAA,qBAClD,OAAO,UAAU,KAAK,QAAQ,IAAI,EAAE;AAAA,mBACtC,MAAM,KAAK,OAAO,OAAO,KAAK,CAAC;AAAA,WACvC,OAAO,KAAK;AAAA,IACjB,CAAC;AAAA;AAAA,EAEL;AACF;AAvGa,iBACJ,SAAS;AAAA,MACZ,gBAAgB;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;AAkDpB;AAAA,EADC,SAAS,EAAE,WAAW,MAAM,CAAC;AAAA,GAnDnB,iBAoDX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAvD9B,iBAwDX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,cAAc,CAAC;AAAA,GA3DzC,iBA4DX;AA5DW,mBAAN;AAAA,EADN,cAAc,sBAAsB;AAAA,GACxB;","names":[]}
@@ -0,0 +1,190 @@
1
+ import {
2
+ cardShellStyles,
3
+ fontFamilyStyles
4
+ } from "./chunk-KMU6ABQF.js";
5
+ import {
6
+ __decorateClass
7
+ } from "./chunk-EUXUH3YW.js";
8
+
9
+ // src/kpi-card/KpiCard.ts
10
+ import { LitElement, css, html } from "lit";
11
+ import { customElement, property } from "lit/decorators.js";
12
+ var KpiCard = class extends LitElement {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.label = "";
16
+ this.value = "";
17
+ this.unit = "";
18
+ this.sub = "";
19
+ this.hero = false;
20
+ this.hasIcon = false;
21
+ }
22
+ connectedCallback() {
23
+ super.connectedCallback();
24
+ this.hasIcon = this.querySelector('[slot="icon"]') !== null;
25
+ }
26
+ render() {
27
+ return html`
28
+ <div class="head" part="head">
29
+ <span class="icon" part="icon"><slot name="icon"></slot></span>
30
+ <span part="label">${this.label}</span>
31
+ </div>
32
+ <div class="value" part="value">
33
+ <span>${this.value}</span>
34
+ ${this.unit ? html`<span class="unit" part="unit">${this.unit}</span>` : ""}
35
+ </div>
36
+ ${this.sub ? html`<div class="sub" part="sub">${this.sub}</div>` : ""}
37
+ <div class="chips" part="chips"><slot name="chips"></slot></div>
38
+ <div class="footer" part="footer"><slot name="footer"></slot></div>
39
+ `;
40
+ }
41
+ };
42
+ KpiCard.styles = css`
43
+ ${fontFamilyStyles}
44
+
45
+ :host {
46
+ display: flex;
47
+ flex-direction: column;
48
+ min-width: 0;
49
+ box-sizing: border-box;
50
+ padding: var(--st-space-20);
51
+ ${cardShellStyles}
52
+ color: var(--st-color-text);
53
+ }
54
+
55
+ :host([hero]) {
56
+ position: relative;
57
+ overflow: hidden;
58
+ border: 0;
59
+ background: linear-gradient(135deg, var(--st-color-accent) 0%, color-mix(in oklch, var(--st-color-accent) 70%, #3aa8e8) 100%);
60
+ color: var(--st-color-on-solid);
61
+ }
62
+
63
+ :host([hero])::after {
64
+ content: '';
65
+ position: absolute;
66
+ top: -40%;
67
+ right: -20%;
68
+ width: 60%;
69
+ padding-bottom: 60%;
70
+ border-radius: var(--st-radius-circle);
71
+ background: color-mix(in oklch, var(--st-color-on-solid) 10%, transparent);
72
+ pointer-events: none;
73
+ }
74
+
75
+ .head {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: var(--st-space-10);
79
+ min-height: 32px;
80
+ font-size: var(--st-text-md);
81
+ font-weight: var(--st-font-weight-medium);
82
+ color: var(--st-color-text-secondary);
83
+ }
84
+
85
+ :host([hero]) .head {
86
+ color: var(--st-color-on-solid);
87
+ opacity: 0.85;
88
+ }
89
+
90
+ .icon {
91
+ display: inline-grid;
92
+ place-items: center;
93
+ width: 32px;
94
+ height: 32px;
95
+ border-radius: var(--st-radius-sm);
96
+ background: var(--st-color-accent-subtle);
97
+ flex: none;
98
+ }
99
+
100
+ :host(:not([has-icon])) .icon {
101
+ display: none;
102
+ }
103
+
104
+ .value {
105
+ display: flex;
106
+ align-items: baseline;
107
+ flex-wrap: wrap;
108
+ gap: var(--st-space-6);
109
+ margin-top: var(--st-space-14);
110
+ font-size: var(--st-text-kpi);
111
+ font-weight: var(--st-font-weight-bold);
112
+ line-height: 1.1;
113
+ letter-spacing: -0.02em;
114
+ font-variant-numeric: tabular-nums;
115
+ color: var(--st-color-text-strong);
116
+ }
117
+
118
+ :host([hero]) .value {
119
+ color: var(--st-color-on-solid);
120
+ font-size: var(--st-text-hero);
121
+ }
122
+
123
+ .unit {
124
+ font-size: var(--st-text-lg);
125
+ font-weight: var(--st-font-weight-medium);
126
+ color: var(--st-color-text-secondary);
127
+ }
128
+
129
+ :host([hero]) .unit {
130
+ color: var(--st-color-on-solid);
131
+ opacity: 0.85;
132
+ }
133
+
134
+ .sub {
135
+ margin-top: var(--st-space-6);
136
+ font-size: var(--st-text-base);
137
+ color: var(--st-color-text-muted);
138
+ }
139
+
140
+ :host([hero]) ::slotted(st-chip) {
141
+ background: color-mix(in oklch, var(--st-color-on-solid) 18%, transparent);
142
+ color: var(--st-color-on-solid);
143
+ }
144
+
145
+ :host([hero]) .sub {
146
+ color: var(--st-color-on-solid);
147
+ opacity: 0.85;
148
+ }
149
+
150
+ .chips {
151
+ display: flex;
152
+ flex-wrap: wrap;
153
+ gap: var(--st-space-8);
154
+ margin-top: var(--st-space-14);
155
+ }
156
+
157
+ .chips:empty {
158
+ display: none;
159
+ }
160
+
161
+ .footer:empty {
162
+ display: none;
163
+ }
164
+ `;
165
+ __decorateClass([
166
+ property({ type: String })
167
+ ], KpiCard.prototype, "label", 2);
168
+ __decorateClass([
169
+ property({ type: String })
170
+ ], KpiCard.prototype, "value", 2);
171
+ __decorateClass([
172
+ property({ type: String })
173
+ ], KpiCard.prototype, "unit", 2);
174
+ __decorateClass([
175
+ property({ type: String })
176
+ ], KpiCard.prototype, "sub", 2);
177
+ __decorateClass([
178
+ property({ type: Boolean, reflect: true })
179
+ ], KpiCard.prototype, "hero", 2);
180
+ __decorateClass([
181
+ property({ type: Boolean, reflect: true, attribute: "has-icon" })
182
+ ], KpiCard.prototype, "hasIcon", 2);
183
+ KpiCard = __decorateClass([
184
+ customElement("st-kpi-card")
185
+ ], KpiCard);
186
+
187
+ export {
188
+ KpiCard
189
+ };
190
+ //# sourceMappingURL=chunk-T55CG4YG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kpi-card/KpiCard.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { cardShellStyles, fontFamilyStyles } from '../shared/styles';\n\n/**\n * A key-figure card for dashboards: a label, one large value with an optional unit (for example\n * \"lakh\" or \"crore\"), a secondary line, and a row of chips. The `icon` slot sits beside the label.\n * `hero` gives the blue gradient card used for the headline figure. The value is shown exactly as\n * passed in: format numbers (Indian grouping, currency symbols) before setting it.\n *\n * Slots: `icon` (optional glyph), `chips` (a row of `st-chip`), `footer` (anything below the chips).\n */\n@customElement('st-kpi-card')\nexport class KpiCard extends LitElement {\n static styles = css`\n ${fontFamilyStyles}\n\n :host {\n display: flex;\n flex-direction: column;\n min-width: 0;\n box-sizing: border-box;\n padding: var(--st-space-20);\n ${cardShellStyles}\n color: var(--st-color-text);\n }\n\n :host([hero]) {\n position: relative;\n overflow: hidden;\n border: 0;\n background: linear-gradient(135deg, var(--st-color-accent) 0%, color-mix(in oklch, var(--st-color-accent) 70%, #3aa8e8) 100%);\n color: var(--st-color-on-solid);\n }\n\n :host([hero])::after {\n content: '';\n position: absolute;\n top: -40%;\n right: -20%;\n width: 60%;\n padding-bottom: 60%;\n border-radius: var(--st-radius-circle);\n background: color-mix(in oklch, var(--st-color-on-solid) 10%, transparent);\n pointer-events: none;\n }\n\n .head {\n display: flex;\n align-items: center;\n gap: var(--st-space-10);\n min-height: 32px;\n font-size: var(--st-text-md);\n font-weight: var(--st-font-weight-medium);\n color: var(--st-color-text-secondary);\n }\n\n :host([hero]) .head {\n color: var(--st-color-on-solid);\n opacity: 0.85;\n }\n\n .icon {\n display: inline-grid;\n place-items: center;\n width: 32px;\n height: 32px;\n border-radius: var(--st-radius-sm);\n background: var(--st-color-accent-subtle);\n flex: none;\n }\n\n :host(:not([has-icon])) .icon {\n display: none;\n }\n\n .value {\n display: flex;\n align-items: baseline;\n flex-wrap: wrap;\n gap: var(--st-space-6);\n margin-top: var(--st-space-14);\n font-size: var(--st-text-kpi);\n font-weight: var(--st-font-weight-bold);\n line-height: 1.1;\n letter-spacing: -0.02em;\n font-variant-numeric: tabular-nums;\n color: var(--st-color-text-strong);\n }\n\n :host([hero]) .value {\n color: var(--st-color-on-solid);\n font-size: var(--st-text-hero);\n }\n\n .unit {\n font-size: var(--st-text-lg);\n font-weight: var(--st-font-weight-medium);\n color: var(--st-color-text-secondary);\n }\n\n :host([hero]) .unit {\n color: var(--st-color-on-solid);\n opacity: 0.85;\n }\n\n .sub {\n margin-top: var(--st-space-6);\n font-size: var(--st-text-base);\n color: var(--st-color-text-muted);\n }\n\n :host([hero]) ::slotted(st-chip) {\n background: color-mix(in oklch, var(--st-color-on-solid) 18%, transparent);\n color: var(--st-color-on-solid);\n }\n\n :host([hero]) .sub {\n color: var(--st-color-on-solid);\n opacity: 0.85;\n }\n\n .chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--st-space-8);\n margin-top: var(--st-space-14);\n }\n\n .chips:empty {\n display: none;\n }\n\n .footer:empty {\n display: none;\n }\n `;\n\n /** Label above the figure. */\n @property({ type: String })\n label = '';\n\n /** The figure, already formatted (for example \"25.88\"). */\n @property({ type: String })\n value = '';\n\n /** Unit shown beside the figure (for example \"lakh\"). */\n @property({ type: String })\n unit = '';\n\n /** Secondary line below the figure (for example the exact amount and the period). */\n @property({ type: String })\n sub = '';\n\n /** The blue gradient headline card. */\n @property({ type: Boolean, reflect: true })\n hero = false;\n\n /** Set when an element is slotted into `icon`, so the icon tile only shows when there is an icon. */\n @property({ type: Boolean, reflect: true, attribute: 'has-icon' })\n hasIcon = false;\n\n connectedCallback() {\n super.connectedCallback();\n this.hasIcon = this.querySelector('[slot=\"icon\"]') !== null;\n }\n\n render() {\n return html`\n <div class=\"head\" part=\"head\">\n <span class=\"icon\" part=\"icon\"><slot name=\"icon\"></slot></span>\n <span part=\"label\">${this.label}</span>\n </div>\n <div class=\"value\" part=\"value\">\n <span>${this.value}</span>\n ${this.unit ? html`<span class=\"unit\" part=\"unit\">${this.unit}</span>` : ''}\n </div>\n ${this.sub ? html`<div class=\"sub\" part=\"sub\">${this.sub}</div>` : ''}\n <div class=\"chips\" part=\"chips\"><slot name=\"chips\"></slot></div>\n <div class=\"footer\" part=\"footer\"><slot name=\"footer\"></slot></div>\n `;\n }\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AAajC,IAAM,UAAN,cAAsB,WAAW;AAAA,EAAjC;AAAA;AA+HL,iBAAQ;AAIR,iBAAQ;AAIR,gBAAO;AAIP,eAAM;AAIN,gBAAO;AAIP,mBAAU;AAAA;AAAA,EAEV,oBAAoB;AAClB,UAAM,kBAAkB;AACxB,SAAK,UAAU,KAAK,cAAc,eAAe,MAAM;AAAA,EACzD;AAAA,EAEA,SAAS;AACP,WAAO;AAAA;AAAA;AAAA,6BAGkB,KAAK,KAAK;AAAA;AAAA;AAAA,gBAGvB,KAAK,KAAK;AAAA,UAChB,KAAK,OAAO,sCAAsC,KAAK,IAAI,YAAY,EAAE;AAAA;AAAA,QAE3E,KAAK,MAAM,mCAAmC,KAAK,GAAG,WAAW,EAAE;AAAA;AAAA;AAAA;AAAA,EAIzE;AACF;AAzKa,QACJ,SAAS;AAAA,MACZ,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQd,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqHrB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Hf,QA+HX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlIf,QAmIX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAtIf,QAuIX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA1If,QA2IX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA9I/B,QA+IX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,MAAM,WAAW,WAAW,CAAC;AAAA,GAlJtD,QAmJX;AAnJW,UAAN;AAAA,EADN,cAAc,aAAa;AAAA,GACf;","names":[]}
@@ -0,0 +1,20 @@
1
+ import * as lit from 'lit';
2
+ import { LitElement } from 'lit';
3
+
4
+ /**
5
+ * A calendar date tile: a month band over a large day number, as used for due dates. `tone`
6
+ * colours the month band: `default` for a neutral date, `warning` for due soon, `danger` for
7
+ * overdue.
8
+ */
9
+ declare class DateTile extends LitElement {
10
+ static styles: lit.CSSResult;
11
+ /** Month abbreviation shown in the band (for example "NOV"). */
12
+ month: string;
13
+ /** Day of the month (for example "11"). */
14
+ day: string;
15
+ /** Colour of the month band. */
16
+ tone: 'default' | 'warning' | 'danger';
17
+ render(): lit.TemplateResult<1>;
18
+ }
19
+
20
+ export { DateTile };
@@ -0,0 +1,9 @@
1
+ import {
2
+ DateTile
3
+ } from "../chunk-DAGSL2JV.js";
4
+ import "../chunk-KMU6ABQF.js";
5
+ import "../chunk-EUXUH3YW.js";
6
+ export {
7
+ DateTile
8
+ };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,12 @@
1
+ export { AttentionPanel } from './attention-panel/index.js';
2
+ export { BarChart } from './bar-chart/index.js';
1
3
  export { BentoGrid, BentoGridItem } from './bento-grid/index.js';
2
4
  export { Card } from './card/index.js';
3
5
  export { Carousel, CarouselChangeEventDetail } from './carousel/index.js';
6
+ export { Chip } from './chip/index.js';
4
7
  export { ContentBlock } from './content-block/index.js';
5
8
  export { CookieConsent, CookieConsentEventDetail, CookieConsentStatus } from './cookie-consent/index.js';
9
+ export { DateTile } from './date-tile/index.js';
6
10
  export { Dropdown, DropdownToggleEventDetail } from './dropdown/index.js';
7
11
  export { FeatureSplit, FeatureSplitActionEventDetail, FeatureSplitImagePosition, FeatureSplitItem } from './feature-split/index.js';
8
12
  export { FeatureItem, FeatureItemData, FeaturesSection } from './features-section/index.js';
@@ -11,13 +15,15 @@ export { Header, LanguageChangedEventDetail } from './header/index.js';
11
15
  export { Hero, HeroActionEventDetail } from './hero/index.js';
12
16
  export { IconButton } from './icon-button/index.js';
13
17
  export { AccordionItem, AccordionToggleEventDetail, ItemsAccordion } from './items-accordion/index.js';
18
+ export { KpiCard } from './kpi-card/index.js';
14
19
  export { Markdown, MarkdownErrorEventDetail } from './markdown/index.js';
15
20
  export { MegaMenu, MegaMenuColumn, MegaMenuFeature, MegaMenuSelectEventDetail } from './mega-menu/index.js';
16
- export { MenuGrid } from './menu-grid/index.js';
17
21
  export { MenuGridItem, MenuGridItemSelectEventDetail } from './menu-grid-item/index.js';
22
+ export { MenuGrid } from './menu-grid/index.js';
18
23
  export { MenuItem, MenuItemSelectEventDetail } from './menu-item/index.js';
19
24
  export { PromoBanner } from './promo-banner/index.js';
20
25
  export { Section } from './section/index.js';
26
+ export { SegmentChangeEventDetail, SegmentedControl, SegmentedOption } from './segmented-control/index.js';
21
27
  export { Select, SelectChangedEventDetail, SelectOption } from './select/index.js';
22
28
  export { StatItem, Stats } from './stats/index.js';
23
29
  export { TestimonialItem, TestimonialMetric, Testimonials, TestimonialsLinkEventDetail } from './testimonials/index.js';
package/dist/index.js CHANGED
@@ -1,9 +1,35 @@
1
+ import {
2
+ Testimonials
3
+ } from "./chunk-DH53HZPB.js";
4
+ import {
5
+ PromoBanner
6
+ } from "./chunk-VWS53WY4.js";
7
+ import {
8
+ Section
9
+ } from "./chunk-7NLZND6Q.js";
10
+ import {
11
+ SegmentedControl
12
+ } from "./chunk-MG2VTZA4.js";
13
+ import {
14
+ Select
15
+ } from "./chunk-BLQV2YMO.js";
1
16
  import {
2
17
  Stats
3
18
  } from "./chunk-YVTFQHVY.js";
4
19
  import {
5
- Testimonials
6
- } from "./chunk-DH53HZPB.js";
20
+ IconButton
21
+ } from "./chunk-YQ42EBK5.js";
22
+ import {
23
+ ItemsAccordion
24
+ } from "./chunk-ALI26WOB.js";
25
+ import {
26
+ KpiCard
27
+ } from "./chunk-T55CG4YG.js";
28
+ import {
29
+ MegaMenu,
30
+ MegaMenuColumn,
31
+ MegaMenuFeature
32
+ } from "./chunk-G3CF7MBO.js";
7
33
  import {
8
34
  MenuGrid
9
35
  } from "./chunk-SMLR736E.js";
@@ -14,14 +40,17 @@ import {
14
40
  MenuItem
15
41
  } from "./chunk-R5G6KFTJ.js";
16
42
  import {
17
- PromoBanner
18
- } from "./chunk-VWS53WY4.js";
43
+ CookieConsent
44
+ } from "./chunk-MSSH3HFK.js";
19
45
  import {
20
- Section
21
- } from "./chunk-7NLZND6Q.js";
46
+ DateTile
47
+ } from "./chunk-DAGSL2JV.js";
22
48
  import {
23
- Select
24
- } from "./chunk-BLQV2YMO.js";
49
+ Dropdown
50
+ } from "./chunk-LEXZKGQX.js";
51
+ import {
52
+ FeatureSplit
53
+ } from "./chunk-WT4OATGP.js";
25
54
  import {
26
55
  FeatureItem,
27
56
  FeaturesSection
@@ -32,20 +61,16 @@ import {
32
61
  import {
33
62
  Header
34
63
  } from "./chunk-XWB4CKDU.js";
64
+ import "./chunk-WTD2YIAA.js";
35
65
  import {
36
66
  Hero
37
67
  } from "./chunk-JKBWZLG4.js";
38
68
  import {
39
- IconButton
40
- } from "./chunk-YQ42EBK5.js";
41
- import {
42
- ItemsAccordion
43
- } from "./chunk-ALI26WOB.js";
69
+ AttentionPanel
70
+ } from "./chunk-4PXZPGWQ.js";
44
71
  import {
45
- MegaMenu,
46
- MegaMenuColumn,
47
- MegaMenuFeature
48
- } from "./chunk-G3CF7MBO.js";
72
+ BarChart
73
+ } from "./chunk-AG2COC64.js";
49
74
  import {
50
75
  BentoGrid
51
76
  } from "./chunk-76AVBQUA.js";
@@ -55,19 +80,12 @@ import {
55
80
  import {
56
81
  Carousel
57
82
  } from "./chunk-EMCQBT3S.js";
83
+ import {
84
+ Chip
85
+ } from "./chunk-LGGLQNSU.js";
58
86
  import {
59
87
  ContentBlock
60
88
  } from "./chunk-BMHMNXIA.js";
61
- import {
62
- CookieConsent
63
- } from "./chunk-MSSH3HFK.js";
64
- import {
65
- Dropdown
66
- } from "./chunk-LEXZKGQX.js";
67
- import "./chunk-WTD2YIAA.js";
68
- import {
69
- FeatureSplit
70
- } from "./chunk-WT4OATGP.js";
71
89
  import {
72
90
  Markdown
73
91
  } from "./chunk-5EBWMPJS.js";
@@ -75,11 +93,15 @@ import "./chunk-FZ36KL73.js";
75
93
  import "./chunk-KMU6ABQF.js";
76
94
  import "./chunk-EUXUH3YW.js";
77
95
  export {
96
+ AttentionPanel,
97
+ BarChart,
78
98
  BentoGrid,
79
99
  Card,
80
100
  Carousel,
101
+ Chip,
81
102
  ContentBlock,
82
103
  CookieConsent,
104
+ DateTile,
83
105
  Dropdown,
84
106
  FeatureItem,
85
107
  FeatureSplit,
@@ -89,6 +111,7 @@ export {
89
111
  Hero,
90
112
  IconButton,
91
113
  ItemsAccordion,
114
+ KpiCard,
92
115
  Markdown,
93
116
  MegaMenu,
94
117
  MegaMenuColumn,
@@ -98,6 +121,7 @@ export {
98
121
  MenuItem,
99
122
  PromoBanner,
100
123
  Section,
124
+ SegmentedControl,
101
125
  Select,
102
126
  Stats,
103
127
  Testimonials
@@ -0,0 +1,30 @@
1
+ import * as lit from 'lit';
2
+ import { LitElement } from 'lit';
3
+
4
+ /**
5
+ * A key-figure card for dashboards: a label, one large value with an optional unit (for example
6
+ * "lakh" or "crore"), a secondary line, and a row of chips. The `icon` slot sits beside the label.
7
+ * `hero` gives the blue gradient card used for the headline figure. The value is shown exactly as
8
+ * passed in: format numbers (Indian grouping, currency symbols) before setting it.
9
+ *
10
+ * Slots: `icon` (optional glyph), `chips` (a row of `st-chip`), `footer` (anything below the chips).
11
+ */
12
+ declare class KpiCard extends LitElement {
13
+ static styles: lit.CSSResult;
14
+ /** Label above the figure. */
15
+ label: string;
16
+ /** The figure, already formatted (for example "25.88"). */
17
+ value: string;
18
+ /** Unit shown beside the figure (for example "lakh"). */
19
+ unit: string;
20
+ /** Secondary line below the figure (for example the exact amount and the period). */
21
+ sub: string;
22
+ /** The blue gradient headline card. */
23
+ hero: boolean;
24
+ /** Set when an element is slotted into `icon`, so the icon tile only shows when there is an icon. */
25
+ hasIcon: boolean;
26
+ connectedCallback(): void;
27
+ render(): lit.TemplateResult<1>;
28
+ }
29
+
30
+ export { KpiCard };