@arbor-education/design-system.components 0.3.5 → 0.4.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.
Files changed (106) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/banner/Banner.d.ts +19 -0
  3. package/dist/components/banner/Banner.d.ts.map +1 -0
  4. package/dist/components/banner/Banner.js +33 -0
  5. package/dist/components/banner/Banner.js.map +1 -0
  6. package/dist/components/banner/Banner.stories.d.ts +72 -0
  7. package/dist/components/banner/Banner.stories.d.ts.map +1 -0
  8. package/dist/components/banner/Banner.stories.js +84 -0
  9. package/dist/components/banner/Banner.stories.js.map +1 -0
  10. package/dist/components/banner/Banner.test.d.ts +2 -0
  11. package/dist/components/banner/Banner.test.d.ts.map +1 -0
  12. package/dist/components/banner/Banner.test.js +72 -0
  13. package/dist/components/banner/Banner.test.js.map +1 -0
  14. package/dist/components/editableText/EditableText.d.ts +10 -0
  15. package/dist/components/editableText/EditableText.d.ts.map +1 -0
  16. package/dist/components/editableText/EditableText.js +36 -0
  17. package/dist/components/editableText/EditableText.js.map +1 -0
  18. package/dist/components/editableText/EditableText.stories.d.ts +44 -0
  19. package/dist/components/editableText/EditableText.stories.d.ts.map +1 -0
  20. package/dist/components/editableText/EditableText.stories.js +94 -0
  21. package/dist/components/editableText/EditableText.stories.js.map +1 -0
  22. package/dist/components/editableText/EditableText.test.d.ts +2 -0
  23. package/dist/components/editableText/EditableText.test.d.ts.map +1 -0
  24. package/dist/components/editableText/EditableText.test.js +187 -0
  25. package/dist/components/editableText/EditableText.test.js.map +1 -0
  26. package/dist/components/heading/Heading.stories.d.ts +26 -0
  27. package/dist/components/heading/Heading.stories.d.ts.map +1 -1
  28. package/dist/components/heading/Heading.stories.js +35 -0
  29. package/dist/components/heading/Heading.stories.js.map +1 -1
  30. package/dist/components/progress/Progress.d.ts +6 -0
  31. package/dist/components/progress/Progress.d.ts.map +1 -0
  32. package/dist/components/progress/Progress.js +9 -0
  33. package/dist/components/progress/Progress.js.map +1 -0
  34. package/dist/components/progress/Progress.stories.d.ts +324 -0
  35. package/dist/components/progress/Progress.stories.d.ts.map +1 -0
  36. package/dist/components/progress/Progress.stories.js +77 -0
  37. package/dist/components/progress/Progress.stories.js.map +1 -0
  38. package/dist/components/progress/Progress.test.d.ts +2 -0
  39. package/dist/components/progress/Progress.test.d.ts.map +1 -0
  40. package/dist/components/progress/Progress.test.js +77 -0
  41. package/dist/components/progress/Progress.test.js.map +1 -0
  42. package/dist/components/toast/Toast.d.ts +10 -0
  43. package/dist/components/toast/Toast.d.ts.map +1 -0
  44. package/dist/components/toast/Toast.js +20 -0
  45. package/dist/components/toast/Toast.js.map +1 -0
  46. package/dist/components/toast/Toast.stories.d.ts +12 -0
  47. package/dist/components/toast/Toast.stories.d.ts.map +1 -0
  48. package/dist/components/toast/Toast.stories.js +73 -0
  49. package/dist/components/toast/Toast.stories.js.map +1 -0
  50. package/dist/components/toast/Toast.test.d.ts +2 -0
  51. package/dist/components/toast/Toast.test.d.ts.map +1 -0
  52. package/dist/components/toast/Toast.test.js +87 -0
  53. package/dist/components/toast/Toast.test.js.map +1 -0
  54. package/dist/components/toast/ToastViewport.d.ts +3 -0
  55. package/dist/components/toast/ToastViewport.d.ts.map +1 -0
  56. package/dist/components/toast/ToastViewport.js +5 -0
  57. package/dist/components/toast/ToastViewport.js.map +1 -0
  58. package/dist/index.css +202 -56
  59. package/dist/index.css.map +1 -1
  60. package/dist/index.d.ts +4 -0
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +4 -0
  63. package/dist/index.js.map +1 -1
  64. package/package.json +2 -1
  65. package/setupTestRuntime.ts +7 -0
  66. package/src/components/banner/Banner.stories.tsx +96 -0
  67. package/src/components/banner/Banner.test.tsx +86 -0
  68. package/src/components/banner/Banner.tsx +81 -0
  69. package/src/components/banner/banner.scss +67 -0
  70. package/src/components/button/button.scss +1 -5
  71. package/src/components/card/card.scss +0 -3
  72. package/src/components/dropdown/dropdown.scss +0 -3
  73. package/src/components/editableText/EditableText.stories.tsx +136 -0
  74. package/src/components/editableText/EditableText.test.tsx +242 -0
  75. package/src/components/editableText/EditableText.tsx +73 -0
  76. package/src/components/editableText/editableText.scss +54 -0
  77. package/src/components/formField/fieldset/fieldset.scss +0 -2
  78. package/src/components/formField/formField.scss +0 -2
  79. package/src/components/formField/inputs/checkbox/checkboxInput.scss +0 -2
  80. package/src/components/formField/inputs/input.scss +0 -3
  81. package/src/components/formField/inputs/radio/radioButtonInput.scss +0 -2
  82. package/src/components/formField/inputs/selectDropdown/selectDropdown.scss +0 -1
  83. package/src/components/formField/label/label.scss +0 -2
  84. package/src/components/heading/Heading.stories.tsx +58 -0
  85. package/src/components/heading/heading.scss +4 -4
  86. package/src/components/modal/modal.scss +0 -3
  87. package/src/components/pill/pill.scss +0 -3
  88. package/src/components/progress/Progress.stories.tsx +90 -0
  89. package/src/components/progress/Progress.test.tsx +88 -0
  90. package/src/components/progress/Progress.tsx +16 -0
  91. package/src/components/progress/progress.scss +13 -0
  92. package/src/components/searchBar/searchBar.scss +0 -3
  93. package/src/components/table/columnFilters/columnFilters.scss +0 -6
  94. package/src/components/table/pagination/pagination.scss +0 -4
  95. package/src/components/tabs/tabs.scss +0 -2
  96. package/src/components/tag/tag.scss +0 -3
  97. package/src/components/toast/Toast.stories.tsx +113 -0
  98. package/src/components/toast/Toast.test.tsx +126 -0
  99. package/src/components/toast/Toast.tsx +35 -0
  100. package/src/components/toast/ToastViewport.tsx +6 -0
  101. package/src/components/toast/toast.scss +79 -0
  102. package/src/components/tooltip/tooltip.scss +0 -3
  103. package/src/global.scss +9 -1
  104. package/src/index.scss +4 -0
  105. package/src/index.ts +4 -0
  106. package/src/tokens.scss +2 -0
