mtrl 0.3.1 → 0.3.2
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/.env +15 -0
- package/CONTRIBUTING.md +8 -8
- package/DOCS.md +3 -3
- package/README.md +43 -20
- package/TESTING.md +128 -18
- package/dist/index.js +14865 -0
- package/git-user-stats.js +545 -0
- package/index.ts +9 -67
- package/package.json +8 -3
- package/src/components/badge/api.ts +15 -1
- package/src/components/badge/badge.ts +43 -4
- package/src/components/badge/config.ts +40 -8
- package/src/components/badge/index.ts +64 -3
- package/src/components/badge/types.ts +175 -33
- package/src/components/button/api.ts +63 -1
- package/src/components/button/button.ts +39 -3
- package/src/components/button/config.ts +21 -4
- package/src/components/button/index.ts +26 -1
- package/src/components/button/types.ts +7 -1
- package/src/components/card/api.ts +78 -9
- package/src/components/card/card.ts +58 -3
- package/src/components/card/config.ts +41 -11
- package/src/components/card/features.ts +39 -12
- package/src/components/card/index.ts +84 -19
- package/src/components/card/types.ts +218 -29
- package/src/components/carousel/carousel.ts +92 -28
- package/src/components/carousel/constants.ts +107 -21
- package/src/components/carousel/index.ts +31 -13
- package/src/components/checkbox/checkbox.ts +83 -16
- package/src/components/checkbox/index.ts +43 -1
- package/src/components/checkbox/types.ts +219 -32
- package/src/components/chips/api.ts +194 -0
- package/src/components/{chip → chips/chip}/api.ts +42 -2
- package/src/components/chips/chip/chip.ts +131 -0
- package/src/components/{chip → chips/chip}/config.ts +3 -3
- package/src/components/chips/chip/index.ts +3 -0
- package/src/components/chips/chips.md +481 -0
- package/src/components/chips/chips.ts +75 -0
- package/src/components/chips/config.ts +109 -0
- package/src/components/chips/constants.ts +61 -0
- package/src/components/chips/features/chip-items.ts +33 -0
- package/src/components/chips/features/container.ts +77 -0
- package/src/components/chips/features/controller.ts +448 -0
- package/src/components/chips/features/index.ts +5 -0
- package/src/components/chips/features/label.ts +108 -0
- package/src/components/chips/index.ts +11 -0
- package/src/components/chips/schema.ts +61 -0
- package/src/components/{chip → chips}/types.ts +203 -92
- package/src/components/dialog/dialog.ts +99 -16
- package/src/components/dialog/index.ts +97 -1
- package/src/components/dialog/types.ts +375 -69
- package/src/components/divider/config.ts +90 -6
- package/src/components/divider/divider.ts +32 -2
- package/src/components/divider/features.ts +26 -0
- package/src/components/divider/index.ts +30 -0
- package/src/components/divider/types.ts +86 -9
- package/src/components/extended-fab/api.ts +53 -1
- package/src/components/extended-fab/config.ts +29 -1
- package/src/components/extended-fab/extended-fab.ts +28 -0
- package/src/components/extended-fab/index.ts +36 -0
- package/src/components/extended-fab/types.ts +458 -13
- package/src/components/fab/api.ts +42 -2
- package/src/components/fab/config.ts +29 -1
- package/src/components/fab/fab.ts +16 -2
- package/src/components/fab/index.ts +35 -0
- package/src/components/fab/types.ts +374 -10
- package/src/components/list/api.ts +12 -2
- package/src/components/list/config.ts +21 -0
- package/src/components/list/features.ts +6 -0
- package/src/components/list/index.ts +56 -1
- package/src/components/list/list-item.ts +46 -2
- package/src/components/list/list.ts +73 -2
- package/src/components/list/types.ts +172 -0
- package/src/components/list/utils.ts +26 -2
- package/src/components/menu/api.ts +217 -20
- package/src/components/menu/config.ts +27 -0
- package/src/components/menu/features/visibility.ts +55 -6
- package/src/components/menu/index.ts +64 -0
- package/src/components/menu/menu-item.ts +46 -3
- package/src/components/menu/menu.ts +77 -1
- package/src/components/menu/types.ts +404 -39
- package/src/components/sheet/config.ts +1 -2
- package/src/components/sheet/features/gestures.ts +1 -1
- package/src/components/sheet/features/position.ts +1 -2
- package/src/components/sheet/features/state.ts +1 -1
- package/src/components/sheet/index.ts +10 -2
- package/src/components/sheet/sheet.ts +1 -2
- package/src/components/sheet/types.ts +29 -1
- package/src/components/slider/api.ts +1 -1
- package/src/components/slider/config.ts +1 -1
- package/src/components/slider/features/controller.ts +1 -1
- package/src/components/slider/features/handlers.ts +1 -1
- package/src/components/slider/features/states.ts +1 -1
- package/src/components/slider/index.ts +12 -5
- package/src/components/slider/schema.ts +1 -1
- package/src/components/slider/types.ts +31 -0
- package/src/components/tabs/tab-api.ts +1 -1
- package/src/components/tabs/types.ts +1 -1
- package/src/components/tooltip/api.ts +6 -2
- package/src/components/tooltip/config.ts +9 -28
- package/src/components/tooltip/index.ts +10 -1
- package/src/components/tooltip/types.ts +38 -3
- package/src/index.ts +129 -31
- package/src/styles/abstract/_mixins.scss +23 -9
- package/src/styles/abstract/_variables.scss +14 -4
- package/src/styles/components/_card.scss +1 -1
- package/src/styles/components/_chip.scss +323 -113
- package/src/styles/components/_tabs.scss +1 -1
- package/CLAUDE.md +0 -33
- package/src/components/checkbox/constants.ts +0 -37
- package/src/components/chip/chip-set.ts +0 -225
- package/src/components/chip/chip.ts +0 -118
- package/src/components/chip/constants.ts +0 -28
- package/src/components/chip/index.ts +0 -12
- package/src/components/list/constants.ts +0 -116
- package/src/components/sheet/constants.ts +0 -20
- package/src/components/slider/constants.ts +0 -32
- package/src/components/tooltip/constants.ts +0 -27
- package/test/components/badge.test.ts +0 -545
- package/test/components/bottom-app-bar.test.ts +0 -303
- package/test/components/button.test.ts +0 -233
- package/test/components/card.test.ts +0 -560
- package/test/components/carousel.test.ts +0 -951
- package/test/components/checkbox.test.ts +0 -462
- package/test/components/chip.test.ts +0 -692
- package/test/components/datepicker.test.ts +0 -1124
- package/test/components/dialog.test.ts +0 -990
- package/test/components/divider.test.ts +0 -412
- package/test/components/extended-fab.test.ts +0 -672
- package/test/components/fab.test.ts +0 -561
- package/test/components/list.test.ts +0 -365
- package/test/components/menu.test.ts +0 -718
- package/test/components/navigation.test.ts +0 -186
- package/test/components/progress.test.ts +0 -567
- package/test/components/radios.test.ts +0 -699
- package/test/components/search.test.ts +0 -1135
- package/test/components/segmented-button.test.ts +0 -732
- package/test/components/sheet.test.ts +0 -641
- package/test/components/slider.test.ts +0 -1220
- package/test/components/snackbar.test.ts +0 -461
- package/test/components/switch.test.ts +0 -452
- package/test/components/tabs.test.ts +0 -1369
- package/test/components/textfield.test.ts +0 -400
- package/test/components/timepicker.test.ts +0 -592
- package/test/components/tooltip.test.ts +0 -630
- package/test/components/top-app-bar.test.ts +0 -566
- package/test/core/dom.attributes.test.ts +0 -148
- package/test/core/dom.classes.test.ts +0 -152
- package/test/core/dom.events.test.ts +0 -243
- package/test/core/emitter.test.ts +0 -141
- package/test/core/ripple.test.ts +0 -99
- package/test/core/state.store.test.ts +0 -189
- package/test/core/utils.normalize.test.ts +0 -61
- package/test/core/utils.object.test.ts +0 -120
- package/test/setup.js +0 -371
- package/test/setup.ts +0 -451
- package/tsconfig.json +0 -22
- package/typedoc.json +0 -28
- package/typedoc.simple.json +0 -14
package/.env
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Application settings
|
|
2
|
+
NODE_ENV=development
|
|
3
|
+
PORT=4000
|
|
4
|
+
# Compression settings
|
|
5
|
+
COMPRESSION_ENABLED=false
|
|
6
|
+
# Cache settings (shorter for development)
|
|
7
|
+
CACHE_STATIC_FILES=0 # No caching in development
|
|
8
|
+
CACHE_CSS_FILES=0
|
|
9
|
+
CACHE_PUBLIC_FILES=0
|
|
10
|
+
# Security settings
|
|
11
|
+
ENABLE_CORS=true
|
|
12
|
+
CORS_ORIGIN=*
|
|
13
|
+
# Application specific settings
|
|
14
|
+
APP_TITLE=MTRL Playground (DEV)
|
|
15
|
+
DEBUG_LEVEL=debug
|
package/CONTRIBUTING.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Contributing to
|
|
1
|
+
# Contributing to mtrl
|
|
2
2
|
|
|
3
|
-
Thank you for your interest in contributing to
|
|
3
|
+
Thank you for your interest in contributing to mtrl! This document provides guidelines and instructions for contributing to this lightweight, ES6-focused JavaScript UI component library.
|
|
4
4
|
|
|
5
5
|
## Why Contribute?
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
mtrl aims to be a modern, flexible UI component library with:
|
|
8
8
|
|
|
9
9
|
- Zero dependencies (except Bun for development)
|
|
10
10
|
- ES6+ focused codebase
|
|
@@ -12,7 +12,7 @@ MTRL aims to be a modern, flexible UI component library with:
|
|
|
12
12
|
- Simple and extensible API
|
|
13
13
|
- Excellent documentation
|
|
14
14
|
|
|
15
|
-
By contributing to
|
|
15
|
+
By contributing to mtrl, you'll help create a lean alternative to heavier frameworks while gaining experience with modern JavaScript patterns and component design.
|
|
16
16
|
|
|
17
17
|
## Getting Started
|
|
18
18
|
|
|
@@ -31,7 +31,7 @@ By contributing to MTRL, you'll help create a lean alternative to heavier framew
|
|
|
31
31
|
|
|
32
32
|
### Testing Your Components with mtrl.app
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
mtrl uses a separate repository called mtrl.app (https://mtrl.app) for showcasing and testing components. There are two ways to test your components:
|
|
35
35
|
|
|
36
36
|
1. **Build and link locally**:
|
|
37
37
|
```bash
|
|
@@ -74,7 +74,7 @@ MTRL uses a separate repository called mtrl.app (https://mtrl.app) for showcasin
|
|
|
74
74
|
|
|
75
75
|
### Component Structure
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
mtrl components follow a consistent pattern:
|
|
78
78
|
|
|
79
79
|
```javascript
|
|
80
80
|
// src/components/mycomponent/index.js
|
|
@@ -172,8 +172,8 @@ For any new feature or component:
|
|
|
172
172
|
|
|
173
173
|
## License
|
|
174
174
|
|
|
175
|
-
By contributing to
|
|
175
|
+
By contributing to mtrl, you agree that your contributions will be licensed under the project's MIT License.
|
|
176
176
|
|
|
177
177
|
---
|
|
178
178
|
|
|
179
|
-
Thank you for contributing to
|
|
179
|
+
Thank you for contributing to mtrl! Your efforts help make this library better for everyone.
|
package/DOCS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# TypeDoc Installation and Usage Guide for
|
|
1
|
+
# TypeDoc Installation and Usage Guide for mtrl
|
|
2
2
|
|
|
3
|
-
This guide will help you set up and use TypeDoc with your
|
|
3
|
+
This guide will help you set up and use TypeDoc with your mtrl library.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -86,7 +86,7 @@ function myFunction(paramName: string): number {
|
|
|
86
86
|
|
|
87
87
|
### Categories
|
|
88
88
|
|
|
89
|
-
Use the `@category` tag to organize your
|
|
89
|
+
Use the `@category` tag to organize your mtrl components and utilities:
|
|
90
90
|
|
|
91
91
|
```typescript
|
|
92
92
|
/**
|
package/README.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mtrl Library
|
|
2
2
|
|
|
3
|
-
> **Project Status:**
|
|
3
|
+
> **Project Status:** mtrl is in active development with TypeScript support! The core architecture and components are established, with more features on the roadmap. We welcome early adopters and contributors who want to help shape mtrl's future!
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
mtrl is a lightweight, composable TypeScript/JavaScript component library inspired by Material Design principles. Built with zero dependencies, mtrl provides a robust foundation for creating modern web interfaces with an emphasis on performance, type safety, and accessibility.
|
|
6
6
|
|
|
7
|
-
## Understanding
|
|
7
|
+
## Understanding mtrl
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
mtrl (pronounced "material") takes its inspiration from Material Design while providing a flexible, framework-agnostic implementation. The library's name is reflected in its component prefix `mtrl-`, which you'll see used consistently throughout the codebase.
|
|
10
10
|
|
|
11
11
|
### Design Philosophy
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
mtrl is built on several core principles:
|
|
14
14
|
|
|
15
15
|
1. **Composition Over Inheritance**: Components are constructed through functional composition with full type safety.
|
|
16
16
|
2. **Zero Dependencies**: The entire library is built with vanilla TypeScript, ensuring minimal bundle size and maximum compatibility.
|
|
17
|
-
3. **Material Design Inspiration**: While inspired by Material Design,
|
|
17
|
+
3. **Material Design Inspiration**: While inspired by Material Design, mtrl provides flexibility in styling and behavior.
|
|
18
18
|
4. **Accessibility First**: Built-in accessibility features ensure your applications are usable by everyone.
|
|
19
19
|
5. **TypeScript First**: Comprehensive type definitions for better developer experience and code reliability.
|
|
20
20
|
|
|
21
21
|
## Core Components
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
mtrl provides a comprehensive set of components, each following Material Design principles:
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
26
|
import { createButton, createTextField } from 'mtrl'
|
|
@@ -63,7 +63,7 @@ bun add mtrl
|
|
|
63
63
|
|
|
64
64
|
## Component Architecture
|
|
65
65
|
|
|
66
|
-
Let's look at how
|
|
66
|
+
Let's look at how mtrl components are constructed:
|
|
67
67
|
|
|
68
68
|
```typescript
|
|
69
69
|
// Example of a button component creation
|
|
@@ -78,7 +78,7 @@ const button = createButton({
|
|
|
78
78
|
|
|
79
79
|
### The Composition System
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
mtrl uses a pipe-based composition system with full type safety for building components:
|
|
82
82
|
|
|
83
83
|
```typescript
|
|
84
84
|
// Internal component creation
|
|
@@ -101,7 +101,7 @@ const createButton = (config: ButtonConfig): ButtonComponent => {
|
|
|
101
101
|
|
|
102
102
|
### TypeScript Integration
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
mtrl provides comprehensive TypeScript definitions:
|
|
105
105
|
|
|
106
106
|
```typescript
|
|
107
107
|
// Component interfaces for better developer experience
|
|
@@ -129,7 +129,7 @@ export interface ButtonComponent extends
|
|
|
129
129
|
|
|
130
130
|
### CSS Classes
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
mtrl follows a consistent class naming convention:
|
|
133
133
|
|
|
134
134
|
```css
|
|
135
135
|
.mtrl-component /* Base component class */
|
|
@@ -140,7 +140,7 @@ MTRL follows a consistent class naming convention:
|
|
|
140
140
|
|
|
141
141
|
## State Management
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
mtrl provides several approaches to state management:
|
|
144
144
|
|
|
145
145
|
### Local Component State
|
|
146
146
|
|
|
@@ -175,7 +175,7 @@ collection.subscribe(({ event, data }) => {
|
|
|
175
175
|
|
|
176
176
|
## Data Integration
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
mtrl provides adapters for different data sources:
|
|
179
179
|
|
|
180
180
|
```typescript
|
|
181
181
|
// MongoDB adapter
|
|
@@ -199,7 +199,7 @@ const routeAdapter = createRouteAdapter({
|
|
|
199
199
|
|
|
200
200
|
### Creating Custom Components
|
|
201
201
|
|
|
202
|
-
Extend
|
|
202
|
+
Extend mtrl by creating custom components with full type safety:
|
|
203
203
|
|
|
204
204
|
```typescript
|
|
205
205
|
interface CustomCardConfig {
|
|
@@ -234,7 +234,7 @@ const createCustomCard = (config: CustomCardConfig): CustomCardComponent => {
|
|
|
234
234
|
|
|
235
235
|
### Styling
|
|
236
236
|
|
|
237
|
-
|
|
237
|
+
mtrl components can be styled through CSS custom properties:
|
|
238
238
|
|
|
239
239
|
```css
|
|
240
240
|
:root {
|
|
@@ -249,7 +249,7 @@ MTRL components can be styled through CSS custom properties:
|
|
|
249
249
|
|
|
250
250
|
### Performance
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
mtrl is designed with performance in mind:
|
|
253
253
|
|
|
254
254
|
- Minimal DOM operations
|
|
255
255
|
- Efficient event handling
|
|
@@ -258,7 +258,7 @@ MTRL is designed with performance in mind:
|
|
|
258
258
|
|
|
259
259
|
### Type Safety
|
|
260
260
|
|
|
261
|
-
|
|
261
|
+
mtrl leverages TypeScript for better developer experience:
|
|
262
262
|
|
|
263
263
|
- Clear component interfaces
|
|
264
264
|
- Type-safe method chaining
|
|
@@ -277,7 +277,7 @@ Built-in accessibility features include:
|
|
|
277
277
|
|
|
278
278
|
## Browser Support
|
|
279
279
|
|
|
280
|
-
|
|
280
|
+
mtrl supports modern browsers:
|
|
281
281
|
|
|
282
282
|
- Chrome (latest)
|
|
283
283
|
- Firefox (latest)
|
|
@@ -290,7 +290,30 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
|
|
|
290
290
|
|
|
291
291
|
## License
|
|
292
292
|
|
|
293
|
-
|
|
293
|
+
mtrl is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
294
|
+
|
|
295
|
+
## Testing
|
|
296
|
+
|
|
297
|
+
mtrl comes with a comprehensive test suite using Bun's test runner. The tests are written in TypeScript and use JSDOM for DOM testing.
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
# Run all tests
|
|
301
|
+
bun test
|
|
302
|
+
|
|
303
|
+
# Run tests in watch mode
|
|
304
|
+
bun test --watch
|
|
305
|
+
|
|
306
|
+
# Run tests with coverage report
|
|
307
|
+
bun test --coverage
|
|
308
|
+
|
|
309
|
+
# Run tests with UI
|
|
310
|
+
bun test --watch --ui
|
|
311
|
+
|
|
312
|
+
# Run a specific test file
|
|
313
|
+
bun test test/components/button.test.ts
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
For more details on writing and running tests, see our [Testing Guide](TESTING.md).
|
|
294
317
|
|
|
295
318
|
## Documentation
|
|
296
319
|
|
package/TESTING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Testing
|
|
1
|
+
# Testing mtrl Components
|
|
2
2
|
|
|
3
|
-
This document provides guidelines for writing and running tests for the
|
|
3
|
+
This document provides guidelines for writing and running tests for the mtrl library. We use Bun's built-in test runner for fast, efficient testing.
|
|
4
4
|
|
|
5
5
|
## Running Tests
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ bun test --coverage
|
|
|
18
18
|
bun test --watch --ui
|
|
19
19
|
|
|
20
20
|
# Run specific test file or pattern
|
|
21
|
-
bun test test/components/button.test.
|
|
21
|
+
bun test test/components/button.test.ts
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
## Test Structure
|
|
@@ -27,29 +27,31 @@ Tests are organized to mirror the source code structure:
|
|
|
27
27
|
|
|
28
28
|
```
|
|
29
29
|
test/
|
|
30
|
-
├── setup.
|
|
30
|
+
├── setup.ts # Global test setup and DOM mocking
|
|
31
31
|
├── components/ # Component tests
|
|
32
|
-
│ ├── button.test.
|
|
33
|
-
│ ├── textfield.test.
|
|
32
|
+
│ ├── button.test.ts
|
|
33
|
+
│ ├── textfield.test.ts
|
|
34
34
|
│ └── ...
|
|
35
35
|
└── core/ # Core functionality tests
|
|
36
|
-
├──
|
|
37
|
-
|
|
38
|
-
├── dom
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
├── dom.classes.test.ts
|
|
37
|
+
├── dom.attributes.test.ts
|
|
38
|
+
├── dom.events.test.ts
|
|
39
|
+
├── utils.normalize.test.ts
|
|
40
|
+
├── utils.object.test.ts
|
|
41
|
+
├── emitter.test.ts
|
|
42
|
+
├── ripple.test.ts
|
|
43
|
+
└── state.store.test.ts
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
## Writing Tests
|
|
45
47
|
|
|
46
|
-
When writing tests for
|
|
48
|
+
When writing tests for mtrl components, follow these guidelines:
|
|
47
49
|
|
|
48
50
|
### 1. Test Component Creation
|
|
49
51
|
|
|
50
52
|
Always verify that components are created correctly with default options:
|
|
51
53
|
|
|
52
|
-
```
|
|
54
|
+
```typescript
|
|
53
55
|
test('should create a component element', () => {
|
|
54
56
|
const component = createComponent();
|
|
55
57
|
expect(component.element).toBeDefined();
|
|
@@ -62,7 +64,7 @@ test('should create a component element', () => {
|
|
|
62
64
|
|
|
63
65
|
Test that configuration options properly affect the component:
|
|
64
66
|
|
|
65
|
-
```
|
|
67
|
+
```typescript
|
|
66
68
|
test('should apply variant class', () => {
|
|
67
69
|
const variant = 'filled';
|
|
68
70
|
const component = createComponent({
|
|
@@ -77,7 +79,7 @@ test('should apply variant class', () => {
|
|
|
77
79
|
|
|
78
80
|
Verify that events are properly emitted and handled:
|
|
79
81
|
|
|
80
|
-
```
|
|
82
|
+
```typescript
|
|
81
83
|
test('should handle click events', () => {
|
|
82
84
|
const component = createComponent();
|
|
83
85
|
const handleClick = mock(() => {});
|
|
@@ -96,9 +98,117 @@ test('should handle click events', () => {
|
|
|
96
98
|
|
|
97
99
|
Test component state changes through its API:
|
|
98
100
|
|
|
99
|
-
```
|
|
101
|
+
```typescript
|
|
100
102
|
test('should support disabled state', () => {
|
|
101
103
|
const component = createComponent();
|
|
102
104
|
|
|
103
105
|
// Initially not disabled
|
|
104
|
-
expect(component.
|
|
106
|
+
expect(component.disabled.isDisabled()).toBe(false);
|
|
107
|
+
|
|
108
|
+
// Disable
|
|
109
|
+
component.disable();
|
|
110
|
+
expect(component.disabled.isDisabled()).toBe(true);
|
|
111
|
+
expect(component.element.classList.contains('mtrl-component--disabled')).toBe(true);
|
|
112
|
+
|
|
113
|
+
// Enable
|
|
114
|
+
component.enable();
|
|
115
|
+
expect(component.disabled.isDisabled()).toBe(false);
|
|
116
|
+
expect(component.element.classList.contains('mtrl-component--disabled')).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## JSDOM Setup
|
|
121
|
+
|
|
122
|
+
We use JSDOM to create a DOM environment for component tests. Each test file that requires DOM manipulation should include the proper JSDOM setup:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Setup jsdom environment
|
|
126
|
+
let dom: JSDOM;
|
|
127
|
+
let window: Window;
|
|
128
|
+
let document: Document;
|
|
129
|
+
let originalGlobalDocument: any;
|
|
130
|
+
let originalGlobalWindow: any;
|
|
131
|
+
|
|
132
|
+
beforeAll(() => {
|
|
133
|
+
// Create a new JSDOM instance
|
|
134
|
+
dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
135
|
+
url: 'http://localhost/',
|
|
136
|
+
pretendToBeVisual: true
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Get window and document from jsdom
|
|
140
|
+
window = dom.window;
|
|
141
|
+
document = window.document;
|
|
142
|
+
|
|
143
|
+
// Store original globals
|
|
144
|
+
originalGlobalDocument = global.document;
|
|
145
|
+
originalGlobalWindow = global.window;
|
|
146
|
+
|
|
147
|
+
// Set globals to use jsdom
|
|
148
|
+
global.document = document;
|
|
149
|
+
global.window = window;
|
|
150
|
+
global.Element = window.Element;
|
|
151
|
+
global.HTMLElement = window.HTMLElement;
|
|
152
|
+
global.Event = window.Event;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
afterAll(() => {
|
|
156
|
+
// Restore original globals
|
|
157
|
+
global.document = originalGlobalDocument;
|
|
158
|
+
global.window = originalGlobalWindow;
|
|
159
|
+
|
|
160
|
+
// Clean up jsdom
|
|
161
|
+
window.close();
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Component Testing Approach
|
|
166
|
+
|
|
167
|
+
For most component tests, we use a mock implementation approach that creates components with the same interface as the real components, but with simplified internals. This approach:
|
|
168
|
+
|
|
169
|
+
1. Avoids circular dependency issues in tests
|
|
170
|
+
2. Makes tests faster and more isolated
|
|
171
|
+
3. Allows testing component interfaces without implementation details
|
|
172
|
+
4. Provides better control over the test environment
|
|
173
|
+
|
|
174
|
+
A typical mock component setup might look like:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const createMockComponent = (config: ComponentConfig = {}): ComponentInterface => {
|
|
178
|
+
// Create base elements
|
|
179
|
+
const element = document.createElement('div');
|
|
180
|
+
element.className = 'mtrl-component';
|
|
181
|
+
|
|
182
|
+
// Apply configuration
|
|
183
|
+
if (config.variant) {
|
|
184
|
+
element.classList.add(`mtrl-component--${config.variant}`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Event tracking
|
|
188
|
+
const eventHandlers: Record<string, Function[]> = {};
|
|
189
|
+
|
|
190
|
+
// Return component interface
|
|
191
|
+
return {
|
|
192
|
+
element,
|
|
193
|
+
|
|
194
|
+
// Component methods matching the real component API
|
|
195
|
+
setValue(value: string) {
|
|
196
|
+
element.setAttribute('value', value);
|
|
197
|
+
return this;
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
getValue() {
|
|
201
|
+
return element.getAttribute('value') || '';
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
on(event: string, handler: Function) {
|
|
205
|
+
if (!eventHandlers[event]) eventHandlers[event] = [];
|
|
206
|
+
eventHandlers[event].push(handler);
|
|
207
|
+
element.addEventListener(event, handler as EventListener);
|
|
208
|
+
return this;
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
// Additional methods as needed...
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
```
|