@codecademy/styleguide 78.5.5-alpha.4615f3.0 → 78.5.5-alpha.6dced4.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/CHANGELOG.md CHANGED
@@ -3,7 +3,7 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ### [78.5.5-alpha.4615f3.0](https://github.com/Codecademy/gamut/compare/@codecademy/styleguide@78.5.4...@codecademy/styleguide@78.5.5-alpha.4615f3.0) (2025-12-19)
6
+ ### [78.5.5-alpha.6dced4.0](https://github.com/Codecademy/gamut/compare/@codecademy/styleguide@78.5.4...@codecademy/styleguide@78.5.5-alpha.6dced4.0) (2026-01-05)
7
7
 
8
8
  **Note:** Version bump only for package @codecademy/styleguide
9
9
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@codecademy/styleguide",
3
3
  "description": "Styleguide & Component library for codecademy.com",
4
- "version": "78.5.5-alpha.4615f3.0",
4
+ "version": "78.5.5-alpha.6dced4.0",
5
5
  "author": "Codecademy Engineering",
6
6
  "license": "MIT",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
10
10
  "repository": "git@github.com:Codecademy/gamut.git",
11
- "gitHead": "ecdbb1e8e5dfbdc49939350ac4b9acd28333725a"
11
+ "gitHead": "e46527aa333a945b06c5ff675d72dc30250f8de3"
12
12
  }
