actual-css 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -1
- package/README.md +24 -9
- package/dist/actual-themes.min.css +1 -0
- package/dist/actual.css +1532 -1114
- package/dist/actual.js +1 -3
- package/dist/actual.min.css +1 -1
- package/dist/optional.css +1048 -0
- package/dist/optional.min.css +1 -0
- package/docs/design-notes/browser-support.md +94 -14
- package/docs/design-notes/cascade-layer.md +7 -6
- package/docs/design-notes/enhancement-contract.md +11 -14
- package/docs/design-notes/forced-colors.md +105 -0
- package/docs/design-notes/naming.md +2 -1
- package/docs/design-notes/platform-alignment.md +492 -0
- package/docs/design-notes/references.md +8 -0
- package/docs/design-notes/widget-primitives.md +37 -1
- package/docs/navigation.json +135 -0
- package/docs/pages/components/accordion.md +80 -0
- package/docs/pages/components/alert.md +203 -0
- package/docs/pages/components/aura.md +35 -0
- package/docs/pages/components/avatar.md +95 -0
- package/docs/pages/components/badge.md +102 -0
- package/docs/pages/components/breadcrumb.md +19 -0
- package/docs/pages/components/button.md +210 -0
- package/docs/pages/components/card.md +195 -0
- package/docs/pages/components/chat.md +50 -0
- package/docs/pages/components/dialog.md +367 -0
- package/docs/pages/components/drawer.md +113 -0
- package/docs/pages/components/fab.md +118 -0
- package/docs/pages/components/key.md +33 -0
- package/docs/pages/components/meter.md +23 -0
- package/docs/pages/components/navbar.md +92 -0
- package/docs/pages/components/pagination.md +55 -0
- package/docs/pages/components/progress.md +29 -0
- package/docs/pages/components/skeleton.md +38 -0
- package/docs/pages/components/spinner.md +93 -0
- package/docs/pages/components/table.md +102 -0
- package/docs/pages/enhancements/flyout.md +391 -0
- package/docs/pages/enhancements/overview.md +36 -0
- package/docs/pages/enhancements/scrollspy.md +71 -0
- package/docs/pages/enhancements/status-bar.md +72 -0
- package/docs/pages/enhancements/tabs.md +80 -0
- package/docs/pages/enhancements/tooltip.md +130 -0
- package/docs/pages/examples/overview.md +43 -0
- package/docs/pages/forms/choice-cards.md +102 -0
- package/docs/pages/forms/controls.md +32 -0
- package/docs/pages/forms/detached-actions.md +59 -0
- package/docs/pages/forms/floating-field.md +88 -0
- package/docs/pages/forms/form-actions.md +56 -0
- package/docs/pages/forms/input-policy.md +91 -0
- package/docs/pages/forms/joined-controls.md +37 -0
- package/docs/pages/forms/labels.md +42 -0
- package/docs/pages/forms/otp.md +50 -0
- package/docs/pages/forms/overview.md +188 -0
- package/docs/pages/forms/password.md +40 -0
- package/docs/pages/forms/range.md +17 -0
- package/docs/pages/forms/states-and-sizes.md +321 -0
- package/docs/pages/forms/sticky-actions.md +187 -0
- package/docs/pages/forms/switch.md +31 -0
- package/docs/pages/forms/validation.md +241 -0
- package/docs/{mental-model.md → pages/foundations/philosophy.md} +33 -18
- package/docs/pages/foundations/theming.md +99 -0
- package/docs/pages/foundations/tokens.md +421 -0
- package/docs/{typography.md → pages/foundations/typography.md} +27 -9
- package/docs/pages/guides/bootstrap.md +438 -0
- package/docs/pages/guides/introduction.md +157 -0
- package/docs/pages/guides/optional-components.md +33 -0
- package/docs/pages/guides/progressive-enhancement.md +686 -0
- package/docs/pages/guides/tailwind.md +455 -0
- package/docs/pages/layout/app-shell.md +25 -0
- package/docs/pages/layout/center.md +29 -0
- package/docs/pages/layout/cluster.md +59 -0
- package/docs/pages/layout/frame.md +30 -0
- package/docs/pages/layout/grid.md +142 -0
- package/docs/pages/layout/list.md +41 -0
- package/docs/pages/layout/media.md +28 -0
- package/docs/pages/layout/overview.md +37 -0
- package/docs/pages/layout/scroll-snap.md +54 -0
- package/docs/pages/layout/sidebar-layout.md +27 -0
- package/docs/pages/layout/stack.md +55 -0
- package/docs/pages/layout/switcher.md +36 -0
- package/docs/pages/layout/topbar.md +23 -0
- package/docs/pages/patterns/actions.md +52 -0
- package/docs/pages/patterns/code-block.md +36 -0
- package/docs/pages/patterns/exclusive-accordion.md +16 -0
- package/docs/pages/patterns/hierarchical-nav.md +26 -0
- package/docs/pages/patterns/icon-input.md +25 -0
- package/docs/pages/patterns/intent-nesting.md +3 -0
- package/docs/pages/patterns/navigation-list.md +235 -0
- package/docs/pages/patterns/overview.md +58 -0
- package/docs/pages/patterns/structured-lists.md +47 -0
- package/docs/pages/utilities/accessibility.md +34 -0
- package/docs/pages/utilities/flex.md +105 -0
- package/docs/pages/utilities/links.md +18 -0
- package/docs/pages/utilities/list.md +32 -0
- package/docs/pages/utilities/overflow.md +43 -0
- package/docs/pages/utilities/overview.md +18 -0
- package/docs/pages/utilities/shape.md +25 -0
- package/docs/pages/utilities/sizing-wrapping.md +115 -0
- package/docs/pages/utilities/spacing.md +79 -0
- package/docs/pages/utilities/text.md +43 -0
- package/llms.txt +4 -4
- package/package.json +21 -12
- package/src/css/actual.css +16 -2
- package/src/css/base.css +3 -5
- package/src/css/components/accordion.css +18 -30
- package/src/css/components/actions.css +4 -1
- package/src/css/components/alert.css +139 -102
- package/src/css/components/avatar.css +16 -10
- package/src/css/components/badge.css +69 -42
- package/src/css/components/breadcrumb.css +7 -15
- package/src/css/components/busy.css +6 -0
- package/src/css/components/button.css +84 -34
- package/src/css/components/card.css +26 -38
- package/src/css/components/drawer.css +30 -13
- package/src/css/components/flyout.css +39 -109
- package/src/css/components/index.css +1 -0
- package/src/css/components/join.css +14 -2
- package/src/css/components/key.css +2 -0
- package/src/css/components/menu.css +125 -0
- package/src/css/components/meter.css +0 -23
- package/src/css/components/modal.css +162 -7
- package/src/css/components/navbar.css +30 -23
- package/src/css/components/overline.css +8 -9
- package/src/css/components/pagination.css +1 -1
- package/src/css/components/progress.css +8 -26
- package/src/css/components/skeleton.css +7 -0
- package/src/css/components/spinner.css +6 -7
- package/src/css/components/status-bar.css +15 -24
- package/src/css/components/surface.css +2 -8
- package/src/css/components/tab.css +19 -48
- package/src/css/components/table.css +7 -5
- package/src/css/components/tooltip.css +14 -7
- package/src/css/focus.css +14 -38
- package/src/css/forms/choice-card.css +13 -14
- package/src/css/forms/choice.css +21 -27
- package/src/css/forms/control.css +18 -17
- package/src/css/forms/custom-select.css +9 -11
- package/src/css/forms/form-actions.css +14 -3
- package/src/css/forms/form.css +7 -4
- package/src/css/forms/index.css +4 -4
- package/src/css/forms/input-icon.css +30 -12
- package/src/css/forms/native.css +50 -11
- package/src/css/forms/range.css +17 -9
- package/src/css/forms/select.css +8 -8
- package/src/css/forms/switch.css +14 -12
- package/src/css/forms/validation.css +32 -5
- package/src/css/grid.css +32 -18
- package/src/css/intents.css +2 -2
- package/src/css/layout.css +45 -2
- package/src/css/optional/aura.css +93 -0
- package/src/css/optional/chat.css +105 -0
- package/src/css/optional/fab.css +104 -0
- package/src/css/optional/floating-field.css +87 -0
- package/src/css/optional/index.css +5 -0
- package/src/css/optional/layout-extra.css +7 -4
- package/src/css/optional/otp.css +115 -0
- package/src/css/optional/scroll-snap.css +6 -0
- package/src/css/optional/scroller.css +13 -7
- package/src/css/optional/typography-fluid.css +5 -0
- package/src/css/optional/utilities-extra.css +17 -2
- package/src/css/prose.css +18 -8
- package/src/css/reset.css +0 -10
- package/src/css/theme.css +21 -5
- package/src/css/themes/cyberpunk.css +1 -1
- package/src/css/themes/dim.css +3 -3
- package/src/css/themes/edge.css +8 -10
- package/src/css/themes/index.css +8 -4
- package/src/css/themes/{dark.css → indigo.css} +5 -4
- package/src/css/themes/neon.css +5 -5
- package/src/css/themes/square.css +0 -3
- package/src/css/tokens.css +74 -20
- package/src/css/utilities.css +8 -10
- package/src/css/variants.css +51 -66
- package/src/js/command.js +1 -3
- package/src/js/context-menu.js +67 -35
- package/src/js/dialog.js +68 -79
- package/src/js/dismiss.js +15 -0
- package/src/js/enhance.js +54 -23
- package/src/js/enhancement-loader.js +301 -0
- package/src/js/events.js +3 -0
- package/src/js/filter.js +3 -3
- package/src/js/floating.js +101 -131
- package/src/js/flyout.js +104 -87
- package/src/js/focus-group.js +116 -0
- package/src/js/focus.js +6 -1
- package/src/js/index.js +4 -2
- package/src/js/input.js +1 -1
- package/src/js/keys.js +27 -0
- package/src/js/mask.js +7 -6
- package/src/js/menu.js +87 -34
- package/src/js/parse-config.js +47 -0
- package/src/js/password.js +9 -1
- package/src/js/scrollspy.js +12 -4
- package/src/js/selectors.js +0 -7
- package/src/js/status.js +3 -1
- package/src/js/surface.js +187 -136
- package/src/js/tab.js +36 -53
- package/src/js/tooltip.js +70 -35
- package/src/js/validation.js +34 -8
- package/dist/actual.js.map +0 -31
- package/docs/README.md +0 -28
- package/docs/components.md +0 -860
- package/docs/design-notes/previous-work.md +0 -5
- package/docs/forms.md +0 -1265
- package/docs/javascript.md +0 -496
- package/docs/layout.md +0 -480
- package/docs/patterns.md +0 -504
- package/docs/reserved.md +0 -7
- package/docs/tokens.md +0 -455
- package/docs/ui.md +0 -929
- package/docs/utilities.md +0 -384
- package/src/css/dialog-fallback.css +0 -56
- package/src/js/dialog-fallback.js +0 -163
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
# Migrating from Bootstrap to Actual CSS
|
|
2
|
+
|
|
3
|
+
This guide targets Bootstrap 5.x. Actual CSS is not a drop-in Bootstrap replacement, but many Bootstrap concepts have direct or close equivalents.
|
|
4
|
+
|
|
5
|
+
The main migration is:
|
|
6
|
+
|
|
7
|
+
**Bootstrap components → Actual components**
|
|
8
|
+
**Bootstrap grid and utilities → Actual layout primitives + small project CSS**
|
|
9
|
+
**Bootstrap JavaScript plugins → native HTML + Actual enhancements**
|
|
10
|
+
|
|
11
|
+
## Before you start: running both frameworks
|
|
12
|
+
|
|
13
|
+
Actual CSS and Bootstrap both use short global class names such as `.btn`, `.card`, `.alert`, and `.table`.
|
|
14
|
+
|
|
15
|
+
Do not assume both complete stylesheets can be loaded side by side without interaction.
|
|
16
|
+
|
|
17
|
+
For an incremental migration, use one of these approaches:
|
|
18
|
+
|
|
19
|
+
* migrate isolated pages or application areas;
|
|
20
|
+
* control precedence with cascade layers or import order;
|
|
21
|
+
* use a project-side prefix transform for Actual while both frameworks coexist.
|
|
22
|
+
|
|
23
|
+
The layered import is the cleanest way to keep both stylesheets during the
|
|
24
|
+
migration:
|
|
25
|
+
|
|
26
|
+
```css
|
|
27
|
+
/* Migration setup — Actual rules sit in @layer actual */
|
|
28
|
+
@import "bootstrap.css";
|
|
29
|
+
@import "actual-css/css/layer";
|
|
30
|
+
/* Unlayered project overrides stay on top */
|
|
31
|
+
@import "app.css";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`actual.layer.css` wraps every Actual rule in a single `@layer actual`, so
|
|
35
|
+
unlayered Bootstrap and project CSS keep precedence while the migration runs.
|
|
36
|
+
See [Cascade layer strategy](https://github.com/lekoala/actual-css/blob/master/docs/design-notes/cascade-layer.md) for the
|
|
37
|
+
limitations of the approach.
|
|
38
|
+
|
|
39
|
+
Remove the compatibility mechanism when Bootstrap is gone. The public Actual API remains unprefixed.
|
|
40
|
+
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
Many common Bootstrap components translate directly.
|
|
44
|
+
|
|
45
|
+
| Bootstrap | Actual CSS |
|
|
46
|
+
|----------------------------|-------------------------|
|
|
47
|
+
| `.btn .btn-primary` | `.btn .primary` |
|
|
48
|
+
| `.btn .btn-outline-danger` | `.btn .danger .outline` |
|
|
49
|
+
| `.btn .btn-sm` | `.btn .sm` |
|
|
50
|
+
| `.btn .btn-lg` | `.btn .lg` |
|
|
51
|
+
| `.badge` | `.badge` |
|
|
52
|
+
| `.alert` | `.alert` |
|
|
53
|
+
| `.card` | `.card` |
|
|
54
|
+
| `.table` | `.table` |
|
|
55
|
+
| `.spinner-*` | `.spinner` |
|
|
56
|
+
| `.breadcrumb` | `.breadcrumb` |
|
|
57
|
+
| `.pagination` | `.pagination` |
|
|
58
|
+
|
|
59
|
+
Bootstrap commonly combines the intent with the component name:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<button class="btn btn-primary btn-lg">Save</button>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Actual separates component, intent, variant, and size:
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<button class="btn primary lg">Save</button>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The same intent classes can be reused across compatible components:
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<button class="btn danger outline">Delete</button>
|
|
75
|
+
<span class="badge success soft">Active</span>
|
|
76
|
+
<div class="alert warning">Check these values.</div>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Do not mechanically translate every Bootstrap modifier. First check whether the distinction belongs to the component, the theme, or the surrounding layout.
|
|
80
|
+
|
|
81
|
+
## Forms
|
|
82
|
+
|
|
83
|
+
Bootstrap:
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<div class="mb-3">
|
|
87
|
+
<label class="form-label" for="email">Email</label>
|
|
88
|
+
<input class="form-control" id="email" type="email">
|
|
89
|
+
</div>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Actual:
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<label class="field">
|
|
96
|
+
<span class="field-label">Email</span>
|
|
97
|
+
<input class="input" type="email">
|
|
98
|
+
</label>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Common translations include:
|
|
102
|
+
|
|
103
|
+
| Bootstrap | Actual CSS |
|
|
104
|
+
|-------------------------------|--------------------------------|
|
|
105
|
+
| `.form-control` on an input | `.input` |
|
|
106
|
+
| `.form-control` on a textarea | `.textarea` |
|
|
107
|
+
| `.form-select` | `.select` |
|
|
108
|
+
| checkbox | `.check` |
|
|
109
|
+
| radio | `.radio` |
|
|
110
|
+
| `.form-switch` | `.switch` |
|
|
111
|
+
| validation feedback | `.field-error` / `.field-help` |
|
|
112
|
+
| grouped actions | `.form-actions` |
|
|
113
|
+
|
|
114
|
+
Actual uses explicit control classes instead of one generic `.form-control`.
|
|
115
|
+
|
|
116
|
+
Floating labels do not have a built-in Actual component. Keep them as project CSS if the design requires them.
|
|
117
|
+
|
|
118
|
+
## Replace rows and columns with layout intent
|
|
119
|
+
|
|
120
|
+
Bootstrap's twelve-column grid does not have a one-to-one equivalent.
|
|
121
|
+
|
|
122
|
+
A Bootstrap layout such as:
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<div class="row g-4">
|
|
126
|
+
<div class="col-12 col-md-6">...</div>
|
|
127
|
+
<div class="col-12 col-md-6">...</div>
|
|
128
|
+
</div>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
usually becomes an Actual grid:
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<div class="container-query">
|
|
135
|
+
<div class="grid-2">
|
|
136
|
+
<div>...</div>
|
|
137
|
+
<div>...</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Or use the intrinsic grid when the real requirement is simply “fit as many useful columns as there is room for”:
|
|
143
|
+
|
|
144
|
+
```html
|
|
145
|
+
<div class="grid" style="--grid-min: 18rem">
|
|
146
|
+
...
|
|
147
|
+
</div>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For asymmetric layouts, express the layout directly:
|
|
151
|
+
|
|
152
|
+
```html
|
|
153
|
+
<div class="dashboard-grid grid">
|
|
154
|
+
...
|
|
155
|
+
</div>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```css
|
|
159
|
+
.dashboard-grid {
|
|
160
|
+
--grid-columns: minmax(0, 2fr) minmax(0, 1fr);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@container (width < 48rem) {
|
|
164
|
+
.dashboard-grid {
|
|
165
|
+
--grid-columns: 1fr;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
This is intentionally different from recreating `col-md-8 col-md-4`.
|
|
171
|
+
|
|
172
|
+
If your Bootstrap markup uses offsets, ordering, and several breakpoint-specific column widths, expect to write some project CSS during migration.
|
|
173
|
+
|
|
174
|
+
## Translate flex utility clusters into layout primitives
|
|
175
|
+
|
|
176
|
+
Bootstrap:
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<div class="d-flex align-items-center justify-content-between gap-3">
|
|
180
|
+
...
|
|
181
|
+
</div>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Actual:
|
|
185
|
+
|
|
186
|
+
```html
|
|
187
|
+
<div class="cluster">
|
|
188
|
+
...
|
|
189
|
+
</div>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Tune the primitive when necessary:
|
|
193
|
+
|
|
194
|
+
```html
|
|
195
|
+
<div
|
|
196
|
+
class="cluster"
|
|
197
|
+
style="--cluster-justify: space-between; --cluster-align: center"
|
|
198
|
+
>
|
|
199
|
+
...
|
|
200
|
+
</div>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
For vertical flows:
|
|
204
|
+
|
|
205
|
+
```html
|
|
206
|
+
<div class="stack">
|
|
207
|
+
...
|
|
208
|
+
</div>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Think in terms of the relationship between children rather than translating each CSS declaration into another class.
|
|
212
|
+
|
|
213
|
+
Typical choices are:
|
|
214
|
+
|
|
215
|
+
| Bootstrap pattern | Actual approach |
|
|
216
|
+
|--------------------------------------------|--------------------------------------------|
|
|
217
|
+
| flex row that may wrap | `.cluster` |
|
|
218
|
+
| vertical flex stack | `.stack` |
|
|
219
|
+
| equal columns | `.grid-2`, `.grid-3`, `.grid-4`, `.grid-6` |
|
|
220
|
+
| intrinsically responsive cards | `.grid` |
|
|
221
|
+
| row that becomes a column when constrained | `.switcher` |
|
|
222
|
+
| sidebar/content layout | `.sidebar-layout` |
|
|
223
|
+
| readable centered content | `.center`, `.measure` |
|
|
224
|
+
|
|
225
|
+
## Do not recreate Bootstrap's utility API
|
|
226
|
+
|
|
227
|
+
Bootstrap offers responsive utilities for spacing, display, flexbox, visibility, sizing, and many other properties.
|
|
228
|
+
|
|
229
|
+
Actual deliberately does not provide an equivalent utility for every declaration.
|
|
230
|
+
|
|
231
|
+
For example:
|
|
232
|
+
|
|
233
|
+
```html
|
|
234
|
+
<div class="d-none d-lg-flex mt-4 px-3 text-end">
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
should not become a collection of newly invented Actual classes.
|
|
238
|
+
|
|
239
|
+
Keep Actual helpers for common composition needs and put application-specific behavior in project CSS:
|
|
240
|
+
|
|
241
|
+
```html
|
|
242
|
+
<div class="account-actions">
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```css
|
|
246
|
+
.account-actions {
|
|
247
|
+
display: none;
|
|
248
|
+
margin-block-start: var(--space-40);
|
|
249
|
+
padding-inline: var(--space-30);
|
|
250
|
+
text-align: end;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
@media (width >= 64rem) {
|
|
254
|
+
.account-actions {
|
|
255
|
+
display: flex;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
This is especially relevant for:
|
|
261
|
+
|
|
262
|
+
* breakpoint-specific display;
|
|
263
|
+
* responsive ordering;
|
|
264
|
+
* unusual widths and positioning;
|
|
265
|
+
* decorative text/background colors;
|
|
266
|
+
* one-off spacing combinations.
|
|
267
|
+
|
|
268
|
+
> **Need something more specific?**
|
|
269
|
+
>
|
|
270
|
+
> 1. Tune the component or layout primitive with a public custom property.
|
|
271
|
+
> 2. Compose an Actual layout primitive.
|
|
272
|
+
> 3. Add a project class for application-specific CSS.
|
|
273
|
+
> 4. Only reach for an optional utility when the rule is genuinely generic.
|
|
274
|
+
|
|
275
|
+
Actual deliberately keeps its utility surface small and grows it only for needs
|
|
276
|
+
that recur across real migrations — a one-off is project CSS, not a new
|
|
277
|
+
framework class.
|
|
278
|
+
|
|
279
|
+
## JavaScript components
|
|
280
|
+
|
|
281
|
+
Do not translate `data-bs-*` attributes mechanically. Actual generally starts from native platform behavior and adds enhancement only where useful.
|
|
282
|
+
|
|
283
|
+
### Modal
|
|
284
|
+
|
|
285
|
+
Bootstrap:
|
|
286
|
+
|
|
287
|
+
```html
|
|
288
|
+
<button
|
|
289
|
+
data-bs-toggle="modal"
|
|
290
|
+
data-bs-target="#settings"
|
|
291
|
+
>
|
|
292
|
+
Settings
|
|
293
|
+
</button>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Actual:
|
|
297
|
+
|
|
298
|
+
```html
|
|
299
|
+
<button
|
|
300
|
+
type="button"
|
|
301
|
+
command="show-modal"
|
|
302
|
+
commandfor="settings"
|
|
303
|
+
aria-haspopup="dialog"
|
|
304
|
+
aria-controls="settings"
|
|
305
|
+
>
|
|
306
|
+
Settings
|
|
307
|
+
</button>
|
|
308
|
+
|
|
309
|
+
<dialog class="modal" id="settings">
|
|
310
|
+
...
|
|
311
|
+
</dialog>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Offcanvas
|
|
315
|
+
|
|
316
|
+
Use a native dialog with the `.drawer` component.
|
|
317
|
+
|
|
318
|
+
```html
|
|
319
|
+
<button
|
|
320
|
+
type="button"
|
|
321
|
+
command="show-modal"
|
|
322
|
+
commandfor="navigation"
|
|
323
|
+
aria-haspopup="dialog"
|
|
324
|
+
aria-controls="navigation"
|
|
325
|
+
>
|
|
326
|
+
Menu
|
|
327
|
+
</button>
|
|
328
|
+
|
|
329
|
+
<dialog class="drawer" id="navigation">
|
|
330
|
+
...
|
|
331
|
+
</dialog>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Dropdown
|
|
335
|
+
|
|
336
|
+
Bootstrap dropdowns normally migrate to an Actual flyout.
|
|
337
|
+
|
|
338
|
+
### Tabs
|
|
339
|
+
|
|
340
|
+
Bootstrap's tab plugin normally migrates to `.tabs` / `.tab` markup with the tabs enhancer.
|
|
341
|
+
|
|
342
|
+
### Tooltip and scrollspy
|
|
343
|
+
|
|
344
|
+
Actual provides dedicated enhancements for both.
|
|
345
|
+
|
|
346
|
+
The important difference is architectural: presentation classes and behavior are separate. `data-enhance` opts an element into Actual behavior instead of making every styled component implicitly dependent on a JavaScript plugin.
|
|
347
|
+
|
|
348
|
+
## Navbar migration
|
|
349
|
+
|
|
350
|
+
A Bootstrap responsive navbar often combines several responsibilities:
|
|
351
|
+
|
|
352
|
+
* horizontal navigation;
|
|
353
|
+
* breakpoint logic;
|
|
354
|
+
* collapse;
|
|
355
|
+
* toggler state;
|
|
356
|
+
* optionally offcanvas behavior.
|
|
357
|
+
|
|
358
|
+
Actual's navbar is intentionally a simpler navigation pattern.
|
|
359
|
+
|
|
360
|
+
Keep the desktop navigation as a navbar and compose the mobile experience from a
|
|
361
|
+
drawer or flyout rather than looking for a `.navbar-expand-lg` equivalent:
|
|
362
|
+
|
|
363
|
+
* desktop → `.navbar` with `.navbar-nav`;
|
|
364
|
+
* mobile → `.drawer` with `.nav-list`;
|
|
365
|
+
* trigger → a `command="show-modal"` / `commandfor` button.
|
|
366
|
+
|
|
367
|
+
The [Navbar component page](../components/navbar.md) shows this composition
|
|
368
|
+
as *the Actual way*: a horizontal `.navbar-nav` on the desktop bar and a vertical
|
|
369
|
+
`.nav-list` inside the mobile drawer, opened with the native dialog command
|
|
370
|
+
pattern. There is no collapse/toggler state to keep in sync.
|
|
371
|
+
|
|
372
|
+
This usually produces simpler behavior, but it is not a class-for-class migration.
|
|
373
|
+
|
|
374
|
+
## Components without a direct replacement
|
|
375
|
+
|
|
376
|
+
Do not expect complete Bootstrap widget parity.
|
|
377
|
+
|
|
378
|
+
For specialized widgets, first decide whether they are still needed, can use a native platform primitive, or should remain application code.
|
|
379
|
+
|
|
380
|
+
Examples that may require a different solution include:
|
|
381
|
+
|
|
382
|
+
* carousels;
|
|
383
|
+
* toast-style transient notifications;
|
|
384
|
+
* generic arbitrary collapse regions;
|
|
385
|
+
* Bootstrap-specific popover behavior.
|
|
386
|
+
|
|
387
|
+
A flyout may replace many popover-style interactive surfaces, but it is not intended as API compatibility with Bootstrap Popover.
|
|
388
|
+
|
|
389
|
+
## Themes and Sass customization
|
|
390
|
+
|
|
391
|
+
If your Bootstrap project mainly customizes Sass variables and theme maps, move stable design decisions into Actual theme tokens and public hooks.
|
|
392
|
+
|
|
393
|
+
Instead of generating additional framework classes such as:
|
|
394
|
+
|
|
395
|
+
```text
|
|
396
|
+
$theme-colors: map-merge(...);
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
prefer project tokens:
|
|
400
|
+
|
|
401
|
+
```css
|
|
402
|
+
:root {
|
|
403
|
+
--primary: ...;
|
|
404
|
+
--radius: ...;
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
and semantic project CSS where a value is application-specific.
|
|
409
|
+
|
|
410
|
+
Do not rebuild Bootstrap's generated utility matrix on top of Actual.
|
|
411
|
+
|
|
412
|
+
## Recommended migration order
|
|
413
|
+
|
|
414
|
+
1. Establish a safe coexistence strategy if both stylesheets must temporarily remain.
|
|
415
|
+
2. Migrate buttons, badges, alerts, cards, and basic content components.
|
|
416
|
+
3. Migrate forms.
|
|
417
|
+
4. Replace Bootstrap JavaScript widgets with native HTML and Actual enhancements.
|
|
418
|
+
5. Replace repeated flex utility clusters with layout primitives.
|
|
419
|
+
6. Migrate the Bootstrap grid.
|
|
420
|
+
7. Replace the remaining utility-heavy markup with small semantic project classes.
|
|
421
|
+
8. Remove Bootstrap and any temporary prefix or cascade compatibility layer.
|
|
422
|
+
|
|
423
|
+
## Where migration is genuinely harder
|
|
424
|
+
|
|
425
|
+
Expect additional work when the application relies heavily on:
|
|
426
|
+
|
|
427
|
+
* twelve-column grid arithmetic;
|
|
428
|
+
* offsets and breakpoint-specific ordering;
|
|
429
|
+
* extensive responsive utility combinations;
|
|
430
|
+
* Bootstrap navbar collapse behavior;
|
|
431
|
+
* floating labels — covered by the optional `.floating-field` module, so the
|
|
432
|
+
cost is an import rather than a custom recipe;
|
|
433
|
+
* specialized Bootstrap JavaScript plugins;
|
|
434
|
+
* Sass-generated application utility classes.
|
|
435
|
+
|
|
436
|
+
Those are real migration costs, not syntax differences.
|
|
437
|
+
|
|
438
|
+
For component-oriented application UI, however, most Bootstrap usage maps naturally to Actual components, layouts, tokens, and enhancements.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Introduction
|
|
2
|
+
|
|
3
|
+
> Actual CSS is a plain CSS component framework for new projects — semantic classes, small tokens, universal variants, theme hooks, and progressive enhancement, with no build step and no framework dependency.
|
|
4
|
+
|
|
5
|
+
Actual CSS claims a small set of global class names and keeps everything opt-in:
|
|
6
|
+
components define structure, variants change the style, and intents set the
|
|
7
|
+
color. It is designed for new projects and works as-is in existing ones through
|
|
8
|
+
cascade layers, import order, or an optional prefix transform.
|
|
9
|
+
|
|
10
|
+
## CSS-first philosophy
|
|
11
|
+
|
|
12
|
+
- CSS owns layout, surfaces, state styling, and transitions.
|
|
13
|
+
- JavaScript is optional and completes the interactive components — dialog,
|
|
14
|
+
flyout, tooltip, tabs, scrollspy, status bar, and more.
|
|
15
|
+
- Semantic markup comes first; behavior is a progressive enhancement layered on
|
|
16
|
+
top of it.
|
|
17
|
+
- Prefer native platform features when they fit, with small helpers where
|
|
18
|
+
browser support or ergonomics need it.
|
|
19
|
+
- Markup stays understandable without JavaScript, and modern features are gated
|
|
20
|
+
with `@supports` so older browsers keep the core layout and controls.
|
|
21
|
+
|
|
22
|
+
The distinction is structural, not stylistic: presentation lives in classes,
|
|
23
|
+
JavaScript behavior opts in through `data-enhance` tokens, semantics come from
|
|
24
|
+
ARIA and native HTML, and per-widget configuration uses self-describing
|
|
25
|
+
`data-*` attributes.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
npm install actual-css
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Import the full framework in your CSS:
|
|
34
|
+
|
|
35
|
+
```css
|
|
36
|
+
@import "actual-css";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or compose only the pieces you use:
|
|
40
|
+
|
|
41
|
+
```css
|
|
42
|
+
@import "actual-css/css/reset";
|
|
43
|
+
@import "actual-css/css/base";
|
|
44
|
+
@import "actual-css/css/tokens";
|
|
45
|
+
@import "actual-css/css/theme";
|
|
46
|
+
@import "actual-css/css/intents";
|
|
47
|
+
@import "actual-css/css/variants";
|
|
48
|
+
@import "actual-css/css/layout";
|
|
49
|
+
@import "actual-css/css/grid";
|
|
50
|
+
@import "actual-css/css/forms";
|
|
51
|
+
@import "actual-css/css/components/button";
|
|
52
|
+
@import "actual-css/css/components/card";
|
|
53
|
+
@import "actual-css/css/components/flyout";
|
|
54
|
+
@import "actual-css/css/utilities";
|
|
55
|
+
/* Keep the focus baseline after components and controls. */
|
|
56
|
+
@import "actual-css/css/focus";
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`focus` is the final interactive baseline in modular builds: older browsers
|
|
60
|
+
retain a visible `:focus` outline, while browsers with `:focus-visible` avoid
|
|
61
|
+
showing it for pointer focus.
|
|
62
|
+
|
|
63
|
+
You can also use the compiled file directly:
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<link rel="stylesheet" href="actual.min.css">
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The package does not maintain separate partial bundles. Modular entrypoints map
|
|
70
|
+
to source files, so each project composes the framework shape it needs.
|
|
71
|
+
|
|
72
|
+
## Class grammar
|
|
73
|
+
|
|
74
|
+
Actual CSS uses a small unprefixed class grammar:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
.component [intent] [variant] [size] [modifier]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Intents are `.primary`, `.secondary`, `.success`, `.warning`, and `.danger`, and
|
|
81
|
+
work across components. Variants such as `.solid`, `.soft`, and `.outline` are
|
|
82
|
+
shared by buttons, badges, alerts, and cards; `.inverted` is a shared surface
|
|
83
|
+
modifier that paints any block with the inverse surface. `.ghost` and `.link`
|
|
84
|
+
are button-only. Size variants `.sm` and `.lg` scale controls consistently.
|
|
85
|
+
Undocumented `is-*` classes are runtime internals.
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<button class="btn">Click me</button>
|
|
89
|
+
<button class="btn primary">Save</button>
|
|
90
|
+
<button class="btn primary outline lg">Publish</button>
|
|
91
|
+
<button class="btn success soft sm">Confirm</button>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## The JavaScript runtime
|
|
95
|
+
|
|
96
|
+
Some components can be enhanced with JavaScript: dialog, drawer, flyout,
|
|
97
|
+
tooltip, tabs, scrollspy, context menu, floating UI, opt-in `data-filter` input
|
|
98
|
+
filtering, and input masks. Presentation and behavior are separate layers —
|
|
99
|
+
import the full runtime or any primitive independently to build custom widgets.
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<script src="actual.js" type="module"></script>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
import "actual-css/js/dialog";
|
|
107
|
+
import "actual-css/js/flyout";
|
|
108
|
+
import "actual-css/js/filter";
|
|
109
|
+
import "actual-css/js/mask";
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
JavaScript modules are safe to import during server-side rendering; outside a
|
|
113
|
+
browser, registration is a no-op. The complete runtime contract — lifecycle
|
|
114
|
+
rules, command routing, the floating and surface contracts, and how to extend
|
|
115
|
+
the runtime — is documented in [The JavaScript Runtime guide](progressive-enhancement.md).
|
|
116
|
+
|
|
117
|
+
## API surface
|
|
118
|
+
|
|
119
|
+
- **Layout** — the layout primitives: stack, cluster, grid, switcher, center,
|
|
120
|
+
media, frame, app-shell, sidebar-layout, and more. See the
|
|
121
|
+
[Layout overview](../layout/overview.md).
|
|
122
|
+
- **Components** — native and CSS-only component classes and examples: button,
|
|
123
|
+
card, badge, alert, table, accordion, breadcrumb, pagination, skeleton,
|
|
124
|
+
spinner, avatar, key, meter, progress, navbar, and more. Each component has
|
|
125
|
+
its own page.
|
|
126
|
+
- **Forms** — field layout, controls, validation states, switches, selects,
|
|
127
|
+
custom selects, and form actions. See the
|
|
128
|
+
[Forms overview](../forms/overview.md).
|
|
129
|
+
- **Enhancements** — JS-enhanced component behavior: flyout, tooltip, tabs,
|
|
130
|
+
scrollspy, and the status bar, each with its own page. See the
|
|
131
|
+
[Enhancements overview](../enhancements/overview.md).
|
|
132
|
+
- **Guides** — [Migrating from Bootstrap](bootstrap.md) and
|
|
133
|
+
[Migrating from Tailwind](tailwind.md) walk through moving an existing
|
|
134
|
+
project; [The JavaScript Runtime](progressive-enhancement.md) documents the
|
|
135
|
+
optional runtime that completes interactive components.
|
|
136
|
+
|
|
137
|
+
Beyond the pages, the repository keeps its design notes — browser support,
|
|
138
|
+
cascade layers, naming, the enhancement contract, and widget primitives — as
|
|
139
|
+
internal design documents for contributors.
|
|
140
|
+
|
|
141
|
+
## Browser support
|
|
142
|
+
|
|
143
|
+
Actual CSS is built around progressive enhancement.
|
|
144
|
+
|
|
145
|
+
| Tier | Firefox | Safari | Chromium |
|
|
146
|
+
|---|---|---|---|
|
|
147
|
+
| Degraded | 78+ | 14+ | 88+ |
|
|
148
|
+
| **Minimal** | **98+** | **15.4+** | **99+** |
|
|
149
|
+
| Intermediate | 121+ | 16+ | 106+ |
|
|
150
|
+
| Recommended | 129+ | 17.5+ | 123+ |
|
|
151
|
+
|
|
152
|
+
**Degraded** — semantic HTML and core CSS remain usable. JavaScript
|
|
153
|
+
enhancements are outside the supported contract.
|
|
154
|
+
|
|
155
|
+
**Minimal** — full Actual support, including the JavaScript runtime. The
|
|
156
|
+
runtime assumes modern browser APIs and ships no legacy compatibility layers or
|
|
157
|
+
polyfills.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Optional components
|
|
2
|
+
|
|
3
|
+
Optional components extend Actual with specialized patterns while keeping the
|
|
4
|
+
same tokens, intents, variants, and density grammar as the core. They add no
|
|
5
|
+
global design tokens and require no JavaScript.
|
|
6
|
+
|
|
7
|
+
Import the complete optional layer after the core:
|
|
8
|
+
|
|
9
|
+
```css
|
|
10
|
+
@import "actual-css/css";
|
|
11
|
+
@import "actual-css/css/optional";
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`actual-css/css/optional` resolves to the minified optional bundle
|
|
15
|
+
(`dist/optional.min.css`). Alternatively, import only the modules a project
|
|
16
|
+
uses from the source tree:
|
|
17
|
+
|
|
18
|
+
```css
|
|
19
|
+
@import "actual-css/css/optional/fab";
|
|
20
|
+
@import "actual-css/css/optional/floating-field";
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
| Module | Use | Import | Documentation |
|
|
24
|
+
|---|---|---|---|
|
|
25
|
+
| OTP | One native one-time-code input with visual cells | `actual-css/css/optional/otp` | [OTP](../forms/otp.md) |
|
|
26
|
+
| Chat | Start/end message rows and bubbles | `actual-css/css/optional/chat` | [Chat](../components/chat.md) |
|
|
27
|
+
| Aura | Decorative intent-colored frame and glow | `actual-css/css/optional/aura` | [Aura](../components/aura.md) |
|
|
28
|
+
| FAB | Fixed action placement and native speed dial | `actual-css/css/optional/fab` | [FAB](../components/fab.md) |
|
|
29
|
+
| Floating field | Floating labels over the text controls | `actual-css/css/optional/floating-field` | [Floating labels](../forms/floating-field.md) |
|
|
30
|
+
|
|
31
|
+
Component-prefixed custom properties documented on each page are author hooks.
|
|
32
|
+
Color and sizing otherwise stay with the existing intent, variant, control,
|
|
33
|
+
and button APIs.
|