@digital2analogue2/parsimony-components 0.1.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/custom-elements.json +3751 -0
- package/dist/alert/alert.d.ts +36 -0
- package/dist/alert/alert.d.ts.map +1 -0
- package/dist/alert/alert.js +179 -0
- package/dist/alert/alert.js.map +1 -0
- package/dist/alert/alert.stories.d.ts +12 -0
- package/dist/alert/alert.stories.d.ts.map +1 -0
- package/dist/alert/alert.stories.js +59 -0
- package/dist/alert/alert.stories.js.map +1 -0
- package/dist/avatar/avatar.d.ts +37 -0
- package/dist/avatar/avatar.d.ts.map +1 -0
- package/dist/avatar/avatar.js +150 -0
- package/dist/avatar/avatar.js.map +1 -0
- package/dist/avatar/avatar.stories.d.ts +10 -0
- package/dist/avatar/avatar.stories.d.ts.map +1 -0
- package/dist/avatar/avatar.stories.js +56 -0
- package/dist/avatar/avatar.stories.js.map +1 -0
- package/dist/badge/badge.d.ts +31 -0
- package/dist/badge/badge.d.ts.map +1 -0
- package/dist/badge/badge.js +104 -0
- package/dist/badge/badge.js.map +1 -0
- package/dist/badge/badge.stories.d.ts +9 -0
- package/dist/badge/badge.stories.d.ts.map +1 -0
- package/dist/badge/badge.stories.js +35 -0
- package/dist/badge/badge.stories.js.map +1 -0
- package/dist/button/button.d.ts +50 -0
- package/dist/button/button.d.ts.map +1 -0
- package/dist/button/button.js +237 -0
- package/dist/button/button.js.map +1 -0
- package/dist/button/button.stories.d.ts +12 -0
- package/dist/button/button.stories.d.ts.map +1 -0
- package/dist/button/button.stories.js +44 -0
- package/dist/button/button.stories.js.map +1 -0
- package/dist/card/card.d.ts +32 -0
- package/dist/card/card.d.ts.map +1 -0
- package/dist/card/card.js +107 -0
- package/dist/card/card.js.map +1 -0
- package/dist/card/card.stories.d.ts +9 -0
- package/dist/card/card.stories.d.ts.map +1 -0
- package/dist/card/card.stories.js +39 -0
- package/dist/card/card.stories.js.map +1 -0
- package/dist/checkbox/checkbox.d.ts +44 -0
- package/dist/checkbox/checkbox.d.ts.map +1 -0
- package/dist/checkbox/checkbox.js +201 -0
- package/dist/checkbox/checkbox.js.map +1 -0
- package/dist/checkbox/checkbox.stories.d.ts +10 -0
- package/dist/checkbox/checkbox.stories.d.ts.map +1 -0
- package/dist/checkbox/checkbox.stories.js +38 -0
- package/dist/checkbox/checkbox.stories.js.map +1 -0
- package/dist/dialog/dialog.d.ts +51 -0
- package/dist/dialog/dialog.d.ts.map +1 -0
- package/dist/dialog/dialog.js +234 -0
- package/dist/dialog/dialog.js.map +1 -0
- package/dist/dialog/dialog.stories.d.ts +7 -0
- package/dist/dialog/dialog.stories.d.ts.map +1 -0
- package/dist/dialog/dialog.stories.js +30 -0
- package/dist/dialog/dialog.stories.js.map +1 -0
- package/dist/icon/icon.d.ts +40 -0
- package/dist/icon/icon.d.ts.map +1 -0
- package/dist/icon/icon.js +99 -0
- package/dist/icon/icon.js.map +1 -0
- package/dist/icon/icon.stories.d.ts +9 -0
- package/dist/icon/icon.stories.d.ts.map +1 -0
- package/dist/icon/icon.stories.js +41 -0
- package/dist/icon/icon.stories.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/input/input.d.ts +61 -0
- package/dist/input/input.d.ts.map +1 -0
- package/dist/input/input.js +233 -0
- package/dist/input/input.js.map +1 -0
- package/dist/input/input.stories.d.ts +10 -0
- package/dist/input/input.stories.d.ts.map +1 -0
- package/dist/input/input.stories.js +48 -0
- package/dist/input/input.stories.js.map +1 -0
- package/dist/link/link.d.ts +39 -0
- package/dist/link/link.d.ts.map +1 -0
- package/dist/link/link.js +112 -0
- package/dist/link/link.js.map +1 -0
- package/dist/link/link.stories.d.ts +9 -0
- package/dist/link/link.stories.d.ts.map +1 -0
- package/dist/link/link.stories.js +44 -0
- package/dist/link/link.stories.js.map +1 -0
- package/dist/progress/progress.d.ts +35 -0
- package/dist/progress/progress.d.ts.map +1 -0
- package/dist/progress/progress.js +116 -0
- package/dist/progress/progress.js.map +1 -0
- package/dist/progress/progress.stories.d.ts +10 -0
- package/dist/progress/progress.stories.d.ts.map +1 -0
- package/dist/progress/progress.stories.js +32 -0
- package/dist/progress/progress.stories.js.map +1 -0
- package/dist/radio/radio-group.d.ts +53 -0
- package/dist/radio/radio-group.d.ts.map +1 -0
- package/dist/radio/radio-group.js +183 -0
- package/dist/radio/radio-group.js.map +1 -0
- package/dist/radio/radio-group.stories.d.ts +9 -0
- package/dist/radio/radio-group.stories.d.ts.map +1 -0
- package/dist/radio/radio-group.stories.js +44 -0
- package/dist/radio/radio-group.stories.js.map +1 -0
- package/dist/radio/radio.d.ts +29 -0
- package/dist/radio/radio.d.ts.map +1 -0
- package/dist/radio/radio.js +166 -0
- package/dist/radio/radio.js.map +1 -0
- package/dist/radio/radio.stories.d.ts +13 -0
- package/dist/radio/radio.stories.d.ts.map +1 -0
- package/dist/radio/radio.stories.js +28 -0
- package/dist/radio/radio.stories.js.map +1 -0
- package/dist/select/select.d.ts +63 -0
- package/dist/select/select.d.ts.map +1 -0
- package/dist/select/select.js +258 -0
- package/dist/select/select.js.map +1 -0
- package/dist/select/select.stories.d.ts +9 -0
- package/dist/select/select.stories.d.ts.map +1 -0
- package/dist/select/select.stories.js +46 -0
- package/dist/select/select.stories.js.map +1 -0
- package/dist/skeleton/skeleton.d.ts +39 -0
- package/dist/skeleton/skeleton.d.ts.map +1 -0
- package/dist/skeleton/skeleton.js +111 -0
- package/dist/skeleton/skeleton.js.map +1 -0
- package/dist/skeleton/skeleton.stories.d.ts +9 -0
- package/dist/skeleton/skeleton.stories.d.ts.map +1 -0
- package/dist/skeleton/skeleton.stories.js +36 -0
- package/dist/skeleton/skeleton.stories.js.map +1 -0
- package/dist/spinner/spinner.d.ts +29 -0
- package/dist/spinner/spinner.d.ts.map +1 -0
- package/dist/spinner/spinner.js +131 -0
- package/dist/spinner/spinner.js.map +1 -0
- package/dist/spinner/spinner.stories.d.ts +8 -0
- package/dist/spinner/spinner.stories.d.ts.map +1 -0
- package/dist/spinner/spinner.stories.js +29 -0
- package/dist/spinner/spinner.stories.js.map +1 -0
- package/dist/tabs/tab-list.d.ts +45 -0
- package/dist/tabs/tab-list.d.ts.map +1 -0
- package/dist/tabs/tab-list.js +150 -0
- package/dist/tabs/tab-list.js.map +1 -0
- package/dist/tabs/tab-list.stories.d.ts +7 -0
- package/dist/tabs/tab-list.stories.d.ts.map +1 -0
- package/dist/tabs/tab-list.stories.js +27 -0
- package/dist/tabs/tab-list.stories.js.map +1 -0
- package/dist/tabs/tab.d.ts +40 -0
- package/dist/tabs/tab.d.ts.map +1 -0
- package/dist/tabs/tab.js +114 -0
- package/dist/tabs/tab.js.map +1 -0
- package/dist/tabs/tab.stories.d.ts +13 -0
- package/dist/tabs/tab.stories.d.ts.map +1 -0
- package/dist/tabs/tab.stories.js +28 -0
- package/dist/tabs/tab.stories.js.map +1 -0
- package/dist/tag/tag.d.ts +38 -0
- package/dist/tag/tag.d.ts.map +1 -0
- package/dist/tag/tag.js +71 -0
- package/dist/tag/tag.js.map +1 -0
- package/dist/tag/tag.stories.d.ts +10 -0
- package/dist/tag/tag.stories.d.ts.map +1 -0
- package/dist/tag/tag.stories.js +43 -0
- package/dist/tag/tag.stories.js.map +1 -0
- package/dist/test-setup.d.ts +2 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +2 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/textarea/textarea.d.ts +60 -0
- package/dist/textarea/textarea.d.ts.map +1 -0
- package/dist/textarea/textarea.js +232 -0
- package/dist/textarea/textarea.js.map +1 -0
- package/dist/textarea/textarea.stories.d.ts +10 -0
- package/dist/textarea/textarea.stories.d.ts.map +1 -0
- package/dist/textarea/textarea.stories.js +47 -0
- package/dist/textarea/textarea.stories.js.map +1 -0
- package/dist/toggle/toggle.d.ts +43 -0
- package/dist/toggle/toggle.d.ts.map +1 -0
- package/dist/toggle/toggle.js +189 -0
- package/dist/toggle/toggle.js.map +1 -0
- package/dist/toggle/toggle.stories.d.ts +9 -0
- package/dist/toggle/toggle.stories.d.ts.map +1 -0
- package/dist/toggle/toggle.stories.js +34 -0
- package/dist/toggle/toggle.stories.js.map +1 -0
- package/package.json +65 -0
- package/src/react.d.ts +199 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { LitElement, html, css } from 'lit';
|
|
8
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
9
|
+
/**
|
|
10
|
+
* `<rr-spinner>` — animated loading indicator.
|
|
11
|
+
*
|
|
12
|
+
* Renders a circular SVG spinner using the action color token.
|
|
13
|
+
* Announces to screen readers via an `aria-live` region.
|
|
14
|
+
*
|
|
15
|
+
* @attr {sm|md|lg} size - Visual size (default: md)
|
|
16
|
+
* @attr label - Accessible label text (default: "Loading")
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* <rr-spinner></rr-spinner>
|
|
20
|
+
* <rr-spinner size="sm" label="Saving…"></rr-spinner>
|
|
21
|
+
*/
|
|
22
|
+
let RrSpinner = class RrSpinner extends LitElement {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
/** Visual size of the spinner. Reflected to the size attribute. */
|
|
26
|
+
this.size = 'md';
|
|
27
|
+
/** Accessible label announced to screen readers via the status region. */
|
|
28
|
+
this.label = 'Loading';
|
|
29
|
+
}
|
|
30
|
+
render() {
|
|
31
|
+
// SVG viewBox is always 24×24; CSS scales via width/height.
|
|
32
|
+
// Track: full circle (circumference ≈ 62.83)
|
|
33
|
+
// Arc: 25% of circumference ≈ 15.7, gap ≈ 47.1; rotated -90° to start at top.
|
|
34
|
+
return html `
|
|
35
|
+
<svg
|
|
36
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
37
|
+
viewBox="0 0 24 24"
|
|
38
|
+
aria-hidden="true"
|
|
39
|
+
focusable="false"
|
|
40
|
+
>
|
|
41
|
+
<circle class="track" cx="12" cy="12" r="10" />
|
|
42
|
+
<circle
|
|
43
|
+
class="arc"
|
|
44
|
+
cx="12"
|
|
45
|
+
cy="12"
|
|
46
|
+
r="10"
|
|
47
|
+
stroke-dasharray="15.7 47.1"
|
|
48
|
+
transform="rotate(-90 12 12)"
|
|
49
|
+
/>
|
|
50
|
+
</svg>
|
|
51
|
+
<span class="sr-only" role="status" aria-live="polite">${this.label}</span>
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
RrSpinner.styles = css `
|
|
56
|
+
:host {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
flex-shrink: 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
svg {
|
|
64
|
+
display: block;
|
|
65
|
+
width: 24px;
|
|
66
|
+
height: 24px;
|
|
67
|
+
animation: rr-spin 0.8s linear infinite;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* A frozen arc still reads as "busy" (plus the aria-label); the rotation
|
|
71
|
+
is decorative, so honor the OS-level motion preference. */
|
|
72
|
+
@media (prefers-reduced-motion: reduce) {
|
|
73
|
+
svg {
|
|
74
|
+
animation: none;
|
|
75
|
+
color: var(--color-foreground-action);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
:host([size='sm']) svg {
|
|
79
|
+
width: 16px;
|
|
80
|
+
height: 16px;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:host([size='lg']) svg {
|
|
84
|
+
width: 32px;
|
|
85
|
+
height: 32px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@keyframes rr-spin {
|
|
89
|
+
to {
|
|
90
|
+
transform: rotate(360deg);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.track {
|
|
95
|
+
stroke: var(--color-border-elevated);
|
|
96
|
+
fill: none;
|
|
97
|
+
stroke-width: 2;
|
|
98
|
+
stroke-linecap: round;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.arc {
|
|
102
|
+
stroke: currentColor;
|
|
103
|
+
fill: none;
|
|
104
|
+
stroke-width: 2;
|
|
105
|
+
stroke-linecap: round;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Visually hidden but accessible */
|
|
109
|
+
.sr-only {
|
|
110
|
+
position: absolute;
|
|
111
|
+
width: 1px;
|
|
112
|
+
height: 1px;
|
|
113
|
+
padding: 0;
|
|
114
|
+
margin: -1px;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
clip: rect(0, 0, 0, 0);
|
|
117
|
+
white-space: nowrap;
|
|
118
|
+
border: 0;
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
__decorate([
|
|
122
|
+
property({ reflect: true })
|
|
123
|
+
], RrSpinner.prototype, "size", void 0);
|
|
124
|
+
__decorate([
|
|
125
|
+
property()
|
|
126
|
+
], RrSpinner.prototype, "label", void 0);
|
|
127
|
+
RrSpinner = __decorate([
|
|
128
|
+
customElement('rr-spinner')
|
|
129
|
+
], RrSpinner);
|
|
130
|
+
export { RrSpinner };
|
|
131
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/spinner/spinner.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI5D;;;;;;;;;;;;GAYG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QAoEL,mEAAmE;QACtC,SAAI,GAAgB,IAAI,CAAC;QAEtD,0EAA0E;QAC9D,UAAK,GAAG,SAAS,CAAC;IA0BhC,CAAC;IAxBC,MAAM;QACJ,4DAA4D;QAC5D,6CAA6C;QAC7C,8EAA8E;QAC9E,OAAO,IAAI,CAAA;;;;;;;;;;;;;;;;;+DAiBgD,IAAI,CAAC,KAAK;KACpE,CAAC;IACJ,CAAC;;AAhGM,gBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiElB,AAjEY,CAiEX;AAG2B;IAA5B,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;uCAA0B;AAG1C;IAAX,QAAQ,EAAE;wCAAmB;AAxEnB,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAkGrB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/web-components-vite';
|
|
2
|
+
import '@digital2analogue2/parsimony-components';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Sizes: Story;
|
|
8
|
+
//# sourceMappingURL=spinner.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.stories.d.ts","sourceRoot":"","sources":["../../src/spinner/spinner.stories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,yCAAyC,CAAC;AAEjD,QAAA,MAAM,IAAI,EAAE,IAcX,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,KAAK,EAAE,KAQnB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import '@digital2analogue2/parsimony-components';
|
|
3
|
+
const meta = {
|
|
4
|
+
title: 'Components/Spinner',
|
|
5
|
+
component: 'rr-spinner',
|
|
6
|
+
argTypes: {
|
|
7
|
+
size: { control: 'select', options: ['sm', 'md', 'lg'] },
|
|
8
|
+
label: { control: 'text' },
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
size: 'md',
|
|
12
|
+
label: 'Loading',
|
|
13
|
+
},
|
|
14
|
+
render: ({ size, label }) => html `
|
|
15
|
+
<rr-spinner size=${size} label=${label}></rr-spinner>
|
|
16
|
+
`,
|
|
17
|
+
};
|
|
18
|
+
export default meta;
|
|
19
|
+
export const Default = {};
|
|
20
|
+
export const Sizes = {
|
|
21
|
+
render: () => html `
|
|
22
|
+
<div style="display: flex; align-items: center; gap: var(--spacing-inline);">
|
|
23
|
+
<rr-spinner size="sm"></rr-spinner>
|
|
24
|
+
<rr-spinner size="md"></rr-spinner>
|
|
25
|
+
<rr-spinner size="lg"></rr-spinner>
|
|
26
|
+
</div>
|
|
27
|
+
`,
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=spinner.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.stories.js","sourceRoot":"","sources":["../../src/spinner/spinner.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,yCAAyC,CAAC;AAEjD,MAAM,IAAI,GAAS;IACjB,KAAK,EAAE,oBAAoB;IAC3B,SAAS,EAAE,YAAY;IACvB,QAAQ,EAAE;QACR,IAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;QACxD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;KAC3B;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,SAAS;KACjB;IACD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,CAAA;uBACZ,IAAI,UAAU,KAAK;GACvC;CACF,CAAC;AACF,eAAe,IAAI,CAAC;AAIpB,MAAM,CAAC,MAAM,OAAO,GAAU,EAAE,CAAC;AAEjC,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAA;;;;;;GAMjB;CACF,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* `<rr-tab-list>` — the accessible tab strip container.
|
|
4
|
+
*
|
|
5
|
+
* Wraps `<rr-tab>` elements and manages selection state, keyboard navigation
|
|
6
|
+
* (left/right arrows, Home, End), and ARIA attributes.
|
|
7
|
+
*
|
|
8
|
+
* The tab panels are managed by the consuming app — listen for the `change`
|
|
9
|
+
* event and show/hide content accordingly.
|
|
10
|
+
*
|
|
11
|
+
* @slot - Place `<rr-tab>` elements here
|
|
12
|
+
*
|
|
13
|
+
* @attr label - Accessible label for the tablist (required)
|
|
14
|
+
* @attr value - Currently selected tab value
|
|
15
|
+
*
|
|
16
|
+
* @fires change - When a tab is selected; detail: { value: string }
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* <rr-tab-list label="View options" value="overview">
|
|
20
|
+
* <rr-tab value="overview">Overview</rr-tab>
|
|
21
|
+
* <rr-tab value="history">History</rr-tab>
|
|
22
|
+
* <rr-tab value="settings">Settings</rr-tab>
|
|
23
|
+
* </rr-tab-list>
|
|
24
|
+
*/
|
|
25
|
+
export declare class RrTabList extends LitElement {
|
|
26
|
+
static styles: import("lit").CSSResult;
|
|
27
|
+
/** Accessible label for the tablist (required); sets aria-label on the role=tablist element. */
|
|
28
|
+
label: string;
|
|
29
|
+
/** Currently selected tab value. Reflected; syncs the matching rr-tab child's selected state. */
|
|
30
|
+
value: string;
|
|
31
|
+
connectedCallback(): void;
|
|
32
|
+
disconnectedCallback(): void;
|
|
33
|
+
updated(changed: Map<PropertyKey, unknown>): void;
|
|
34
|
+
private _getTabs;
|
|
35
|
+
private _syncTabs;
|
|
36
|
+
private _onTabSelect;
|
|
37
|
+
private _onKeyDown;
|
|
38
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
39
|
+
}
|
|
40
|
+
declare global {
|
|
41
|
+
interface HTMLElementTagNameMap {
|
|
42
|
+
'rr-tab-list': RrTabList;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=tab-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab-list.d.ts","sourceRoot":"","sources":["../../src/tabs/tab-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,MAAM,CAAC,MAAM,0BAiBX;IAEF,gGAAgG;IACpF,KAAK,SAAM;IAEvB,iGAAiG;IACpE,KAAK,SAAM;IAExC,iBAAiB;IAQjB,oBAAoB;IAMpB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC;IAM1C,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,YAAY,CASlB;IAEF,OAAO,CAAC,UAAU,CAmChB;IAEF,MAAM;CAWP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,SAAS,CAAC;KAC1B;CACF"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { LitElement, html, css } from 'lit';
|
|
8
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
9
|
+
/**
|
|
10
|
+
* `<rr-tab-list>` — the accessible tab strip container.
|
|
11
|
+
*
|
|
12
|
+
* Wraps `<rr-tab>` elements and manages selection state, keyboard navigation
|
|
13
|
+
* (left/right arrows, Home, End), and ARIA attributes.
|
|
14
|
+
*
|
|
15
|
+
* The tab panels are managed by the consuming app — listen for the `change`
|
|
16
|
+
* event and show/hide content accordingly.
|
|
17
|
+
*
|
|
18
|
+
* @slot - Place `<rr-tab>` elements here
|
|
19
|
+
*
|
|
20
|
+
* @attr label - Accessible label for the tablist (required)
|
|
21
|
+
* @attr value - Currently selected tab value
|
|
22
|
+
*
|
|
23
|
+
* @fires change - When a tab is selected; detail: { value: string }
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* <rr-tab-list label="View options" value="overview">
|
|
27
|
+
* <rr-tab value="overview">Overview</rr-tab>
|
|
28
|
+
* <rr-tab value="history">History</rr-tab>
|
|
29
|
+
* <rr-tab value="settings">Settings</rr-tab>
|
|
30
|
+
* </rr-tab-list>
|
|
31
|
+
*/
|
|
32
|
+
let RrTabList = class RrTabList extends LitElement {
|
|
33
|
+
constructor() {
|
|
34
|
+
super(...arguments);
|
|
35
|
+
/** Accessible label for the tablist (required); sets aria-label on the role=tablist element. */
|
|
36
|
+
this.label = '';
|
|
37
|
+
/** Currently selected tab value. Reflected; syncs the matching rr-tab child's selected state. */
|
|
38
|
+
this.value = '';
|
|
39
|
+
this._onTabSelect = (e) => {
|
|
40
|
+
e.stopPropagation();
|
|
41
|
+
this.value = e.detail.value;
|
|
42
|
+
this._syncTabs();
|
|
43
|
+
this.dispatchEvent(new CustomEvent('change', {
|
|
44
|
+
bubbles: true,
|
|
45
|
+
composed: true,
|
|
46
|
+
detail: { value: this.value },
|
|
47
|
+
}));
|
|
48
|
+
};
|
|
49
|
+
this._onKeyDown = (e) => {
|
|
50
|
+
const tabs = this._getTabs().filter(t => !t.disabled);
|
|
51
|
+
if (tabs.length === 0)
|
|
52
|
+
return;
|
|
53
|
+
const current = tabs.findIndex(t => t.value === this.value);
|
|
54
|
+
let next = -1;
|
|
55
|
+
switch (e.key) {
|
|
56
|
+
case 'ArrowRight':
|
|
57
|
+
next = (current + 1) % tabs.length;
|
|
58
|
+
break;
|
|
59
|
+
case 'ArrowLeft':
|
|
60
|
+
next = (current - 1 + tabs.length) % tabs.length;
|
|
61
|
+
break;
|
|
62
|
+
case 'Home':
|
|
63
|
+
next = 0;
|
|
64
|
+
break;
|
|
65
|
+
case 'End':
|
|
66
|
+
next = tabs.length - 1;
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
const target = tabs[next];
|
|
73
|
+
this.value = target.value;
|
|
74
|
+
this._syncTabs();
|
|
75
|
+
this.dispatchEvent(new CustomEvent('change', {
|
|
76
|
+
bubbles: true,
|
|
77
|
+
composed: true,
|
|
78
|
+
detail: { value: this.value },
|
|
79
|
+
}));
|
|
80
|
+
// Move focus to the newly selected tab
|
|
81
|
+
target.focus();
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
connectedCallback() {
|
|
85
|
+
super.connectedCallback();
|
|
86
|
+
this.addEventListener('rr-tab-select', this._onTabSelect);
|
|
87
|
+
this.addEventListener('keydown', this._onKeyDown);
|
|
88
|
+
// Sync on first connect in case value is preset
|
|
89
|
+
this._syncTabs();
|
|
90
|
+
}
|
|
91
|
+
disconnectedCallback() {
|
|
92
|
+
super.disconnectedCallback();
|
|
93
|
+
this.removeEventListener('rr-tab-select', this._onTabSelect);
|
|
94
|
+
this.removeEventListener('keydown', this._onKeyDown);
|
|
95
|
+
}
|
|
96
|
+
updated(changed) {
|
|
97
|
+
if (changed.has('value')) {
|
|
98
|
+
this._syncTabs();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
_getTabs() {
|
|
102
|
+
return [...this.querySelectorAll('rr-tab')];
|
|
103
|
+
}
|
|
104
|
+
_syncTabs() {
|
|
105
|
+
const tabs = this._getTabs();
|
|
106
|
+
tabs.forEach(tab => {
|
|
107
|
+
tab.selected = tab.value === this.value;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
render() {
|
|
111
|
+
return html `
|
|
112
|
+
<div
|
|
113
|
+
class="tablist"
|
|
114
|
+
role="tablist"
|
|
115
|
+
aria-label="${this.label}"
|
|
116
|
+
>
|
|
117
|
+
<slot @slotchange="${this._syncTabs}"></slot>
|
|
118
|
+
</div>
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
RrTabList.styles = css `
|
|
123
|
+
:host {
|
|
124
|
+
display: block;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.tablist {
|
|
128
|
+
display: flex;
|
|
129
|
+
align-items: flex-end;
|
|
130
|
+
gap: 0;
|
|
131
|
+
border-bottom: 1px solid var(--color-border-alt);
|
|
132
|
+
overflow-x: auto;
|
|
133
|
+
scrollbar-width: none;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.tablist::-webkit-scrollbar {
|
|
137
|
+
display: none;
|
|
138
|
+
}
|
|
139
|
+
`;
|
|
140
|
+
__decorate([
|
|
141
|
+
property()
|
|
142
|
+
], RrTabList.prototype, "label", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
property({ reflect: true })
|
|
145
|
+
], RrTabList.prototype, "value", void 0);
|
|
146
|
+
RrTabList = __decorate([
|
|
147
|
+
customElement('rr-tab-list')
|
|
148
|
+
], RrTabList);
|
|
149
|
+
export { RrTabList };
|
|
150
|
+
//# sourceMappingURL=tab-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab-list.js","sourceRoot":"","sources":["../../src/tabs/tab-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/web-components-vite';
|
|
2
|
+
import '@digital2analogue2/parsimony-components';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
//# sourceMappingURL=tab-list.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab-list.stories.d.ts","sourceRoot":"","sources":["../../src/tabs/tab-list.stories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,yCAAyC,CAAC;AAEjD,QAAA,MAAM,IAAI,EAAE,IAqBX,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import '@digital2analogue2/parsimony-components';
|
|
3
|
+
const meta = {
|
|
4
|
+
title: 'Components/Tab List',
|
|
5
|
+
component: 'rr-tab-list',
|
|
6
|
+
argTypes: {
|
|
7
|
+
label: { control: 'text' },
|
|
8
|
+
value: { control: 'text' },
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
label: 'View options',
|
|
12
|
+
value: 'overview',
|
|
13
|
+
},
|
|
14
|
+
render: ({ label, value }) => html `
|
|
15
|
+
<rr-tab-list label=${label} value=${value}>
|
|
16
|
+
<rr-tab value="overview">Overview</rr-tab>
|
|
17
|
+
<rr-tab value="history">History</rr-tab>
|
|
18
|
+
<rr-tab value="settings">Settings</rr-tab>
|
|
19
|
+
</rr-tab-list>
|
|
20
|
+
<div style="padding-top: var(--spacing-element); color: var(--color-foreground-default);">
|
|
21
|
+
Panel content for the selected tab.
|
|
22
|
+
</div>
|
|
23
|
+
`,
|
|
24
|
+
};
|
|
25
|
+
export default meta;
|
|
26
|
+
export const Default = {};
|
|
27
|
+
//# sourceMappingURL=tab-list.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab-list.stories.js","sourceRoot":"","sources":["../../src/tabs/tab-list.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,yCAAyC,CAAC;AAEjD,MAAM,IAAI,GAAS;IACjB,KAAK,EAAE,qBAAqB;IAC5B,SAAS,EAAE,aAAa;IACxB,QAAQ,EAAE;QACR,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;QAC1B,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;KAC3B;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,cAAc;QACrB,KAAK,EAAE,UAAU;KAClB;IACD,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,CAAA;yBACX,KAAK,UAAU,KAAK;;;;;;;;GAQ1C;CACF,CAAC;AACF,eAAe,IAAI,CAAC;AAIpB,MAAM,CAAC,MAAM,OAAO,GAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* `<rr-tab>` — a single tab button, used inside `<rr-tab-list>`.
|
|
4
|
+
*
|
|
5
|
+
* Selection state is managed by the parent `<rr-tab-list>`. Do not set
|
|
6
|
+
* `selected` directly — use `rr-tab-list[value]` to control which tab is active.
|
|
7
|
+
*
|
|
8
|
+
* @slot - Tab label text (and optional icon)
|
|
9
|
+
*
|
|
10
|
+
* @attr value - Unique identifier for this tab (required)
|
|
11
|
+
* @attr selected - Set by parent; marks the active tab
|
|
12
|
+
* @attr disabled - Prevents selection
|
|
13
|
+
*
|
|
14
|
+
* @fires rr-tab-select - Bubbles up to rr-tab-list when clicked
|
|
15
|
+
*/
|
|
16
|
+
export declare class RrTab extends LitElement {
|
|
17
|
+
static shadowRootOptions: {
|
|
18
|
+
delegatesFocus: boolean;
|
|
19
|
+
clonable?: boolean;
|
|
20
|
+
customElementRegistry?: CustomElementRegistry | null;
|
|
21
|
+
mode: ShadowRootMode;
|
|
22
|
+
serializable?: boolean;
|
|
23
|
+
slotAssignment?: SlotAssignmentMode;
|
|
24
|
+
};
|
|
25
|
+
static styles: import("lit").CSSResult;
|
|
26
|
+
/** Unique identifier for this tab; must match the value rr-tab-list uses for selection. Reflected. */
|
|
27
|
+
value: string;
|
|
28
|
+
/** Marks the active tab. Set by the parent rr-tab-list — do not set directly. Reflected. */
|
|
29
|
+
selected: boolean;
|
|
30
|
+
/** Prevents selection. Reflected. */
|
|
31
|
+
disabled: boolean;
|
|
32
|
+
private _handleClick;
|
|
33
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
34
|
+
}
|
|
35
|
+
declare global {
|
|
36
|
+
interface HTMLElementTagNameMap {
|
|
37
|
+
'rr-tab': RrTab;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=tab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab.d.ts","sourceRoot":"","sources":["../../src/tabs/tab.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,KAAK,CAAC;AAGrD;;;;;;;;;;;;;GAaG;AACH,qBACa,KAAM,SAAQ,UAAU;IACnC,MAAM,CAAC,iBAAiB;;;;;;;MAA6D;IAErF,MAAM,CAAC,MAAM,0BA2CX;IAEF,sGAAsG;IACzE,KAAK,SAAM;IAExC,4FAA4F;IAChD,QAAQ,UAAS;IAE7D,qCAAqC;IACO,QAAQ,UAAS;IAE7D,OAAO,CAAC,YAAY;IASpB,MAAM;CAaP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,QAAQ,EAAE,KAAK,CAAC;KACjB;CACF"}
|
package/dist/tabs/tab.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { LitElement, html, css } from 'lit';
|
|
8
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
9
|
+
/**
|
|
10
|
+
* `<rr-tab>` — a single tab button, used inside `<rr-tab-list>`.
|
|
11
|
+
*
|
|
12
|
+
* Selection state is managed by the parent `<rr-tab-list>`. Do not set
|
|
13
|
+
* `selected` directly — use `rr-tab-list[value]` to control which tab is active.
|
|
14
|
+
*
|
|
15
|
+
* @slot - Tab label text (and optional icon)
|
|
16
|
+
*
|
|
17
|
+
* @attr value - Unique identifier for this tab (required)
|
|
18
|
+
* @attr selected - Set by parent; marks the active tab
|
|
19
|
+
* @attr disabled - Prevents selection
|
|
20
|
+
*
|
|
21
|
+
* @fires rr-tab-select - Bubbles up to rr-tab-list when clicked
|
|
22
|
+
*/
|
|
23
|
+
let RrTab = class RrTab extends LitElement {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
/** Unique identifier for this tab; must match the value rr-tab-list uses for selection. Reflected. */
|
|
27
|
+
this.value = '';
|
|
28
|
+
/** Marks the active tab. Set by the parent rr-tab-list — do not set directly. Reflected. */
|
|
29
|
+
this.selected = false;
|
|
30
|
+
/** Prevents selection. Reflected. */
|
|
31
|
+
this.disabled = false;
|
|
32
|
+
}
|
|
33
|
+
_handleClick() {
|
|
34
|
+
if (this.disabled || this.selected)
|
|
35
|
+
return;
|
|
36
|
+
this.dispatchEvent(new CustomEvent('rr-tab-select', {
|
|
37
|
+
bubbles: true,
|
|
38
|
+
composed: true,
|
|
39
|
+
detail: { value: this.value },
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
render() {
|
|
43
|
+
return html `
|
|
44
|
+
<button
|
|
45
|
+
role="tab"
|
|
46
|
+
aria-selected="${this.selected ? 'true' : 'false'}"
|
|
47
|
+
tabindex="${this.selected ? 0 : -1}"
|
|
48
|
+
?disabled="${this.disabled}"
|
|
49
|
+
@click="${this._handleClick}"
|
|
50
|
+
>
|
|
51
|
+
<slot></slot>
|
|
52
|
+
</button>
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
RrTab.shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };
|
|
57
|
+
RrTab.styles = css `
|
|
58
|
+
:host {
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
button {
|
|
63
|
+
all: unset;
|
|
64
|
+
display: inline-flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
gap: var(--spacing-tight);
|
|
67
|
+
padding: var(--spacing-tight) var(--spacing-inline);
|
|
68
|
+
font: var(--font-label-medium);
|
|
69
|
+
color: var(--color-foreground-muted);
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
border-bottom: 2px solid transparent;
|
|
72
|
+
transition:
|
|
73
|
+
color var(--motion-duration-instant) var(--motion-easing-default),
|
|
74
|
+
border-color var(--motion-duration-instant) var(--motion-easing-default);
|
|
75
|
+
white-space: nowrap;
|
|
76
|
+
position: relative;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
button:hover {
|
|
80
|
+
color: var(--color-foreground-alt);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
button:focus-visible {
|
|
84
|
+
outline: 2px solid var(--color-border-focus);
|
|
85
|
+
outline-offset: 2px;
|
|
86
|
+
border-radius: var(--radius-sm);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
:host([selected]) button {
|
|
90
|
+
color: var(--color-foreground-action);
|
|
91
|
+
border-bottom-color: var(--color-background-action);
|
|
92
|
+
font: var(--font-label-strong-medium);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
:host([disabled]) button {
|
|
96
|
+
color: var(--color-foreground-disabled);
|
|
97
|
+
cursor: not-allowed;
|
|
98
|
+
pointer-events: none;
|
|
99
|
+
}
|
|
100
|
+
`;
|
|
101
|
+
__decorate([
|
|
102
|
+
property({ reflect: true })
|
|
103
|
+
], RrTab.prototype, "value", void 0);
|
|
104
|
+
__decorate([
|
|
105
|
+
property({ type: Boolean, reflect: true })
|
|
106
|
+
], RrTab.prototype, "selected", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
property({ type: Boolean, reflect: true })
|
|
109
|
+
], RrTab.prototype, "disabled", void 0);
|
|
110
|
+
RrTab = __decorate([
|
|
111
|
+
customElement('rr-tab')
|
|
112
|
+
], RrTab);
|
|
113
|
+
export { RrTab };
|
|
114
|
+
//# sourceMappingURL=tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab.js","sourceRoot":"","sources":["../../src/tabs/tab.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAW,MAAM,KAAK,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AAEI,IAAM,KAAK,GAAX,MAAM,KAAM,SAAQ,UAAU;IAA9B;;QAgDL,sGAAsG;QACzE,UAAK,GAAG,EAAE,CAAC;QAExC,4FAA4F;QAChD,aAAQ,GAAG,KAAK,CAAC;QAE7D,qCAAqC;QACO,aAAQ,GAAG,KAAK,CAAC;IAwB/D,CAAC;IAtBS,YAAY;QAClB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC3C,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,eAAe,EAAE;YAClD,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;SAC9B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;yBAGU,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;oBACrC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;qBACrB,IAAI,CAAC,QAAQ;kBAChB,IAAI,CAAC,YAAY;;;;KAI9B,CAAC;IACJ,CAAC;;AA7EM,uBAAiB,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,EAAE,cAAc,EAAE,IAAI,EAAE,AAA5D,CAA6D;AAE9E,YAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2ClB,AA3CY,CA2CX;AAG2B;IAA5B,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;oCAAY;AAGI;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;uCAAkB;AAGjB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;uCAAkB;AAvDlD,KAAK;IADjB,aAAa,CAAC,QAAQ,CAAC;GACX,KAAK,CA+EjB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/web-components-vite';
|
|
2
|
+
import '@digital2analogue2/parsimony-components';
|
|
3
|
+
/**
|
|
4
|
+
* `rr-tab` is a single tab button. Selection is normally managed by the
|
|
5
|
+
* parent `rr-tab-list` (it sets `selected` and handles keyboard navigation).
|
|
6
|
+
* This standalone story shows one tab in isolation for reference — see the
|
|
7
|
+
* Tab List stories for real usage.
|
|
8
|
+
*/
|
|
9
|
+
declare const meta: Meta;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj;
|
|
12
|
+
export declare const Default: Story;
|
|
13
|
+
//# sourceMappingURL=tab.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab.stories.d.ts","sourceRoot":"","sources":["../../src/tabs/tab.stories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,yCAAyC,CAAC;AAEjD;;;;;GAKG;AACH,QAAA,MAAM,IAAI,EAAE,IAgBX,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import '@digital2analogue2/parsimony-components';
|
|
3
|
+
/**
|
|
4
|
+
* `rr-tab` is a single tab button. Selection is normally managed by the
|
|
5
|
+
* parent `rr-tab-list` (it sets `selected` and handles keyboard navigation).
|
|
6
|
+
* This standalone story shows one tab in isolation for reference — see the
|
|
7
|
+
* Tab List stories for real usage.
|
|
8
|
+
*/
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Components/Tab',
|
|
11
|
+
component: 'rr-tab',
|
|
12
|
+
argTypes: {
|
|
13
|
+
value: { control: 'text' },
|
|
14
|
+
selected: { control: 'boolean' },
|
|
15
|
+
disabled: { control: 'boolean' },
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
value: 'overview',
|
|
19
|
+
selected: true,
|
|
20
|
+
disabled: false,
|
|
21
|
+
},
|
|
22
|
+
render: ({ value, selected, disabled }) => html `
|
|
23
|
+
<rr-tab value=${value} ?selected=${selected} ?disabled=${disabled}>Overview</rr-tab>
|
|
24
|
+
`,
|
|
25
|
+
};
|
|
26
|
+
export default meta;
|
|
27
|
+
export const Default = {};
|
|
28
|
+
//# sourceMappingURL=tab.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab.stories.js","sourceRoot":"","sources":["../../src/tabs/tab.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,yCAAyC,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,IAAI,GAAS;IACjB,KAAK,EAAE,gBAAgB;IACvB,SAAS,EAAE,QAAQ;IACnB,QAAQ,EAAE;QACR,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;QAC1B,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;QAChC,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;KACjC;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,KAAK;KAChB;IACD,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,IAAI,CAAA;oBAC7B,KAAK,cAAc,QAAQ,cAAc,QAAQ;GAClE;CACF,CAAC;AACF,eAAe,IAAI,CAAC;AAIpB,MAAM,CAAC,MAAM,OAAO,GAAU,EAAE,CAAC"}
|