@digicreon/mucss 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/dist/mu.amber.css +2 -0
- package/dist/mu.azure.css +2 -0
- package/dist/mu.blue.css +2 -0
- package/dist/mu.css +2 -0
- package/dist/mu.cyan.css +2 -0
- package/dist/mu.fuchsia.css +2 -0
- package/dist/mu.green.css +2 -0
- package/dist/mu.grey.css +2 -0
- package/dist/mu.indigo.css +2 -0
- package/dist/mu.jade.css +2 -0
- package/dist/mu.lime.css +2 -0
- package/dist/mu.orange.css +2 -0
- package/dist/mu.pink.css +2 -0
- package/dist/mu.pumpkin.css +2 -0
- package/dist/mu.purple.css +2 -0
- package/dist/mu.red.css +2 -0
- package/dist/mu.sand.css +2 -0
- package/dist/mu.slate.css +2 -0
- package/dist/mu.violet.css +2 -0
- package/dist/mu.yellow.css +2 -0
- package/dist/mu.zinc.css +2 -0
- package/documentation/mu.accordion.md +119 -0
- package/documentation/mu.alert.md +134 -0
- package/documentation/mu.badge.md +155 -0
- package/documentation/mu.breadcrumb.md +140 -0
- package/documentation/mu.button.md +147 -0
- package/documentation/mu.card.md +135 -0
- package/documentation/mu.checkbox-radio.md +121 -0
- package/documentation/mu.dropdown.md +183 -0
- package/documentation/mu.forms-advanced.md +164 -0
- package/documentation/mu.forms.md +147 -0
- package/documentation/mu.grid.md +175 -0
- package/documentation/mu.group.md +102 -0
- package/documentation/mu.loading.md +99 -0
- package/documentation/mu.modal.md +163 -0
- package/documentation/mu.pagination.md +196 -0
- package/documentation/mu.progress.md +123 -0
- package/documentation/mu.range.md +103 -0
- package/documentation/mu.spinner.md +102 -0
- package/documentation/mu.switch.md +110 -0
- package/documentation/mu.table.md +147 -0
- package/documentation/mu.tabs.md +164 -0
- package/documentation/mu.tooltip.md +98 -0
- package/documentation/mu.typography.md +196 -0
- package/package.json +31 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# µForms
|
|
2
|
+
|
|
3
|
+
**µForms** extends PicoCSS form controls with size variants and validation states, part of the [µCSS](.) framework. It applies to `<input>`, `<textarea>`, and `<select>` elements.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Input sizes
|
|
8
|
+
|
|
9
|
+
Two size modifiers adjust padding and font size. Without a size class, the default PicoCSS styling applies.
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<label>Small input
|
|
13
|
+
<input type="text" class="input-sm" placeholder="Small input">
|
|
14
|
+
</label>
|
|
15
|
+
<label>Default input
|
|
16
|
+
<input type="text" placeholder="Default input">
|
|
17
|
+
</label>
|
|
18
|
+
<label>Large input
|
|
19
|
+
<input type="text" class="input-lg" placeholder="Large input">
|
|
20
|
+
</label>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Size reference
|
|
24
|
+
|
|
25
|
+
| Class | Padding | Font size | Applies to |
|
|
26
|
+
|-------------|--------------------------|---------------|----------------------------------|
|
|
27
|
+
| `.input-sm` | `0.375rem 0.625rem` | `0.8125rem` | `input`, `textarea`, `select` |
|
|
28
|
+
| *(default)* | *(PicoCSS default)* | *(default)* | `input`, `textarea`, `select` |
|
|
29
|
+
| `.input-lg` | `0.75rem 1rem` | `1.125rem` | `input`, `textarea`, `select` |
|
|
30
|
+
|
|
31
|
+
### Textarea sizes
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<label>Small textarea
|
|
35
|
+
<textarea class="input-sm" placeholder="Small textarea"></textarea>
|
|
36
|
+
</label>
|
|
37
|
+
<label>Large textarea
|
|
38
|
+
<textarea class="input-lg" placeholder="Large textarea"></textarea>
|
|
39
|
+
</label>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Select sizes
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<label>Small select
|
|
46
|
+
<select class="input-sm">
|
|
47
|
+
<option>Option 1</option>
|
|
48
|
+
<option>Option 2</option>
|
|
49
|
+
</select>
|
|
50
|
+
</label>
|
|
51
|
+
<label>Large select
|
|
52
|
+
<select class="input-lg">
|
|
53
|
+
<option>Option 1</option>
|
|
54
|
+
<option>Option 2</option>
|
|
55
|
+
</select>
|
|
56
|
+
</label>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Validation states
|
|
62
|
+
|
|
63
|
+
µForms provides two validation classes that set border color and focus ring color. For error states, use the native `aria-invalid="true"` attribute (handled by PicoCSS).
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<label>Success
|
|
67
|
+
<input type="text" class="input-success" value="Valid value">
|
|
68
|
+
</label>
|
|
69
|
+
<label>Warning
|
|
70
|
+
<input type="text" class="input-warning" value="Needs attention">
|
|
71
|
+
</label>
|
|
72
|
+
<label>Error (native)
|
|
73
|
+
<input type="text" aria-invalid="true" value="Invalid value">
|
|
74
|
+
</label>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Validation reference
|
|
78
|
+
|
|
79
|
+
| Class / Attribute | Border color | Focus ring color |
|
|
80
|
+
|--------------------------|-----------------------|---------------------------|
|
|
81
|
+
| `.input-success` | `--pico-success` | `--pico-success-focus` |
|
|
82
|
+
| `.input-warning` | `--pico-warning` | `--pico-warning-focus` |
|
|
83
|
+
| `aria-invalid="true"` | *(PicoCSS built-in)* | *(PicoCSS built-in)* |
|
|
84
|
+
|
|
85
|
+
### Validation on textarea
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<label>Success textarea
|
|
89
|
+
<textarea class="input-success">This content is valid.</textarea>
|
|
90
|
+
</label>
|
|
91
|
+
<label>Warning textarea
|
|
92
|
+
<textarea class="input-warning">This content needs review.</textarea>
|
|
93
|
+
</label>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Validation on select
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<label>Success select
|
|
100
|
+
<select class="input-success">
|
|
101
|
+
<option>Valid choice</option>
|
|
102
|
+
</select>
|
|
103
|
+
</label>
|
|
104
|
+
<label>Warning select
|
|
105
|
+
<select class="input-warning">
|
|
106
|
+
<option>Needs review</option>
|
|
107
|
+
</select>
|
|
108
|
+
</label>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Combining size and validation
|
|
114
|
+
|
|
115
|
+
Size and validation classes can be used together on the same element:
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<label>Small + success
|
|
119
|
+
<input type="text" class="input-sm input-success" value="Small valid">
|
|
120
|
+
</label>
|
|
121
|
+
<label>Large + warning
|
|
122
|
+
<input type="text" class="input-lg input-warning" value="Large needs attention">
|
|
123
|
+
</label>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## CSS classes reference
|
|
129
|
+
|
|
130
|
+
| Class | Type | Description |
|
|
131
|
+
|-------------------|------------|------------------------------------------------------|
|
|
132
|
+
| `.input-sm` | Size | Smaller padding and font size |
|
|
133
|
+
| `.input-lg` | Size | Larger padding and font size |
|
|
134
|
+
| `.input-success` | Validation | Green border, green focus ring |
|
|
135
|
+
| `.input-warning` | Validation | Orange/yellow border, orange/yellow focus ring |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Accessibility
|
|
140
|
+
|
|
141
|
+
- Use `aria-invalid="true"` for error states (PicoCSS native support).
|
|
142
|
+
- Always wrap form controls inside `<label>` elements for proper association.
|
|
143
|
+
- Validation colors supplement, but do not replace, text-based error messages.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
→ [Voir l'exemple](../examples/forms.html)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# µGrid
|
|
2
|
+
|
|
3
|
+
**µGrid** is a lightweight flexbox-based 12-column responsive grid system, part of the [µCSS](.) framework. It provides a Bootstrap-compatible grid fallback for CSS frameworks that lack a built-in responsive grid (such as PicoCSS).
|
|
4
|
+
|
|
5
|
+
**Weight:** ~4 KB uncompressed, ~1 KB gzipped.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Breakpoints
|
|
10
|
+
|
|
11
|
+
µGrid uses a mobile-first approach with 4 breakpoints:
|
|
12
|
+
|
|
13
|
+
| Name | Prefix | Min-width | Typical use |
|
|
14
|
+
|------|--------|-----------|----------------------|
|
|
15
|
+
| — | *(none)* | 0 | Mobile (default) |
|
|
16
|
+
| sm | `-sm-` | 640px | Mobile landscape |
|
|
17
|
+
| md | `-md-` | 960px | Tablet |
|
|
18
|
+
| lg | `-lg-` | 1200px | Desktop |
|
|
19
|
+
| xl | `-xl-` | 1400px | Large desktop |
|
|
20
|
+
|
|
21
|
+
All classes without a breakpoint prefix apply to all screen sizes. Prefixed classes apply from the specified breakpoint and up.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Container
|
|
26
|
+
|
|
27
|
+
Containers center and constrain content horizontally.
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<!-- Fixed-width container (max-width: 1200px) -->
|
|
31
|
+
<div class="container">...</div>
|
|
32
|
+
|
|
33
|
+
<!-- Full-width container -->
|
|
34
|
+
<div class="container-fluid">...</div>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Both containers have `1rem` horizontal padding.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Row
|
|
42
|
+
|
|
43
|
+
A `.row` creates a flex container for columns. It uses negative margins to compensate for column gutters.
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<div class="container">
|
|
47
|
+
<div class="row">
|
|
48
|
+
<div class="col-6">Half</div>
|
|
49
|
+
<div class="col-6">Half</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Columns
|
|
57
|
+
|
|
58
|
+
Columns are defined using `.col-{n}` and `.col-{bp}-{n}` classes, where `{n}` is a number from 1 to 12.
|
|
59
|
+
|
|
60
|
+
Each column has a `0.75rem` padding on each side (1.5rem gutter between columns).
|
|
61
|
+
|
|
62
|
+
### Basic usage
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<div class="row">
|
|
66
|
+
<div class="col-12">Full width</div>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<div class="row">
|
|
70
|
+
<div class="col-4">One third</div>
|
|
71
|
+
<div class="col-8">Two thirds</div>
|
|
72
|
+
</div>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Responsive columns
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<div class="row">
|
|
79
|
+
<!-- Full width on mobile, half on tablet, one third on desktop -->
|
|
80
|
+
<div class="col-12 col-md-6 col-lg-4">Content</div>
|
|
81
|
+
<div class="col-12 col-md-6 col-lg-4">Content</div>
|
|
82
|
+
<div class="col-12 col-md-12 col-lg-4">Content</div>
|
|
83
|
+
</div>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Column reference
|
|
87
|
+
|
|
88
|
+
| Class pattern | Width |
|
|
89
|
+
|------------------|------------|
|
|
90
|
+
| `.col-{bp}-1` | 8.3333% |
|
|
91
|
+
| `.col-{bp}-2` | 16.6667% |
|
|
92
|
+
| `.col-{bp}-3` | 25% |
|
|
93
|
+
| `.col-{bp}-4` | 33.3333% |
|
|
94
|
+
| `.col-{bp}-5` | 41.6667% |
|
|
95
|
+
| `.col-{bp}-6` | 50% |
|
|
96
|
+
| `.col-{bp}-7` | 58.3333% |
|
|
97
|
+
| `.col-{bp}-8` | 66.6667% |
|
|
98
|
+
| `.col-{bp}-9` | 75% |
|
|
99
|
+
| `.col-{bp}-10` | 83.3333% |
|
|
100
|
+
| `.col-{bp}-11` | 91.6667% |
|
|
101
|
+
| `.col-{bp}-12` | 100% |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Offsets
|
|
106
|
+
|
|
107
|
+
Offsets push a column to the right by a given number of columns using `margin-left`.
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<div class="row">
|
|
111
|
+
<div class="col-6 offset-3">Centered content</div>
|
|
112
|
+
</div>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Responsive offsets
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<div class="row">
|
|
119
|
+
<div class="col-12 col-md-8 col-lg-4 offset-md-2 offset-lg-4">Content</div>
|
|
120
|
+
</div>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Use `.offset-{bp}-0` to reset an offset at a given breakpoint.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Ordering
|
|
128
|
+
|
|
129
|
+
Change the visual order of columns without changing the HTML source order.
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<div class="row">
|
|
133
|
+
<div class="col-6 order-2">Appears second</div>
|
|
134
|
+
<div class="col-6 order-1">Appears first</div>
|
|
135
|
+
</div>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Special values
|
|
139
|
+
|
|
140
|
+
| Class | Effect |
|
|
141
|
+
|------------------------|--------------|
|
|
142
|
+
| `.order-{bp}-first` | `order: -1` |
|
|
143
|
+
| `.order-{bp}-last` | `order: 13` |
|
|
144
|
+
| `.order-{bp}-0` to `.order-{bp}-12` | `order: 0` to `order: 12` |
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Display / Visibility
|
|
149
|
+
|
|
150
|
+
| Class | Effect |
|
|
151
|
+
|-------------------|---------------------|
|
|
152
|
+
| `.d-{bp}-none` | `display: none` |
|
|
153
|
+
| `.d-{bp}-block` | `display: block` |
|
|
154
|
+
| `.d-{bp}-flex` | `display: flex` |
|
|
155
|
+
|
|
156
|
+
When showing a `.row` that was previously hidden, use `d-{bp}-flex` instead of `d-{bp}-block` to preserve the flex layout.
|
|
157
|
+
|
|
158
|
+
```html
|
|
159
|
+
<div class="row d-none d-md-flex">
|
|
160
|
+
<div class="col-md-6">A</div>
|
|
161
|
+
<div class="col-md-6">B</div>
|
|
162
|
+
</div>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Bootstrap compatibility
|
|
168
|
+
|
|
169
|
+
µGrid uses the same class naming conventions as Bootstrap 5. Main differences:
|
|
170
|
+
|
|
171
|
+
- **4 breakpoints** instead of 5: Bootstrap's `xl` and `xxl` are merged into `xl`.
|
|
172
|
+
- **Breakpoint values differ slightly**: `sm` is 640px (vs 576px), `md` is 960px (vs 768px).
|
|
173
|
+
- **No auto-sizing columns**: `.col` (without a number) is not supported.
|
|
174
|
+
- **No `row-cols-*`**: automatic column count per row is not supported.
|
|
175
|
+
- **No flex alignment utilities**: `justify-content-*`, `align-items-*` are not included.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# µGroup
|
|
2
|
+
|
|
3
|
+
**µGroup** permet de regrouper visuellement des champs de formulaire et des boutons en une seule ligne, grace a l'attribut `role="group"` style par [PicoCSS](https://picocss.com) au sein du framework [µCSS](.). Les elements groupes partagent des bordures communes et s'alignent horizontalement.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Groupe de boutons
|
|
8
|
+
|
|
9
|
+
L'attribut `role="group"` sur un conteneur regroupe les boutons en une barre horizontale avec des bordures fusionnees.
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<div role="group">
|
|
13
|
+
<button>Left</button>
|
|
14
|
+
<button>Center</button>
|
|
15
|
+
<button>Right</button>
|
|
16
|
+
</div>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Input + bouton
|
|
22
|
+
|
|
23
|
+
Combinez un champ de saisie et un bouton dans un meme groupe pour creer un formulaire inline compact.
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<div role="group">
|
|
27
|
+
<input type="email" placeholder="Enter your email">
|
|
28
|
+
<button>Subscribe</button>
|
|
29
|
+
</div>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Groupe de recherche
|
|
35
|
+
|
|
36
|
+
Utilisez `role="search"` pour un groupe semantiquement identifie comme zone de recherche. Le rendu visuel est identique a `role="group"`.
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<div role="search">
|
|
40
|
+
<input type="search" placeholder="Search...">
|
|
41
|
+
<button>Search</button>
|
|
42
|
+
</div>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Input + select + bouton
|
|
48
|
+
|
|
49
|
+
Un groupe peut contenir plus de deux elements, par exemple un `<select>`, un `<input>` et un `<button>`.
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<div role="group">
|
|
53
|
+
<select>
|
|
54
|
+
<option>USD</option>
|
|
55
|
+
<option>EUR</option>
|
|
56
|
+
<option>GBP</option>
|
|
57
|
+
</select>
|
|
58
|
+
<input type="number" placeholder="Amount">
|
|
59
|
+
<button>Convert</button>
|
|
60
|
+
</div>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Boutons outline
|
|
66
|
+
|
|
67
|
+
Les boutons `.outline` fonctionnent egalement dans un groupe, offrant un style de barre de selection (toggle bar).
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<div role="group">
|
|
71
|
+
<button class="outline">Day</button>
|
|
72
|
+
<button class="outline">Week</button>
|
|
73
|
+
<button class="outline">Month</button>
|
|
74
|
+
</div>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Resume des roles
|
|
80
|
+
|
|
81
|
+
| Attribut | Usage |
|
|
82
|
+
|----------|-------|
|
|
83
|
+
| `role="group"` | Groupe generique (boutons, inputs, selects) |
|
|
84
|
+
| `role="search"` | Groupe de recherche (semantique) |
|
|
85
|
+
|
|
86
|
+
## Elements supportes dans un groupe
|
|
87
|
+
|
|
88
|
+
| Element | Comportement |
|
|
89
|
+
|---------|-------------|
|
|
90
|
+
| `<button>` | Bouton d'action |
|
|
91
|
+
| `<input>` | Champ de saisie (text, email, search, number, etc.) |
|
|
92
|
+
| `<select>` | Liste de selection |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Accessibilite
|
|
97
|
+
|
|
98
|
+
- `role="group"` informe les technologies d'assistance que les elements sont lies et forment un ensemble logique.
|
|
99
|
+
- `role="search"` identifie semantiquement la zone comme fonctionnalite de recherche, ce qui aide la navigation au lecteur d'ecran.
|
|
100
|
+
- Les elements du groupe restent accessibles individuellement au clavier (navigation par `Tab`).
|
|
101
|
+
|
|
102
|
+
→ [Voir l'exemple](../examples/group.html)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# µLoading
|
|
2
|
+
|
|
3
|
+
**µLoading** describes the loading indicator states available natively in [µCSS](.) via PicoCSS. Loading states are activated using the standard `aria-busy="true"` attribute on any element, which displays an animated spinner without requiring any additional CSS class or JavaScript library.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
Add `aria-busy="true"` to any HTML element to show a loading spinner. The spinner is rendered via CSS and adapts to the element's context (inline for buttons and paragraphs, block-level for containers).
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<button aria-busy="true">Please wait...</button>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Remove the loading state by setting `aria-busy="false"` or removing the attribute entirely.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Button loading
|
|
20
|
+
|
|
21
|
+
Apply `aria-busy="true"` on `<button>` elements to show a spinner alongside the button text. This works with all button variants.
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<button aria-busy="true">Please wait...</button>
|
|
25
|
+
<button aria-busy="true" class="secondary">Loading</button>
|
|
26
|
+
<button aria-busy="true" class="contrast">Processing</button>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Standalone spinner
|
|
32
|
+
|
|
33
|
+
Use an empty `<div>` with `aria-busy="true"` to display a standalone centered spinner. Set a `min-height` so the spinner has space to render.
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<div aria-busy="true" style="min-height: 3rem;"></div>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Loading on a card
|
|
42
|
+
|
|
43
|
+
Apply `aria-busy="true"` on an `<article>` to indicate the entire card is in a loading state.
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<article aria-busy="true">
|
|
47
|
+
<p>This card is loading...</p>
|
|
48
|
+
</article>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Loading paragraph
|
|
54
|
+
|
|
55
|
+
Apply `aria-busy="true"` directly on a `<p>` element to show a spinner inline with text content.
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<p aria-busy="true">Loading content...</p>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Toggle loading dynamically
|
|
64
|
+
|
|
65
|
+
Use JavaScript to toggle the `aria-busy` attribute on any element to control the loading state at runtime.
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<button onclick="var t = document.getElementById('target'); t.ariaBusy = t.ariaBusy === 'true' ? 'false' : 'true';">
|
|
69
|
+
Toggle loading state
|
|
70
|
+
</button>
|
|
71
|
+
<article id="target" aria-busy="false">
|
|
72
|
+
<p>Click the button above to toggle the loading state on this card.</p>
|
|
73
|
+
</article>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Supported elements
|
|
79
|
+
|
|
80
|
+
| Element | Behavior |
|
|
81
|
+
|---------------|-----------------------------------------------|
|
|
82
|
+
| `<button>` | Spinner displayed inline before the text |
|
|
83
|
+
| `<div>` | Centered block-level spinner |
|
|
84
|
+
| `<article>` | Spinner overlays the card content |
|
|
85
|
+
| `<p>` | Spinner displayed inline with text |
|
|
86
|
+
|
|
87
|
+
Any element that accepts `aria-busy` can display the loading indicator.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Accessibility
|
|
92
|
+
|
|
93
|
+
- `aria-busy="true"` is a standard WAI-ARIA attribute. Screen readers will announce the element as busy/loading.
|
|
94
|
+
- Always provide descriptive text content (e.g., "Please wait...") alongside the spinner for assistive technologies.
|
|
95
|
+
- Set `aria-busy="false"` when loading completes to notify screen readers that content is ready.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
→ [Voir l'exemple](../examples/loading.html)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# µModal
|
|
2
|
+
|
|
3
|
+
**µModal** provides size variants and a close button for native `<dialog>` modals, part of the [µCSS](.) framework. It builds on PicoCSS's dialog styling with small, large, and fullscreen options.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
Modals use the native HTML `<dialog>` element containing an `<article>`. Open with JavaScript's `.showModal()` method and close with `.close()`.
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<dialog id="my-modal">
|
|
13
|
+
<article>
|
|
14
|
+
<button class="modal-close" aria-label="Close"
|
|
15
|
+
onclick="document.getElementById('my-modal').close()">×</button>
|
|
16
|
+
<h3>Modal title</h3>
|
|
17
|
+
<p>Modal content goes here.</p>
|
|
18
|
+
<footer>
|
|
19
|
+
<button class="btn btn-primary"
|
|
20
|
+
onclick="document.getElementById('my-modal').close()">Close</button>
|
|
21
|
+
</footer>
|
|
22
|
+
</article>
|
|
23
|
+
</dialog>
|
|
24
|
+
|
|
25
|
+
<!-- Trigger button -->
|
|
26
|
+
<button onclick="document.getElementById('my-modal').showModal()">Open modal</button>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Size variants
|
|
32
|
+
|
|
33
|
+
4 sizes are available. Without a size class, the default PicoCSS dialog width applies.
|
|
34
|
+
|
|
35
|
+
| Class | Max-width | Description |
|
|
36
|
+
|---------------------|--------------|--------------------------------------|
|
|
37
|
+
| `.modal-sm` | 400px | Confirmations and simple prompts |
|
|
38
|
+
| *(default)* | *(PicoCSS)* | Suitable for most content |
|
|
39
|
+
| `.modal-lg` | 900px | Forms or detailed content |
|
|
40
|
+
| `.modal-fullscreen` | 100vw | Full viewport, no border-radius |
|
|
41
|
+
|
|
42
|
+
Size classes are applied on the `<dialog>` element, not on the inner `<article>`.
|
|
43
|
+
|
|
44
|
+
### Small modal
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<dialog id="modal-sm" class="modal-sm">
|
|
48
|
+
<article>
|
|
49
|
+
<button class="modal-close" aria-label="Close"
|
|
50
|
+
onclick="document.getElementById('modal-sm').close()">×</button>
|
|
51
|
+
<h3>Small modal</h3>
|
|
52
|
+
<p>This is a small modal (max-width: 400px). Ideal for confirmations and simple prompts.</p>
|
|
53
|
+
<footer>
|
|
54
|
+
<button class="btn btn-ghost btn-secondary"
|
|
55
|
+
onclick="document.getElementById('modal-sm').close()">Cancel</button>
|
|
56
|
+
<button class="btn btn-primary"
|
|
57
|
+
onclick="document.getElementById('modal-sm').close()">Confirm</button>
|
|
58
|
+
</footer>
|
|
59
|
+
</article>
|
|
60
|
+
</dialog>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Large modal
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<dialog id="modal-lg" class="modal-lg">
|
|
67
|
+
<article>
|
|
68
|
+
<button class="modal-close" aria-label="Close"
|
|
69
|
+
onclick="document.getElementById('modal-lg').close()">×</button>
|
|
70
|
+
<h3>Large modal</h3>
|
|
71
|
+
<p>This is a large modal (max-width: 900px). Useful for forms or detailed content.</p>
|
|
72
|
+
<div class="row">
|
|
73
|
+
<div class="col-6">
|
|
74
|
+
<label>First name <input type="text" placeholder="First name"></label>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="col-6">
|
|
77
|
+
<label>Last name <input type="text" placeholder="Last name"></label>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<label>Email <input type="email" placeholder="Email address"></label>
|
|
81
|
+
<footer>
|
|
82
|
+
<button class="btn btn-ghost btn-secondary"
|
|
83
|
+
onclick="document.getElementById('modal-lg').close()">Cancel</button>
|
|
84
|
+
<button class="btn btn-success"
|
|
85
|
+
onclick="document.getElementById('modal-lg').close()">Save</button>
|
|
86
|
+
</footer>
|
|
87
|
+
</article>
|
|
88
|
+
</dialog>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Fullscreen modal
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<dialog id="modal-fullscreen" class="modal-fullscreen">
|
|
95
|
+
<article>
|
|
96
|
+
<button class="modal-close" aria-label="Close"
|
|
97
|
+
onclick="document.getElementById('modal-fullscreen').close()">×</button>
|
|
98
|
+
<h3>Fullscreen modal</h3>
|
|
99
|
+
<p>This modal covers the entire viewport. Suitable for immersive experiences,
|
|
100
|
+
image galleries, or complex workflows.</p>
|
|
101
|
+
<footer>
|
|
102
|
+
<button class="btn btn-error"
|
|
103
|
+
onclick="document.getElementById('modal-fullscreen').close()">Close</button>
|
|
104
|
+
</footer>
|
|
105
|
+
</article>
|
|
106
|
+
</dialog>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The fullscreen variant sets `width: 100vw`, `min-height: 100vh`, `border-radius: 0`, and `margin: 0` on the inner `<article>`.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Close button
|
|
114
|
+
|
|
115
|
+
The `.modal-close` class styles a close button positioned absolutely in the top-right corner of the `<article>`.
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<button class="modal-close" aria-label="Close"
|
|
119
|
+
onclick="document.getElementById('my-modal').close()">×</button>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| Property | Value |
|
|
123
|
+
|-------------------|---------------------------------|
|
|
124
|
+
| Position | Absolute, top-right corner |
|
|
125
|
+
| Size | 3rem x 3rem |
|
|
126
|
+
| Background | Transparent |
|
|
127
|
+
| Color | `--pico-secondary` |
|
|
128
|
+
| Opacity | 0.6 (1 on hover) |
|
|
129
|
+
| Focus indicator | 2px solid outline, 0.25rem radius |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## CSS classes reference
|
|
134
|
+
|
|
135
|
+
| Class | Applied to | Description |
|
|
136
|
+
|---------------------|--------------|-------------------------------------------|
|
|
137
|
+
| `.modal-sm` | `<dialog>` | Small modal (max-width: 400px) |
|
|
138
|
+
| `.modal-lg` | `<dialog>` | Large modal (max-width: 900px) |
|
|
139
|
+
| `.modal-fullscreen` | `<dialog>` | Full viewport modal |
|
|
140
|
+
| `.modal-close` | `<button>` | Positioned close button (top-right) |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Opening and closing
|
|
145
|
+
|
|
146
|
+
Modals rely on the native `<dialog>` API. No JavaScript is bundled with µCSS -- behavior is the application's responsibility.
|
|
147
|
+
|
|
148
|
+
- **Open**: `document.getElementById('modal-id').showModal()`
|
|
149
|
+
- **Close**: `document.getElementById('modal-id').close()`
|
|
150
|
+
- **Backdrop click**: handled natively by `<dialog>` when opened via `.showModal()`
|
|
151
|
+
- **Escape key**: closes the dialog natively
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Accessibility
|
|
156
|
+
|
|
157
|
+
- Always include `aria-label="Close"` on the `.modal-close` button.
|
|
158
|
+
- The `.modal-close` button has a `:focus-visible` outline for keyboard navigation.
|
|
159
|
+
- Use `.showModal()` (not `.show()`) to get the modal backdrop and trap focus inside the dialog.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
→ [Voir l'exemple](../examples/modal.html)
|