@@ -38,7 +38,6 @@ export const VENDOR_ICONS = pick(
38
38
  'ReactIcon',
39
39
  'RedditIcon',
40
40
  'RedditSolidIcon',
41
- 'SkillsoftIcon',
42
41
  'SlackIcon',
43
42
  'SpotifyIcon',
44
43
  'TikTokIcon',
@@ -0,0 +1,92 @@
1
+ import { Canvas, Controls, Meta } from '@storybook/blocks';
2
+
3
+ import { ComponentHeader } from '~styleguide/blocks';
4
+
5
+ import * as BarChartStories from './BarChart.stories';
6
+
7
+ export const parameters = {
8
+ subtitle: `A horizontal bar chart for visualizing comparative data`,
9
+ design: {
10
+ type: 'figma',
11
+ url: 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=55123-4176',
12
+ },
13
+ status: 'current',
14
+ source: {
15
+ repo: 'gamut',
16
+ githubLink:
17
+ 'https://github.com/Codecademy/gamut/blob/main/packages/gamut/src/BarChart',
18
+ },
19
+ };
20
+
21
+ <Meta of={BarChartStories} />;
22
+
23
+ <ComponentHeader {...parameters} />
24
+
25
+ ## Usage
26
+
27
+ Use BarChart to display comparative data across categories, such as skills progress, XP earned, or any quantitative metrics that benefit from visual comparison.
28
+
29
+ ### Best practices:
30
+
31
+ - Use consistent units across all bars in a chart
32
+ - Limit the number of bars to maintain readability (5-10 is optimal)
33
+ - Consider using the stacked variant to show progress toward a goal
34
+ - Sort bars by value (descending) when ranking is important
35
+
36
+ When NOT to use
37
+
38
+ - For showing trends over time - use a line chart instead
39
+ - For showing parts of a whole - use a pie or donut chart
40
+ - For very small datasets (1-2 items) - consider using ProgressBar
41
+
42
+ ## Variants
43
+
44
+ ### Simple (Non-stacked)
45
+
46
+ Use the simple variant when showing single values per category. Only `seriesOneValue` is provided.
47
+
48
+ <Canvas of={BarChartStories.Default} />
49
+
50
+ ### Stacked
51
+
52
+ Use the stacked variant when showing progress within a total. Provide both `seriesOneValue` (progress) and `seriesTwoValue` (total).
53
+
54
+ <Canvas of={BarChartStories.Stacked} />
55
+
56
+ ### With Icons
57
+
58
+ Add icons to labels for better visual identification of categories.
59
+
60
+ <Canvas of={BarChartStories.WithIcons} />
61
+
62
+ ### Animated
63
+
64
+ Enable entrance animations for a more engaging experience.
65
+
66
+ <Canvas of={BarChartStories.Animated} />
67
+
68
+ ### Interactive
69
+
70
+ Rows can be made interactive with `onClick` handlers or `href` links.
71
+
72
+ <Canvas of={BarChartStories.Interactive} />
73
+
74
+ ## Playground
75
+
76
+ <Canvas sourceState="shown" of={BarChartStories.Default} />
77
+
78
+ <Controls />
79
+
80
+ ## Accessibility considerations
81
+
82
+ - Always provide either `aria-label` or `aria-labelledby` to describe the chart
83
+ - Each row automatically generates an accessible label summarizing its values
84
+ - Interactive rows (with onClick/href) are properly announced as buttons/links
85
+ - Grid lines are marked as decorative and hidden from screen readers
86
+ - The scale header is hidden on small screens and marked as decorative
87
+
88
+ ## UX writing
89
+
90
+ - Keep y-axis labels concise (1-3 words)
91
+ - Use consistent unit labels (e.g., "XP", "hours", "points")
92
+ - Consider locale-aware number formatting for international audiences
@@ -0,0 +1,183 @@
1
+ import { BarChart, BarProps } from '@codecademy/gamut';
2
+ import {
3
+ BookFlipPageIcon,
4
+ CodeIcon,
5
+ DataScienceIcon,
6
+ GameControllerIcon,
7
+ TerminalIcon,
8
+ } from '@codecademy/gamut-icons';
9
+ import { action } from '@storybook/addon-actions';
10
+ import type { Meta, StoryObj } from '@storybook/react';
11
+
12
+ const meta: Meta<typeof BarChart> = {
13
+ component: BarChart,
14
+ args: {
15
+ 'aria-label': 'Skills experience chart',
16
+ minRange: 0,
17
+ maxRange: 2000,
18
+ unit: 'XP',
19
+ },
20
+ };
21
+
22
+ export default meta;
23
+ type Story = StoryObj<typeof BarChart>;
24
+
25
+ // Sample data for non-stacked (simple) bars
26
+ const simpleBarData: BarProps[] = [
27
+ { yLabel: 'Python', seriesOneValue: 1500 },
28
+ { yLabel: 'JavaScript', seriesOneValue: 2000 },
29
+ { yLabel: 'HTML/CSS', seriesOneValue: 800 },
30
+ { yLabel: 'SQL', seriesOneValue: 600 },
31
+ { yLabel: 'React', seriesOneValue: 450 },
32
+ ];
33
+
34
+ // Sample data for stacked bars (with seriesTwoValue)
35
+ const stackedBarData: BarProps[] = [
36
+ { yLabel: 'Python', seriesOneValue: 200, seriesTwoValue: 1500 },
37
+ { yLabel: 'JavaScript', seriesOneValue: 1800, seriesTwoValue: 2000 },
38
+ { yLabel: 'HTML/CSS', seriesOneValue: 100, seriesTwoValue: 800 },
39
+ { yLabel: 'SQL', seriesOneValue: 50, seriesTwoValue: 600 },
40
+ { yLabel: 'React', seriesOneValue: 75, seriesTwoValue: 450 },
41
+ ];
42
+
43
+ // Sample data with icons
44
+ const barDataWithIcons: BarProps[] = [
45
+ {
46
+ yLabel: 'Python',
47
+ seriesOneValue: 200,
48
+ seriesTwoValue: 1500,
49
+ icon: CodeIcon,
50
+ },
51
+ {
52
+ yLabel: 'JavaScript',
53
+ seriesOneValue: 150,
54
+ seriesTwoValue: 2000,
55
+ icon: TerminalIcon,
56
+ },
57
+ {
58
+ yLabel: 'Data Science',
59
+ seriesOneValue: 100,
60
+ seriesTwoValue: 800,
61
+ icon: DataScienceIcon,
62
+ },
63
+ {
64
+ yLabel: 'Game Dev',
65
+ seriesOneValue: 50,
66
+ seriesTwoValue: 600,
67
+ icon: GameControllerIcon,
68
+ },
69
+ {
70
+ yLabel: 'Reading',
71
+ seriesOneValue: 75,
72
+ seriesTwoValue: 450,
73
+ icon: BookFlipPageIcon,
74
+ },
75
+ ];
76
+
77
+ /**
78
+ * Default non-stacked bar chart showing single values
79
+ */
80
+ export const Default: Story = {
81
+ args: {
82
+ barValues: simpleBarData,
83
+ },
84
+ };
85
+
86
+ /**
87
+ * Stacked bar chart showing progress (seriesOneValue) over total (seriesTwoValue)
88
+ */
89
+ export const Stacked: Story = {
90
+ args: {
91
+ barValues: stackedBarData,
92
+ },
93
+ };
94
+
95
+ /**
96
+ * Bar chart with icons next to labels
97
+ */
98
+ export const WithIcons: Story = {
99
+ args: {
100
+ barValues: barDataWithIcons,
101
+ },
102
+ };
103
+
104
+ /**
105
+ * Animated bar chart with staggered entrance
106
+ */
107
+ export const Animated: Story = {
108
+ args: {
109
+ barValues: stackedBarData,
110
+ animate: true,
111
+ },
112
+ };
113
+
114
+ /**
115
+ * Bar chart sorted by value in descending order
116
+ */
117
+ export const SortedByValue: Story = {
118
+ args: {
119
+ barValues: simpleBarData,
120
+ sortBy: 'value',
121
+ order: 'descending',
122
+ },
123
+ };
124
+
125
+ /**
126
+ * Bar chart sorted alphabetically by label
127
+ */
128
+ export const SortedByLabel: Story = {
129
+ args: {
130
+ barValues: simpleBarData,
131
+ sortBy: 'label',
132
+ order: 'ascending',
133
+ },
134
+ };
135
+
136
+ /**
137
+ * Interactive bar chart with clickable rows
138
+ */
139
+ export const Interactive: Story = {
140
+ args: {
141
+ barValues: simpleBarData.map((bar) => ({
142
+ ...bar,
143
+ onClick: action(`Clicked ${bar.yLabel}`),
144
+ })),
145
+ },
146
+ };
147
+
148
+ /**
149
+ * Interactive bar chart with linked rows
150
+ */
151
+ export const WithLinks: Story = {
152
+ args: {
153
+ barValues: simpleBarData.map((bar) => ({
154
+ ...bar,
155
+ href: `#${bar.yLabel.toLowerCase().replace(/\s+/g, '-')}`,
156
+ })),
157
+ },
158
+ };
159
+
160
+ /**
161
+ * Bar chart with custom styling
162
+ */
163
+ export const CustomStyles: Story = {
164
+ args: {
165
+ barValues: stackedBarData,
166
+ styleConfig: {
167
+ backgroundBarColor: 'paleGreen',
168
+ foregroundBarColor: 'feedback-success',
169
+ textColor: 'navy',
170
+ },
171
+ },
172
+ };
173
+
174
+ /**
175
+ * Bar chart with custom xScale interval
176
+ */
177
+ export const CustomScale: Story = {
178
+ args: {
179
+ barValues: simpleBarData,
180
+ maxRange: 2000,
181
+ xScale: 250,
182
+ },
183
+ };