actual-css 0.11.1 → 0.12.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/CHANGELOG.md +47 -0
- package/README.md +26 -6
- package/components.json +4 -16
- package/dist/actual.full.css +296 -267
- package/dist/actual.full.min.css +1 -1
- package/docs/brand/favicon.svg +5 -0
- package/docs/brand/lockup.svg +12 -0
- package/docs/brand/logo-dark.svg +9 -0
- package/docs/brand/logo-light.svg +9 -0
- package/docs/brand/logo.svg +11 -0
- package/docs/brand/mark.svg +11 -0
- package/docs/navigation.json +3 -2
- package/docs/pages/components/alert.md +2 -10
- package/docs/pages/components/badge.md +3 -9
- package/docs/pages/components/card.md +31 -2
- package/docs/pages/components/dialog.md +121 -33
- package/docs/pages/components/drawer.md +2 -2
- package/docs/pages/components/navbar.md +8 -9
- package/docs/pages/components/table.md +3 -3
- package/docs/pages/enhancements/flyout.md +2 -2
- package/docs/pages/enhancements/scrollspy.md +1 -1
- package/docs/pages/enhancements/status-bar.md +2 -2
- package/docs/pages/examples/overview.md +2 -1
- package/docs/pages/forms/date-picker.md +90 -0
- package/docs/pages/forms/detached-actions.md +37 -30
- package/docs/pages/forms/form-actions.md +61 -28
- package/docs/pages/forms/input-policy.md +1 -1
- package/docs/pages/forms/overview.md +6 -5
- package/docs/pages/forms/sticky-actions.md +85 -83
- package/docs/pages/forms/validation.md +5 -5
- package/docs/pages/foundations/philosophy.md +5 -3
- package/docs/pages/foundations/theming.md +15 -4
- package/docs/pages/foundations/tokens.md +50 -33
- package/docs/pages/foundations/typography.md +4 -7
- package/docs/pages/guides/bootstrap.md +2 -2
- package/docs/pages/guides/design-tools.md +2 -2
- package/docs/pages/guides/integrating-actual-css.md +5 -1
- package/docs/pages/guides/introduction.md +3 -4
- package/docs/pages/guides/modular-import.md +3 -0
- package/docs/pages/guides/progressive-enhancement.md +2 -2
- package/docs/pages/guides/tailwind.md +70 -0
- package/docs/pages/guides/upgrading.md +74 -0
- package/docs/pages/layout/cluster.md +28 -2
- package/docs/pages/layout/overview.md +1 -1
- package/docs/pages/layout/stack.md +21 -16
- package/docs/pages/layout/topbar.md +1 -1
- package/docs/pages/patterns/navigation-list.md +16 -46
- package/docs/pages/patterns/overview.md +3 -4
- package/docs/pages/utilities/flex.md +30 -20
- package/docs/pages/utilities/sizing-wrapping.md +1 -1
- package/docs/pages/utilities/spacing.md +4 -3
- package/package.json +2 -2
- package/reserved-classes.json +3 -3
- package/skills/actual-css/references/enhancements.md +10 -7
- package/src/cli/actual-css.js +39 -13
- package/src/css/components/avatar.css +16 -9
- package/src/css/components/badge.css +1 -5
- package/src/css/components/button.css +3 -9
- package/src/css/components/card.css +18 -10
- package/src/css/components/chat.css +4 -5
- package/src/css/components/drawer.css +19 -3
- package/src/css/components/flyout.css +3 -0
- package/src/css/components/index.css +0 -1
- package/src/css/components/modal.css +96 -124
- package/src/css/components/navbar.css +14 -25
- package/src/css/core/base.css +1 -1
- package/src/css/core/reset.css +2 -1
- package/src/css/core/theme.css +4 -0
- package/src/css/core/tokens.css +28 -10
- package/src/css/core/variants.css +41 -14
- package/src/css/forms/form-actions.css +15 -10
- package/src/css/layout/cluster.css +11 -0
- package/src/css/layout/topbar.css +12 -6
- package/src/css/utilities/base.css +5 -0
- package/src/css/utilities/extra.css +3 -7
- package/src/tooling/color.js +65 -0
- package/src/tooling/design-tokens.js +9 -1
- package/src/tooling/theme-contrast.js +209 -0
- package/docs/pages/patterns/actions.md +0 -52
- package/src/css/components/actions.css +0 -27
|
@@ -14,7 +14,7 @@ rest show it composed, isolated, or under stress.
|
|
|
14
14
|
|
|
15
15
|
### Start here
|
|
16
16
|
|
|
17
|
-
- [Visual guide](../../demo/templates/visual-guide.html) -
|
|
17
|
+
- [Visual guide](../../demo/templates/visual-guide.html) - twenty illustrated figures on the spacing scale, the layout primitives, and rhythm versus density versus local size
|
|
18
18
|
- [Color guide](../../demo/templates/color-guide.html) - theming principles measured live on `ocean` and `sunset`, in light and dark, as `data-theme` islands
|
|
19
19
|
- [Kitchen sink](../../demo/templates/kitchen-sink.html) - one-screen test bed for themes, scopes, variants and interactions
|
|
20
20
|
|
|
@@ -60,6 +60,7 @@ extension points.
|
|
|
60
60
|
|
|
61
61
|
- [Data grid](../../demo/templates/data-grid.html) - an external data grid component themed with Actual tokens (sort, filter, search, selection)
|
|
62
62
|
- [Combobox](../../demo/templates/combobox.html) - an external combobox themed with Actual tokens (search, tags, autocomplete)
|
|
63
|
+
- [Date fields](../../demo/templates/date-fields.html) - a native date input, a masked text field and an external date picker on Actual tokens, side by side
|
|
63
64
|
|
|
64
65
|
## Sites
|
|
65
66
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Date picker
|
|
2
|
+
|
|
3
|
+
> A JavaScript date picker is not shipped by the framework — the native `<input type="date">` stays the baseline. Use `data-mask` for a fixed text shape, or theme an external picker with Actual tokens.
|
|
4
|
+
|
|
5
|
+
The native control is the default: a real calendar, no JavaScript, and an ISO
|
|
6
|
+
`yyyy-mm-dd` value whatever the platform displays. Reach for an external picker
|
|
7
|
+
only when the product needs a shape the native control cannot express — a month
|
|
8
|
+
grid for a range, a typed constraint, a styled calendar.
|
|
9
|
+
|
|
10
|
+
**Related terms:** date field, datepicker, calendar, native date, date input, masked date, input mask, date range.
|
|
11
|
+
|
|
12
|
+
## Native baseline
|
|
13
|
+
|
|
14
|
+
```html demo
|
|
15
|
+
<label class="field">
|
|
16
|
+
<span class="field-label">Start date</span>
|
|
17
|
+
<input class="input" type="date" />
|
|
18
|
+
</label>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Masked text field
|
|
22
|
+
|
|
23
|
+
`data-mask` structures a plain text field to a fixed shape and the `date` rule
|
|
24
|
+
validates meaning. The mask enforces shape, not validity, so `2026-13-40` needs
|
|
25
|
+
the rule (or server validation).
|
|
26
|
+
|
|
27
|
+
```html demo
|
|
28
|
+
<label class="field">
|
|
29
|
+
<span class="field-label">Date</span>
|
|
30
|
+
<input class="input" data-mask="9999-99-99" inputmode="numeric" autocomplete="off" placeholder="yyyy-mm-dd" />
|
|
31
|
+
</label>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Theme bridge
|
|
35
|
+
|
|
36
|
+
The [date fields template](../../demo/templates/date-fields.html) puts the native
|
|
37
|
+
control, the masked field and
|
|
38
|
+
[`@lekoala/date-picker`](https://github.com/lekoala/date-picker) side by side, the
|
|
39
|
+
picker skinned entirely with Actual tokens.
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<label class="field">
|
|
43
|
+
<span class="field-label">Booking date</span>
|
|
44
|
+
<date-picker value="2026-09-25" open-on-focus="false">
|
|
45
|
+
<input class="input" name="date">
|
|
46
|
+
</date-picker>
|
|
47
|
+
</label>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```css
|
|
51
|
+
date-picker,
|
|
52
|
+
date-calendar {
|
|
53
|
+
--dp-bg: var(--surface-raised);
|
|
54
|
+
--dp-fg: var(--text);
|
|
55
|
+
--dp-muted: var(--text-muted);
|
|
56
|
+
--dp-border: var(--border);
|
|
57
|
+
--dp-hover: var(--surface-subtle);
|
|
58
|
+
--dp-accent: var(--primary);
|
|
59
|
+
--dp-accent-fg: var(--primary-fg);
|
|
60
|
+
--dp-radius: var(--radius);
|
|
61
|
+
/* Trigger glyph on the select chevron axis. */
|
|
62
|
+
--dp-picker-button-size: calc(var(--control-pad-x) * 2 + 1em + var(--border-width) * 2);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.dp-calendar-header :where(button, select, input):focus-visible {
|
|
66
|
+
border-color: var(--dp-border);
|
|
67
|
+
outline: var(--focus-ring-width) solid var(--focus);
|
|
68
|
+
outline-offset: calc(var(--focus-ring-width) * -1);
|
|
69
|
+
box-shadow: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.dp-picker-button:focus-visible,
|
|
73
|
+
.dp-day:focus-visible {
|
|
74
|
+
outline-color: var(--focus);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The field is a plain `.input`, so the core inset focus outline already outranks
|
|
79
|
+
the library's halo; the calendar's own controls paint a `--dp-accent` halo, so
|
|
80
|
+
the two focus rules map them onto the core outline. The calendar popup is its own
|
|
81
|
+
element, so the `--dp-*` map is declared on `date-picker`/`date-calendar` rather
|
|
82
|
+
than inherited from a wrapper.
|
|
83
|
+
As with the combobox, the bridge stays in docs/demo — it is a recipe, not package
|
|
84
|
+
API, and pins no widget version.
|
|
85
|
+
|
|
86
|
+
## Which one?
|
|
87
|
+
|
|
88
|
+
- A plain date the platform can collect: native `<input type="date">`.
|
|
89
|
+
- A fixed text format that must survive as typed text: `data-mask` plus the `date` rule.
|
|
90
|
+
- A calendar, range, or constraint the native control cannot express: an external picker on the token bridge.
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
The simplest case stays inside the form.
|
|
6
6
|
|
|
7
7
|
```html
|
|
8
|
-
<form novalidate>
|
|
8
|
+
<form class="stack" novalidate>
|
|
9
9
|
<div class="stack">
|
|
10
10
|
<!-- fields -->
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
|
-
<div class="form-actions">
|
|
13
|
+
<div class="cluster form-actions">
|
|
14
14
|
<button type="button" class="btn outline">Cancel</button>
|
|
15
15
|
<button type="submit" class="btn primary">Save changes</button>
|
|
16
16
|
</div>
|
|
@@ -20,40 +20,47 @@ The simplest case stays inside the form.
|
|
|
20
20
|
For sticky page footers, dialog footers, card footers, and split layouts, detach the actions and connect the submit button with `form="<id>"`.
|
|
21
21
|
|
|
22
22
|
```html
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
</
|
|
23
|
+
<div class="stack">
|
|
24
|
+
<form id="profile-form" novalidate>
|
|
25
|
+
<div class="stack">
|
|
26
|
+
<!-- long form fields -->
|
|
27
|
+
</div>
|
|
28
|
+
</form>
|
|
28
29
|
|
|
29
|
-
<footer class="form-actions">
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
</footer>
|
|
30
|
+
<footer class="cluster form-actions">
|
|
31
|
+
<button type="button" class="btn outline">Cancel</button>
|
|
32
|
+
<button type="submit" class="btn primary" form="profile-form">
|
|
33
|
+
Save changes
|
|
34
|
+
</button>
|
|
35
|
+
</footer>
|
|
36
|
+
</div>
|
|
35
37
|
```
|
|
36
38
|
|
|
39
|
+
The wrapper that holds the form and its detached actions owns the distance
|
|
40
|
+
between them: give it `.stack`.
|
|
41
|
+
|
|
37
42
|
For multiple submit intents, pair the `form` attribute with `formaction`. The form has one action; each submit button can override it.
|
|
38
43
|
|
|
39
44
|
```html
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
<div class="stack">
|
|
46
|
+
<form id="article-form"
|
|
47
|
+
action="/articles/publish"
|
|
48
|
+
method="post">
|
|
49
|
+
<!-- fields -->
|
|
50
|
+
</form>
|
|
45
51
|
|
|
46
|
-
<div class="form-actions">
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
<div class="cluster form-actions">
|
|
53
|
+
<button type="submit"
|
|
54
|
+
class="btn outline"
|
|
55
|
+
form="article-form"
|
|
56
|
+
formaction="/articles/draft">
|
|
57
|
+
Save draft
|
|
58
|
+
</button>
|
|
59
|
+
<button type="submit"
|
|
60
|
+
class="btn primary"
|
|
61
|
+
form="article-form">
|
|
62
|
+
Publish
|
|
63
|
+
</button>
|
|
64
|
+
</div>
|
|
58
65
|
</div>
|
|
59
66
|
```
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
# Form Actions
|
|
2
2
|
|
|
3
|
-
> `.form-actions` is
|
|
4
|
-
> inside or outside the `<form>` (see Detached Actions) and has an opt-in
|
|
3
|
+
> `.form-actions` is the role of the `.cluster` row that closes a form. It may
|
|
4
|
+
> live inside or outside the `<form>` (see Detached Actions) and has an opt-in
|
|
5
5
|
> sticky variant (see Sticky Actions).
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
`.cluster` owns the row: flex, wrap and gap. `.form-actions` adds the alignment
|
|
8
|
+
policy for form actions and the sticky behaviour. The space before the row
|
|
9
|
+
belongs to the parent layout: put `.stack` on the form.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
`.form-actions` refines `.cluster` with alignment rules of equal specificity,
|
|
12
|
+
so it wins on import order. In a modular build, import `layout/cluster` before
|
|
13
|
+
`forms/form-actions`; the family entries and the full bundle already do.
|
|
14
|
+
|
|
15
|
+
```html demo
|
|
16
|
+
<form class="stack" novalidate>
|
|
17
|
+
<label class="field">
|
|
18
|
+
<span class="field-label">Project name</span>
|
|
19
|
+
<input class="input" type="text" value="Atlas" />
|
|
20
|
+
</label>
|
|
16
21
|
|
|
17
|
-
<div class="form-actions">
|
|
22
|
+
<div class="cluster form-actions">
|
|
18
23
|
<button type="button" class="btn outline">Cancel</button>
|
|
19
24
|
<button type="submit" class="btn primary">Save changes</button>
|
|
20
25
|
</div>
|
|
@@ -23,34 +28,62 @@ separates the actions from the fields above.
|
|
|
23
28
|
|
|
24
29
|
## CSS hooks
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
- `--form-actions-justify` — main-axis distribution (`justify-content`).
|
|
32
|
+
- `--form-actions-align` — cross-axis alignment (`align-items`).
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
Both are inherited role hooks: set them on a page or container to align every
|
|
35
|
+
form action row inside it, without touching other clusters. Below, the
|
|
36
|
+
container right-aligns the form actions while the tag row, also a `.cluster`,
|
|
37
|
+
keeps its start alignment.
|
|
31
38
|
|
|
32
|
-
|
|
39
|
+
```html demo
|
|
40
|
+
<section class="stack" style="--form-actions-justify: flex-end">
|
|
41
|
+
<div class="cluster">
|
|
42
|
+
<span class="badge">Draft</span>
|
|
43
|
+
<span class="badge">Internal</span>
|
|
44
|
+
</div>
|
|
33
45
|
|
|
34
|
-
|
|
46
|
+
<form class="stack" novalidate>
|
|
47
|
+
<label class="field">
|
|
48
|
+
<span class="field-label">Release title</span>
|
|
49
|
+
<input class="input" type="text" value="Autumn update" />
|
|
50
|
+
</label>
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
52
|
+
<div class="cluster form-actions">
|
|
53
|
+
<button type="button" class="btn outline">Cancel</button>
|
|
54
|
+
<button type="submit" class="btn primary">Publish</button>
|
|
55
|
+
</div>
|
|
56
|
+
</form>
|
|
57
|
+
</section>
|
|
40
58
|
```
|
|
41
59
|
|
|
42
|
-
|
|
60
|
+
In application CSS, the same policy is one declaration on the region:
|
|
43
61
|
|
|
44
62
|
```css
|
|
45
|
-
.
|
|
46
|
-
--form-actions-
|
|
63
|
+
.checkout {
|
|
64
|
+
--form-actions-justify: flex-end;
|
|
47
65
|
}
|
|
48
66
|
```
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
On a form action row, `--cluster-justify` and `--cluster-align` have no effect;
|
|
69
|
+
use the hooks above, or a `.justify-content-*` / `.items-*` utility on one row.
|
|
70
|
+
A split pair keeps the dismissive action at the leading edge and the committing
|
|
71
|
+
one at the trailing edge:
|
|
72
|
+
|
|
73
|
+
```html demo
|
|
74
|
+
<form class="stack" novalidate>
|
|
75
|
+
<label class="field">
|
|
76
|
+
<span class="field-label">Display name</span>
|
|
77
|
+
<input class="input" type="text" value="Jane Doe" />
|
|
78
|
+
</label>
|
|
79
|
+
|
|
80
|
+
<div class="cluster form-actions justify-content-space-between">
|
|
81
|
+
<button type="button" class="btn outline">Cancel</button>
|
|
82
|
+
<button type="submit" class="btn primary">Save</button>
|
|
83
|
+
</div>
|
|
84
|
+
</form>
|
|
85
|
+
```
|
|
52
86
|
|
|
53
87
|
> The sticky variant adds `--form-actions-sticky-block-offset`,
|
|
54
88
|
> `--form-actions-sticky-padding`, and `--form-actions-sticky-inline-offset` —
|
|
55
|
-
> see Sticky Actions.
|
|
56
|
-
> outside the form — see Detached Actions.
|
|
89
|
+
> see Sticky Actions.
|
|
@@ -124,7 +124,7 @@ of the value and never rewrites it.
|
|
|
124
124
|
</span>
|
|
125
125
|
</label>
|
|
126
126
|
|
|
127
|
-
<div class="form-actions">
|
|
127
|
+
<div class="cluster form-actions">
|
|
128
128
|
<button class="btn primary" type="submit">Submit</button>
|
|
129
129
|
<button class="btn neutral outline" type="reset">Reset</button>
|
|
130
130
|
</div>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- `.field-group` and `.choice` provide layout without depending on parent scope.
|
|
11
11
|
- Customizable select is progressive enhancement only — the native select remains the baseline.
|
|
12
12
|
- Searchable selects, tags and autocomplete are a JavaScript widget concern; theme an external combobox with Actual tokens — see the [combobox template](../../demo/templates/combobox.html).
|
|
13
|
+
- A date is native `<input type="date">` first; use `data-mask` for a fixed text shape, or theme an external picker — see [date picker](date-picker.md) and the [date fields template](../../demo/templates/date-fields.html).
|
|
13
14
|
- Formatted text (bold, lists, links) is a hosted-editor concern; the native textarea stays the baseline and an external engine is themed the same way — see the [rich-text template](../../demo/templates/rich-text.html) and the [composer template](../../demo/templates/composer.html) for the plain-text case.
|
|
14
15
|
|
|
15
16
|
**Related terms:** form controls, select, custom select, dropdown, input, textarea, checkbox, radio.
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
| `.field-error` | Composition | Inline error message, shown while invalid. |
|
|
34
35
|
| `.field-group` | Composition | `<fieldset>` with a tunable legend gutter. |
|
|
35
36
|
| `.choice` | Composition | Choice-label layout around an inline control. |
|
|
36
|
-
| `.form-actions` | Composition |
|
|
37
|
+
| `.form-actions` | Composition | Role of the `.cluster` row closing a form. |
|
|
37
38
|
|
|
38
39
|
`.input` shares the text-control recipe with `.textarea` and `.select`, and
|
|
39
40
|
`.select` also has an opt-in enhanced picker. `.field-label` works on a
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
A full form using the control classes, field wrappers, and form actions:
|
|
47
48
|
|
|
48
49
|
```html demo
|
|
49
|
-
<form novalidate>
|
|
50
|
+
<form class="stack" novalidate>
|
|
50
51
|
<div class="stack">
|
|
51
52
|
|
|
52
53
|
<label class="field">
|
|
@@ -101,7 +102,7 @@ A full form using the control classes, field wrappers, and form actions:
|
|
|
101
102
|
|
|
102
103
|
<fieldset class="field-group">
|
|
103
104
|
<legend class="field-label">Availability</legend>
|
|
104
|
-
<div class="stack
|
|
105
|
+
<div class="stack tight">
|
|
105
106
|
<label class="choice">
|
|
106
107
|
<input class="radio" type="radio" name="availability" value="available" checked />
|
|
107
108
|
<span>Available for work</span>
|
|
@@ -161,7 +162,7 @@ A full form using the control classes, field wrappers, and form actions:
|
|
|
161
162
|
|
|
162
163
|
</div>
|
|
163
164
|
|
|
164
|
-
<div class="form-actions">
|
|
165
|
+
<div class="cluster form-actions">
|
|
165
166
|
<button type="button" class="btn outline">Cancel</button>
|
|
166
167
|
<button type="submit" class="btn primary">Save changes</button>
|
|
167
168
|
</div>
|
|
@@ -185,7 +186,7 @@ it a stronger fill.
|
|
|
185
186
|
- `.choice` is the choice-label API. Use `.check` or `.radio` on the nested control. The control goes first, the label group second, so multi-line labels align the control with the first line.
|
|
186
187
|
- For a switch, use `class="switch"` and `role="switch"`.
|
|
187
188
|
- `.range` skins the native range control (`appearance: none` track, thumb, and focus ring). Add `data-enhance="range"` for the fill share, named `datalist` values, and output sync.
|
|
188
|
-
- `.form-actions`
|
|
189
|
+
- `.form-actions` is the role of a `.cluster` row (`class="cluster form-actions"`) and carries no outer margin: `.stack` on the form spaces it from the fields. It is class-only and may live inside or outside `<form>`. See Detached Actions below.
|
|
189
190
|
- `.join` visually joins adjacent controls into a single unit. Use `.join-addon` for static prefix/suffix content. The container still carries `role="group"` for accessibility.
|
|
190
191
|
|
|
191
192
|
## Optional automatic required marks
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Sticky Actions
|
|
2
2
|
|
|
3
|
-
> Use `.form-actions
|
|
3
|
+
> Use `.cluster.form-actions.sticky` when long forms need reachable submit actions while scrolling.
|
|
4
4
|
|
|
5
5
|
## Inside the form
|
|
6
6
|
|
|
@@ -8,8 +8,8 @@ The `<form>` is the bounding parent. The sticky stays pinned to the viewport bot
|
|
|
8
8
|
|
|
9
9
|
Scroll the page to see the actions stay reachable.
|
|
10
10
|
|
|
11
|
-
```html demo
|
|
12
|
-
<form novalidate>
|
|
11
|
+
```html demo sticky
|
|
12
|
+
<form class="stack" novalidate>
|
|
13
13
|
<div class="stack">
|
|
14
14
|
<label class="field">
|
|
15
15
|
<span class="field-label">Full name <span class="required-mark" aria-hidden="true">*</span></span>
|
|
@@ -57,7 +57,7 @@ Scroll the page to see the actions stay reachable.
|
|
|
57
57
|
|
|
58
58
|
<fieldset class="field-group">
|
|
59
59
|
<legend class="field-label">Theme</legend>
|
|
60
|
-
<div class="stack
|
|
60
|
+
<div class="stack tight">
|
|
61
61
|
<label class="choice">
|
|
62
62
|
<input class="radio" type="radio" name="theme" value="light" checked />
|
|
63
63
|
<span>Light</span>
|
|
@@ -79,7 +79,7 @@ Scroll the page to see the actions stay reachable.
|
|
|
79
79
|
</label>
|
|
80
80
|
</div>
|
|
81
81
|
|
|
82
|
-
<div class="form-actions sticky">
|
|
82
|
+
<div class="cluster form-actions sticky">
|
|
83
83
|
<button type="button" class="btn outline">Cancel</button>
|
|
84
84
|
<button type="submit" class="btn primary">Save changes</button>
|
|
85
85
|
</div>
|
|
@@ -92,84 +92,86 @@ For a sticky page footer, dialog footer, or card footer, detach the actions and
|
|
|
92
92
|
|
|
93
93
|
Scroll the page to see the detached footer stay reachable.
|
|
94
94
|
|
|
95
|
-
```html demo
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
<
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
<
|
|
125
|
-
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
<
|
|
146
|
-
<
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
<
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
<
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
</
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
<
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
</
|
|
95
|
+
```html demo sticky
|
|
96
|
+
<div class="stack">
|
|
97
|
+
<form id="account-form" novalidate>
|
|
98
|
+
<div class="stack">
|
|
99
|
+
<label class="field">
|
|
100
|
+
<span class="field-label">Full name <span class="required-mark" aria-hidden="true">*</span></span>
|
|
101
|
+
<input class="input" type="text" autocomplete="name" required placeholder="Jane Doe" />
|
|
102
|
+
</label>
|
|
103
|
+
|
|
104
|
+
<label class="field">
|
|
105
|
+
<span class="field-label">Email <span class="required-mark" aria-hidden="true">*</span></span>
|
|
106
|
+
<input class="input" type="email" autocomplete="email" required />
|
|
107
|
+
</label>
|
|
108
|
+
|
|
109
|
+
<label class="field">
|
|
110
|
+
<span class="field-label">Phone</span>
|
|
111
|
+
<input class="input" type="tel" autocomplete="tel" />
|
|
112
|
+
</label>
|
|
113
|
+
|
|
114
|
+
<label class="field">
|
|
115
|
+
<span class="field-label">Bio</span>
|
|
116
|
+
<textarea class="textarea" rows="4" placeholder="Tell us about yourself…"></textarea>
|
|
117
|
+
</label>
|
|
118
|
+
|
|
119
|
+
<label class="field">
|
|
120
|
+
<span class="field-label">Website</span>
|
|
121
|
+
<input class="input" type="url" autocomplete="url" placeholder="https://example.com" />
|
|
122
|
+
</label>
|
|
123
|
+
|
|
124
|
+
<label class="field">
|
|
125
|
+
<span class="field-label">Language</span>
|
|
126
|
+
<select class="select">
|
|
127
|
+
<option>English</option>
|
|
128
|
+
<option>Français</option>
|
|
129
|
+
<option>Deutsch</option>
|
|
130
|
+
</select>
|
|
131
|
+
</label>
|
|
132
|
+
|
|
133
|
+
<label class="field">
|
|
134
|
+
<span class="field-label">Experience level</span>
|
|
135
|
+
<input class="range" type="range" min="0" max="10" value="5" />
|
|
136
|
+
</label>
|
|
137
|
+
|
|
138
|
+
<label class="field">
|
|
139
|
+
<span class="field-label">Profile picture</span>
|
|
140
|
+
<input class="file" type="file" accept="image/*" />
|
|
141
|
+
</label>
|
|
142
|
+
|
|
143
|
+
<fieldset class="field-group">
|
|
144
|
+
<legend class="field-label">Theme</legend>
|
|
145
|
+
<div class="stack tight">
|
|
146
|
+
<label class="choice">
|
|
147
|
+
<input class="radio" type="radio" name="theme-detached" value="light" checked />
|
|
148
|
+
<span>Light</span>
|
|
149
|
+
</label>
|
|
150
|
+
<label class="choice">
|
|
151
|
+
<input class="radio" type="radio" name="theme-detached" value="dark" />
|
|
152
|
+
<span>Dark</span>
|
|
153
|
+
</label>
|
|
154
|
+
<label class="choice">
|
|
155
|
+
<input class="radio" type="radio" name="theme-detached" value="auto" />
|
|
156
|
+
<span>System</span>
|
|
157
|
+
</label>
|
|
158
|
+
</div>
|
|
159
|
+
</fieldset>
|
|
160
|
+
|
|
161
|
+
<label class="choice">
|
|
162
|
+
<input class="check" type="checkbox" />
|
|
163
|
+
<span>Email notifications</span>
|
|
164
|
+
</label>
|
|
165
|
+
</div>
|
|
166
|
+
</form>
|
|
167
|
+
|
|
168
|
+
<footer class="cluster form-actions sticky">
|
|
169
|
+
<button type="button" class="btn outline">Cancel</button>
|
|
170
|
+
<button type="submit" class="btn primary" form="account-form">
|
|
171
|
+
Save changes
|
|
172
|
+
</button>
|
|
173
|
+
</footer>
|
|
174
|
+
</div>
|
|
173
175
|
```
|
|
174
176
|
|
|
175
177
|
## CSS hooks
|
|
@@ -62,7 +62,7 @@ there is no init call. To opt in forms you cannot mark up, call
|
|
|
62
62
|
`actual-css/js/enhance`.
|
|
63
63
|
|
|
64
64
|
```html demo
|
|
65
|
-
<form class="needs-validation" data-enhance="validation" data-validation-message="Please check the highlighted fields.">
|
|
65
|
+
<form class="stack needs-validation" data-enhance="validation" data-validation-message="Please check the highlighted fields.">
|
|
66
66
|
<div class="stack">
|
|
67
67
|
<label class="field">
|
|
68
68
|
<span class="field-label">Password</span>
|
|
@@ -81,7 +81,7 @@ there is no init call. To opt in forms you cannot mark up, call
|
|
|
81
81
|
</label>
|
|
82
82
|
</div>
|
|
83
83
|
|
|
84
|
-
<div class="form-actions">
|
|
84
|
+
<div class="cluster form-actions">
|
|
85
85
|
<button class="btn primary" type="submit">Submit</button>
|
|
86
86
|
<button class="btn neutral outline" type="reset">Reset</button>
|
|
87
87
|
</div>
|
|
@@ -139,7 +139,7 @@ The status bar (`actual-css/js/status`) auto-wires to that event: import it and
|
|
|
139
139
|
Switch this on to submit.
|
|
140
140
|
</span>
|
|
141
141
|
</div>
|
|
142
|
-
<div class="form-actions">
|
|
142
|
+
<div class="cluster form-actions">
|
|
143
143
|
<button class="btn primary" type="submit">Submit</button>
|
|
144
144
|
<button class="btn neutral outline" type="reset">Reset</button>
|
|
145
145
|
</div>
|
|
@@ -197,7 +197,7 @@ Add your own with `FormValidator.registerRule(name, (value, el, ...opts) => bool
|
|
|
197
197
|
<span class="field-error" id="attachment-error">Choose a .pdf or .csv file.</span>
|
|
198
198
|
</label>
|
|
199
199
|
|
|
200
|
-
<div class="form-actions">
|
|
200
|
+
<div class="cluster form-actions">
|
|
201
201
|
<button class="btn primary" type="submit">Submit</button>
|
|
202
202
|
<button class="btn neutral outline" type="reset">Reset</button>
|
|
203
203
|
</div>
|
|
@@ -246,7 +246,7 @@ The `date` rule pairs naturally with `data-mask` — the mask structures input,
|
|
|
246
246
|
</span>
|
|
247
247
|
</label>
|
|
248
248
|
|
|
249
|
-
<div class="form-actions">
|
|
249
|
+
<div class="cluster form-actions">
|
|
250
250
|
<button class="btn primary" type="submit">Submit</button>
|
|
251
251
|
<button class="btn neutral outline" type="reset">Reset</button>
|
|
252
252
|
</div>
|