astro-component-kit 0.4.1 → 0.5.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.
@@ -0,0 +1,500 @@
1
+ import type { ComponentDoc } from './types';
2
+
3
+ export const charts: ComponentDoc[] = [
4
+ {
5
+ slug: 'area-chart',
6
+ name: 'Area Chart',
7
+ description: 'A premium, smooth area chart with gradient fills and glassmorphism tooltips.',
8
+ category: 'charts',
9
+ tags: ['data', 'analytics', 'chart', 'area', 'premium'],
10
+ featured: true,
11
+ code: `---
12
+ import { AreaChart } from 'astro-component-kit/charts';
13
+
14
+ // Example 1: Basic Revenue
15
+ const cat1 = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
16
+ const ser1 = [{ name: 'Revenue', data: [31, 40, 28, 51, 42] }];
17
+
18
+ // Example 2: Comparison
19
+ const cat2 = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
20
+ const ser2 = [
21
+ { name: 'Direct', data: [45, 52, 38, 24, 33] },
22
+ { name: 'Social', data: [12, 17, 11, 9, 15] }
23
+ ];
24
+ ---
25
+
26
+ <!-- Single Series -->
27
+ <AreaChart
28
+ title="Monthly Revenue"
29
+ categories={cat1}
30
+ series={ser1}
31
+ />
32
+
33
+ <!-- Multi-series Comparison -->
34
+ <AreaChart
35
+ title="Traffic Sources"
36
+ subtitle="Comparing direct vs social traffic"
37
+ categories={cat2}
38
+ series={ser2}
39
+ colors={['#b8860b', '#3b82f6']}
40
+ />`,
41
+ installation: {
42
+ command: `npm install apexcharts`,
43
+ manual: `1. Install apexcharts as a dependency.
44
+ 2. Copy the AreaChart.astro file to your components folder.
45
+ 3. Import and use the component in your pages.`
46
+ },
47
+ usage: `---
48
+ import { AreaChart } from 'astro-component-kit';
49
+
50
+ const categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
51
+ const series = [{
52
+ name: 'Sales',
53
+ data: [31, 40, 28, 51, 42]
54
+ }];
55
+ ---
56
+
57
+ <AreaChart
58
+ title="Monthly Sales"
59
+ categories={categories}
60
+ series={series}
61
+ variant="primary"
62
+ />`,
63
+ },
64
+ {
65
+ slug: 'bar-chart',
66
+ name: 'Bar Chart',
67
+ description: 'A clean bar chart with rounded corners and multi-series support.',
68
+ category: 'charts',
69
+ tags: ['data', 'analytics', 'chart', 'bar'],
70
+ featured: false,
71
+ code: `---
72
+ import { BarChart } from 'astro-component-kit/charts';
73
+
74
+ // Example 1: Vertical Bars
75
+ const cat1 = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
76
+ const ser1 = [{ name: 'Sessions', data: [44, 55, 41, 67, 22] }];
77
+
78
+ // Example 2: Horizontal Stacked
79
+ const cat2 = ['Q1', 'Q2', 'Q3', 'Q4'];
80
+ const ser2 = [
81
+ { name: 'Product A', data: [12, 17, 11, 9] },
82
+ { name: 'Product B', data: [15, 11, 14, 18] }
83
+ ];
84
+ ---
85
+
86
+ <!-- Basic Vertical -->
87
+ <BarChart
88
+ title="Daily Sessions"
89
+ categories={cat1}
90
+ series={ser1}
91
+ />
92
+
93
+ <!-- Horizontal Stacked -->
94
+ <BarChart
95
+ title="Quarterly Sales"
96
+ subtitle="Product distribution by quarter"
97
+ categories={cat2}
98
+ series={ser2}
99
+ horizontal={true}
100
+ stacked={true}
101
+ />`,
102
+ installation: {
103
+ command: `npm install apexcharts`,
104
+ manual: `1. Install apexcharts as a dependency.
105
+ 2. Copy the BarChart.astro file to your components folder.
106
+ 3. Import and use the component in your pages.`
107
+ },
108
+ usage: `---
109
+ import { BarChart } from 'astro-component-kit';
110
+
111
+ const categories = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
112
+ const series = [{ name: 'Sessions', data: [44, 55, 41, 67, 22] }];
113
+ ---
114
+
115
+ <BarChart
116
+ title="Daily Traffic"
117
+ categories={categories}
118
+ series={series}
119
+ />`,
120
+ },
121
+ {
122
+ slug: 'donut-chart',
123
+ name: 'Donut Chart',
124
+ description: 'A minimalist donut chart with a centered label and interactive segments.',
125
+ category: 'charts',
126
+ tags: ['data', 'analytics', 'chart', 'donut', 'pie'],
127
+ featured: false,
128
+ code: `---
129
+ import { DonutChart } from 'astro-component-kit/charts';
130
+
131
+ // Example 1: Standard Donut
132
+ const labels1 = ['Desktop', 'Mobile', 'Tablet'];
133
+ const series1 = [65, 25, 10];
134
+
135
+ // Example 2: Full Pie
136
+ const labels2 = ['Completed', 'Pending', 'Delayed'];
137
+ const series2 = [70, 20, 10];
138
+ ---
139
+
140
+ <!-- Standard Donut -->
141
+ <DonutChart
142
+ title="Device Distribution"
143
+ labels={labels1}
144
+ series={series1}
145
+ centerLabel="Devices"
146
+ />
147
+
148
+ <!-- Full Pie Chart -->
149
+ <DonutChart
150
+ title="Task Status"
151
+ labels={labels2}
152
+ series={series2}
153
+ pie={true}
154
+ colors={['#10b981', '#f59e0b', '#ef4444']}
155
+ />`,
156
+ installation: {
157
+ command: `npm install apexcharts`,
158
+ manual: `1. Install apexcharts as a dependency.
159
+ 2. Copy the DonutChart.astro file to your components folder.
160
+ 3. Import and use the component in your pages.`
161
+ },
162
+ usage: `---
163
+ import { DonutChart } from 'astro-component-kit';
164
+
165
+ const labels = ['Desktop', 'Mobile', 'Tablet'];
166
+ const series = [65, 25, 10];
167
+ ---
168
+
169
+ <DonutChart
170
+ title="Device Share"
171
+ labels={labels}
172
+ series={series}
173
+ centerLabel="Devices"
174
+ />`,
175
+ },
176
+ {
177
+ slug: 'radar-metric-chart',
178
+ name: 'Radar Metric Chart',
179
+ description: 'Polygon spider radar chart visualizing multi-attribute scores (e.g. Speed, SEO, Accessibility, Security) with SVG canvas.',
180
+ category: 'charts',
181
+ tags: ["charts","radar","polygon","spider","metrics"],
182
+ featured: true,
183
+ code: `---
184
+ /**
185
+ * RadarMetricChart — Pure SVG radar / spider chart for multi-axis skill and performance visualization.
186
+ *
187
+ * @param {string} title - Chart title. Default is 'Performance Metrics'.
188
+ * @param {Array<{axis: string, value: number}>} data - 5 or 6 axis points (values 0 to 100).
189
+ * @param {string} color - Primary chart fill & stroke color. Default is '#d4a017'.
190
+ * @param {number} size - Pixel width/height of the radar. Default is 320.
191
+ */
192
+ interface Props {
193
+ title?: string;
194
+ data?: Array<{ axis: string; value: number }>;
195
+ color?: string;
196
+ size?: number;
197
+ }
198
+
199
+ const {
200
+ title = 'System Capabilities',
201
+ data = [
202
+ { axis: 'Speed', value: 95 },
203
+ { axis: 'A11y', value: 98 },
204
+ { axis: 'SEO', value: 100 },
205
+ { axis: 'Design', value: 92 },
206
+ { axis: 'Zero-JS', value: 96 },
207
+ { axis: 'Security', value: 90 },
208
+ ],
209
+ color = '#d4a017',
210
+ size = 320,
211
+ } = Astro.props;
212
+
213
+ const center = size / 2;
214
+ const radius = (size - 70) / 2;
215
+ const totalAxes = data.length;
216
+ const angleSlice = (Math.PI * 2) / totalAxes;
217
+
218
+ // Concentric polygon grid levels (20%, 40%, 60%, 80%, 100%)
219
+ const levels = [0.2, 0.4, 0.6, 0.8, 1.0];
220
+ const gridPolygons = levels.map((lvl) => {
221
+ return data
222
+ .map((_, i) => {
223
+ const r = radius * lvl;
224
+ const x = center + r * Math.cos(angleSlice * i - Math.PI / 2);
225
+ const y = center + r * Math.sin(angleSlice * i - Math.PI / 2);
226
+ return \`\${x},\${y}\`;
227
+ })
228
+ .join(' ');
229
+ });
230
+
231
+ // Data polygon points
232
+ const dataPoints = data
233
+ .map((d, i) => {
234
+ const r = radius * (Math.min(100, Math.max(0, d.value)) / 100);
235
+ const x = center + r * Math.cos(angleSlice * i - Math.PI / 2);
236
+ const y = center + r * Math.sin(angleSlice * i - Math.PI / 2);
237
+ return \`\${x},\${y}\`;
238
+ })
239
+ .join(' ');
240
+ ---
241
+
242
+ <div class="radar-card" style={\`--radar-size: \${size}px; --radar-color: \${color};\`}>
243
+ {title && <h5 class="radar-card__title">{title}</h5>}
244
+
245
+ <div class="radar-card__wrap">
246
+ <svg width={size} height={size} class="radar-card__svg">
247
+ <!-- Background concentric webs -->
248
+ {gridPolygons.map((pts) => (
249
+ <polygon points={pts} class="radar-web" />
250
+ ))}
251
+
252
+ <!-- Axes radial spokes -->
253
+ {data.map((_, i) => {
254
+ const x2 = center + radius * Math.cos(angleSlice * i - Math.PI / 2);
255
+ const y2 = center + radius * Math.sin(angleSlice * i - Math.PI / 2);
256
+ return <line x1={center} y1={center} x2={x2} y2={y2} class="radar-spoke" />;
257
+ })}
258
+
259
+ <!-- Data polygon -->
260
+ <polygon points={dataPoints} class="radar-data" />
261
+
262
+ <!-- Data nodes -->
263
+ {data.map((d, i) => {
264
+ const r = radius * (d.value / 100);
265
+ const cx = center + r * Math.cos(angleSlice * i - Math.PI / 2);
266
+ const cy = center + r * Math.sin(angleSlice * i - Math.PI / 2);
267
+ return <circle cx={cx} cy={cy} r="4" class="radar-node" />;
268
+ })}
269
+
270
+ <!-- Axis Labels -->
271
+ {data.map((d, i) => {
272
+ const labelRadius = radius + 22;
273
+ const lx = center + labelRadius * Math.cos(angleSlice * i - Math.PI / 2);
274
+ const ly = center + labelRadius * Math.sin(angleSlice * i - Math.PI / 2);
275
+ return (
276
+ <text
277
+ x={lx}
278
+ y={ly}
279
+ class="radar-label"
280
+ text-anchor="middle"
281
+ dominant-baseline="central"
282
+ >
283
+ {d.axis} ({d.value})
284
+ </text>
285
+ );
286
+ })}
287
+ </svg>
288
+ </div>
289
+ </div>
290
+
291
+ <style>
292
+ .radar-card {
293
+ display: flex;
294
+ flex-direction: column;
295
+ align-items: center;
296
+ padding: var(--sp-6, 1.5rem);
297
+ background: rgba(255, 255, 255, 0.02);
298
+ backdrop-filter: blur(16px);
299
+ border: 1px solid rgba(255, 255, 255, 0.08);
300
+ border-radius: var(--r-xl, 24px);
301
+ width: 100%;
302
+ max-width: fit-content;
303
+ font-family: var(--font-sans, system-ui, sans-serif);
304
+ }
305
+
306
+ .radar-card__title {
307
+ font-size: 0.95rem;
308
+ font-weight: 800;
309
+ color: var(--c-text-1, #ffffff);
310
+ margin: 0 0 12px 0;
311
+ }
312
+
313
+ .radar-card__wrap {
314
+ display: flex;
315
+ align-items: center;
316
+ justify-content: center;
317
+ }
318
+
319
+ .radar-web {
320
+ fill: none;
321
+ stroke: rgba(255, 255, 255, 0.08);
322
+ stroke-width: 1;
323
+ }
324
+
325
+ .radar-spoke {
326
+ stroke: rgba(255, 255, 255, 0.08);
327
+ stroke-width: 1;
328
+ }
329
+
330
+ .radar-data {
331
+ fill: rgba(184, 134, 11, 0.25);
332
+ stroke: var(--radar-color);
333
+ stroke-width: 2.5;
334
+ transition: all 0.4s ease;
335
+ }
336
+
337
+ .radar-node {
338
+ fill: var(--radar-color);
339
+ stroke: #050505;
340
+ stroke-width: 2;
341
+ }
342
+
343
+ .radar-label {
344
+ fill: var(--c-text-2, #a3a3a3);
345
+ font-size: 10.5px;
346
+ font-weight: 700;
347
+ text-transform: uppercase;
348
+ letter-spacing: 0.05em;
349
+ }
350
+ </style>
351
+ `,
352
+ usage: `<RadarMetricChart title="Performance Audit" metrics={[{ label: 'Speed', value: 92 }, { label: 'SEO', value: 98 }, { label: 'a11y', value: 100 }, { label: 'Security', value: 95 }, { label: 'PWA', value: 88 }]} />`,
353
+ },
354
+ {
355
+ slug: 'linear-progress-gauge',
356
+ name: 'Linear Progress Gauge',
357
+ description: 'Segmented target quota and budget gauge bar with colored threshold markers and percent label.',
358
+ category: 'charts',
359
+ tags: ["charts","gauge","linear","progress","quota"],
360
+ featured: false,
361
+ code: `---
362
+ /**
363
+ * LinearProgressGauge — Multi-segmented horizontal memory or budget progress bar with breakdown legend.
364
+ *
365
+ * @param {string} title - Gauge header label. Default is 'Resource Allocation'.
366
+ * @param {Array<{label: string, value: number, color: string}>} segments - Proportion breakdown chunks.
367
+ * @param {string} total - Formatted total capacity string (e.g. '16 GB', '100%'). Default is '100%'.
368
+ */
369
+ interface Props {
370
+ title?: string;
371
+ segments?: Array<{ label: string; value: number; color: string }>;
372
+ total?: string;
373
+ }
374
+
375
+ const {
376
+ title = 'System Resource Allocation',
377
+ segments = [
378
+ { label: 'SSR Execution', value: 45, color: '#d4a017' },
379
+ { label: 'Asset Caching', value: 25, color: '#38bdf8' },
380
+ { label: 'Edge Worker', value: 15, color: '#a855f7' },
381
+ { label: 'Free Headroom', value: 15, color: 'rgba(255,255,255,0.1)' },
382
+ ],
383
+ total = '100%',
384
+ } = Astro.props;
385
+
386
+ const totalSum = segments.reduce((acc, s) => acc + s.value, 0) || 100;
387
+ ---
388
+
389
+ <div class="linear-gauge">
390
+ <div class="linear-gauge__header">
391
+ <span class="linear-gauge__title">{title}</span>
392
+ <span class="linear-gauge__total">{total}</span>
393
+ </div>
394
+
395
+ <div class="linear-gauge__bar" role="progressbar" aria-valuemax="100" aria-valuemin="0">
396
+ {segments.map((seg) => {
397
+ const pct = (seg.value / totalSum) * 100;
398
+ return (
399
+ <div
400
+ class="linear-gauge__chunk"
401
+ style={\`width: \${pct}%; background-color: \${seg.color};\`}
402
+ title={\`\${seg.label}: \${seg.value}%\`}
403
+ />
404
+ );
405
+ })}
406
+ </div>
407
+
408
+ <div class="linear-gauge__legend">
409
+ {segments.map((seg) => (
410
+ <div class="legend-item">
411
+ <span class="legend-item__dot" style={\`background-color: \${seg.color};\`}></span>
412
+ <span class="legend-item__name">{seg.label}</span>
413
+ <span class="legend-item__val">{seg.value}%</span>
414
+ </div>
415
+ ))}
416
+ </div>
417
+ </div>
418
+
419
+ <style>
420
+ .linear-gauge {
421
+ display: flex;
422
+ flex-direction: column;
423
+ gap: 12px;
424
+ width: 100%;
425
+ max-width: 440px;
426
+ padding: var(--sp-6, 1.5rem);
427
+ background: rgba(255, 255, 255, 0.02);
428
+ backdrop-filter: blur(16px);
429
+ border: 1px solid rgba(255, 255, 255, 0.08);
430
+ border-radius: var(--r-xl, 20px);
431
+ font-family: var(--font-sans, system-ui, sans-serif);
432
+ }
433
+
434
+ .linear-gauge__header {
435
+ display: flex;
436
+ justify-content: space-between;
437
+ align-items: center;
438
+ }
439
+
440
+ .linear-gauge__title {
441
+ font-size: 0.88rem;
442
+ font-weight: 700;
443
+ color: var(--c-text-1, #ffffff);
444
+ }
445
+
446
+ .linear-gauge__total {
447
+ font-size: 0.82rem;
448
+ font-weight: 800;
449
+ color: var(--c-primary-light, #d4a017);
450
+ }
451
+
452
+ .linear-gauge__bar {
453
+ display: flex;
454
+ height: 10px;
455
+ border-radius: var(--r-full, 9999px);
456
+ overflow: hidden;
457
+ background: rgba(255, 255, 255, 0.05);
458
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5);
459
+ }
460
+
461
+ .linear-gauge__chunk {
462
+ height: 100%;
463
+ transition: width 0.4s ease;
464
+ }
465
+
466
+ .linear-gauge__legend {
467
+ display: grid;
468
+ grid-template-columns: repeat(2, 1fr);
469
+ gap: 8px 12px;
470
+ margin-top: 4px;
471
+ }
472
+
473
+ .legend-item {
474
+ display: flex;
475
+ align-items: center;
476
+ gap: 6px;
477
+ font-size: 0.75rem;
478
+ }
479
+
480
+ .legend-item__dot {
481
+ width: 8px;
482
+ height: 8px;
483
+ border-radius: 50%;
484
+ flex-shrink: 0;
485
+ }
486
+
487
+ .legend-item__name {
488
+ color: var(--c-text-2, #a3a3a3);
489
+ flex: 1;
490
+ }
491
+
492
+ .legend-item__val {
493
+ font-weight: 700;
494
+ color: var(--c-text-1, #ffffff);
495
+ }
496
+ </style>
497
+ `,
498
+ usage: `<LinearProgressGauge title="Monthly Storage Quota" current={42.8} max={50} unit="GB" />`,
499
+ },
500
+ ];