@abstraks-dev/ui-library 1.0.1
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/LICENSE +21 -0
- package/README.md +708 -0
- package/dist/__tests__/Anchor.test.js +145 -0
- package/dist/__tests__/ArrowRight.test.js +91 -0
- package/dist/__tests__/Avatar.test.js +123 -0
- package/dist/__tests__/Button.test.js +82 -0
- package/dist/__tests__/Card.test.js +198 -0
- package/dist/__tests__/CheckCircle.test.js +98 -0
- package/dist/__tests__/Checkbox.test.js +161 -0
- package/dist/__tests__/ChevronDown.test.js +73 -0
- package/dist/__tests__/Close.test.js +98 -0
- package/dist/__tests__/EditSquare.test.js +99 -0
- package/dist/__tests__/Error.test.js +74 -0
- package/dist/__tests__/Footer.test.js +66 -0
- package/dist/__tests__/Heading.test.js +227 -0
- package/dist/__tests__/Hero.test.js +74 -0
- package/dist/__tests__/Label.test.js +123 -0
- package/dist/__tests__/Loader.test.js +115 -0
- package/dist/__tests__/MenuHover.test.js +137 -0
- package/dist/__tests__/Paragraph.test.js +93 -0
- package/dist/__tests__/PlusCircle.test.js +99 -0
- package/dist/__tests__/Radio.test.js +153 -0
- package/dist/__tests__/Select.test.js +187 -0
- package/dist/__tests__/Tabs.test.js +162 -0
- package/dist/__tests__/TextArea.test.js +127 -0
- package/dist/__tests__/TextInput.test.js +181 -0
- package/dist/__tests__/Toggle.test.js +120 -0
- package/dist/__tests__/TrashX.test.js +99 -0
- package/dist/__tests__/useHeadingAccessibility.test.js +144 -0
- package/dist/components/Anchor.js +131 -0
- package/dist/components/Animation.js +129 -0
- package/dist/components/AnimationGroup.js +207 -0
- package/dist/components/AnimationToggle.js +216 -0
- package/dist/components/Avatar.js +153 -0
- package/dist/components/Button.js +218 -0
- package/dist/components/Card.js +222 -0
- package/dist/components/Checkbox.js +305 -0
- package/dist/components/Crud.js +564 -0
- package/dist/components/DragAndDrop.js +337 -0
- package/dist/components/Error.js +206 -0
- package/dist/components/Footer.js +99 -0
- package/dist/components/Form.js +412 -0
- package/dist/components/Header.js +372 -0
- package/dist/components/Heading.js +134 -0
- package/dist/components/Hero.js +181 -0
- package/dist/components/Label.js +256 -0
- package/dist/components/Loader.js +302 -0
- package/dist/components/MenuHover.js +114 -0
- package/dist/components/Paragraph.js +128 -0
- package/dist/components/Prompt.js +61 -0
- package/dist/components/Radio.js +254 -0
- package/dist/components/Select.js +422 -0
- package/dist/components/SideMenu.js +313 -0
- package/dist/components/Tabs.js +297 -0
- package/dist/components/TextArea.js +370 -0
- package/dist/components/TextInput.js +286 -0
- package/dist/components/Toggle.js +186 -0
- package/dist/components/crudFiles/CrudEditBase.js +150 -0
- package/dist/components/crudFiles/CrudViewBase.js +39 -0
- package/dist/components/crudFiles/crudDevelopment.js +118 -0
- package/dist/components/crudFiles/crudEditHandlers.js +50 -0
- package/dist/constants/animation.js +30 -0
- package/dist/icons/ArrowIcon.js +32 -0
- package/dist/icons/ArrowRight.js +33 -0
- package/dist/icons/CheckCircle.js +33 -0
- package/dist/icons/ChevronDown.js +28 -0
- package/dist/icons/Close.js +33 -0
- package/dist/icons/EditSquare.js +33 -0
- package/dist/icons/Ellipses.js +34 -0
- package/dist/icons/Hamburger.js +39 -0
- package/dist/icons/LoadingSpinner.js +42 -0
- package/dist/icons/PlusCircle.js +33 -0
- package/dist/icons/SaveIcon.js +32 -0
- package/dist/icons/TrashX.js +33 -0
- package/dist/icons/__tests__/CheckCircle.test.js +9 -0
- package/dist/icons/__tests__/ChevronDown.test.js +9 -0
- package/dist/icons/__tests__/Close.test.js +9 -0
- package/dist/icons/__tests__/EditSquare.test.js +9 -0
- package/dist/icons/__tests__/PlusCircle.test.js +9 -0
- package/dist/icons/__tests__/TrashX.test.js +9 -0
- package/dist/icons/index.js +89 -0
- package/dist/index.js +332 -0
- package/dist/setupTests.js +3 -0
- package/dist/styles/_variables.scss +286 -0
- package/dist/styles/anchor.scss +40 -0
- package/dist/styles/animation-accessibility.scss +96 -0
- package/dist/styles/animation-toggle.scss +233 -0
- package/dist/styles/animation.scss +3781 -0
- package/dist/styles/avatar.scss +285 -0
- package/dist/styles/button.scss +430 -0
- package/dist/styles/card.scss +210 -0
- package/dist/styles/checkbox.scss +160 -0
- package/dist/styles/crud.scss +474 -0
- package/dist/styles/dragAndDrop.scss +312 -0
- package/dist/styles/error.scss +232 -0
- package/dist/styles/footer.scss +58 -0
- package/dist/styles/form.scss +420 -0
- package/dist/styles/grid.scss +29 -0
- package/dist/styles/header.scss +276 -0
- package/dist/styles/heading.scss +118 -0
- package/dist/styles/hero.scss +185 -0
- package/dist/styles/htmlElements.scss +20 -0
- package/dist/styles/image.scss +9 -0
- package/dist/styles/label.scss +340 -0
- package/dist/styles/list-item.scss +5 -0
- package/dist/styles/loader.scss +354 -0
- package/dist/styles/logo.scss +19 -0
- package/dist/styles/main.css +9056 -0
- package/dist/styles/main.css.map +1 -0
- package/dist/styles/main.scss +0 -0
- package/dist/styles/menu-hover.scss +30 -0
- package/dist/styles/paragraph.scss +88 -0
- package/dist/styles/prompt.scss +51 -0
- package/dist/styles/radio.scss +202 -0
- package/dist/styles/select.scss +363 -0
- package/dist/styles/side-menu.scss +334 -0
- package/dist/styles/tabs.scss +540 -0
- package/dist/styles/text-area.scss +388 -0
- package/dist/styles/text-input.scss +171 -0
- package/dist/styles/toggle.scss +0 -0
- package/dist/styles/unordered-list.scss +8 -0
- package/dist/utils/ScrollHandler.js +30 -0
- package/dist/utils/accessibility.js +128 -0
- package/dist/utils/heroUtils.js +316 -0
- package/dist/utils/index.js +104 -0
- package/dist/utils/inputValidation.js +29 -0
- package/dist/utils/keyboardNavigation.js +536 -0
- package/dist/utils/labelUtils.js +708 -0
- package/dist/utils/loaderUtils.js +387 -0
- package/dist/utils/menuUtils.js +575 -0
- package/dist/utils/useHeadingAccessibility.js +298 -0
- package/dist/utils/useRadioGroup.js +260 -0
- package/dist/utils/useSelectAccessibility.js +426 -0
- package/dist/utils/useTabsAccessibility.js +278 -0
- package/dist/utils/useTextAreaAccessibility.js +255 -0
- package/dist/utils/useTextInputAccessibility.js +295 -0
- package/dist/utils/useTypographyAccessibility.js +168 -0
- package/dist/utils/useWindowSize.js +32 -0
- package/dist/utils/utils/ScrollHandler.js +26 -0
- package/dist/utils/utils/accessibility.js +133 -0
- package/dist/utils/utils/heroUtils.js +348 -0
- package/dist/utils/utils/index.js +9 -0
- package/dist/utils/utils/inputValidation.js +22 -0
- package/dist/utils/utils/keyboardNavigation.js +664 -0
- package/dist/utils/utils/labelUtils.js +772 -0
- package/dist/utils/utils/loaderUtils.js +436 -0
- package/dist/utils/utils/menuUtils.js +651 -0
- package/dist/utils/utils/useHeadingAccessibility.js +334 -0
- package/dist/utils/utils/useRadioGroup.js +311 -0
- package/dist/utils/utils/useSelectAccessibility.js +498 -0
- package/dist/utils/utils/useTabsAccessibility.js +316 -0
- package/dist/utils/utils/useTextAreaAccessibility.js +303 -0
- package/dist/utils/utils/useTextInputAccessibility.js +338 -0
- package/dist/utils/utils/useTypographyAccessibility.js +180 -0
- package/dist/utils/utils/useWindowSize.js +26 -0
- package/dist/utils/utils/validation.js +131 -0
- package/dist/utils/validation.js +139 -0
- package/package.json +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
# ui-library
|
|
2
|
+
|
|
3
|
+
A comprehensive React UI component library with modern styling and robust testing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install ui-library
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
import { Button, Card, TextInput } from 'ui-library';
|
|
15
|
+
import 'ui-library/dist/styles/main.css';
|
|
16
|
+
|
|
17
|
+
function App() {
|
|
18
|
+
return (
|
|
19
|
+
<div>
|
|
20
|
+
<Card>
|
|
21
|
+
<TextInput label="Name" placeholder="Enter your name" />
|
|
22
|
+
<Button variant="primary">Submit</Button>
|
|
23
|
+
</Card>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Development
|
|
30
|
+
|
|
31
|
+
### Setup
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install
|
|
35
|
+
npm test
|
|
36
|
+
npm run storybook
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Building
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm run build
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### SCSS Development
|
|
46
|
+
|
|
47
|
+
The library uses SCSS for styling. Available SCSS commands:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Build CSS from SCSS
|
|
51
|
+
npm run build-css
|
|
52
|
+
|
|
53
|
+
# Watch SCSS files for changes (development)
|
|
54
|
+
npm run build-css:watch
|
|
55
|
+
|
|
56
|
+
# Build compressed CSS for production
|
|
57
|
+
npm run build-css:compressed
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Deployment
|
|
61
|
+
|
|
62
|
+
This library is automatically deployed to npm using GitHub Actions.
|
|
63
|
+
|
|
64
|
+
### Automatic Deployment
|
|
65
|
+
|
|
66
|
+
- Push a version tag (e.g., `v1.0.0`) to trigger automatic deployment
|
|
67
|
+
- The workflow will run tests, build the library, and publish to npm
|
|
68
|
+
|
|
69
|
+
### Manual Deployment
|
|
70
|
+
|
|
71
|
+
- Go to the Actions tab in GitHub
|
|
72
|
+
- Select "Deploy to NPM" workflow
|
|
73
|
+
- Click "Run workflow" and choose version bump type (patch/minor/major)
|
|
74
|
+
|
|
75
|
+
### Setting Up NPM Token
|
|
76
|
+
|
|
77
|
+
1. Generate an npm token at <https://www.npmjs.com/settings/tokens>
|
|
78
|
+
2. Add it as `NPM_TOKEN` in repository secrets (Settings → Secrets and variables → Actions)
|
|
79
|
+
|
|
80
|
+
### Version Tags
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Create and push a version tag
|
|
84
|
+
git tag v1.0.0
|
|
85
|
+
git push origin v1.0.0
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# UI Library Testing
|
|
90
|
+
|
|
91
|
+
This document explains how to run and write tests for the UI Library components.
|
|
92
|
+
|
|
93
|
+
## 🏃♂️ Running Tests
|
|
94
|
+
|
|
95
|
+
### Basic Commands
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Run all tests
|
|
99
|
+
npm test
|
|
100
|
+
|
|
101
|
+
# Run tests in watch mode (automatically re-runs when files change)
|
|
102
|
+
npm run test:watch
|
|
103
|
+
|
|
104
|
+
# Run tests with coverage report
|
|
105
|
+
npm run test:coverage
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Test Files Structure
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
src/
|
|
112
|
+
├── components/
|
|
113
|
+
│ ├── __tests__/
|
|
114
|
+
│ │ ├── Button.test.jsx
|
|
115
|
+
│ │ ├── Heading.test.jsx
|
|
116
|
+
│ │ ├── Label.test.jsx
|
|
117
|
+
│ │ ├── Checkbox.test.jsx
|
|
118
|
+
│ │ └── MenuHover.test.jsx
|
|
119
|
+
│ └── [component files]
|
|
120
|
+
├── icons/
|
|
121
|
+
│ ├── __tests__/
|
|
122
|
+
│ │ ├── ChevronDown.test.jsx
|
|
123
|
+
│ │ └── ArrowRight.test.jsx
|
|
124
|
+
│ └── [icon files]
|
|
125
|
+
└── setupTests.js
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## ✅ Current Test Coverage
|
|
129
|
+
|
|
130
|
+
We have comprehensive unit tests for:
|
|
131
|
+
|
|
132
|
+
### Components
|
|
133
|
+
- **Button** - 9 tests covering props, events, states, and rendering
|
|
134
|
+
- **Heading** - 8 tests covering different heading levels and props
|
|
135
|
+
- **Label** - 12 tests covering label text, required states, and children
|
|
136
|
+
- **Checkbox** - 15 tests covering state management, props, and interactions
|
|
137
|
+
- **MenuHover** - 8 tests covering toggle behavior, CSS classes, and props
|
|
138
|
+
|
|
139
|
+
### Icons
|
|
140
|
+
- **ChevronDown** - 8 tests covering SVG properties, styling, and props
|
|
141
|
+
- **ArrowRight** - 10 tests covering multi-path SVG structure and props
|
|
142
|
+
|
|
143
|
+
**Total: 70 tests passing** ✅
|
|
144
|
+
|
|
145
|
+
## 🧪 Testing Framework
|
|
146
|
+
|
|
147
|
+
### Tech Stack
|
|
148
|
+
- **Jest** - Test runner and assertion library
|
|
149
|
+
- **React Testing Library** - Component testing utilities
|
|
150
|
+
- **@testing-library/user-event** - User interaction simulation
|
|
151
|
+
- **@testing-library/jest-dom** - Extended Jest matchers
|
|
152
|
+
|
|
153
|
+
### Configuration
|
|
154
|
+
- **Jest Config**: `jest.config.json`
|
|
155
|
+
- **Babel Config**: `babel.config.json`
|
|
156
|
+
- **Setup File**: `src/setupTests.js`
|
|
157
|
+
|
|
158
|
+
### Key Features
|
|
159
|
+
- **CSS Import Mocking** - CSS files are automatically mocked
|
|
160
|
+
- **Custom Test ID Attribute** - Uses `data-test-id` instead of `data-testid`
|
|
161
|
+
- **SVG Testing** - Proper handling of SVG components
|
|
162
|
+
- **User Interaction Testing** - Simulated clicks, form inputs, etc.
|
|
163
|
+
|
|
164
|
+
## 📝 Writing New Tests
|
|
165
|
+
|
|
166
|
+
### Basic Test Structure
|
|
167
|
+
|
|
168
|
+
```jsx
|
|
169
|
+
import React from 'react';
|
|
170
|
+
import { render, screen } from '@testing-library/react';
|
|
171
|
+
import userEvent from '@testing-library/user-event';
|
|
172
|
+
import { YourComponent } from '../YourComponent';
|
|
173
|
+
|
|
174
|
+
describe('YourComponent', () => {
|
|
175
|
+
test('renders correctly', () => {
|
|
176
|
+
render(<YourComponent />);
|
|
177
|
+
|
|
178
|
+
expect(screen.getByRole('button')).toBeInTheDocument();
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('handles user interaction', async () => {
|
|
182
|
+
const user = userEvent.setup();
|
|
183
|
+
const handleClick = jest.fn();
|
|
184
|
+
|
|
185
|
+
render(<YourComponent onClick={handleClick} />);
|
|
186
|
+
|
|
187
|
+
await user.click(screen.getByRole('button'));
|
|
188
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Testing Patterns
|
|
194
|
+
|
|
195
|
+
#### 1. **Component Rendering**
|
|
196
|
+
```jsx
|
|
197
|
+
test('renders with default props', () => {
|
|
198
|
+
render(<Button>Click me</Button>);
|
|
199
|
+
|
|
200
|
+
const button = screen.getByRole('button');
|
|
201
|
+
expect(button).toBeInTheDocument();
|
|
202
|
+
expect(button).toHaveTextContent('Click me');
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### 2. **Props Testing**
|
|
207
|
+
```jsx
|
|
208
|
+
test('applies custom className', () => {
|
|
209
|
+
render(<Button additionalClassName="custom">Test</Button>);
|
|
210
|
+
|
|
211
|
+
const button = screen.getByRole('button');
|
|
212
|
+
expect(button).toHaveClass('button', 'custom');
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### 3. **User Interactions**
|
|
217
|
+
```jsx
|
|
218
|
+
test('handles click events', async () => {
|
|
219
|
+
const user = userEvent.setup();
|
|
220
|
+
const handleClick = jest.fn();
|
|
221
|
+
|
|
222
|
+
render(<Button onClick={handleClick}>Click</Button>);
|
|
223
|
+
|
|
224
|
+
await user.click(screen.getByRole('button'));
|
|
225
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### 4. **State Testing**
|
|
230
|
+
```jsx
|
|
231
|
+
test('toggles state when clicked', async () => {
|
|
232
|
+
const user = userEvent.setup();
|
|
233
|
+
render(<Checkbox labelText="Test" setName="test" />);
|
|
234
|
+
|
|
235
|
+
const checkbox = screen.getByRole('checkbox');
|
|
236
|
+
|
|
237
|
+
expect(checkbox).not.toBeChecked();
|
|
238
|
+
await user.click(checkbox);
|
|
239
|
+
expect(checkbox).toBeChecked();
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### 5. **SVG/Icon Testing**
|
|
244
|
+
```jsx
|
|
245
|
+
test('renders SVG with correct attributes', () => {
|
|
246
|
+
render(<ChevronDown size={32} color="blue" />);
|
|
247
|
+
|
|
248
|
+
const svg = document.querySelector('svg');
|
|
249
|
+
expect(svg).toHaveAttribute('width', '32');
|
|
250
|
+
expect(svg).toHaveAttribute('height', '32');
|
|
251
|
+
|
|
252
|
+
const path = svg.querySelector('path');
|
|
253
|
+
expect(path).toHaveAttribute('stroke', 'blue');
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Best Practices
|
|
258
|
+
|
|
259
|
+
1. **Use semantic queries** - Prefer `getByRole()`, `getByLabelText()`, etc.
|
|
260
|
+
2. **Test user behavior** - Focus on what users do, not implementation details
|
|
261
|
+
3. **Use data-test-id sparingly** - Only when semantic queries aren't sufficient
|
|
262
|
+
4. **Mock external dependencies** - Keep tests isolated and fast
|
|
263
|
+
5. **Test error states** - Include edge cases and error conditions
|
|
264
|
+
6. **Keep tests readable** - Use descriptive test names and clear assertions
|
|
265
|
+
|
|
266
|
+
### Common Queries
|
|
267
|
+
|
|
268
|
+
```jsx
|
|
269
|
+
// Semantic queries (preferred)
|
|
270
|
+
screen.getByRole('button')
|
|
271
|
+
screen.getByLabelText('Email')
|
|
272
|
+
screen.getByText('Submit')
|
|
273
|
+
screen.getByPlaceholderText('Enter email')
|
|
274
|
+
|
|
275
|
+
// Test ID queries (when semantic queries aren't enough)
|
|
276
|
+
screen.getByTestId('custom-component')
|
|
277
|
+
|
|
278
|
+
// Query variants
|
|
279
|
+
getBy* // Throws error if not found
|
|
280
|
+
queryBy* // Returns null if not found
|
|
281
|
+
findBy* // Async, waits for element to appear
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## 🐛 Debugging Tests
|
|
285
|
+
|
|
286
|
+
### Common Issues
|
|
287
|
+
|
|
288
|
+
1. **Element not found** - Check if element is rendered and query is correct
|
|
289
|
+
2. **CSS not loading** - CSS is automatically mocked, so style-based queries won't work
|
|
290
|
+
3. **Async operations** - Use `findBy*` queries or `waitFor()` for async updates
|
|
291
|
+
4. **SVG elements** - Use `document.querySelector()` instead of `getByRole()`
|
|
292
|
+
|
|
293
|
+
### Debug Tools
|
|
294
|
+
|
|
295
|
+
```jsx
|
|
296
|
+
// Print rendered HTML
|
|
297
|
+
screen.debug();
|
|
298
|
+
|
|
299
|
+
// Print specific element
|
|
300
|
+
screen.debug(screen.getByRole('button'));
|
|
301
|
+
|
|
302
|
+
// Log available roles
|
|
303
|
+
screen.logTestingPlaygroundURL();
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## 📊 Coverage Goals
|
|
307
|
+
|
|
308
|
+
- **Statements**: 80%+
|
|
309
|
+
- **Branches**: 80%+
|
|
310
|
+
- **Functions**: 80%+
|
|
311
|
+
- **Lines**: 80%+
|
|
312
|
+
|
|
313
|
+
Current coverage is low because we only have tests for a few components. Add tests for remaining components to improve coverage.
|
|
314
|
+
|
|
315
|
+
## 🚀 Next Steps
|
|
316
|
+
|
|
317
|
+
1. **Add tests for remaining components** - Cover all components in the library
|
|
318
|
+
2. **Integration tests** - Test component interactions and workflows
|
|
319
|
+
3. **Visual regression tests** - Consider adding Chromatic or similar tools
|
|
320
|
+
4. **Performance tests** - Test rendering performance for complex components
|
|
321
|
+
5. **Accessibility tests** - Add automated a11y testing
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
Happy testing! 🧪✨
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
# Accessibility Utilities Usage Guide
|
|
329
|
+
|
|
330
|
+
## Overview
|
|
331
|
+
|
|
332
|
+
The `utils/accessibility.js` module provides safe, SSR-compatible utilities for common accessibility patterns throughout the UI library. These utilities help ensure consistent, robust accessibility implementations across components and stories.
|
|
333
|
+
|
|
334
|
+
## Available Utilities
|
|
335
|
+
|
|
336
|
+
### `announceToScreenReader(message, priority, timeout)`
|
|
337
|
+
Safe screen reader announcements using ARIA live regions.
|
|
338
|
+
- **Parameters**:
|
|
339
|
+
- `message` (string): Message to announce
|
|
340
|
+
- `priority` ('polite'|'assertive'): Announcement priority (default: 'polite')
|
|
341
|
+
- `timeout` (number): Cleanup timeout in ms (default: 1000)
|
|
342
|
+
- **Returns**: Cleanup function for manual cleanup
|
|
343
|
+
- **SSR Safe**: Yes (returns no-op function)
|
|
344
|
+
|
|
345
|
+
### `createLiveRegion(priority)`
|
|
346
|
+
Creates a persistent live region for multiple announcements.
|
|
347
|
+
- **Parameters**:
|
|
348
|
+
- `priority` ('polite'|'assertive'): Announcement priority (default: 'polite')
|
|
349
|
+
- **Returns**: Object with `announce(message)` and `destroy()` methods
|
|
350
|
+
- **SSR Safe**: Yes (returns no-op methods)
|
|
351
|
+
|
|
352
|
+
### `safeFocus(element, options)`
|
|
353
|
+
Safely focuses an element with fallback handling.
|
|
354
|
+
- **Parameters**:
|
|
355
|
+
- `element` (HTMLElement|string): Element or selector to focus
|
|
356
|
+
- `options` (object): Focus options (optional)
|
|
357
|
+
- **Returns**: Boolean indicating focus success
|
|
358
|
+
- **Features**: Error handling, selector support, focus verification
|
|
359
|
+
|
|
360
|
+
## Updated Components
|
|
361
|
+
|
|
362
|
+
### ✅ Components Using Accessibility Utilities
|
|
363
|
+
|
|
364
|
+
1. **Error.jsx**
|
|
365
|
+
- Uses built-in ARIA live regions (no manual utilities needed)
|
|
366
|
+
- Serves as example of proper component-level accessibility
|
|
367
|
+
|
|
368
|
+
2. **Form.jsx**
|
|
369
|
+
- **Updated**: Uses `safeFocus` for error field focusing
|
|
370
|
+
- **Updated**: Uses `announceToScreenReader` for form validation announcements
|
|
371
|
+
- **Location**: Lines 1-4 (imports), Line 184 (focus call)
|
|
372
|
+
|
|
373
|
+
3. **DragAndDrop.jsx**
|
|
374
|
+
- **Updated**: Uses `safeFocus` for keyboard navigation
|
|
375
|
+
- **Location**: Lines 12 (import), 123 (drag start), 174 & 184 (keyboard navigation)
|
|
376
|
+
|
|
377
|
+
### ✅ Stories Using Accessibility Utilities
|
|
378
|
+
|
|
379
|
+
1. **Avatar.stories.js**
|
|
380
|
+
- **Updated**: Replaced manual DOM manipulation with `announceToScreenReader`
|
|
381
|
+
- **Removed**: 13 lines of unsafe DOM manipulation code
|
|
382
|
+
- **Benefits**: SSR safety, consistent behavior, proper cleanup
|
|
383
|
+
|
|
384
|
+
2. **AnimationGroup.stories.js**
|
|
385
|
+
- **Updated**: Replaced manual DOM manipulation with `announceToScreenReader`
|
|
386
|
+
- **Removed**: 15 lines of unsafe DOM manipulation code
|
|
387
|
+
- **Benefits**: Better positioning, consistent ARIA attributes
|
|
388
|
+
|
|
389
|
+
3. **AnimationToggle.stories.js**
|
|
390
|
+
- **Updated**: Uses `safeFocus` for focus management
|
|
391
|
+
- **Updated**: Uses `announceToScreenReader` for state announcements
|
|
392
|
+
- **Benefits**: Safer focus operations, proper error handling
|
|
393
|
+
|
|
394
|
+
4. **Card.stories.js**
|
|
395
|
+
- **Updated**: Replaced manual DOM manipulation with `announceToScreenReader`
|
|
396
|
+
- **Updated**: Uses `safeFocus` for ellipses menu focus management
|
|
397
|
+
- **Removed**: 14 lines of duplicate DOM manipulation code
|
|
398
|
+
|
|
399
|
+
5. **DragAndDrop.stories.js**
|
|
400
|
+
- **Updated**: Uses `announceToScreenReader` instead of setState pattern
|
|
401
|
+
- **Benefits**: More reliable announcements, consistent with other stories
|
|
402
|
+
|
|
403
|
+
## Components That Could Benefit Further
|
|
404
|
+
|
|
405
|
+
### 🔄 Potential Future Updates
|
|
406
|
+
|
|
407
|
+
1. **AnimationToggle.jsx** (Component level)
|
|
408
|
+
- Could use `safeFocus` for internal focus management
|
|
409
|
+
- Currently relies on native focus which works well
|
|
410
|
+
|
|
411
|
+
2. **Crud.jsx**
|
|
412
|
+
- Has built-in screen reader announcements (lines 538-542)
|
|
413
|
+
- Could potentially use `createLiveRegion` for efficiency with many operations
|
|
414
|
+
- Current implementation is already quite good
|
|
415
|
+
|
|
416
|
+
3. **Button.jsx**
|
|
417
|
+
- Has comprehensive ARIA support
|
|
418
|
+
- Focus management handled by browser - no updates needed
|
|
419
|
+
|
|
420
|
+
4. **Select.jsx**, **TextInput.jsx**, **TextArea.jsx**, **Radio.jsx**, **Checkbox.jsx**
|
|
421
|
+
- These form elements have focus/blur handlers
|
|
422
|
+
- Current native focus handling is appropriate for form elements
|
|
423
|
+
- No updates recommended - browser handles focus well for form controls
|
|
424
|
+
|
|
425
|
+
### ❓ Stories with Existing Accessibility Patterns
|
|
426
|
+
|
|
427
|
+
1. **Crud.stories.js**
|
|
428
|
+
- Has comprehensive ARIA live regions built into component
|
|
429
|
+
- No manual DOM manipulation found - well implemented
|
|
430
|
+
|
|
431
|
+
2. **Button.stories.js**
|
|
432
|
+
- Uses component's built-in ARIA features
|
|
433
|
+
- No manual screen reader code found - good as is
|
|
434
|
+
|
|
435
|
+
## Best Practices
|
|
436
|
+
|
|
437
|
+
### ✅ When to Use These Utilities
|
|
438
|
+
|
|
439
|
+
1. **Use `announceToScreenReader`** when:
|
|
440
|
+
- Making dynamic announcements in Storybook stories
|
|
441
|
+
- Announcing user actions or state changes
|
|
442
|
+
- Providing feedback for asynchronous operations
|
|
443
|
+
|
|
444
|
+
2. **Use `createLiveRegion`** when:
|
|
445
|
+
- Making multiple announcements in succession
|
|
446
|
+
- Need more control over announcement timing
|
|
447
|
+
- Building components with frequent status updates
|
|
448
|
+
|
|
449
|
+
3. **Use `safeFocus`** when:
|
|
450
|
+
- Focusing elements that might not exist
|
|
451
|
+
- Implementing custom focus management
|
|
452
|
+
- Focus operations that could fail (dynamic content, conditional elements)
|
|
453
|
+
|
|
454
|
+
### ❌ When NOT to Use These Utilities
|
|
455
|
+
|
|
456
|
+
1. **Don't use for**:
|
|
457
|
+
- Form elements with native focus handling
|
|
458
|
+
- Components with built-in ARIA live regions
|
|
459
|
+
- Simple static content that doesn't need announcements
|
|
460
|
+
|
|
461
|
+
2. **Prefer component-level ARIA** for:
|
|
462
|
+
- Built-in component state announcements
|
|
463
|
+
- Semantic HTML with proper roles
|
|
464
|
+
- Standard form validation messages
|
|
465
|
+
|
|
466
|
+
## Implementation Benefits
|
|
467
|
+
|
|
468
|
+
### 🚀 Improvements Achieved
|
|
469
|
+
|
|
470
|
+
1. **Safety**: SSR-compatible with browser environment checks
|
|
471
|
+
2. **Consistency**: Standardized ARIA attributes and cleanup patterns
|
|
472
|
+
3. **Maintainability**: Centralized accessibility logic
|
|
473
|
+
4. **Reliability**: Proper error handling and fallbacks
|
|
474
|
+
5. **Performance**: Efficient DOM cleanup and reuse patterns
|
|
475
|
+
|
|
476
|
+
### 📈 Code Quality Improvements
|
|
477
|
+
|
|
478
|
+
- **Removed**: 57+ lines of duplicate DOM manipulation code
|
|
479
|
+
- **Added**: 3 robust, reusable utilities
|
|
480
|
+
- **Improved**: Error handling for focus operations
|
|
481
|
+
- **Enhanced**: Screen reader announcement reliability
|
|
482
|
+
|
|
483
|
+
## Testing Recommendations
|
|
484
|
+
|
|
485
|
+
### Screen Reader Testing
|
|
486
|
+
- Test with NVDA, JAWS, VoiceOver to verify announcements
|
|
487
|
+
- Verify announcements work in different browser environments
|
|
488
|
+
- Test SSR scenarios to ensure no client-side errors
|
|
489
|
+
|
|
490
|
+
### Focus Management Testing
|
|
491
|
+
- Test keyboard navigation flows
|
|
492
|
+
- Verify focus indicators are visible
|
|
493
|
+
- Test with dynamic content scenarios
|
|
494
|
+
|
|
495
|
+
### Cross-browser Testing
|
|
496
|
+
- Verify utilities work across different browsers
|
|
497
|
+
- Test in high contrast mode
|
|
498
|
+
- Verify reduced motion preferences are respected
|
|
499
|
+
|
|
500
|
+
## Future Enhancements
|
|
501
|
+
|
|
502
|
+
### Potential Additional Utilities
|
|
503
|
+
|
|
504
|
+
1. **Focus Trap**: For modal dialogs and complex widgets
|
|
505
|
+
2. **ARIA State Manager**: For complex state announcements
|
|
506
|
+
3. **Keyboard Navigation Helper**: For arrow key navigation patterns
|
|
507
|
+
4. **High Contrast Utilities**: For dynamic high contrast adaptations
|
|
508
|
+
|
|
509
|
+
This comprehensive integration ensures the UI library follows accessibility best practices while maintaining clean, maintainable code.
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
# Deployment Guide
|
|
514
|
+
|
|
515
|
+
This guide explains how to deploy the UI library to npm using the automated GitHub Actions workflow.
|
|
516
|
+
|
|
517
|
+
## Prerequisites
|
|
518
|
+
|
|
519
|
+
1. **NPM Account**: Ensure you have an npm account and access to publish packages
|
|
520
|
+
2. **Repository Access**: Admin access to the GitHub repository to configure secrets
|
|
521
|
+
3. **Package Configuration**: Verify `package.json` is properly configured
|
|
522
|
+
|
|
523
|
+
## Setup Process
|
|
524
|
+
|
|
525
|
+
### 1. Configure NPM Token
|
|
526
|
+
|
|
527
|
+
1. Go to [npm Access Tokens](https://www.npmjs.com/settings/tokens)
|
|
528
|
+
2. Click "Generate New Token"
|
|
529
|
+
3. Select "Automation" (for CI/CD use)
|
|
530
|
+
4. Copy the generated token
|
|
531
|
+
|
|
532
|
+
### 2. Add GitHub Secret
|
|
533
|
+
|
|
534
|
+
1. Go to your repository on GitHub
|
|
535
|
+
2. Navigate to Settings → Secrets and variables → Actions
|
|
536
|
+
3. Click "New repository secret"
|
|
537
|
+
4. Name: `NPM_TOKEN`
|
|
538
|
+
5. Value: Paste your npm token
|
|
539
|
+
6. Click "Add secret"
|
|
540
|
+
|
|
541
|
+
### 3. Package Configuration
|
|
542
|
+
|
|
543
|
+
Ensure your `package.json` has:
|
|
544
|
+
|
|
545
|
+
```json
|
|
546
|
+
{
|
|
547
|
+
"name": "your-package-name",
|
|
548
|
+
"version": "1.0.0",
|
|
549
|
+
"main": "dist/index.js",
|
|
550
|
+
"files": ["dist"],
|
|
551
|
+
"scripts": {
|
|
552
|
+
"build": "npm run build-command"
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
## Deployment Methods
|
|
558
|
+
|
|
559
|
+
### Method 1: Tag-based Deployment (Recommended)
|
|
560
|
+
|
|
561
|
+
This method automatically deploys when you push a version tag:
|
|
562
|
+
|
|
563
|
+
```bash
|
|
564
|
+
# Make sure your code is ready
|
|
565
|
+
git add .
|
|
566
|
+
git commit -m "Prepare for release v1.0.0"
|
|
567
|
+
git push origin main
|
|
568
|
+
|
|
569
|
+
# Create and push a version tag
|
|
570
|
+
git tag v1.0.0
|
|
571
|
+
git push origin v1.0.0
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
The workflow will:
|
|
575
|
+
1. ✅ Run all tests
|
|
576
|
+
2. ✅ Build the library
|
|
577
|
+
3. ✅ Publish to npm
|
|
578
|
+
4. ✅ Create a GitHub release
|
|
579
|
+
|
|
580
|
+
### Method 2: Manual Deployment
|
|
581
|
+
|
|
582
|
+
Use this for immediate deployment or when you want to control the version bump:
|
|
583
|
+
|
|
584
|
+
1. Go to GitHub Actions tab in your repository
|
|
585
|
+
2. Select "Deploy to NPM" workflow
|
|
586
|
+
3. Click "Run workflow"
|
|
587
|
+
4. Choose version bump type:
|
|
588
|
+
- **patch**: Bug fixes (1.0.0 → 1.0.1)
|
|
589
|
+
- **minor**: New features (1.0.0 → 1.1.0)
|
|
590
|
+
- **major**: Breaking changes (1.0.0 → 2.0.0)
|
|
591
|
+
5. Click "Run workflow"
|
|
592
|
+
|
|
593
|
+
## Workflow Steps
|
|
594
|
+
|
|
595
|
+
The deployment workflow performs these steps:
|
|
596
|
+
|
|
597
|
+
### 1. Testing Phase
|
|
598
|
+
- ✅ Checkout code
|
|
599
|
+
- ✅ Setup Node.js
|
|
600
|
+
- ✅ Install dependencies
|
|
601
|
+
- ✅ Run test suite
|
|
602
|
+
- ✅ Generate coverage report
|
|
603
|
+
|
|
604
|
+
### 2. Build and Deploy Phase
|
|
605
|
+
- ✅ Build the library
|
|
606
|
+
- ✅ Version management
|
|
607
|
+
- ✅ Verify build artifacts
|
|
608
|
+
- ✅ Publish to npm
|
|
609
|
+
- ✅ Create GitHub release (for tags)
|
|
610
|
+
|
|
611
|
+
## Monitoring Deployment
|
|
612
|
+
|
|
613
|
+
### Check GitHub Actions
|
|
614
|
+
1. Go to Actions tab in your repository
|
|
615
|
+
2. Click on the running/completed workflow
|
|
616
|
+
3. Review logs for each step
|
|
617
|
+
4. Verify success or investigate failures
|
|
618
|
+
|
|
619
|
+
### Verify NPM Publication
|
|
620
|
+
1. Check [npmjs.com](https://www.npmjs.com/package/your-package-name)
|
|
621
|
+
2. Verify the new version is available
|
|
622
|
+
3. Test installation: `npm install your-package-name@latest`
|
|
623
|
+
|
|
624
|
+
### Test Installation
|
|
625
|
+
```bash
|
|
626
|
+
# Create a test project
|
|
627
|
+
mkdir test-installation && cd test-installation
|
|
628
|
+
npm init -y
|
|
629
|
+
|
|
630
|
+
# Install your package
|
|
631
|
+
npm install your-package-name
|
|
632
|
+
|
|
633
|
+
# Test import
|
|
634
|
+
node -e "console.log(require('your-package-name'))"
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
## Troubleshooting
|
|
638
|
+
|
|
639
|
+
### Common Issues
|
|
640
|
+
|
|
641
|
+
**❌ NPM_TOKEN not set**
|
|
642
|
+
- Error: `npm ERR! need auth`
|
|
643
|
+
- Solution: Verify the NPM_TOKEN secret is correctly configured
|
|
644
|
+
|
|
645
|
+
**❌ Package name already exists**
|
|
646
|
+
- Error: `npm ERR! 403 Forbidden`
|
|
647
|
+
- Solution: Choose a unique package name or scope it (`@username/package-name`)
|
|
648
|
+
|
|
649
|
+
**❌ Build failures**
|
|
650
|
+
- Error: Various build errors
|
|
651
|
+
- Solution: Run `npm run build` locally first to identify issues
|
|
652
|
+
|
|
653
|
+
**❌ Test failures**
|
|
654
|
+
- Error: Tests fail in CI
|
|
655
|
+
- Solution: Ensure all tests pass locally with `npm test`
|
|
656
|
+
|
|
657
|
+
### Debug Steps
|
|
658
|
+
|
|
659
|
+
1. **Local verification**:
|
|
660
|
+
```bash
|
|
661
|
+
npm ci
|
|
662
|
+
npm test
|
|
663
|
+
npm run build
|
|
664
|
+
ls -la dist/ # Verify build output
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
2. **Check workflow logs**:
|
|
668
|
+
- Go to Actions → Failed workflow → Click on failed step
|
|
669
|
+
- Review error messages and stack traces
|
|
670
|
+
|
|
671
|
+
3. **Test npm authentication**:
|
|
672
|
+
```bash
|
|
673
|
+
npm whoami # Should show your npm username
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
## Best Practices
|
|
677
|
+
|
|
678
|
+
### Version Management
|
|
679
|
+
- Use semantic versioning (semver)
|
|
680
|
+
- Document changes in CHANGELOG.md
|
|
681
|
+
- Test thoroughly before releasing
|
|
682
|
+
|
|
683
|
+
### Quality Gates
|
|
684
|
+
- All tests must pass
|
|
685
|
+
- Code coverage maintained
|
|
686
|
+
- Build artifacts verified
|
|
687
|
+
- Documentation updated
|
|
688
|
+
|
|
689
|
+
### Release Notes
|
|
690
|
+
- Use descriptive commit messages
|
|
691
|
+
- Tag releases with clear version numbers
|
|
692
|
+
- Maintain changelog for users
|
|
693
|
+
|
|
694
|
+
## Security Considerations
|
|
695
|
+
|
|
696
|
+
- 🔒 NPM tokens have write access - keep them secure
|
|
697
|
+
- 🔒 Use "Automation" tokens for CI/CD (not "Publish" tokens)
|
|
698
|
+
- 🔒 Regularly rotate tokens
|
|
699
|
+
- 🔒 Monitor package downloads for suspicious activity
|
|
700
|
+
|
|
701
|
+
## Support
|
|
702
|
+
|
|
703
|
+
If you encounter issues:
|
|
704
|
+
1. Check this guide first
|
|
705
|
+
2. Review GitHub Actions logs
|
|
706
|
+
3. Verify npm token permissions
|
|
707
|
+
4. Test build process locally
|
|
708
|
+
5. Check npm registry status
|