@@ -0,0 +1,242 @@
1
+ import { render, screen, waitFor } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, it, expect, vi } from 'vitest';
4
+ import '@testing-library/jest-dom/vitest';
5
+ import { EditableText } from './EditableText';
6
+
7
+ describe('EditableText', () => {
8
+ const defaultProps = {
9
+ text: 'Test Text',
10
+ onEditSave: vi.fn(),
11
+ };
12
+
13
+ it('renders as a span element', () => {
14
+ const { container } = render(<EditableText {...defaultProps} />);
15
+ const span = container.querySelector('.ds-editable-text');
16
+ expect(span).toBeInTheDocument();
17
+ expect(span?.tagName).toBe('SPAN');
18
+ });
19
+
20
+ it('displays the text in view mode', () => {
21
+ render(<EditableText {...defaultProps} />);
22
+ const button = screen.getByRole('button', { name: /edit text/i });
23
+ expect(button).toHaveTextContent('Test Text');
24
+ });
25
+
26
+ it('applies custom className', () => {
27
+ const { container } = render(<EditableText {...defaultProps} className="custom-class" />);
28
+ const span = container.querySelector('.ds-editable-text');
29
+ expect(span).toHaveClass('ds-editable-text', 'custom-class');
30
+ });
31
+
32
+ it('renders edit button with pencil icon in view mode', () => {
33
+ render(<EditableText {...defaultProps} />);
34
+ const button = screen.getByRole('button', { name: /edit text/i });
35
+ expect(button).toBeInTheDocument();
36
+ expect(button.querySelector('.ds-editable-text__button-icon')).toBeInTheDocument();
37
+ });
38
+
39
+ it('enters edit mode when edit button is clicked', async () => {
40
+ const user = userEvent.setup();
41
+ render(<EditableText {...defaultProps} />);
42
+
43
+ const button = screen.getByRole('button', { name: /edit text/i });
44
+ await user.click(button);
45
+
46
+ const input = screen.getByRole('textbox', { name: /text/i });
47
+ expect(input).toBeInTheDocument();
48
+ expect(input).toHaveValue('Test Text');
49
+ expect(input).toHaveFocus();
50
+ });
51
+
52
+ it('calls onEditSave when Enter key is pressed', async () => {
53
+ const user = userEvent.setup();
54
+ const onEditSave = vi.fn();
55
+ render(<EditableText {...defaultProps} onEditSave={onEditSave} />);
56
+
57
+ const button = screen.getByRole('button', { name: /edit text/i });
58
+ await user.click(button);
59
+
60
+ const input = screen.getByRole('textbox', { name: /text/i });
61
+ await user.clear(input);
62
+ await user.type(input, 'New Text');
63
+ await user.keyboard('{Enter}');
64
+
65
+ expect(onEditSave).toHaveBeenCalledWith('New Text');
66
+ });
67
+
68
+ it('calls onEditSave when input is blurred', async () => {
69
+ const user = userEvent.setup();
70
+ const onEditSave = vi.fn();
71
+ render(<EditableText {...defaultProps} onEditSave={onEditSave} />);
72
+
73
+ const button = screen.getByRole('button', { name: /edit text/i });
74
+ await user.click(button);
75
+
76
+ const input = screen.getByRole('textbox', { name: /text/i });
77
+ await user.clear(input);
78
+ await user.type(input, 'Updated Text');
79
+ await user.tab(); // Blur the input
80
+
81
+ await waitFor(() => {
82
+ expect(onEditSave).toHaveBeenCalledWith('Updated Text');
83
+ });
84
+ });
85
+
86
+ it('exits edit mode after saving', async () => {
87
+ const user = userEvent.setup();
88
+ render(<EditableText {...defaultProps} />);
89
+
90
+ const button = screen.getByRole('button', { name: /edit text/i });
91
+ await user.click(button);
92
+
93
+ const input = screen.getByRole('textbox', { name: /text/i });
94
+ await user.keyboard('{Enter}');
95
+
96
+ await waitFor(() => {
97
+ expect(input).not.toBeInTheDocument();
98
+ expect(screen.getByRole('button', { name: /edit text/i })).toBeInTheDocument();
99
+ });
100
+ });
101
+
102
+ it('reverts text when Escape key is pressed', async () => {
103
+ const user = userEvent.setup();
104
+ const onEditSave = vi.fn();
105
+ render(<EditableText {...defaultProps} onEditSave={onEditSave} />);
106
+
107
+ const button = screen.getByRole('button', { name: /edit text/i });
108
+ await user.click(button);
109
+
110
+ const input = screen.getByRole('textbox', { name: /text/i });
111
+ await user.clear(input);
112
+ await user.type(input, 'Changed Text');
113
+ await user.keyboard('{Escape}');
114
+
115
+ await waitFor(() => {
116
+ expect(onEditSave).not.toHaveBeenCalled();
117
+ const viewButton = screen.getByRole('button', { name: /edit text/i });
118
+ expect(viewButton).toHaveTextContent('Test Text');
119
+ });
120
+ });
121
+
122
+ it('updates text when text prop changes', () => {
123
+ const { rerender } = render(<EditableText {...defaultProps} text="Original" />);
124
+
125
+ expect(screen.getByRole('button', { name: /edit text/i })).toHaveTextContent('Original');
126
+
127
+ rerender(<EditableText {...defaultProps} text="Updated" />);
128
+
129
+ expect(screen.getByRole('button', { name: /edit text/i })).toHaveTextContent('Updated');
130
+ });
131
+
132
+ it('starts in edit mode when isEditing prop is true', () => {
133
+ render(<EditableText {...defaultProps} isEditing={true} />);
134
+
135
+ const input = screen.getByRole('textbox', { name: /text/i });
136
+ expect(input).toBeInTheDocument();
137
+ expect(input).toHaveValue('Test Text');
138
+ });
139
+
140
+ it('switches to edit mode when isEditing prop changes to true', () => {
141
+ const { rerender } = render(<EditableText {...defaultProps} isEditing={false} />);
142
+
143
+ expect(screen.getByRole('button', { name: /edit text/i })).toBeInTheDocument();
144
+
145
+ rerender(<EditableText {...defaultProps} isEditing={true} />);
146
+
147
+ expect(screen.getByRole('textbox', { name: /text/i })).toBeInTheDocument();
148
+ });
149
+
150
+ it('preserves text value across edit sessions', async () => {
151
+ const user = userEvent.setup();
152
+ const onEditSave = vi.fn();
153
+ render(<EditableText {...defaultProps} onEditSave={onEditSave} />);
154
+
155
+ // First edit
156
+ const button = screen.getByRole('button', { name: /edit text/i });
157
+ await user.click(button);
158
+ const input = screen.getByRole('textbox', { name: /text/i });
159
+ await user.clear(input);
160
+ await user.type(input, 'First Edit');
161
+ await user.keyboard('{Enter}');
162
+
163
+ await waitFor(() => {
164
+ expect(onEditSave).toHaveBeenCalledWith('First Edit');
165
+ });
166
+
167
+ // Second edit - should start with previous saved value
168
+ const buttonAgain = await screen.findByRole('button', { name: /edit text/i });
169
+ await user.click(buttonAgain);
170
+ const inputAgain = screen.getByRole('textbox', { name: /text/i });
171
+ expect(inputAgain).toHaveValue('First Edit');
172
+
173
+ await user.clear(inputAgain);
174
+ await user.type(inputAgain, 'Second Edit');
175
+ await user.keyboard('{Escape}'); // Cancel this time
176
+
177
+ // Should still have first edit value
178
+ await waitFor(() => {
179
+ const finalButton = screen.getByRole('button', { name: /edit text/i });
180
+ expect(finalButton).toHaveTextContent('First Edit');
181
+ });
182
+ });
183
+
184
+ it('inherits styles from parent element', () => {
185
+ const { container } = render(
186
+ <h1 style={{ fontSize: '32px', fontWeight: 'bold' }}>
187
+ <EditableText {...defaultProps} />
188
+ </h1>,
189
+ );
190
+
191
+ const span = container.querySelector('.ds-editable-text');
192
+ expect(span).toBeInTheDocument();
193
+ // Component should inherit font-size and font-weight from parent h1
194
+ });
195
+
196
+ it('renders textarea when multiline is true', async () => {
197
+ const user = userEvent.setup();
198
+ render(<EditableText {...defaultProps} multiline={true} />);
199
+
200
+ const button = screen.getByRole('button', { name: /edit text/i });
201
+ await user.click(button);
202
+
203
+ const textarea = screen.getByRole('textbox', { name: /text/i });
204
+ expect(textarea).toBeInTheDocument();
205
+ expect(textarea.tagName).toBe('TEXTAREA');
206
+ });
207
+
208
+ it('does not save on Enter key when multiline is true', async () => {
209
+ const user = userEvent.setup();
210
+ const onEditSave = vi.fn();
211
+ render(<EditableText {...defaultProps} onEditSave={onEditSave} multiline={true} />);
212
+
213
+ const button = screen.getByRole('button', { name: /edit text/i });
214
+ await user.click(button);
215
+
216
+ const textarea = screen.getByRole('textbox', { name: /text/i });
217
+ await user.clear(textarea);
218
+ await user.type(textarea, 'Line 1{Enter}Line 2');
219
+
220
+ // Enter should NOT trigger save in multiline mode
221
+ expect(onEditSave).not.toHaveBeenCalled();
222
+ expect(textarea).toHaveValue('Line 1\nLine 2');
223
+ });
224
+
225
+ it('saves multiline text on blur', async () => {
226
+ const user = userEvent.setup();
227
+ const onEditSave = vi.fn();
228
+ render(<EditableText {...defaultProps} onEditSave={onEditSave} multiline={true} />);
229
+
230
+ const button = screen.getByRole('button', { name: /edit text/i });
231
+ await user.click(button);
232
+
233
+ const textarea = screen.getByRole('textbox', { name: /text/i });
234
+ await user.clear(textarea);
235
+ await user.type(textarea, 'Line 1{Enter}Line 2{Enter}Line 3');
236
+ await user.tab(); // Blur the textarea
237
+
238
+ await waitFor(() => {
239
+ expect(onEditSave).toHaveBeenCalledWith('Line 1\nLine 2\nLine 3');
240
+ });
241
+ });
242
+ });
@@ -0,0 +1,73 @@
1
+ import classNames from 'classnames';
2
+ import { TextInput } from 'Components/formField/inputs/text/TextInput';
3
+ import { TextArea } from 'Components/formField/inputs/textArea/TextArea';
4
+ import { Icon } from 'Components/icon/Icon';
5
+ import { useEffect, useRef, useState, type KeyboardEvent } from 'react';
6
+
7
+ type EditableTextProps = {
8
+ text: string;
9
+ className?: string;
10
+ onEditSave: (newText: string) => void;
11
+ isEditing?: boolean;
12
+ multiline?: boolean;
13
+ };
14
+
15
+ export const EditableText = ({ text: textProp, className = '', onEditSave, isEditing: isEditingProp = false, multiline = false }: EditableTextProps) => {
16
+ const [isEditing, setIsEditing] = useState(false);
17
+ const [text, setText] = useState(textProp);
18
+ const preEditText = useRef(textProp);
19
+
20
+ useEffect(() => {
21
+ setText(textProp);
22
+ }, [textProp]);
23
+
24
+ useEffect(() => {
25
+ setIsEditing(isEditingProp);
26
+ }, [isEditingProp]);
27
+
28
+ const handleEditSave = () => {
29
+ onEditSave(text);
30
+ preEditText.current = text;
31
+ setIsEditing(false);
32
+ };
33
+
34
+ const handleKeyDown = (e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
35
+ if (e.key === 'Enter' && !multiline) {
36
+ handleEditSave();
37
+ }
38
+ if (e.key === 'Escape') {
39
+ setText(preEditText.current);
40
+ setIsEditing(false);
41
+ }
42
+ };
43
+
44
+ const InputComponent = multiline ? TextArea : TextInput;
45
+
46
+ return (
47
+ <span className={classNames('ds-editable-text', className)}>
48
+ {isEditing
49
+ ? (
50
+ <InputComponent
51
+ name="editable-text"
52
+ aria-label="Text"
53
+ className="ds-editable-text__input"
54
+ value={text}
55
+ onChange={e => setText(e.target.value)}
56
+ onBlur={handleEditSave}
57
+ onKeyDown={handleKeyDown}
58
+ autoFocus
59
+ />
60
+ )
61
+ : (
62
+ <button
63
+ className="ds-editable-text__button"
64
+ aria-label="Edit text"
65
+ onClick={() => setIsEditing(true)}
66
+ >
67
+ {text}
68
+ <Icon name="pencil" size={16} className="ds-editable-text__button-icon" />
69
+ </button>
70
+ )}
71
+ </span>
72
+ );
73
+ };
@@ -0,0 +1,54 @@
1
+ .ds-editable-text {
2
+ width: 100%;
3
+ box-sizing: border-box;
4
+ font-size: inherit;
5
+ font-weight: inherit;
6
+ font-family: inherit;
7
+ line-height: inherit;
8
+ color: inherit;
9
+ text-align: inherit;
10
+ text-decoration: inherit;
11
+ text-transform: inherit;
12
+ letter-spacing: inherit;
13
+
14
+ &__input, &__button {
15
+ width: 100%;
16
+ box-sizing: border-box;
17
+ height: auto;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: flex-start;
21
+ min-width: 0;
22
+ font-size: inherit;
23
+ font-weight: inherit;
24
+ font-family: inherit;
25
+ line-height: inherit;
26
+ color: inherit;
27
+ text-align: inherit;
28
+ text-decoration: inherit;
29
+ text-transform: inherit;
30
+ letter-spacing: inherit;
31
+ }
32
+
33
+ .ds-input--M {
34
+ height: auto;
35
+ }
36
+
37
+ &__button {
38
+ border: var(--border-weight) solid transparent;
39
+ border-radius: var(--form-field-radius);
40
+ background-color: transparent;
41
+ padding: 0 var(--form-field-spacing-horizontal);
42
+ cursor: pointer;
43
+
44
+ &:hover {
45
+ background-color: var(--color-grey-100);
46
+ }
47
+ }
48
+
49
+ &__button-icon {
50
+ color: var(--color-grey-500);
51
+ margin-left: var(--spacing-small);
52
+ flex-shrink: 0;
53
+ }
54
+ }
@@ -9,8 +9,6 @@
9
9
  }
