@universityofmaryland/web-elements-library 1.3.6 → 1.3.7
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/README.md +233 -370
- package/dist/atomic/_types.d.ts +1 -1
- package/dist/atomic/_types.d.ts.map +1 -1
- package/dist/atomic/assets/image/background.d.ts +1 -0
- package/dist/atomic/assets/image/background.d.ts.map +1 -1
- package/dist/composite/hero/overlay.d.ts.map +1 -1
- package/dist/composite/media/elements/gif.d.ts +10 -0
- package/dist/composite/media/elements/gif.d.ts.map +1 -0
- package/dist/composite/media/elements/index.d.ts +2 -10
- package/dist/composite/media/elements/index.d.ts.map +1 -1
- package/dist/composite/media/index.d.ts +1 -1
- package/dist/composite/media/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +8 -4
- package/dist/layout/image.d.ts.map +1 -1
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# University of Maryland Web Elements Library
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@universityofmaryland/web-elements-library)
|
|
4
4
|
|
|
5
|
-
Foundational UI
|
|
5
|
+
Foundational UI building blocks for the UMD Design System, providing atomic elements that combine to create complex, accessible, and brand-compliant University of Maryland digital experiences.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The UMD Web Elements Library provides the essential building blocks used to construct the UMD Web Components Library. Think of elements as atoms in a design system - they are the smallest, indivisible units that maintain meaning and functionality. These elements handle core UI patterns like buttons, images, text layouts, and containers while remaining unopinionated about their final appearance, relying on the Styles Library for visual presentation.
|
|
6
10
|
|
|
7
11
|
## Installation
|
|
8
12
|
|
|
@@ -14,505 +18,364 @@ npm install @universityofmaryland/web-elements-library
|
|
|
14
18
|
yarn add @universityofmaryland/web-elements-library
|
|
15
19
|
```
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
### Peer Dependencies
|
|
22
|
+
|
|
23
|
+
Elements are styled by the Styles package:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @universityofmaryland/web-styles-library
|
|
27
|
+
```
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
## Quick Start
|
|
20
30
|
|
|
21
31
|
```javascript
|
|
22
|
-
import { Composite } from '@universityofmaryland/web-elements-library';
|
|
32
|
+
import { Composite, Atomic } from '@universityofmaryland/web-elements-library';
|
|
23
33
|
|
|
24
|
-
// Create a
|
|
25
|
-
const
|
|
26
|
-
headline: document.createElement('
|
|
34
|
+
// Create a card element
|
|
35
|
+
const card = Composite.card.block({
|
|
36
|
+
headline: document.createElement('h3'),
|
|
27
37
|
text: document.createElement('p'),
|
|
28
38
|
image: document.querySelector('img'),
|
|
29
39
|
isThemeDark: true
|
|
30
40
|
});
|
|
31
41
|
|
|
32
|
-
// Add
|
|
33
|
-
document.
|
|
42
|
+
// Add to DOM
|
|
43
|
+
document.querySelector('.container').appendChild(card.element);
|
|
34
44
|
|
|
35
|
-
//
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
document.head.appendChild(
|
|
45
|
+
// Apply associated styles
|
|
46
|
+
const style = document.createElement('style');
|
|
47
|
+
style.textContent = card.styles;
|
|
48
|
+
document.head.appendChild(style);
|
|
39
49
|
```
|
|
40
50
|
|
|
41
|
-
##
|
|
51
|
+
## Architecture
|
|
52
|
+
|
|
53
|
+
### Element Categories
|
|
54
|
+
|
|
55
|
+
#### Atomic Elements
|
|
56
|
+
The most basic building blocks:
|
|
57
|
+
- **actions** - Buttons and interactive elements
|
|
58
|
+
- **animations** - Animation patterns and effects
|
|
59
|
+
- **assets** - Images, videos, and media handling
|
|
60
|
+
- **buttons** - Specialized button components
|
|
61
|
+
- **events** - Event-related display elements
|
|
62
|
+
- **layout** - Basic layout structures
|
|
63
|
+
- **textLockup** - Text grouping patterns
|
|
64
|
+
|
|
65
|
+
#### Composite Elements
|
|
66
|
+
Combinations of atomic elements forming UI patterns:
|
|
67
|
+
- **accordion** - Expandable content sections
|
|
68
|
+
- **alert** - Notification and alert displays
|
|
69
|
+
- **banner** - Banner and promotional elements
|
|
70
|
+
- **card** - Content cards (block, list, overlay)
|
|
71
|
+
- **carousel** - Image and content sliders
|
|
72
|
+
- **footer** - Footer compositions
|
|
73
|
+
- **hero** - Hero sections (see detailed documentation below)
|
|
74
|
+
- **layout** - Complex layout patterns
|
|
75
|
+
- **media** - Media display compositions
|
|
76
|
+
- **navigation** - Navigation structures
|
|
77
|
+
- **pathway** - User journey elements
|
|
78
|
+
- **person** - Profile and bio displays
|
|
79
|
+
- **quote** - Quote and testimonial blocks
|
|
80
|
+
- **slider** - Content slider variations
|
|
81
|
+
- **social** - Social media integrations
|
|
82
|
+
- **stat** - Statistics displays
|
|
83
|
+
- **tabs** - Tabbed interfaces
|
|
84
|
+
|
|
85
|
+
### Element Return Structure
|
|
86
|
+
|
|
87
|
+
All elements return a consistent interface:
|
|
42
88
|
|
|
43
|
-
|
|
89
|
+
```typescript
|
|
90
|
+
interface ElementModel {
|
|
91
|
+
element: HTMLElement | DocumentFragment;
|
|
92
|
+
styles: string;
|
|
93
|
+
events?: {
|
|
94
|
+
load?: () => void;
|
|
95
|
+
resize?: () => void;
|
|
96
|
+
destroy?: () => void;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
```
|
|
44
100
|
|
|
45
|
-
|
|
46
|
-
// Import specific element categories
|
|
47
|
-
import { Atomic, Composite, Layout } from '@universityofmaryland/web-elements-library';
|
|
101
|
+
## Integration with Other Packages
|
|
48
102
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
url: '#',
|
|
53
|
-
isStyled: true
|
|
54
|
-
});
|
|
103
|
+
### Styles Package Dependency
|
|
104
|
+
|
|
105
|
+
Elements rely entirely on the Styles package for visual presentation:
|
|
55
106
|
|
|
56
|
-
|
|
57
|
-
|
|
107
|
+
```javascript
|
|
108
|
+
import { Composite } from '@universityofmaryland/web-elements-library';
|
|
109
|
+
// Styles are automatically included in the element.styles property
|
|
58
110
|
```
|
|
59
111
|
|
|
60
|
-
|
|
112
|
+
### Components Package Relationship
|
|
113
|
+
|
|
114
|
+
Components are built using Elements:
|
|
115
|
+
- Elements provide structure and behavior
|
|
116
|
+
- Components add web component wrapper and lifecycle
|
|
117
|
+
- Elements can be used standalone for custom implementations
|
|
61
118
|
|
|
62
|
-
|
|
119
|
+
### Usage in Feeds Package
|
|
120
|
+
|
|
121
|
+
Feed layouts use Elements for content display:
|
|
122
|
+
```javascript
|
|
123
|
+
// Feeds internally use card and grid elements
|
|
124
|
+
import { card } from '@universityofmaryland/web-elements-library/Composite';
|
|
125
|
+
```
|
|
63
126
|
|
|
64
|
-
|
|
127
|
+
## Common Element Patterns
|
|
65
128
|
|
|
66
|
-
|
|
129
|
+
### Actions Elements
|
|
67
130
|
|
|
68
131
|
```javascript
|
|
69
132
|
import { Atomic } from '@universityofmaryland/web-elements-library';
|
|
70
133
|
|
|
71
|
-
//
|
|
72
|
-
const
|
|
134
|
+
// Text-based action
|
|
135
|
+
const textAction = Atomic.actions.text({
|
|
73
136
|
text: 'Learn More',
|
|
74
137
|
url: '/learn-more',
|
|
75
138
|
isStyled: true
|
|
76
139
|
});
|
|
77
140
|
|
|
78
|
-
//
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
141
|
+
// Icon action
|
|
142
|
+
const iconAction = Atomic.actions.icon({
|
|
143
|
+
icon: 'arrow-right',
|
|
144
|
+
url: '#',
|
|
145
|
+
ariaLabel: 'Next page'
|
|
82
146
|
});
|
|
83
147
|
```
|
|
84
148
|
|
|
85
|
-
|
|
86
|
-
- `actions` - Buttons and interactive elements
|
|
87
|
-
- `animations` - Animation elements
|
|
88
|
-
- `assets` - Images, icons, and media elements
|
|
89
|
-
- `buttons` - Button variations
|
|
90
|
-
- `events` - Event-related elements
|
|
91
|
-
- `layout` - Basic layout elements
|
|
92
|
-
- `textLockup` - Text grouping elements
|
|
93
|
-
|
|
94
|
-
### Composite Elements
|
|
95
|
-
|
|
96
|
-
Composite elements are combinations of atomic elements that form more complex UI patterns:
|
|
149
|
+
### Card Elements
|
|
97
150
|
|
|
98
151
|
```javascript
|
|
99
152
|
import { Composite } from '@universityofmaryland/web-elements-library';
|
|
100
153
|
|
|
101
|
-
|
|
154
|
+
// Block card
|
|
155
|
+
const blockCard = Composite.card.block({
|
|
102
156
|
headline: document.querySelector('h3'),
|
|
103
157
|
text: document.querySelector('p'),
|
|
104
158
|
image: document.querySelector('img'),
|
|
105
|
-
actions: document.querySelector('.actions')
|
|
159
|
+
actions: document.querySelector('.actions'),
|
|
160
|
+
isThemeDark: false
|
|
106
161
|
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Available composite elements:
|
|
110
|
-
- `accordion` - Expandable content sections
|
|
111
|
-
- `alert` - Alert/notification elements
|
|
112
|
-
- `banner` - Banner elements
|
|
113
|
-
- `card` - Card elements (block, list, overlay)
|
|
114
|
-
- `carousel` - Carousel/slider elements
|
|
115
|
-
- `hero` - Hero section elements (see detailed section below)
|
|
116
|
-
- `layout` - Layout compositions
|
|
117
|
-
- `media` - Media display elements
|
|
118
|
-
- `navigation` - Navigation elements
|
|
119
|
-
- `pathway` - Pathway/journey elements
|
|
120
|
-
- `person` - Person/profile elements
|
|
121
|
-
- `quote` - Quote display elements
|
|
122
|
-
- `slider` - Slider elements
|
|
123
|
-
- `social` - Social media elements
|
|
124
|
-
- `tabs` - Tabbed interface elements
|
|
125
|
-
|
|
126
|
-
#### Hero Elements
|
|
127
|
-
|
|
128
|
-
The hero category provides multiple variations for creating impactful page headers and feature sections:
|
|
129
|
-
|
|
130
|
-
##### Standard Hero
|
|
131
|
-
The default hero pattern with flexible content and media options:
|
|
132
162
|
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
headline:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
image: document.querySelector('img'),
|
|
140
|
-
video: document.querySelector('video'),
|
|
141
|
-
includesAnimation: true,
|
|
142
|
-
isHeightSmall: false,
|
|
143
|
-
isHeightFull: false,
|
|
144
|
-
isTextCenter: false,
|
|
145
|
-
isTextRight: false,
|
|
163
|
+
// Overlay card
|
|
164
|
+
const overlayCard = Composite.card.overlay({
|
|
165
|
+
headline: headlineElement,
|
|
166
|
+
text: textElement,
|
|
167
|
+
image: imageElement,
|
|
168
|
+
isTypeColor: true,
|
|
146
169
|
isThemeDark: true
|
|
147
170
|
});
|
|
148
171
|
```
|
|
149
172
|
|
|
150
|
-
|
|
151
|
-
A simplified hero with essential content only:
|
|
152
|
-
|
|
153
|
-
```javascript
|
|
154
|
-
const heroMinimal = Composite.hero.minimal({
|
|
155
|
-
headline: document.createElement('h1'),
|
|
156
|
-
text: document.createElement('p'),
|
|
157
|
-
eyebrow: document.createElement('span'),
|
|
158
|
-
isThemeDark: false
|
|
159
|
-
});
|
|
160
|
-
```
|
|
173
|
+
### Hero Elements
|
|
161
174
|
|
|
162
|
-
|
|
163
|
-
Hero with vertically stacked content and media:
|
|
175
|
+
The hero category offers multiple variations for impactful layouts:
|
|
164
176
|
|
|
177
|
+
#### Standard Hero
|
|
165
178
|
```javascript
|
|
166
|
-
const
|
|
179
|
+
const hero = Composite.hero.standard({
|
|
167
180
|
headline: document.createElement('h1'),
|
|
181
|
+
eyebrow: document.createElement('span'),
|
|
168
182
|
text: document.createElement('p'),
|
|
169
|
-
|
|
183
|
+
actions: document.createElement('div'),
|
|
184
|
+
image: imageElement,
|
|
170
185
|
includesAnimation: true,
|
|
171
|
-
isHeightSmall: false,
|
|
172
|
-
isHeightFull: true,
|
|
173
|
-
isWidthLarge: true, // Stacked-specific property
|
|
174
186
|
isThemeDark: true
|
|
175
187
|
});
|
|
176
188
|
```
|
|
177
189
|
|
|
178
|
-
|
|
179
|
-
Hero with overlay effects and advanced styling options:
|
|
180
|
-
|
|
190
|
+
#### Minimal Hero
|
|
181
191
|
```javascript
|
|
182
|
-
const
|
|
192
|
+
const minimalHero = Composite.hero.minimal({
|
|
183
193
|
headline: document.createElement('h1'),
|
|
184
194
|
text: document.createElement('p'),
|
|
185
|
-
|
|
186
|
-
hasBorder: true,
|
|
187
|
-
isTransparent: false,
|
|
188
|
-
isSticky: false,
|
|
189
|
-
isTextCenter: true,
|
|
190
|
-
isThemeDark: true
|
|
195
|
+
eyebrow: document.createElement('span')
|
|
191
196
|
});
|
|
192
197
|
```
|
|
193
198
|
|
|
194
|
-
|
|
195
|
-
Hero featuring institutional branding:
|
|
196
|
-
|
|
199
|
+
#### Overlay Hero
|
|
197
200
|
```javascript
|
|
198
|
-
const
|
|
199
|
-
headline:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
isThemeMaryland: false
|
|
201
|
+
const overlayHero = Composite.hero.overlay({
|
|
202
|
+
headline: headlineElement,
|
|
203
|
+
text: textElement,
|
|
204
|
+
image: imageElement,
|
|
205
|
+
hasBorder: true,
|
|
206
|
+
isTransparent: false,
|
|
207
|
+
isSticky: true,
|
|
208
|
+
isTextCenter: true
|
|
207
209
|
});
|
|
208
210
|
```
|
|
209
211
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
The library also provides specialized hero patterns for specific use cases:
|
|
213
|
-
|
|
214
|
-
###### Expand Hero
|
|
215
|
-
Hero with expandable content sections:
|
|
212
|
+
#### Custom Variations
|
|
216
213
|
|
|
214
|
+
**Grid Hero** - Content blocks in grid layout:
|
|
217
215
|
```javascript
|
|
218
|
-
const
|
|
219
|
-
headline:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
includesAnimation: true,
|
|
216
|
+
const gridHero = Composite.hero.custom.grid({
|
|
217
|
+
headline: headlineElement,
|
|
218
|
+
blocks: [block1, block2, block3, block4],
|
|
219
|
+
image: backgroundImage,
|
|
223
220
|
isThemeDark: true
|
|
224
221
|
});
|
|
225
222
|
```
|
|
226
223
|
|
|
227
|
-
|
|
228
|
-
Hero with content blocks arranged in a grid:
|
|
229
|
-
|
|
224
|
+
**Expand Hero** - With expandable content:
|
|
230
225
|
```javascript
|
|
231
|
-
const
|
|
232
|
-
headline:
|
|
233
|
-
text:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
document.createElement('div'), // Grid block 2
|
|
237
|
-
document.createElement('div'), // Grid block 3
|
|
238
|
-
document.createElement('div') // Grid block 4
|
|
239
|
-
],
|
|
240
|
-
image: document.querySelector('img'),
|
|
241
|
-
isThemeDark: true
|
|
226
|
+
const expandHero = Composite.hero.custom.expand({
|
|
227
|
+
headline: headlineElement,
|
|
228
|
+
text: textElement,
|
|
229
|
+
expandedContent: hiddenContent,
|
|
230
|
+
includesAnimation: true
|
|
242
231
|
});
|
|
243
232
|
```
|
|
244
233
|
|
|
245
|
-
###### Video Arrow Hero
|
|
246
|
-
Hero with prominent video playback controls:
|
|
247
|
-
|
|
248
|
-
```javascript
|
|
249
|
-
const heroVideoArrow = Composite.hero.custom.videoArrow({
|
|
250
|
-
headline: document.createElement('h1'),
|
|
251
|
-
text: document.createElement('p'),
|
|
252
|
-
video: document.querySelector('video'),
|
|
253
|
-
image: document.querySelector('img'), // Poster image
|
|
254
|
-
videoControls: true,
|
|
255
|
-
includesAnimation: true,
|
|
256
|
-
isThemeDark: true
|
|
257
|
-
});
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
##### Hero Properties Reference
|
|
261
|
-
|
|
262
|
-
Common properties across hero variants:
|
|
263
|
-
- `headline` - Main heading element
|
|
264
|
-
- `eyebrow` - Small text above headline
|
|
265
|
-
- `text` - Descriptive paragraph text
|
|
266
|
-
- `actions` - CTA buttons or links
|
|
267
|
-
- `image` - Hero image element
|
|
268
|
-
- `video` - Hero video element
|
|
269
|
-
- `includesAnimation` - Enable entrance animations
|
|
270
|
-
- `isThemeDark` - Dark theme styling
|
|
271
|
-
|
|
272
|
-
Size properties (Standard, Stacked, Overlay):
|
|
273
|
-
- `isHeightSmall` - Reduced height variant
|
|
274
|
-
- `isHeightFull` - Full viewport height
|
|
275
|
-
|
|
276
|
-
Layout properties (Standard, Overlay):
|
|
277
|
-
- `isTextCenter` - Center-aligned text
|
|
278
|
-
- `isTextRight` - Right-aligned text
|
|
279
|
-
|
|
280
|
-
Theme properties (Logo):
|
|
281
|
-
- `isThemeLight` - Light theme variant
|
|
282
|
-
- `isThemeMaryland` - Maryland brand theme
|
|
283
|
-
|
|
284
|
-
Unique properties:
|
|
285
|
-
- `isWidthLarge` (Stacked) - Extended width layout
|
|
286
|
-
- `hasBorder`, `isTransparent`, `isSticky` (Overlay) - Styling options
|
|
287
|
-
- `expandedContent` (Expand) - Hidden content section
|
|
288
|
-
- `blocks` (Grid) - Array of content blocks
|
|
289
|
-
- `videoControls` (Video Arrow) - Show video controls
|
|
290
|
-
|
|
291
234
|
### Layout Elements
|
|
292
235
|
|
|
293
|
-
Elements specifically designed for controlling page layout:
|
|
294
|
-
|
|
295
236
|
```javascript
|
|
296
|
-
import {
|
|
237
|
+
import { Composite } from '@universityofmaryland/web-elements-library';
|
|
297
238
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
239
|
+
// Sticky columns
|
|
240
|
+
const stickyLayout = Composite.layout.stickyColumns({
|
|
241
|
+
leftColumn: sidebarContent,
|
|
242
|
+
rightColumn: mainContent,
|
|
243
|
+
stickyOffset: 100
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Image expand layout
|
|
247
|
+
const imageExpand = Composite.layout.image.expand({
|
|
248
|
+
image: imageElement,
|
|
249
|
+
caption: 'Image caption',
|
|
250
|
+
isExpanded: false
|
|
301
251
|
});
|
|
302
252
|
```
|
|
303
253
|
|
|
304
|
-
|
|
254
|
+
## Advanced Usage
|
|
305
255
|
|
|
306
|
-
|
|
256
|
+
### Event Handling
|
|
307
257
|
|
|
308
258
|
```javascript
|
|
309
|
-
|
|
259
|
+
const element = Composite.card.block({
|
|
260
|
+
headline: headlineEl,
|
|
261
|
+
text: textEl
|
|
262
|
+
});
|
|
310
263
|
|
|
311
|
-
//
|
|
312
|
-
|
|
264
|
+
// Use lifecycle events
|
|
265
|
+
if (element.events) {
|
|
266
|
+
// Call after adding to DOM
|
|
267
|
+
element.events.load?.();
|
|
268
|
+
|
|
269
|
+
// Call on window resize
|
|
270
|
+
element.events.resize?.();
|
|
271
|
+
|
|
272
|
+
// Clean up before removing
|
|
273
|
+
element.events.destroy?.();
|
|
274
|
+
}
|
|
313
275
|
```
|
|
314
276
|
|
|
315
|
-
###
|
|
277
|
+
### Dynamic Updates
|
|
316
278
|
|
|
317
|
-
|
|
279
|
+
Many elements support property updates:
|
|
318
280
|
|
|
319
281
|
```javascript
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
282
|
+
const hero = Composite.hero.standard({
|
|
283
|
+
headline: headlineEl,
|
|
284
|
+
isThemeDark: false
|
|
285
|
+
});
|
|
324
286
|
|
|
325
|
-
//
|
|
326
|
-
|
|
287
|
+
// Update theme dynamically
|
|
288
|
+
hero.element.setAttribute('data-theme', 'dark');
|
|
289
|
+
if (hero.events?.resize) {
|
|
290
|
+
hero.events.resize();
|
|
291
|
+
}
|
|
327
292
|
```
|
|
328
293
|
|
|
329
|
-
|
|
294
|
+
### Custom Styling
|
|
330
295
|
|
|
331
|
-
|
|
296
|
+
While elements include default styles, you can extend them:
|
|
332
297
|
|
|
333
298
|
```javascript
|
|
334
|
-
{
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
299
|
+
const card = Composite.card.block({ /* props */ });
|
|
300
|
+
|
|
301
|
+
// Add custom styles
|
|
302
|
+
const customStyles = `
|
|
303
|
+
${card.styles}
|
|
304
|
+
.my-custom-class {
|
|
305
|
+
/* Custom styles */
|
|
306
|
+
}
|
|
307
|
+
`;
|
|
341
308
|
```
|
|
342
309
|
|
|
343
|
-
|
|
310
|
+
## TypeScript Support
|
|
344
311
|
|
|
345
|
-
|
|
346
|
-
const button = Atomic.buttons.primary({
|
|
347
|
-
text: 'Learn More',
|
|
348
|
-
url: '#'
|
|
349
|
-
});
|
|
312
|
+
Full TypeScript definitions for type safety:
|
|
350
313
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
314
|
+
```typescript
|
|
315
|
+
import type {
|
|
316
|
+
ElementModel,
|
|
317
|
+
HeroStandardProps,
|
|
318
|
+
CardBlockProps,
|
|
319
|
+
ThemeProps
|
|
320
|
+
} from '@universityofmaryland/web-elements-library';
|
|
321
|
+
|
|
322
|
+
const heroProps: HeroStandardProps = {
|
|
323
|
+
headline: document.createElement('h1'),
|
|
324
|
+
isThemeDark: true,
|
|
325
|
+
includesAnimation: false
|
|
326
|
+
};
|
|
356
327
|
```
|
|
357
328
|
|
|
358
329
|
## Browser Support
|
|
359
330
|
|
|
360
|
-
|
|
361
|
-
-
|
|
362
|
-
-
|
|
363
|
-
-
|
|
364
|
-
- Edge
|
|
331
|
+
- Chrome 90+
|
|
332
|
+
- Firefox 88+
|
|
333
|
+
- Safari 14+
|
|
334
|
+
- Edge 90+
|
|
365
335
|
|
|
366
336
|
## Performance Considerations
|
|
367
337
|
|
|
368
|
-
|
|
369
|
-
- Tree-
|
|
370
|
-
-
|
|
371
|
-
-
|
|
372
|
-
- Efficient event handling patterns
|
|
338
|
+
- **Lightweight** - Minimal JavaScript, no framework dependencies
|
|
339
|
+
- **Tree-shakeable** - Import only needed elements
|
|
340
|
+
- **Efficient** - Reusable element instances
|
|
341
|
+
- **Lazy-loadable** - Load elements on demand
|
|
373
342
|
|
|
374
343
|
## Accessibility
|
|
375
344
|
|
|
376
|
-
All elements
|
|
377
|
-
-
|
|
378
|
-
-
|
|
379
|
-
- ARIA attributes where appropriate
|
|
345
|
+
All elements follow WCAG 2.1 AA standards:
|
|
346
|
+
- Semantic HTML structure
|
|
347
|
+
- ARIA attributes where needed
|
|
380
348
|
- Keyboard navigation support
|
|
349
|
+
- Screen reader compatibility
|
|
381
350
|
- Focus management utilities
|
|
382
351
|
|
|
383
352
|
## Documentation
|
|
384
353
|
|
|
385
|
-
|
|
354
|
+
- **[Element Reference](https://umd-digital.github.io/design-system/docs/elements/)** - Complete API documentation
|
|
355
|
+
- **[TypeScript Definitions](https://umd-digital.github.io/design-system/docs/elements/interfaces/)** - Type interfaces
|
|
356
|
+
- **[Usage Examples](https://github.com/umd-digital/design-system/tree/main/packages/elements/source)** - Source code examples
|
|
357
|
+
- **[Design System](https://designsystem.umd.edu)** - Complete design system documentation
|
|
386
358
|
|
|
387
359
|
## Testing
|
|
388
360
|
|
|
389
|
-
The Elements library includes comprehensive test coverage for all components. Tests are written using Jest and follow a consistent pattern:
|
|
390
|
-
|
|
391
|
-
### Running Tests
|
|
392
|
-
|
|
393
361
|
```bash
|
|
394
|
-
# Run
|
|
362
|
+
# Run tests
|
|
395
363
|
npm test
|
|
396
364
|
|
|
397
|
-
#
|
|
365
|
+
# Watch mode
|
|
398
366
|
npm run test:watch
|
|
399
367
|
|
|
400
|
-
#
|
|
368
|
+
# Coverage report
|
|
401
369
|
npm run test:coverage
|
|
402
370
|
|
|
403
|
-
#
|
|
404
|
-
npm test --
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### Test Structure
|
|
408
|
-
|
|
409
|
-
Tests are organized by component category and located in `__tests__` directories:
|
|
410
|
-
|
|
411
|
-
```
|
|
412
|
-
source/
|
|
413
|
-
├── composite/
|
|
414
|
-
│ └── __tests__/
|
|
415
|
-
│ ├── hero/
|
|
416
|
-
│ │ ├── standard.test.ts
|
|
417
|
-
│ │ ├── minimal.test.ts
|
|
418
|
-
│ │ ├── stacked.test.ts
|
|
419
|
-
│ │ ├── overlay.test.ts
|
|
420
|
-
│ │ ├── logo.test.ts
|
|
421
|
-
│ │ └── custom/
|
|
422
|
-
│ │ ├── expand.test.ts
|
|
423
|
-
│ │ ├── grid.test.ts
|
|
424
|
-
│ │ └── video-arrow.test.ts
|
|
425
|
-
│ ├── card/
|
|
426
|
-
│ │ ├── block.test.ts
|
|
427
|
-
│ │ ├── list.test.ts
|
|
428
|
-
│ │ └── overlay.test.ts
|
|
429
|
-
│ └── types/
|
|
430
|
-
│ ├── hero-types.test.ts
|
|
431
|
-
│ └── card-types.test.ts
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
### Writing Tests
|
|
435
|
-
|
|
436
|
-
When adding new elements, include tests that cover:
|
|
437
|
-
|
|
438
|
-
1. **Basic Structure** - Element creation with minimal props
|
|
439
|
-
2. **Content Properties** - All content variations
|
|
440
|
-
3. **Asset Properties** - Image and video handling
|
|
441
|
-
4. **Animation Properties** - Animation flags and behaviors
|
|
442
|
-
5. **Theme Properties** - Theme variations
|
|
443
|
-
6. **Edge Cases** - Null/undefined handling
|
|
444
|
-
7. **Type Safety** - TypeScript interface compliance
|
|
445
|
-
|
|
446
|
-
Example test pattern:
|
|
447
|
-
|
|
448
|
-
```javascript
|
|
449
|
-
import { Composite } from '@universityofmaryland/web-elements-library';
|
|
450
|
-
import type { HeroStandardProps } from '../../hero/_types';
|
|
451
|
-
|
|
452
|
-
describe('Hero Standard Component', () => {
|
|
453
|
-
beforeEach(() => {
|
|
454
|
-
jest.clearAllMocks();
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
it('should create a standard hero with minimal props', () => {
|
|
458
|
-
const props: HeroStandardProps = {
|
|
459
|
-
isThemeDark: true
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
const result = Composite.hero.standard(props);
|
|
463
|
-
|
|
464
|
-
expect(result).toBeDefined();
|
|
465
|
-
expect(result.element).toBeInstanceOf(HTMLElement);
|
|
466
|
-
expect(typeof result.styles).toBe('string');
|
|
467
|
-
});
|
|
468
|
-
});
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
## TypeScript Support
|
|
472
|
-
|
|
473
|
-
The library is written in TypeScript and provides comprehensive type definitions for all elements:
|
|
474
|
-
|
|
475
|
-
### Import Types
|
|
476
|
-
|
|
477
|
-
```typescript
|
|
478
|
-
import type {
|
|
479
|
-
HeroStandardProps,
|
|
480
|
-
HeroMinimalProps,
|
|
481
|
-
HeroStackedProps,
|
|
482
|
-
HeroOverlayProps,
|
|
483
|
-
HeroLogoProps,
|
|
484
|
-
HeroGridProps,
|
|
485
|
-
HeroExpandProps,
|
|
486
|
-
HeroVideoArrowProps,
|
|
487
|
-
CardBlockProps,
|
|
488
|
-
CardListProps,
|
|
489
|
-
CardOverlayProps
|
|
490
|
-
} from '@universityofmaryland/web-elements-library';
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
### Type Safety
|
|
494
|
-
|
|
495
|
-
All element functions are strictly typed to ensure proper usage:
|
|
496
|
-
|
|
497
|
-
```typescript
|
|
498
|
-
// TypeScript will enforce required properties
|
|
499
|
-
const hero: HeroStandardProps = {
|
|
500
|
-
headline: document.createElement('h1'),
|
|
501
|
-
// isThemeDark is optional with boolean type
|
|
502
|
-
isThemeDark: true
|
|
503
|
-
};
|
|
504
|
-
|
|
505
|
-
// Type error if invalid property is provided
|
|
506
|
-
const invalidHero: HeroStandardProps = {
|
|
507
|
-
headline: document.createElement('h1'),
|
|
508
|
-
invalidProp: true // TypeScript error
|
|
509
|
-
};
|
|
371
|
+
# Test specific category
|
|
372
|
+
npm test -- composite/hero
|
|
510
373
|
```
|
|
511
374
|
|
|
512
375
|
## Contributing
|
|
513
376
|
|
|
514
|
-
|
|
377
|
+
See the [main repository](https://github.com/umd-digital/design-system) for contribution guidelines.
|
|
515
378
|
|
|
516
379
|
## License
|
|
517
380
|
|
|
518
|
-
|
|
381
|
+
University of Maryland
|