ux4g-components-web 1.1.0 → 1.1.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/README.md +1031 -25
- package/dist/runtime/bootstrap.cjs +1091 -2
- package/dist/runtime/bootstrap.mjs +1090 -1
- package/dist/runtime/index.cjs +1056 -241
- package/dist/runtime/index.d.ts +4 -27
- package/dist/runtime/index.mjs +1056 -241
- package/package.json +2 -2
- package/styles/ux4g.css +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# ux4g-components-web
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CSS bundle, design tokens, utilities, shared types, and runtime module for the **UX4G Design System**.
|
|
4
|
+
|
|
5
|
+
This is the foundation package — it provides the complete CSS system that powers all UX4G components. Framework wrappers (`ux4g-components-react`, `ux4g-components-angular`) depend on this package for styles and Class_Builder types.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -8,38 +10,962 @@ The CSS system, design tokens, utilities, and shared Class_Builder types for the
|
|
|
8
10
|
npm install ux4g-components-web
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### HTML / CSS
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
```html
|
|
18
|
+
<!DOCTYPE html>
|
|
19
|
+
<html>
|
|
20
|
+
<head>
|
|
21
|
+
<link rel="stylesheet" href="node_modules/ux4g-components-web/styles/ux4g.css" />
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<button class="ux4g-btn-primary ux4g-btn-md">Save</button>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
27
|
+
```
|
|
14
28
|
|
|
15
|
-
|
|
29
|
+
### JavaScript / TypeScript bundler
|
|
16
30
|
|
|
17
31
|
```ts
|
|
18
|
-
// JavaScript/TypeScript
|
|
19
32
|
import 'ux4g-components-web/styles.css';
|
|
20
33
|
```
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
<!-- HTML -->
|
|
24
|
-
<link rel="stylesheet" href="node_modules/ux4g-components-web/styles/ux4g.css" />
|
|
25
|
-
```
|
|
35
|
+
### CSS @import
|
|
26
36
|
|
|
27
37
|
```css
|
|
28
|
-
/* CSS */
|
|
29
38
|
@import 'ux4g-components-web/styles.css';
|
|
30
39
|
```
|
|
31
40
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Available Exports
|
|
44
|
+
|
|
45
|
+
| Export Path | Description |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `ux4g-components-web/styles.css` | Pre-built CSS bundle (~7 MB, fonts embedded as base64) |
|
|
48
|
+
| `ux4g-components-web/types` | Class_Builder functions and TypeScript types |
|
|
49
|
+
| `ux4g-components-web/runtime` | `initRuntime()` / `destroyRuntime()` — explicit control |
|
|
50
|
+
| `ux4g-components-web/runtime/bootstrap` | Side-effect import — auto-initializes runtime on import |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## CSS Bundle
|
|
55
|
+
|
|
56
|
+
The bundle includes all layers in the correct cascade order:
|
|
57
|
+
|
|
58
|
+
1. **Reset** — browser normalization
|
|
59
|
+
2. **Tokens** — CSS custom properties (primitive values)
|
|
60
|
+
3. **Semantic** — semantic aliases (`--ux4g-bg-primary-strong`, etc.)
|
|
61
|
+
4. **Foundations** — fonts and icons (base64-embedded)
|
|
62
|
+
5. **Utilities** — 27 single-purpose helper class modules
|
|
63
|
+
6. **Components** — approved component CSS
|
|
64
|
+
7. **Layout** — container, flex-grid, grid utilities
|
|
65
|
+
8. **Cascade Fixes** — vendor specificity overrides
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Component Examples (Plain HTML/CSS)
|
|
70
|
+
|
|
71
|
+
### Button
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<!-- Primary button -->
|
|
75
|
+
<button class="ux4g-btn-primary ux4g-btn-md">Save</button>
|
|
76
|
+
|
|
77
|
+
<!-- Outline danger, large -->
|
|
78
|
+
<button class="ux4g-btn-outline-danger ux4g-btn-lg">Delete</button>
|
|
79
|
+
|
|
80
|
+
<!-- Tonal primary, pill shape, small -->
|
|
81
|
+
<button class="ux4g-btn-tonal-primary ux4g-btn-sm ux4g-btn-pill">Tag</button>
|
|
82
|
+
|
|
83
|
+
<!-- Disabled state -->
|
|
84
|
+
<button class="ux4g-btn-primary ux4g-btn-md ux4g-btn-disabled" disabled>Disabled</button>
|
|
85
|
+
|
|
86
|
+
<!-- Loading state -->
|
|
87
|
+
<button class="ux4g-btn-primary ux4g-btn-md ux4g-btn-loading">
|
|
88
|
+
<span class="ux4g-btn-spinner" aria-hidden="true"></span>
|
|
89
|
+
Saving...
|
|
90
|
+
</button>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Available classes:**
|
|
94
|
+
- Variants: `ux4g-btn-primary`, `ux4g-btn-outline-primary`, `ux4g-btn-text-primary`, `ux4g-btn-tonal-primary`, `ux4g-btn-danger`, `ux4g-btn-outline-danger`, `ux4g-btn-text-danger`, `ux4g-btn-tonal-danger`
|
|
95
|
+
- Sizes: `ux4g-btn-xl`, `ux4g-btn-lg`, `ux4g-btn-md`, `ux4g-btn-sm`, `ux4g-btn-xs`
|
|
96
|
+
- Modifiers: `ux4g-btn-pill`, `ux4g-btn-disabled`, `ux4g-btn-loading`
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
### Spinner
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<!-- Primary full spinner, medium (default) -->
|
|
103
|
+
<span class="ux4g-spinner-primary-full" role="status" aria-label="Loading"></span>
|
|
104
|
+
|
|
105
|
+
<!-- Danger split spinner, large -->
|
|
106
|
+
<span class="ux4g-spinner-danger-split ux4g-spinner-lg" role="status" aria-label="Loading"></span>
|
|
107
|
+
|
|
108
|
+
<!-- Inverse partial spinner, extra small -->
|
|
109
|
+
<span class="ux4g-spinner-inverse-partial ux4g-spinner-xs" role="status" aria-label="Loading"></span>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Pattern:** `ux4g-spinner-{variant}-{type}` + optional `ux4g-spinner-{size}`
|
|
113
|
+
- Variants: `primary`, `inverse`, `danger`
|
|
114
|
+
- Types: `full`, `split`, `partial`
|
|
115
|
+
- Sizes: `ux4g-spinner-xl`, `ux4g-spinner-lg`, `ux4g-spinner-sm`, `ux4g-spinner-xs` (md is default, no class needed)
|
|
116
|
+
|
|
117
|
+
### Link
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<!-- Default link, medium -->
|
|
121
|
+
<a href="#" class="ux4g-text-link-md">Learn more</a>
|
|
122
|
+
|
|
123
|
+
<!-- Neutral link, small -->
|
|
124
|
+
<a href="#" class="ux4g-text-link-neutral-sm">View details</a>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Pattern:** `ux4g-text-link-{size}` or `ux4g-text-link-neutral-{size}`
|
|
128
|
+
- Variants: `default`, `neutral`
|
|
129
|
+
- Sizes: `sm`, `md`
|
|
130
|
+
|
|
131
|
+
### Badge
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<!-- Dot badge, primary -->
|
|
135
|
+
<span class="ux4g-badge-dot-primary"></span>
|
|
136
|
+
|
|
137
|
+
<!-- Digit badge, danger, medium -->
|
|
138
|
+
<span class="ux4g-badge-digit-danger ux4g-badge-m">5</span>
|
|
139
|
+
|
|
140
|
+
<!-- Icon badge, success, large -->
|
|
141
|
+
<span class="ux4g-badge-icon-success ux4g-badge-l">
|
|
142
|
+
<i class="ux4g-icon-check"></i>
|
|
143
|
+
</span>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Pattern:** `ux4g-badge-{type}-{color}` + optional `ux4g-badge-{size}`
|
|
147
|
+
- Types: `dot`, `icon`, `digit`
|
|
148
|
+
- Colors: `primary`, `success`, `warning`, `danger`, `info`, `secondary`, `tertiary`, `neutral`
|
|
149
|
+
- Sizes: `s`, `m`, `l`, `profile-l`, `profile-xl`, `profile-2xl`, `profile-3xl`
|
|
150
|
+
|
|
151
|
+
### Avatar
|
|
152
|
+
|
|
153
|
+
```html
|
|
154
|
+
<!-- Status avatar, medium -->
|
|
155
|
+
<div class="ux4g-avatar ux4g-avatar-status ux4g-avatar-m">
|
|
156
|
+
<img src="user.jpg" alt="User" />
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<!-- Profile avatar, large -->
|
|
160
|
+
<div class="ux4g-avatar ux4g-avatar-profile ux4g-avatar-l">
|
|
161
|
+
<img src="profile.jpg" alt="Profile" />
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
<!-- Avatar group -->
|
|
165
|
+
<div class="ux4g-avatar-group">
|
|
166
|
+
<div class="ux4g-avatar ux4g-avatar-status ux4g-avatar-s"><img src="u1.jpg" alt="" /></div>
|
|
167
|
+
<div class="ux4g-avatar ux4g-avatar-status ux4g-avatar-s"><img src="u2.jpg" alt="" /></div>
|
|
168
|
+
</div>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Pattern:** `ux4g-avatar ux4g-avatar-{type}` + optional `ux4g-avatar-{size}`
|
|
172
|
+
- Types: `status`, `profile`, `group`
|
|
173
|
+
- Sizes: `xs`, `s`, `m`, `l`, `xl`, `2xl`, `3xl`
|
|
174
|
+
|
|
175
|
+
### Image
|
|
176
|
+
|
|
177
|
+
```html
|
|
178
|
+
<!-- Basic image with ratio -->
|
|
179
|
+
<div class="ux4g-ratio-16-9">
|
|
180
|
+
<img src="photo.jpg" alt="Photo" />
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<!-- Rounded image with overlay -->
|
|
184
|
+
<div class="ux4g-img-overlay ux4g-img-rounded ux4g-ratio-4-3">
|
|
185
|
+
<img src="photo.jpg" alt="Photo" />
|
|
186
|
+
<div class="ux4g-img-overlay-content">Caption</div>
|
|
187
|
+
</div>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Classes:** `ux4g-img-overlay`, `ux4g-img-rounded`, `ux4g-ratio-{ratio}`
|
|
191
|
+
- Ratios: `1-1`, `4-3`, `3-2`, `16-10`, `16-9`, `2-1`, `5-2`, `3-1`, `1-16`, `2-3`, `3-4`
|
|
192
|
+
|
|
193
|
+
### Chip
|
|
194
|
+
|
|
195
|
+
```html
|
|
196
|
+
<!-- Filter chip, medium -->
|
|
197
|
+
<button class="ux4g-filter-chip-md">Category</button>
|
|
198
|
+
|
|
199
|
+
<!-- Choice chip, small, active -->
|
|
200
|
+
<button class="ux4g-choice-chip-sm active">Selected</button>
|
|
201
|
+
|
|
202
|
+
<!-- Input chip, extra small -->
|
|
203
|
+
<span class="ux4g-input-chip-xs">Tag <button class="ux4g-chip-close">×</button></span>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Pattern:** `ux4g-{type}-chip-{size}` + optional `active`
|
|
207
|
+
- Types: `filter`, `choice`, `input`
|
|
208
|
+
- Sizes: `md`, `sm`, `xs` (xs only valid for input chips)
|
|
209
|
+
|
|
210
|
+
### Tag
|
|
211
|
+
|
|
212
|
+
```html
|
|
213
|
+
<!-- Tonal neutral tag -->
|
|
214
|
+
<span class="ux4g-tag-tonal-neutral">Default</span>
|
|
215
|
+
|
|
216
|
+
<!-- Filled success tag, small -->
|
|
217
|
+
<span class="ux4g-tag-filled-success ux4g-tag-s">Active</span>
|
|
218
|
+
|
|
219
|
+
<!-- Outline error tag -->
|
|
220
|
+
<span class="ux4g-tag-outline-error">Error</span>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Pattern:** `ux4g-tag-{variant}-{color}` + optional `ux4g-tag-s`
|
|
224
|
+
- Variants: `tonal`, `filled`, `outline`, `text`
|
|
225
|
+
- Colors: `neutral`, `brand`, `success`, `warning`, `error`, `info`
|
|
226
|
+
|
|
227
|
+
### Divider
|
|
228
|
+
|
|
229
|
+
```html
|
|
230
|
+
<!-- Horizontal divider -->
|
|
231
|
+
<hr class="ux4g-divider-horizontal" />
|
|
232
|
+
|
|
233
|
+
<!-- Vertical divider -->
|
|
234
|
+
<div class="ux4g-divider-vertical"></div>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Breadcrumb
|
|
238
|
+
|
|
239
|
+
```html
|
|
240
|
+
<!-- Breadcrumb with divider separator -->
|
|
241
|
+
<nav class="ux4g-breadcrumb ux4g-breadcrumb-divider">
|
|
242
|
+
<a href="#">Home</a>
|
|
243
|
+
<a href="#">Products</a>
|
|
244
|
+
<span>Current Page</span>
|
|
245
|
+
</nav>
|
|
246
|
+
|
|
247
|
+
<!-- Breadcrumb with icon separator -->
|
|
248
|
+
<nav class="ux4g-breadcrumb ux4g-breadcrumb-icon">
|
|
249
|
+
<a href="#">Home</a>
|
|
250
|
+
<a href="#">Category</a>
|
|
251
|
+
<span>Item</span>
|
|
252
|
+
</nav>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Checkbox
|
|
256
|
+
|
|
257
|
+
```html
|
|
258
|
+
<!-- Medium checkbox -->
|
|
259
|
+
<label class="ux4g-checkbox ux4g-checkbox-md">
|
|
260
|
+
<input type="checkbox" />
|
|
261
|
+
<span>Accept terms</span>
|
|
262
|
+
</label>
|
|
263
|
+
|
|
264
|
+
<!-- Small checkbox with error -->
|
|
265
|
+
<label class="ux4g-checkbox ux4g-checkbox-sm ux4g-checkbox-error">
|
|
266
|
+
<input type="checkbox" />
|
|
267
|
+
<span>Required field</span>
|
|
268
|
+
</label>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Sizes:** `ux4g-checkbox-sm`, `ux4g-checkbox-md`, `ux4g-checkbox-lg`
|
|
272
|
+
|
|
273
|
+
### Radio
|
|
274
|
+
|
|
275
|
+
```html
|
|
276
|
+
<!-- Medium radio -->
|
|
277
|
+
<label class="ux4g-radio ux4g-radio-md">
|
|
278
|
+
<input type="radio" name="option" />
|
|
279
|
+
<span>Option A</span>
|
|
280
|
+
</label>
|
|
281
|
+
|
|
282
|
+
<!-- Large radio with error -->
|
|
283
|
+
<label class="ux4g-radio ux4g-radio-lg ux4g-radio-error">
|
|
284
|
+
<input type="radio" name="option" />
|
|
285
|
+
<span>Option B</span>
|
|
286
|
+
</label>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Sizes:** `ux4g-radio-sm`, `ux4g-radio-md`, `ux4g-radio-lg`
|
|
290
|
+
|
|
291
|
+
### Switch
|
|
292
|
+
|
|
293
|
+
```html
|
|
294
|
+
<!-- Medium switch -->
|
|
295
|
+
<label class="ux4g-switch ux4g-switch-md">
|
|
296
|
+
<input type="checkbox" role="switch" />
|
|
297
|
+
<span>Enable notifications</span>
|
|
298
|
+
</label>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Sizes:** `ux4g-switch-sm`, `ux4g-switch-md`, `ux4g-switch-lg`
|
|
302
|
+
|
|
303
|
+
### Card
|
|
304
|
+
|
|
305
|
+
```html
|
|
306
|
+
<!-- Solid vertical card -->
|
|
307
|
+
<div class="ux4g-card ux4g-card-solid ux4g-card-vertical">
|
|
308
|
+
<div class="ux4g-card-header">Title</div>
|
|
309
|
+
<div class="ux4g-card-body">Content goes here.</div>
|
|
310
|
+
<div class="ux4g-card-footer">Footer</div>
|
|
311
|
+
</div>
|
|
312
|
+
|
|
313
|
+
<!-- Outline horizontal card -->
|
|
314
|
+
<div class="ux4g-card ux4g-card-outline ux4g-card-horizontal">
|
|
315
|
+
<img src="thumb.jpg" alt="" />
|
|
316
|
+
<div class="ux4g-card-body">Horizontal layout</div>
|
|
317
|
+
</div>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Variants:** `ux4g-card-solid`, `ux4g-card-outline`, `ux4g-card-no-fill`
|
|
321
|
+
**Layouts:** `ux4g-card-vertical`, `ux4g-card-horizontal`
|
|
322
|
+
|
|
323
|
+
### Input
|
|
324
|
+
|
|
325
|
+
```html
|
|
326
|
+
<!-- Medium input, default state -->
|
|
327
|
+
<div class="ux4g-input-container ux4g-input-md ux4g-input-default">
|
|
328
|
+
<label>Email</label>
|
|
329
|
+
<input type="email" placeholder="Enter email" />
|
|
330
|
+
</div>
|
|
331
|
+
|
|
332
|
+
<!-- Large input, error state -->
|
|
333
|
+
<div class="ux4g-input-container ux4g-input-lg ux4g-input-error">
|
|
334
|
+
<label>Password</label>
|
|
335
|
+
<input type="password" />
|
|
336
|
+
<span class="ux4g-input-helper">Password is required</span>
|
|
337
|
+
</div>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Sizes:** `ux4g-input-sm`, `ux4g-input-md`, `ux4g-input-lg`, `ux4g-input-xl`
|
|
341
|
+
**States:** `ux4g-input-default`, `ux4g-input-error`, `ux4g-input-success`, `ux4g-input-warning`
|
|
342
|
+
|
|
343
|
+
### List
|
|
344
|
+
|
|
345
|
+
```html
|
|
346
|
+
<ul class="ux4g-list ux4g-list-default ux4g-list-m">
|
|
347
|
+
<li>Item one</li>
|
|
348
|
+
<li>Item two</li>
|
|
349
|
+
<li>Item three</li>
|
|
350
|
+
</ul>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Variants:** `ux4g-list-default`, `ux4g-list-error`, `ux4g-list-success`, `ux4g-list-warning`
|
|
354
|
+
**Sizes:** `ux4g-list-s`, `ux4g-list-m`, `ux4g-list-l`, `ux4g-list-xl`
|
|
355
|
+
|
|
356
|
+
### Dropdown
|
|
357
|
+
|
|
358
|
+
```html
|
|
359
|
+
<div class="ux4g-dropdown ux4g-dropdown-selection ux4g-dropdown-single ux4g-dropdown-md ux4g-dropdown-default">
|
|
360
|
+
<button data-ux-toggle="dropdown" aria-expanded="false">Select option</button>
|
|
361
|
+
<ul class="dropdown-menu">
|
|
362
|
+
<li>Option 1</li>
|
|
363
|
+
<li>Option 2</li>
|
|
364
|
+
<li>Option 3</li>
|
|
365
|
+
</ul>
|
|
366
|
+
</div>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Types:** `ux4g-dropdown-selection`, `ux4g-dropdown-button`, `ux4g-dropdown-overflow`
|
|
370
|
+
**Modes:** `ux4g-dropdown-single`, `ux4g-dropdown-multi`
|
|
371
|
+
**Sizes:** `ux4g-dropdown-sm`, `ux4g-dropdown-md`, `ux4g-dropdown-lg`
|
|
372
|
+
**States:** `ux4g-dropdown-default`, `ux4g-dropdown-error`, `ux4g-dropdown-success`, `ux4g-dropdown-warning`
|
|
373
|
+
**Open state:** `is-open`
|
|
374
|
+
|
|
375
|
+
### Combobox
|
|
376
|
+
|
|
377
|
+
```html
|
|
378
|
+
<div class="ux4g-combobox ux4g-combobox-single ux4g-combobox-md ux4g-combobox-default">
|
|
379
|
+
<input type="text" role="combobox" aria-expanded="false" placeholder="Search..." />
|
|
380
|
+
<ul class="dropdown-menu" role="listbox">
|
|
381
|
+
<li role="option">Result 1</li>
|
|
382
|
+
<li role="option">Result 2</li>
|
|
383
|
+
</ul>
|
|
384
|
+
</div>
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**Types:** `ux4g-combobox-single`, `ux4g-combobox-multi`
|
|
388
|
+
**Sizes:** `ux4g-combobox-sm`, `ux4g-combobox-md`, `ux4g-combobox-lg`
|
|
389
|
+
**States:** `ux4g-combobox-default`, `ux4g-combobox-error`, `ux4g-combobox-success`, `ux4g-combobox-warning`
|
|
390
|
+
|
|
391
|
+
### Modal
|
|
392
|
+
|
|
393
|
+
```html
|
|
394
|
+
<!-- Trigger -->
|
|
395
|
+
<button data-ux-toggle="modal" data-ux-target="#myModal">Open Modal</button>
|
|
396
|
+
|
|
397
|
+
<!-- Modal -->
|
|
398
|
+
<div id="myModal" class="ux4g-modal-backdrop ux4g-modal-backdrop-50" role="dialog" aria-modal="true">
|
|
399
|
+
<div class="ux4g-modal-box ux4g-modal-m">
|
|
400
|
+
<div class="ux4g-modal-header">
|
|
401
|
+
<h2>Title</h2>
|
|
402
|
+
<button data-ux-dismiss="modal">×</button>
|
|
403
|
+
</div>
|
|
404
|
+
<div class="ux4g-modal-body">Content here</div>
|
|
405
|
+
<div class="ux4g-modal-footer">
|
|
406
|
+
<button class="ux4g-btn-primary ux4g-btn-md">Confirm</button>
|
|
407
|
+
</div>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**Backdrop:** `ux4g-modal-backdrop-25`, `ux4g-modal-backdrop-50`, `ux4g-modal-backdrop-75`
|
|
413
|
+
**Blur:** `ux4g-modal-backdrop-blur`
|
|
414
|
+
**Sizes:** `ux4g-modal-s`, `ux4g-modal-m`, `ux4g-modal-l`
|
|
415
|
+
**Center content:** `ux4g-modal-center-content`
|
|
416
|
+
|
|
417
|
+
### Alert / Toast
|
|
418
|
+
|
|
419
|
+
```html
|
|
420
|
+
<!-- Inline alert -->
|
|
421
|
+
<div class="ux4g-alert ux4g-alert-info">
|
|
422
|
+
<span>This is an informational message.</span>
|
|
423
|
+
</div>
|
|
424
|
+
|
|
425
|
+
<!-- Context alert -->
|
|
426
|
+
<div class="ux4g-context-alert ux4g-alert-warning">
|
|
427
|
+
<span>Warning: Check your input.</span>
|
|
428
|
+
</div>
|
|
429
|
+
|
|
430
|
+
<!-- Alert container (for toast positioning) -->
|
|
431
|
+
<div class="ux4g-alert-container ux4g-alert-top-right">
|
|
432
|
+
<div class="ux4g-alert ux4g-alert-success">Saved successfully!</div>
|
|
433
|
+
</div>
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Variants:** `ux4g-alert-info`, `ux4g-alert-success`, `ux4g-alert-warning`, `ux4g-alert-error`
|
|
437
|
+
**Layouts:** `ux4g-alert-center`, `ux4g-alert-wide`
|
|
438
|
+
**Positions:** `ux4g-alert-top-left`, `ux4g-alert-top-right`, `ux4g-alert-bottom-left`, `ux4g-alert-bottom-right`
|
|
439
|
+
|
|
440
|
+
### Search
|
|
441
|
+
|
|
442
|
+
```html
|
|
443
|
+
<div class="ux4g-search-container ux4g-search-m">
|
|
444
|
+
<input type="search" placeholder="Search..." />
|
|
445
|
+
<button class="ux4g-search-btn" aria-label="Search">
|
|
446
|
+
<i class="ux4g-icon-search"></i>
|
|
447
|
+
</button>
|
|
448
|
+
</div>
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**Sizes:** `ux4g-search-s`, `ux4g-search-m`, `ux4g-search-lg`
|
|
452
|
+
|
|
453
|
+
### Pagination
|
|
454
|
+
|
|
455
|
+
```html
|
|
456
|
+
<!-- Default pagination -->
|
|
457
|
+
<nav class="ux4g-pagination">
|
|
458
|
+
<button class="ux4g-pagination-prev">«</button>
|
|
459
|
+
<button class="active">1</button>
|
|
460
|
+
<button>2</button>
|
|
461
|
+
<button>3</button>
|
|
462
|
+
<button class="ux4g-pagination-next">»</button>
|
|
463
|
+
</nav>
|
|
464
|
+
|
|
465
|
+
<!-- Dotted pagination, solid style -->
|
|
466
|
+
<nav class="ux4g-pagination ux4g-pagination-dotted ux4g-pagination-solid">
|
|
467
|
+
<span class="active"></span>
|
|
468
|
+
<span></span>
|
|
469
|
+
<span></span>
|
|
470
|
+
</nav>
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Variants:** default, `ux4g-pagination-dotted`
|
|
474
|
+
**Styles (dotted only):** `ux4g-pagination-solid`, `ux4g-pagination-translucent`
|
|
475
|
+
|
|
476
|
+
### Table
|
|
477
|
+
|
|
478
|
+
```html
|
|
479
|
+
<table class="ux4g-table ux4g-table-m">
|
|
480
|
+
<thead>
|
|
481
|
+
<tr><th>Name</th><th>Email</th><th>Role</th></tr>
|
|
482
|
+
</thead>
|
|
483
|
+
<tbody>
|
|
484
|
+
<tr><td>Alice</td><td>alice@example.com</td><td>Admin</td></tr>
|
|
485
|
+
<tr><td>Bob</td><td>bob@example.com</td><td>User</td></tr>
|
|
486
|
+
</tbody>
|
|
487
|
+
</table>
|
|
488
|
+
|
|
489
|
+
<!-- Interactive table with zebra rows and column dividers -->
|
|
490
|
+
<table class="ux4g-table ux4g-table-s ux4g-table-column-dividers ux4g-table-zebra-rows ux4g-table-interactive">
|
|
491
|
+
...
|
|
492
|
+
</table>
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Sizes:** `ux4g-table-s`, `ux4g-table-m`, `ux4g-table-lg`
|
|
496
|
+
**Dividers:** `ux4g-table-column-dividers`, `ux4g-table-no-row-dividers`
|
|
497
|
+
**Zebra:** `ux4g-table-zebra-rows`, `ux4g-table-zebra-cols`
|
|
498
|
+
**Modifiers:** `ux4g-table-interactive`, `ux4g-table-sortable`, `ux4g-table-resizable`, `ux4g-table-header-brand`
|
|
499
|
+
|
|
500
|
+
### Popover
|
|
501
|
+
|
|
502
|
+
```html
|
|
503
|
+
<button data-ux-toggle="popover" data-ux-content="Popover body text" data-ux-title="Popover Title" data-ux-placement="right">
|
|
504
|
+
Show Popover
|
|
505
|
+
</button>
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
**Placements:** `top`, `top-start`, `top-end`, `bottom`, `bottom-start`, `bottom-end`, `left`, `left-start`, `left-end`, `right`, `right-start`, `right-end`
|
|
509
|
+
|
|
510
|
+
### Tooltip
|
|
511
|
+
|
|
512
|
+
```html
|
|
513
|
+
<button data-ux-toggle="tooltip" data-ux-content="Tooltip text" data-ux-placement="top" title="Tooltip text">
|
|
514
|
+
Hover me
|
|
515
|
+
</button>
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
**Placements:** `top-left`, `top-center`, `top-right`, `bottom-left`, `bottom-center`, `bottom-right`, `left-center`, `right-center`
|
|
519
|
+
**Sizes:** `ux4g-tooltip-s`, `ux4g-tooltip-xs`
|
|
520
|
+
|
|
521
|
+
### Tab
|
|
522
|
+
|
|
523
|
+
```html
|
|
524
|
+
<div class="ux4g-tab ux4g-tab-underline ux4g-tab-md">
|
|
525
|
+
<nav class="nav" role="tablist">
|
|
526
|
+
<button role="tab" data-ux-toggle="tab" data-ux-target="#tab1" class="active" aria-selected="true">Tab 1</button>
|
|
527
|
+
<button role="tab" data-ux-toggle="tab" data-ux-target="#tab2">Tab 2</button>
|
|
528
|
+
</nav>
|
|
529
|
+
<div class="tab-content">
|
|
530
|
+
<div id="tab1" class="tab-pane active show">Content 1</div>
|
|
531
|
+
<div id="tab2" class="tab-pane">Content 2</div>
|
|
532
|
+
</div>
|
|
533
|
+
</div>
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**Variants:** `ux4g-tab-underline`, `ux4g-tab-pill`
|
|
537
|
+
**Sizes:** `ux4g-tab-sm`, `ux4g-tab-md`, `ux4g-tab-lg`
|
|
538
|
+
**Vertical:** `ux4g-tab-vertical`
|
|
539
|
+
|
|
540
|
+
### Icon Button
|
|
541
|
+
|
|
542
|
+
```html
|
|
543
|
+
<button class="ux4g-icon-btn ux4g-icon-btn-primary ux4g-icon-btn-md">
|
|
544
|
+
<i class="ux4g-icon-edit"></i>
|
|
545
|
+
</button>
|
|
546
|
+
|
|
547
|
+
<!-- Pill icon button -->
|
|
548
|
+
<button class="ux4g-icon-btn ux4g-icon-btn-tonal-primary ux4g-icon-btn-lg ux4g-icon-btn-pill">
|
|
549
|
+
<i class="ux4g-icon-plus"></i>
|
|
550
|
+
</button>
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**Variants:** `ux4g-icon-btn-primary`, `ux4g-icon-btn-outline-primary`, `ux4g-icon-btn-tonal-primary`, `ux4g-icon-btn-text-primary`
|
|
554
|
+
**Sizes:** `ux4g-icon-btn-xl`, `ux4g-icon-btn-lg`, `ux4g-icon-btn-md`, `ux4g-icon-btn-sm`, `ux4g-icon-btn-xs`
|
|
555
|
+
**Pill:** `ux4g-icon-btn-pill`
|
|
556
|
+
|
|
557
|
+
### Accessibility Bar
|
|
558
|
+
|
|
559
|
+
```html
|
|
560
|
+
<div class="ux4g-topbar">
|
|
561
|
+
<a href="#main-content" class="ux4g-skip-link">Skip to main content</a>
|
|
562
|
+
<!-- Additional accessibility controls -->
|
|
563
|
+
</div>
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Accordion
|
|
567
|
+
|
|
568
|
+
```html
|
|
569
|
+
<div class="ux4g-accordion ux4g-accordion-arrow-right">
|
|
570
|
+
<div class="ux4g-accordion-item">
|
|
571
|
+
<button data-ux-toggle="collapse" data-ux-target="#acc1" aria-expanded="false">
|
|
572
|
+
Section 1
|
|
573
|
+
</button>
|
|
574
|
+
<div id="acc1" class="collapse">
|
|
575
|
+
<div class="ux4g-accordion-body">Content for section 1</div>
|
|
576
|
+
</div>
|
|
577
|
+
</div>
|
|
578
|
+
</div>
|
|
579
|
+
|
|
580
|
+
<!-- Bordered variant with left arrow -->
|
|
581
|
+
<div class="ux4g-accordion ux4g-accordion-arrow-left ux4g-accordion-bordered">
|
|
582
|
+
...
|
|
583
|
+
</div>
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
**Arrow position:** `ux4g-accordion-arrow-right`, `ux4g-accordion-arrow-left`
|
|
587
|
+
**Variant:** `ux4g-accordion-bordered`
|
|
588
|
+
|
|
589
|
+
### Stepper
|
|
590
|
+
|
|
591
|
+
```html
|
|
592
|
+
<!-- Horizontal stepper -->
|
|
593
|
+
<div class="ux4g-stepper">
|
|
594
|
+
<div class="ux4g-stepper-step completed">Step 1</div>
|
|
595
|
+
<div class="ux4g-stepper-step active">Step 2</div>
|
|
596
|
+
<div class="ux4g-stepper-step">Step 3</div>
|
|
597
|
+
</div>
|
|
598
|
+
|
|
599
|
+
<!-- Vertical stepper, small -->
|
|
600
|
+
<div class="ux4g-stepper ux4g-stepper-vertical ux4g-stepper-s">
|
|
601
|
+
...
|
|
602
|
+
</div>
|
|
603
|
+
|
|
604
|
+
<!-- Horizontal centered with bottom-line variant -->
|
|
605
|
+
<div class="ux4g-stepper ux4g-stepper-horizontal ux4g-stepper-center ux4g-stepper-bottom-line">
|
|
606
|
+
...
|
|
607
|
+
</div>
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**Orientation:** `ux4g-stepper-vertical`, `ux4g-stepper-horizontal`
|
|
611
|
+
**Alignment:** `ux4g-stepper-center`, `ux4g-stepper-left`
|
|
612
|
+
**Variants:** `ux4g-stepper-bottom-line`, `ux4g-stepper-bottom-line-fill`, `ux4g-stepper-mobile`, `ux4g-stepper-progress`
|
|
613
|
+
**Size:** `ux4g-stepper-s`
|
|
614
|
+
|
|
615
|
+
### Slider
|
|
616
|
+
|
|
617
|
+
```html
|
|
618
|
+
<div class="ux4g-slider-field">
|
|
619
|
+
<input type="range" min="0" max="100" value="50" />
|
|
620
|
+
</div>
|
|
621
|
+
|
|
622
|
+
<!-- Medium slider -->
|
|
623
|
+
<div class="ux4g-slider-field ux4g-slider-md">
|
|
624
|
+
<input type="range" min="0" max="100" value="75" />
|
|
625
|
+
</div>
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
**Sizes:** default (sm), `ux4g-slider-md`
|
|
629
|
+
|
|
630
|
+
### Drawer
|
|
631
|
+
|
|
632
|
+
```html
|
|
633
|
+
<!-- Trigger -->
|
|
634
|
+
<button data-ux-toggle="offcanvas" data-ux-target="#drawer1">Open Drawer</button>
|
|
635
|
+
|
|
636
|
+
<!-- Drawer -->
|
|
637
|
+
<div id="drawer1" class="ux4g-drawer ux4g-drawer-right">
|
|
638
|
+
<div class="ux4g-drawer-header">
|
|
639
|
+
<h3>Drawer Title</h3>
|
|
640
|
+
<button data-ux-dismiss="offcanvas">×</button>
|
|
641
|
+
</div>
|
|
642
|
+
<div class="ux4g-drawer-body">Drawer content</div>
|
|
643
|
+
</div>
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
**Placements:** `ux4g-drawer-right`, `ux4g-drawer-left`, `ux4g-drawer-top`, `ux4g-drawer-bottom`
|
|
647
|
+
**Open state:** `ux4g-drawer-open`
|
|
648
|
+
|
|
649
|
+
### Date-Time Picker
|
|
650
|
+
|
|
651
|
+
```html
|
|
652
|
+
<!-- Date picker -->
|
|
653
|
+
<div class="ux4g-date-picker-container">
|
|
654
|
+
<input type="date" />
|
|
655
|
+
</div>
|
|
656
|
+
|
|
657
|
+
<!-- Time picker -->
|
|
658
|
+
<div class="ux4g-time-picker-container">
|
|
659
|
+
<input type="time" />
|
|
660
|
+
</div>
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
### Status Pipeline
|
|
664
|
+
|
|
665
|
+
```html
|
|
666
|
+
<div class="ux4g-status-pipeline-stepper">
|
|
667
|
+
<div class="ux4g-status-pipeline-step completed">Submitted</div>
|
|
668
|
+
<div class="ux4g-status-pipeline-step active">In Review</div>
|
|
669
|
+
<div class="ux4g-status-pipeline-step">Approved</div>
|
|
670
|
+
</div>
|
|
671
|
+
|
|
672
|
+
<!-- Vertical status pipeline -->
|
|
673
|
+
<div class="ux4g-status-pipeline-stepper ux4g-status-pipeline-vertical">
|
|
674
|
+
...
|
|
675
|
+
</div>
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
**Orientation:** `ux4g-status-pipeline-vertical`, `ux4g-status-pipeline-horizontal`
|
|
679
|
+
**Alignment:** `ux4g-status-pipeline-center`, `ux4g-status-pipeline-left`
|
|
680
|
+
**Variants:** `ux4g-status-pipeline-bottom-line`, `ux4g-status-pipeline-bottom-line-fill`, `ux4g-status-pipeline-mobile`, `ux4g-status-pipeline-progress`
|
|
681
|
+
**Size:** `ux4g-status-pipeline-s`
|
|
682
|
+
|
|
683
|
+
### Journey Timeline
|
|
684
|
+
|
|
685
|
+
```html
|
|
686
|
+
<!-- Vertical timeline (default) -->
|
|
687
|
+
<div class="ux4g-journey-timeline ux4g-journey-timeline--vertical">
|
|
688
|
+
<div class="ux4g-journey-timeline-item">
|
|
689
|
+
<div class="ux4g-journey-timeline-marker"></div>
|
|
690
|
+
<div class="ux4g-journey-timeline-content">Event 1</div>
|
|
691
|
+
</div>
|
|
692
|
+
</div>
|
|
693
|
+
|
|
694
|
+
<!-- Horizontal timeline -->
|
|
695
|
+
<div class="ux4g-journey-timeline ux4g-journey-timeline--horizontal">
|
|
696
|
+
...
|
|
697
|
+
</div>
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### Form Field Group
|
|
701
|
+
|
|
702
|
+
```html
|
|
703
|
+
<div class="ux4g-form-group">
|
|
704
|
+
<label>Full Name</label>
|
|
705
|
+
<input type="text" class="ux4g-input-md" />
|
|
706
|
+
<span class="ux4g-form-helper">Enter your full legal name</span>
|
|
707
|
+
</div>
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### OTP Input
|
|
711
|
+
|
|
712
|
+
```html
|
|
713
|
+
<!-- Default OTP -->
|
|
714
|
+
<div class="ux4g-otp">
|
|
715
|
+
<input type="text" maxlength="1" />
|
|
716
|
+
<input type="text" maxlength="1" />
|
|
717
|
+
<input type="text" maxlength="1" />
|
|
718
|
+
<input type="text" maxlength="1" />
|
|
719
|
+
</div>
|
|
720
|
+
|
|
721
|
+
<!-- Error state -->
|
|
722
|
+
<div class="ux4g-otp ux4g-otp-error">
|
|
723
|
+
...
|
|
724
|
+
</div>
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
**States:** default, `ux4g-otp-success`, `ux4g-otp-error`, `ux4g-otp-locked`
|
|
39
728
|
|
|
40
|
-
###
|
|
729
|
+
### File Upload
|
|
41
730
|
|
|
42
|
-
|
|
731
|
+
```html
|
|
732
|
+
<div class="ux4g-upload ux4g-upload-state-default">
|
|
733
|
+
<input type="file" />
|
|
734
|
+
<span>Drag & drop or click to upload</span>
|
|
735
|
+
</div>
|
|
736
|
+
|
|
737
|
+
<!-- Uploaded state -->
|
|
738
|
+
<div class="ux4g-upload ux4g-upload-state-uploaded">
|
|
739
|
+
<span>document.pdf</span>
|
|
740
|
+
<button class="ux4g-upload-remove">×</button>
|
|
741
|
+
</div>
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
**States:** `ux4g-upload-state-default`, `ux4g-upload-state-default-vle`, `ux4g-upload-state-selecting`, `ux4g-upload-state-scanning`, `ux4g-upload-state-uploaded`, `ux4g-upload-state-uploaded-vle`, `ux4g-upload-state-error`
|
|
745
|
+
|
|
746
|
+
### Progress Indicator
|
|
747
|
+
|
|
748
|
+
```html
|
|
749
|
+
<!-- Bar progress -->
|
|
750
|
+
<div class="ux4g-progress-bar">
|
|
751
|
+
<div class="ux4g-progress-bar-fill" style="width: 60%"></div>
|
|
752
|
+
</div>
|
|
753
|
+
|
|
754
|
+
<!-- Circle progress -->
|
|
755
|
+
<div class="ux4g-progress-circle">
|
|
756
|
+
<svg><!-- circle SVG --></svg>
|
|
757
|
+
</div>
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
**Types:** `ux4g-progress-bar`, `ux4g-progress-circle`
|
|
761
|
+
|
|
762
|
+
### Feedback
|
|
763
|
+
|
|
764
|
+
```html
|
|
765
|
+
<div class="ux4g-feedback">
|
|
766
|
+
<p>Was this helpful?</p>
|
|
767
|
+
<button>Yes</button>
|
|
768
|
+
<button>No</button>
|
|
769
|
+
</div>
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
### Draft Status Banner
|
|
773
|
+
|
|
774
|
+
```html
|
|
775
|
+
<!-- Default -->
|
|
776
|
+
<div class="ux4g-daft-staus-bar">Draft saved</div>
|
|
777
|
+
|
|
778
|
+
<!-- Auto-save variant -->
|
|
779
|
+
<div class="ux4g-auto-daft-staus-bar">Auto-saving...</div>
|
|
780
|
+
|
|
781
|
+
<!-- Success variant -->
|
|
782
|
+
<div class="ux4g-success-daft-staus-bar">Published successfully</div>
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
### SLA Progress Indicator
|
|
786
|
+
|
|
787
|
+
```html
|
|
788
|
+
<!-- Circle SLA -->
|
|
789
|
+
<div class="ux4g-sla-circle">
|
|
790
|
+
<span>75%</span>
|
|
791
|
+
</div>
|
|
792
|
+
|
|
793
|
+
<!-- Linear SLA -->
|
|
794
|
+
<div class="ux4g-sla-linear">
|
|
795
|
+
<div class="ux4g-sla-fill" style="width: 75%"></div>
|
|
796
|
+
</div>
|
|
797
|
+
|
|
798
|
+
<!-- Badge SLA -->
|
|
799
|
+
<span class="ux4g-sla-badge">On Track</span>
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
**Types:** `ux4g-sla-circle`, `ux4g-sla-linear`, `ux4g-sla-badge`
|
|
803
|
+
|
|
804
|
+
### Carousel
|
|
805
|
+
|
|
806
|
+
```html
|
|
807
|
+
<div class="ux4g-carousel" data-ux-ride="carousel">
|
|
808
|
+
<div class="carousel-inner">
|
|
809
|
+
<div class="carousel-item active">Slide 1</div>
|
|
810
|
+
<div class="carousel-item">Slide 2</div>
|
|
811
|
+
<div class="carousel-item">Slide 3</div>
|
|
812
|
+
</div>
|
|
813
|
+
<button data-ux-slide="prev">Prev</button>
|
|
814
|
+
<button data-ux-slide="next">Next</button>
|
|
815
|
+
</div>
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### Empty State
|
|
819
|
+
|
|
820
|
+
```html
|
|
821
|
+
<div class="ux4g-empty-state">
|
|
822
|
+
<img src="empty-illustration.svg" alt="" />
|
|
823
|
+
<h3>No results found</h3>
|
|
824
|
+
<p>Try adjusting your search or filters.</p>
|
|
825
|
+
<button class="ux4g-btn-primary ux4g-btn-md">Reset Filters</button>
|
|
826
|
+
</div>
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
### Chip Group
|
|
830
|
+
|
|
831
|
+
```html
|
|
832
|
+
<!-- Filter chip group -->
|
|
833
|
+
<div class="ux4g-filter-chip-group">
|
|
834
|
+
<button class="ux4g-filter-chip-md active">All</button>
|
|
835
|
+
<button class="ux4g-filter-chip-md">Category A</button>
|
|
836
|
+
<button class="ux4g-filter-chip-md">Category B</button>
|
|
837
|
+
</div>
|
|
838
|
+
|
|
839
|
+
<!-- Choice chip group -->
|
|
840
|
+
<div class="ux4g-choice-chip-group">
|
|
841
|
+
<button class="ux4g-choice-chip-md active">Option 1</button>
|
|
842
|
+
<button class="ux4g-choice-chip-md">Option 2</button>
|
|
843
|
+
</div>
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
### Navbar
|
|
847
|
+
|
|
848
|
+
```html
|
|
849
|
+
<nav class="ux4g-navbar">
|
|
850
|
+
<a href="/" class="ux4g-navbar-brand">Logo</a>
|
|
851
|
+
<ul class="ux4g-navbar-nav">
|
|
852
|
+
<li><a href="#">Home</a></li>
|
|
853
|
+
<li><a href="#">About</a></li>
|
|
854
|
+
<li><a href="#">Contact</a></li>
|
|
855
|
+
</ul>
|
|
856
|
+
</nav>
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
### Social Links
|
|
860
|
+
|
|
861
|
+
```html
|
|
862
|
+
<div class="ux4g-d-flex ux4g-gap-s">
|
|
863
|
+
<a href="#" aria-label="Twitter"><i class="ux4g-icon-twitter"></i></a>
|
|
864
|
+
<a href="#" aria-label="LinkedIn"><i class="ux4g-icon-linkedin"></i></a>
|
|
865
|
+
<a href="#" aria-label="GitHub"><i class="ux4g-icon-github"></i></a>
|
|
866
|
+
</div>
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
**Size via gap:** `ux4g-gap-xs` (sm), `ux4g-gap-s` (md), `ux4g-gap-m` (lg)
|
|
870
|
+
|
|
871
|
+
### Slot Grid
|
|
872
|
+
|
|
873
|
+
```html
|
|
874
|
+
<!-- Weekly slot grid -->
|
|
875
|
+
<div class="ux4g-time-slot-weekly-container">
|
|
876
|
+
<div class="ux4g-time-slot">9:00 AM</div>
|
|
877
|
+
<div class="ux4g-time-slot">10:00 AM</div>
|
|
878
|
+
</div>
|
|
879
|
+
|
|
880
|
+
<!-- Compact slot grid -->
|
|
881
|
+
<div class="ux4g-time-slot-compact-container">
|
|
882
|
+
<div class="ux4g-time-slot">9:00</div>
|
|
883
|
+
<div class="ux4g-time-slot">9:30</div>
|
|
884
|
+
</div>
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
### Footer
|
|
888
|
+
|
|
889
|
+
```html
|
|
890
|
+
<footer class="ux4g-footer-primary">
|
|
891
|
+
<div class="ux4g-footer-content">
|
|
892
|
+
<p>© 2024 Company Name</p>
|
|
893
|
+
</div>
|
|
894
|
+
</footer>
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
**Themes:** default (no class), `ux4g-footer-primary`, `ux4g-footer-dark`
|
|
898
|
+
|
|
899
|
+
### Result List Row
|
|
900
|
+
|
|
901
|
+
```html
|
|
902
|
+
<div class="ux4g-result-list">
|
|
903
|
+
<div class="ux4g-result-list-item">
|
|
904
|
+
<h4>Result Title</h4>
|
|
905
|
+
<p>Description text</p>
|
|
906
|
+
</div>
|
|
907
|
+
</div>
|
|
908
|
+
|
|
909
|
+
<!-- Variation v2 -->
|
|
910
|
+
<div class="ux4g-result-list ux4g-result-list-v2">
|
|
911
|
+
...
|
|
912
|
+
</div>
|
|
913
|
+
```
|
|
914
|
+
|
|
915
|
+
**Variations:** default, `ux4g-result-list-v1`, `ux4g-result-list-v2`, `ux4g-result-list-v3`, `ux4g-result-list-v4`, `ux4g-result-list-v5`
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
## Runtime Module
|
|
920
|
+
|
|
921
|
+
The runtime module provides interactive behaviors (dropdowns, modals, tooltips, accordions, carousels, drawers, tabs) without requiring React or Angular. It uses event delegation on `document` — no per-element binding needed.
|
|
922
|
+
|
|
923
|
+
### Explicit Initialization (recommended for apps that need control)
|
|
924
|
+
|
|
925
|
+
```ts
|
|
926
|
+
import { initRuntime, destroyRuntime } from 'ux4g-components-web/runtime';
|
|
927
|
+
|
|
928
|
+
// Call once at app startup
|
|
929
|
+
initRuntime();
|
|
930
|
+
|
|
931
|
+
// Call for cleanup (testing, SSR teardown)
|
|
932
|
+
destroyRuntime();
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
### Auto-Bootstrap (side-effect import)
|
|
936
|
+
|
|
937
|
+
```ts
|
|
938
|
+
import 'ux4g-components-web/runtime/bootstrap';
|
|
939
|
+
// Runtime is initialized immediately on import
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
### Behaviors Provided
|
|
943
|
+
|
|
944
|
+
| Behavior | Data Attribute | Description |
|
|
945
|
+
|---|---|---|
|
|
946
|
+
| Dropdown | `data-ux-toggle="dropdown"` | Toggle dropdown menus |
|
|
947
|
+
| Modal | `data-ux-toggle="modal"` | Open/close modals with escape/backdrop |
|
|
948
|
+
| Tooltip | `data-ux-toggle="tooltip"` | Show/hide on hover/focus |
|
|
949
|
+
| Popover | `data-ux-toggle="popover"` | Show/hide on click |
|
|
950
|
+
| Collapse | `data-ux-toggle="collapse"` | Expand/collapse sections |
|
|
951
|
+
| Tab | `data-ux-toggle="tab"` | Switch tab panels |
|
|
952
|
+
| Carousel | `data-ux-ride="carousel"` | Auto-slide, next/prev controls |
|
|
953
|
+
| Offcanvas/Drawer | `data-ux-toggle="offcanvas"` | Slide-in panels |
|
|
954
|
+
| Toast | `.toast` | Auto-hide notifications |
|
|
955
|
+
| ScrollSpy | `data-ux-spy="scroll"` | Highlight nav on scroll |
|
|
956
|
+
|
|
957
|
+
### Design Notes
|
|
958
|
+
|
|
959
|
+
- **Singleton guard:** `window.__UX4G_RUNTIME_INITIALIZED__` prevents duplicate initialization
|
|
960
|
+
- **SSR-safe:** No-ops when `window`/`document` are unavailable
|
|
961
|
+
- **Event delegation:** All listeners attached to `document`
|
|
962
|
+
- **Cleanup:** `destroyRuntime()` removes all listeners and resets the guard
|
|
963
|
+
|
|
964
|
+
---
|
|
965
|
+
|
|
966
|
+
## Shared Types (Class_Builder)
|
|
967
|
+
|
|
968
|
+
Framework wrappers import Class_Builder functions from this package to map typed props to CSS class strings:
|
|
43
969
|
|
|
44
970
|
```ts
|
|
45
971
|
import { buildButtonClasses, ButtonVariant, ButtonSize } from 'ux4g-components-web/types';
|
|
@@ -48,7 +974,25 @@ const classes = buildButtonClasses('primary', 'md', false, false);
|
|
|
48
974
|
// → "ux4g-btn-primary ux4g-btn-md"
|
|
49
975
|
```
|
|
50
976
|
|
|
51
|
-
###
|
|
977
|
+
### Custom Integrations
|
|
978
|
+
|
|
979
|
+
You can use Class_Builder functions in any framework (Vue, Svelte, vanilla JS):
|
|
980
|
+
|
|
981
|
+
```ts
|
|
982
|
+
import { buildCardClasses } from 'ux4g-components-web/types';
|
|
983
|
+
import { buildSpinnerClasses } from 'ux4g-components-web/types';
|
|
984
|
+
|
|
985
|
+
// Use in a Vue component
|
|
986
|
+
const cardClass = buildCardClasses('outline', 'horizontal');
|
|
987
|
+
// → "ux4g-card ux4g-card-outline ux4g-card-horizontal"
|
|
988
|
+
|
|
989
|
+
const spinnerClass = buildSpinnerClasses('primary', 'lg', 'full');
|
|
990
|
+
// → "ux4g-spinner-primary-full ux4g-spinner-lg"
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
---
|
|
994
|
+
|
|
995
|
+
## Utility Classes
|
|
52
996
|
|
|
53
997
|
Use utility classes directly in HTML — no wrapper component needed:
|
|
54
998
|
|
|
@@ -58,12 +1002,74 @@ Use utility classes directly in HTML — no wrapper component needed:
|
|
|
58
1002
|
</div>
|
|
59
1003
|
```
|
|
60
1004
|
|
|
61
|
-
|
|
1005
|
+
### Available Utility Categories (27 modules)
|
|
62
1006
|
|
|
63
|
-
|
|
|
64
|
-
|
|
65
|
-
|
|
|
66
|
-
| `
|
|
1007
|
+
| Category | Modules |
|
|
1008
|
+
|---|---|
|
|
1009
|
+
| Typography & Text | `typography`, `typescale`, `colors`, `text-transform`, `vertical-align` |
|
|
1010
|
+
| Layout & Spacing | `spacing`, `sizing`, `gap`, `object-fit`, `overflow`, `position`, `z-index`, `visibility`, `display`, `display-responsive` |
|
|
1011
|
+
| Flexbox & Grid | `flex`, `flex-responsive`, `align`, `justify`, `order` |
|
|
1012
|
+
| Visual Effects | `background`, `border`, `radius`, `shadow`, `opacity`, `blur` |
|
|
1013
|
+
| Interaction | `interaction` |
|
|
1014
|
+
|
|
1015
|
+
### Common Utility Examples
|
|
1016
|
+
|
|
1017
|
+
```html
|
|
1018
|
+
<!-- Flexbox layout -->
|
|
1019
|
+
<div class="ux4g-d-flex ux4g-justify-between ux4g-align-center ux4g-gap-m">
|
|
1020
|
+
...
|
|
1021
|
+
</div>
|
|
1022
|
+
|
|
1023
|
+
<!-- Typography -->
|
|
1024
|
+
<h1 class="ux4g-heading-xl-bold">Title</h1>
|
|
1025
|
+
<p class="ux4g-body-m-default">Body text</p>
|
|
1026
|
+
|
|
1027
|
+
<!-- Spacing -->
|
|
1028
|
+
<div class="ux4g-p-l ux4g-m-m">Padded and margined</div>
|
|
1029
|
+
|
|
1030
|
+
<!-- Background and border -->
|
|
1031
|
+
<div class="ux4g-bg-neutral-soft ux4g-border-neutral ux4g-radius-lg ux4g-shadow-md">
|
|
1032
|
+
Card-like container
|
|
1033
|
+
</div>
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
---
|
|
1037
|
+
|
|
1038
|
+
## Dark Theme
|
|
1039
|
+
|
|
1040
|
+
Apply the dark theme by adding the `data-theme="dark"` attribute to any container or the `<html>` element:
|
|
1041
|
+
|
|
1042
|
+
```html
|
|
1043
|
+
<html data-theme="dark">
|
|
1044
|
+
<!-- All components automatically use dark tokens -->
|
|
1045
|
+
</html>
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
Or scope it to a section:
|
|
1049
|
+
|
|
1050
|
+
```html
|
|
1051
|
+
<div data-theme="dark">
|
|
1052
|
+
<button class="ux4g-btn-primary ux4g-btn-md">Dark themed button</button>
|
|
1053
|
+
</div>
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
The design tokens automatically switch values based on the `data-theme` attribute — no additional CSS imports needed.
|
|
1057
|
+
|
|
1058
|
+
---
|
|
1059
|
+
|
|
1060
|
+
## Focus Ring
|
|
1061
|
+
|
|
1062
|
+
UX4G provides built-in focus ring styles for keyboard accessibility. Focus rings appear automatically when users navigate with the keyboard and are suppressed for mouse interactions:
|
|
1063
|
+
|
|
1064
|
+
```html
|
|
1065
|
+
<!-- Focus ring is applied automatically to interactive elements -->
|
|
1066
|
+
<button class="ux4g-btn-primary ux4g-btn-md">Focusable</button>
|
|
1067
|
+
|
|
1068
|
+
<!-- Custom focus ring via utility -->
|
|
1069
|
+
<div tabindex="0" class="ux4g-focus-ring">Custom focusable element</div>
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
---
|
|
67
1073
|
|
|
68
1074
|
## Related Packages
|
|
69
1075
|
|