10
10
 
11
11
  .ds-fieldset__legend {
12
- font-family: var(--font-family-standard);
13
- font-size: var(--font-size-2-13);
14
12
  font-weight: var(--type-body-bold-weight);
15
13
  color: var(--form-field-label-color-text);
16
14
  line-height: 150%;
@@ -1,6 +1,4 @@
1
1
  .ds-form-field {
2
- font-family: var(--font-family-standard);
3
- font-size: var(--font-size-2-13);
4
2
  line-height: 150%;
5
3
  width: 100%;
6
4
  box-sizing: border-box;
@@ -43,8 +43,6 @@
43
43
 
44
44
  .ds-checkbox-label__text {
45
45
  flex: 1 0 0;
46
- font-size: var(--type-body-p-size);
47
- font-weight: var(--type-body-p-weight);
48
46
  color: var(--checkbox-default-color-text);
49
47
  line-height: var(--line-height-default);
50
48
  }
@@ -2,9 +2,6 @@
2
2
 
3
3
  .ds-input {
4
4
  width: 100%;
5
- font-size: var(--type-body-p-size);
6
- font-family: var(--font-family-standard);
7
- font-weight: var(--font-weight-regular);
8
5
  border: var(--border-weight) solid var(--form-field-text-default-color-border);
9
6
  border-radius: var(--form-field-radius);
10
7
  color: var(--form-field-text-default-color-text);
@@ -19,8 +19,6 @@
19
19
 
20
20
  .ds-radio-button-input__text {
21
21
  flex: 1 0 0;
22
- font-size: var(--type-body-p-size);
23
- font-weight: var(--type-body-p-weight);
24
22
  color: var(--checkbox-default-color-text);
25
23
  line-height: var(--line-height-default);
26
24
  user-select: none;
@@ -16,7 +16,6 @@
16
16
  .ds-select-dropdown__items--header {
17
17
  margin: 0;
18
18
  color: var(--form-dropdown-form-drop-item-title-color-text);
19
- font-size: var(--font-size-2-13);
20
19
  padding: var(--spacing-xsmall) var(--spacing-small) var(--spacing-medium) var(--spacing-small);
21
20
  border-bottom: var(--border-weight) solid var(--page-base-color-border);
22
21
  }
@@ -1,6 +1,4 @@
1
1
  .ds-label {
2
- font-family: var(--font-family-standard);
3
- font-size: var(--font-size-2-13);
4
2
  font-weight: var(--type-body-bold-weight);
5
3
  color: var(--form-field-label-color-text);
6
4
  line-height: 150%;
@@ -2,6 +2,7 @@ import type { Meta } from '@storybook/react-vite';
2
2
  import { Heading } from './Heading';
3
3
  import { Button } from '../button/Button';
4
4
  import { Icon } from '../icon/Icon';
5
+ import { EditableText } from 'Components/editableText/EditableText';
5
6
 
6
7
  const meta: Meta<typeof Heading> = {
7
8
  title: 'Components/Heading',
@@ -13,6 +14,14 @@ export const Default = {
13
14
  children: ['Heading Text'],
14
15
  level: 1,
15
16
  },
17
+ argTypes: {
18
+ level: {
19
+ control: 'select',
20
+ options: [1, 2, 3, 4],
21
+ description: 'Heading level (h1-h4)',
22
+ },
23
+ },
24
+ tags: ['autodocs'],
16
25
  };
17
26
 
18
27
  export const FloatingChildren = {
@@ -81,4 +90,53 @@ export const HeadingWithButtonsBothSides = {
81
90
  },
82
91
  };
83
92
 
93
+ export const HeadingWithEditableText = {
94
+ args: {
95
+ level: 1,
96
+ children: [
97
+ <EditableText key={2} text="Editable Heading" onEditSave={() => {}} />,
98
+ ],
99
+ },
100
+ };
101
+
102
+ export const HeadingWithEditableTextAndButton = {
103
+ args: {
104
+ level: 1,
105
+ children: [
106
+ <Heading.InnerContainer key={1}><EditableText text="Editable Heading" onEditSave={() => {}} /></Heading.InnerContainer>,
107
+ <Heading.InnerContainer key={2}>
108
+ <Button>
109
+ <Icon name="info" />
110
+ Button Text
111
+ </Button>
112
+ </Heading.InnerContainer>,
113
+ ],
114
+ },
115
+ };
116
+
117
+ export const HeadingWithEditableTextAndButtonsBothSides = {
118
+ args: {
119
+ level: 1,
120
+ children: [
121
+ <Heading.InnerContainer key={1} className="medium-spacing-gap">
122
+ <Button variant="tertiary">
123
+ <Icon name="chevron-left" />
124
+ Button Text
125
+ </Button>
126
+ <EditableText text="Editable Heading" onEditSave={() => {}} />
127
+ </Heading.InnerContainer>,
128
+ <Heading.InnerContainer key={2} className="medium-spacing-gap">
129
+ <Button variant="secondary">
130
+ <Icon name="info" />
131
+ Button Text
132
+ </Button>
133
+ <Button>
134
+ <Icon name="info" />
135
+ Button Text
136
+ </Button>
137
+ </Heading.InnerContainer>,
138
+ ],
139
+ },
140
+ };
141
+
84
142
  export default meta;
@@ -17,7 +17,7 @@
17
17
  }
18
18
 
19
19
  h1 {
20
- &.ds-heading {
20
+ &.ds-heading, .ds-editable-text__button, .ds-editable-text__input {
21
21
  font-family: var(--type-headings-h1-family);
22
22
  font-size: var(--type-headings-h1-size);
23
23
  font-weight: var(--type-headings-h1-weight);
@@ -26,7 +26,7 @@ h1 {
26
26
  }
27
27
 
28
28
  h2 {
29
- &.ds-heading {
29
+ &.ds-heading, .ds-editable-text__button, .ds-editable-text__input {
30
30
  font-family: var(--type-headings-h2-family);
31
31
  font-size: var(--type-headings-h2-size);
32
32
  font-weight: var(--type-headings-h2-weight);
@@ -35,7 +35,7 @@ h2 {
35
35
  }
36
36
 
37
37
  h3 {
38
- &.ds-heading {
38
+ &.ds-heading, .ds-editable-text__button, .ds-editable-text__input {
39
39
  font-family: var(--type-headings-h3-family);
40
40
  font-size: var(--type-headings-h3-size);
41
41
  font-weight: var(--type-headings-h3-weight);
@@ -44,7 +44,7 @@ h3 {
44
44
  }
45
45
 
46
46
  h4 {
47
- &.ds-heading {
47
+ &.ds-heading, .ds-editable-text__button, .ds-editable-text__input {
48
48
  font-family: var(--type-headings-h4-family);
49
49
  font-size: var(--type-headings-h4-size);
50
50
  font-weight: var(--type-headings-h4-weight);
@@ -23,9 +23,6 @@
23
23
  max-width: calc(100vw - var(--spacing-medium));
24
24
  max-height: calc(100vh - var(--spacing-medium));
25
25
  min-width: var(--modal-min-width);
26
- font-family: var(--type-body-p-family);
27
- font-size: var(--type-body-p-size);
28
- font-weight: var(--type-body-p-weight);
29
26
  line-height: var(--type-body-line-height);
30
27
  color: var(--type-body-p-color);
31
28
 
@@ -10,10 +10,7 @@
10
10
  cursor: pointer;
11
11
 
12
12
  /* typography/body/p1-reg */
13
- font-family: var(--type-body-p-family, Inter);
14
- font-size: var(--type-body-p-size);
15
13
  font-style: normal;
16
- font-weight: var(--type-body-p-weight);
17
14
  line-height: 150%; /* 19.5px */
18
15
 
19
16
  &__inactive{
@@ -0,0 +1,90 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { Progress } from './Progress';
3
+
4
+ const meta = {
5
+ title: 'Components/Progress',
6
+ component: Progress,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ args: {
12
+ 'aria-label': 'Progress bar',
13
+ },
14
+ argTypes: {
15
+ value: {
16
+ control: { type: 'number', min: 0, max: 100 },
17
+ description: 'Current progress value',
18
+ },
19
+ max: {
20
+ control: 'number',
21
+ description: 'Maximum progress value',
22
+ },
23
+ },
24
+ decorators: [
25
+ Story => (
26
+ <div style={{ width: '400px' }}>
27
+ <Story />
28
+ </div>
29
+ ),
30
+ ],
31
+ } satisfies Meta<typeof Progress>;
32
+
33
+ export default meta;
34
+ type Story = StoryObj<typeof meta>;
35
+
36
+ // Default progress
37
+ export const Default: Story = {
38
+ args: {
39
+ value: 50,
40
+ max: 100,
41
+ },
42
+ };
43
+
44
+ // Empty progress
45
+ export const Empty: Story = {
46
+ args: {
47
+ value: 0,
48
+ max: 100,
49
+ },
50
+ };
51
+
52
+ // Quarter progress
53
+ export const Quarter: Story = {
54
+ args: {
55
+ value: 25,
56
+ max: 100,
57
+ },
58
+ };
59
+
60
+ // Half progress
61
+ export const Half: Story = {
62
+ args: {
63
+ value: 50,
64
+ max: 100,
65
+ },
66
+ };
67
+
68
+ // Three quarters progress
69
+ export const ThreeQuarters: Story = {
70
+ args: {
71
+ value: 75,
72
+ max: 100,
73
+ },
74
+ };
75
+
76
+ // Complete progress
77
+ export const Complete: Story = {
78
+ args: {
79
+ value: 100,
80
+ max: 100,
81
+ },
82
+ };
83
+
84
+ // Custom max value
85
+ export const CustomMax: Story = {
86
+ args: {
87
+ value: 30,
88
+ max: 50,
89
+ },
90
+ };