Skip to content

Commit 2b86453

Browse files
committed
feat(admin): implement ChartLegend component with Storybook stories #206
1 parent 8d7c815 commit 2b86453

2 files changed

Lines changed: 399 additions & 0 deletions

File tree

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
<!--
2+
SPDX-FileCopyrightText: 2025 hexaTune LLC
3+
SPDX-License-Identifier: MIT
4+
-->
5+
6+
<script module>
7+
import { defineMeta } from '@storybook/addon-svelte-csf';
8+
import ChartLegend from './ChartLegend.svelte';
9+
10+
const { Story } = defineMeta({
11+
title: 'Admin/Dashboard/ChartLegend',
12+
component: ChartLegend,
13+
tags: ['autodocs'],
14+
argTypes: {
15+
items: {
16+
control: 'object',
17+
description: 'Array of legend items to display'
18+
},
19+
orientation: {
20+
control: { type: 'select' },
21+
options: ['horizontal', 'vertical'],
22+
description: 'Layout orientation of the legend'
23+
},
24+
position: {
25+
control: { type: 'select' },
26+
options: ['top', 'bottom', 'left', 'right'],
27+
description: 'Position of the legend relative to chart'
28+
},
29+
size: {
30+
control: { type: 'select' },
31+
options: ['xs', 'sm', 'md', 'lg'],
32+
description: 'Size of the legend items'
33+
},
34+
interactive: {
35+
control: 'boolean',
36+
description: 'Enable interactive mode (clickable items)'
37+
},
38+
showValues: {
39+
control: 'boolean',
40+
description: 'Show values next to labels'
41+
},
42+
spacing: {
43+
control: { type: 'select' },
44+
options: ['compact', 'normal', 'relaxed'],
45+
description: 'Spacing between legend items'
46+
},
47+
ariaLabel: {
48+
control: 'text',
49+
description: 'Accessible label for the legend'
50+
},
51+
ariaLive: {
52+
control: { type: 'select' },
53+
options: ['off', 'polite', 'assertive'],
54+
description: 'Screen reader announcement level'
55+
}
56+
},
57+
args: {
58+
items: [
59+
{ label: 'Series 1', color: '#3b82f6' },
60+
{ label: 'Series 2', color: '#10b981' },
61+
{ label: 'Series 3', color: '#f59e0b' }
62+
],
63+
orientation: 'horizontal',
64+
position: 'bottom',
65+
size: 'md',
66+
interactive: false,
67+
showValues: false,
68+
spacing: 'normal',
69+
ariaLabel: 'Chart legend'
70+
}
71+
});
72+
</script>
73+
74+
<!-- Default Story -->
75+
<Story
76+
name="Default"
77+
args={{
78+
items: [
79+
{ label: 'Series 1', color: '#3b82f6' },
80+
{ label: 'Series 2', color: '#10b981' },
81+
{ label: 'Series 3', color: '#f59e0b' }
82+
]
83+
}}
84+
/>
85+
86+
<!-- Size Variants -->
87+
<Story
88+
name="Small Size"
89+
args={{
90+
items: [
91+
{ label: 'Desktop', color: '#3b82f6', value: '45%' },
92+
{ label: 'Mobile', color: '#10b981', value: '35%' },
93+
{ label: 'Tablet', color: '#f59e0b', value: '20%' }
94+
],
95+
size: 'sm',
96+
showValues: true
97+
}}
98+
/>
99+
100+
<Story
101+
name="Large Size"
102+
args={{
103+
items: [
104+
{ label: 'Desktop', color: '#3b82f6', value: '45%' },
105+
{ label: 'Mobile', color: '#10b981', value: '35%' },
106+
{ label: 'Tablet', color: '#f59e0b', value: '20%' }
107+
],
108+
size: 'lg',
109+
showValues: true
110+
}}
111+
/>
112+
113+
<!-- Orientation & Spacing -->
114+
<Story
115+
name="Vertical Orientation"
116+
args={{
117+
items: [
118+
{ label: 'Q1 Sales', color: '#3b82f6', value: '$125K' },
119+
{ label: 'Q2 Sales', color: '#10b981', value: '$142K' },
120+
{ label: 'Q3 Sales', color: '#f59e0b', value: '$138K' },
121+
{ label: 'Q4 Sales', color: '#8b5cf6', value: '$165K' }
122+
],
123+
orientation: 'vertical',
124+
showValues: true
125+
}}
126+
/>
127+
128+
<Story
129+
name="Compact Spacing"
130+
args={{
131+
items: [
132+
{ label: 'Chrome', color: '#3b82f6' },
133+
{ label: 'Firefox', color: '#f59e0b' },
134+
{ label: 'Safari', color: '#10b981' },
135+
{ label: 'Edge', color: '#06b6d4' },
136+
{ label: 'Other', color: '#6b7280' }
137+
],
138+
spacing: 'compact'
139+
}}
140+
/>
141+
142+
<!-- Interactive & States -->
143+
<Story
144+
name="Interactive"
145+
args={{
146+
items: [
147+
{ label: 'Active Users', color: '#3b82f6', value: '1,234' },
148+
{ label: 'New Users', color: '#10b981', value: '567' },
149+
{ label: 'Returning Users', color: '#f59e0b', value: '890' }
150+
],
151+
interactive: true,
152+
showValues: true
153+
}}
154+
/>
155+
156+
<Story
157+
name="Disabled Items"
158+
args={{
159+
items: [
160+
{ label: 'Active', color: '#10b981', value: '1,234' },
161+
{ label: 'Inactive', color: '#6b7280', value: '567', disabled: true },
162+
{ label: 'Pending', color: '#f59e0b', value: '89', disabled: true }
163+
],
164+
interactive: true,
165+
showValues: true
166+
}}
167+
/>
168+
169+
<Story
170+
name="Empty State"
171+
args={{
172+
items: [],
173+
ariaLabel: 'No data available'
174+
}}
175+
/>
176+
177+
<!-- Color Variants -->
178+
<Story
179+
name="Vibrant Colors"
180+
args={{
181+
items: [
182+
{ label: 'Red', color: '#ef4444', value: '25%' },
183+
{ label: 'Orange', color: '#f97316', value: '20%' },
184+
{ label: 'Yellow', color: '#eab308', value: '15%' },
185+
{ label: 'Green', color: '#22c55e', value: '18%' },
186+
{ label: 'Blue', color: '#3b82f6', value: '22%' }
187+
],
188+
showValues: true
189+
}}
190+
/>
191+
192+
<!-- Accessibility Testing -->
193+
<Story
194+
name="Accessibility Test"
195+
args={{
196+
items: [
197+
{ label: 'Keyboard Navigable', color: '#3b82f6', value: 'Tab to focus' },
198+
{ label: 'Enter/Space to Click', color: '#10b981', value: 'Try it!' },
199+
{ label: 'Screen Reader Friendly', color: '#f59e0b', value: 'ARIA labels' }
200+
],
201+
interactive: true,
202+
showValues: true,
203+
ariaLabel: 'Accessibility demonstration legend',
204+
ariaLive: 'assertive'
205+
}}
206+
/>
207+
208+
<!-- Playground -->
209+
<Story
210+
name="Playground"
211+
args={{
212+
items: [
213+
{ label: 'Primary', color: '#3b82f6', value: '45%' },
214+
{ label: 'Success', color: '#10b981', value: '30%' },
215+
{ label: 'Warning', color: '#f59e0b', value: '15%', disabled: false },
216+
{ label: 'Error', color: '#ef4444', value: '10%', disabled: false }
217+
],
218+
orientation: 'horizontal',
219+
position: 'bottom',
220+
size: 'md',
221+
interactive: true,
222+
showValues: true,
223+
spacing: 'normal',
224+
ariaLabel: 'Interactive playground legend',
225+
ariaLive: 'polite'
226+
}}
227+
/>

0 commit comments

Comments
 (0)