its-swiss 0.8.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +127 -1
- data/README.md +94 -173
- data/app/assets/javascripts/its_swiss.js +12 -0
- data/app/assets/stylesheets/its_swiss/components.css +189 -288
- data/app/assets/stylesheets/its_swiss/grid.css +35 -35
- data/app/assets/stylesheets/its_swiss/specimen.css +5 -1
- data/app/assets/stylesheets/its_swiss/tokens.css +48 -111
- data/app/assets/stylesheets/its_swiss/type.css +34 -103
- data/app/helpers/its_swiss/application_helper.rb +43 -7
- data/app/views/its_swiss/specimen/_buttons.html.erb +3 -3
- data/app/views/its_swiss/specimen/_figure.html.erb +12 -0
- data/app/views/its_swiss/specimen/_filters.html.erb +2 -2
- data/app/views/its_swiss/specimen/_form.html.erb +13 -1
- data/app/views/its_swiss/specimen/_grid.html.erb +13 -0
- data/app/views/its_swiss/specimen/_page_head.html.erb +19 -0
- data/app/views/layouts/its_swiss/shell.html.erb +3 -0
- data/config/importmap.rb +3 -5
- data/lib/its_swiss/form_builder.rb +11 -0
- data/lib/its_swiss/version.rb +1 -1
- data/lib/its_swiss.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e87eed3705a969f109f9e21d5c4242173bcbcbbb6d0700441fbeb588c5aa6845
|
|
4
|
+
data.tar.gz: ac3ab6f0964280e6ea4f2ac67db52975ab7f55cfd9a341976515a76718275d2b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38eb6ffa9089d649da9a1f6fd57ebc71e54515445051147acb4aad296c2d68bf1641926113f45b8a79f757cc52f1a5034a19f447d11ce01b2cd51c8b4e32b055
|
|
7
|
+
data.tar.gz: f48734b201bf2528f749c1990065d7ae68c1da803d3d67aec8f717f11bf48da95620f9a1b469ec0294fc794d603c3ad2be3c038475d4e670e5e9eefddcb76201
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,132 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
Semver. Consumers pin `~> 0
|
|
3
|
+
Semver. Consumers pin `~> 1.0`.
|
|
4
|
+
|
|
5
|
+
## 1.0.0 — 2026-09-08
|
|
6
|
+
|
|
7
|
+
The surface three applications settled on, reviewed as a whole: what a tech
|
|
8
|
+
lead found and what Müller-Brockmann would have said. The library's
|
|
9
|
+
arguments now live in `DESIGN.md`, once.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **`--span` no longer inherits.** A custom property inherits by default, so
|
|
14
|
+
a grid inside a spanned item started every child of its own at the parent's
|
|
15
|
+
span. `--span` is a registered property with `inherits: false` and no
|
|
16
|
+
initial value, so a child that says nothing still runs the whole field.
|
|
17
|
+
- **The metric-override script carries the page's nonce.** The shell renders
|
|
18
|
+
`csp_meta_tag`, and a content security policy blocked the one inline script
|
|
19
|
+
the library writes, which left Safari in step and not registered with
|
|
20
|
+
nobody seeing why.
|
|
21
|
+
- **A field is the page's field.** `--field` was derived from `--page-max`,
|
|
22
|
+
so below 82rem `.fields` was wider than the viewport and the measure was
|
|
23
|
+
600px on a phone. It is measured in container units from the `.page` the
|
|
24
|
+
fields are laid out in; `.fields` never exceeds its box.
|
|
25
|
+
- **A control's focus is its rule.** The focus ring was a box drawn 3px
|
|
26
|
+
outside a two-line control whose only visible part is a rule, and it
|
|
27
|
+
crossed the label above it. The focus is the rule going heavy, in the
|
|
28
|
+
accent, with the box still two lines.
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **The measure is a count of characters.** `--measure-characters` (65) in
|
|
33
|
+
the type's own font, taken up to the nearest whole run of fields with
|
|
34
|
+
`round()`, and never past the page. Three fields whatever the count was a
|
|
35
|
+
proportion: a quarter of a twelve-column page, and wider than a phone.
|
|
36
|
+
- **The module.** `--module` (6) is a field's height in lines: the columns
|
|
37
|
+
divide the page across and the module divides it down. `.modules` is a
|
|
38
|
+
block of whole modules and `.figure--modular` a picture in one, which is
|
|
39
|
+
the grid's proportion rather than the window's.
|
|
40
|
+
- **The dense form.** `.form--dense` puts each label on its control's line of
|
|
41
|
+
air, directly above the text on its rule: three lines a field rather than
|
|
42
|
+
four, for a form of many fields or a panel.
|
|
43
|
+
- **A textarea is measured in lines.** `rows:` on the builder's `text_area`
|
|
44
|
+
writes `--rows`, which the stylesheet reads; four when it is not given.
|
|
45
|
+
- **The library registers its own controllers.** `its_swiss.js` registers
|
|
46
|
+
the clipboard and the live search with the host's Stimulus application,
|
|
47
|
+
and the shell imports it. A host has nothing to write; the two lines it
|
|
48
|
+
wrote before are harmless.
|
|
49
|
+
- **`DESIGN.md`.** The arguments, moved out of the stylesheets and stated
|
|
50
|
+
once; the stylesheets say what a rule is for in a sentence.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- **A form has no width of its own.** `.form` was at the measure and started
|
|
55
|
+
its children on the left; a form laid out on the fields had to undo both.
|
|
56
|
+
`its_swiss_form_with` writes `class="form measure"`, so a form written
|
|
57
|
+
through the helper is where it was. A form written with `form_with` and
|
|
58
|
+
`class: "form"` is full width now: add `measure`.
|
|
59
|
+
- **One filled button.** `.button--accent` is gone: the primary action is in
|
|
60
|
+
ink, and a second filled box was a standing temptation against the one red
|
|
61
|
+
a page has.
|
|
62
|
+
- **The explanation's mark is a word.** `explain` writes "About" in the
|
|
63
|
+
small register rather than a question mark; `label:` says another word.
|
|
64
|
+
- **The control's rule at rest is the strong rule**, `--rule-strong`, which
|
|
65
|
+
the library had declared and never used; ink under the hand, the accent
|
|
66
|
+
when refused or focused.
|
|
67
|
+
- **Tokens nothing used are gone**: `--space-5`, `--space-13`, `--line-6`.
|
|
68
|
+
`--space-6`, `--space-8` and `--line-4` remain. Pandatone read two of them
|
|
69
|
+
and will move to the ladder when it takes 1.0.
|
|
70
|
+
- **The tests that pinned formatting pin behaviour.** Three assertions that
|
|
71
|
+
matched exact runs of CSS text are computed-style assertions in the
|
|
72
|
+
browser suite; the guards that are about the source stay.
|
|
73
|
+
|
|
74
|
+
### Migration
|
|
75
|
+
|
|
76
|
+
- `gem "its-swiss", "~> 1.0"`.
|
|
77
|
+
- A `form_with(..., class: "form")` that wants the measure adds `measure`.
|
|
78
|
+
- `.button--accent` becomes `.button--primary`.
|
|
79
|
+
- `--space-5` becomes `--space-6` or a line; `--space-13` becomes
|
|
80
|
+
`calc(var(--space-unit) * 13)` if it is truly wanted; `--line-6` becomes
|
|
81
|
+
`calc(var(--line) * 6)`.
|
|
82
|
+
- The two Stimulus registrations in the host's `controllers/index.js` can go.
|
|
83
|
+
- A test that read the explanation's `?` reads "About".
|
|
84
|
+
|
|
85
|
+
## 0.9.1 — 2026-09-07
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
|
|
89
|
+
- **The suite, and so the release, under json 3.0.0.** json 3.0.0 came out
|
|
90
|
+
twenty minutes after 0.9.0's pull request went green and changed the
|
|
91
|
+
signature of `JSON.parse`; Active Support 8.1.3.1 still calls it the old
|
|
92
|
+
way when it reads a signed cookie, so the session and the flash raised on
|
|
93
|
+
every request and the release of 0.9.0 stopped at its own tests. The
|
|
94
|
+
Gemfile holds json below 3 until a Rails that takes it. Nothing in the
|
|
95
|
+
library changed; 0.9.1 is 0.9.0 released.
|
|
96
|
+
|
|
97
|
+
## 0.9.0 — 2026-09-07
|
|
98
|
+
|
|
99
|
+
A day of use, and what a day asks of a style: less talk and one red.
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
|
|
103
|
+
- **Sections.** `page_head(title, sections:)` names the surfaces of one
|
|
104
|
+
page under its title — what a thing is made of, what it wears, how it
|
|
105
|
+
leaves — the one shown in the weight, and a page shows that one alone.
|
|
106
|
+
A working page must not scroll: what is done daily is reached from the
|
|
107
|
+
head, in the same position on every page, never by scrolling past what
|
|
108
|
+
was done yesterday. `page_sections(sections)` writes the nav on its own.
|
|
109
|
+
|
|
110
|
+
- **Explanations.** `explain(text)` puts what a section means behind one
|
|
111
|
+
mark: a question mark on the line, closed, and the text in the hint
|
|
112
|
+
register under it when it is asked for. A sentence over every table is
|
|
113
|
+
needed on the first day and never again.
|
|
114
|
+
|
|
115
|
+
### Changed
|
|
116
|
+
|
|
117
|
+
- **One red per page.** The chosen filter and a current menu are in the
|
|
118
|
+
weight, in ink. The accent is for where you are on the site — the nav,
|
|
119
|
+
the subnav, the page numbers — and for the one thing that cannot be
|
|
120
|
+
undone. A page that said "this one" in red five times above the fold
|
|
121
|
+
had no signal left.
|
|
122
|
+
|
|
123
|
+
- **Hints are prose.** `.hint` is set at body size. The small size is for
|
|
124
|
+
labels and metadata, and a hint set in it at a body line's leading read
|
|
125
|
+
as a list of afterthoughts. Table headings go the other way: the label
|
|
126
|
+
register, bold, on the line.
|
|
127
|
+
|
|
128
|
+
- **The filter block is ruled once, below.** The rule above it was a third
|
|
129
|
+
rule in ten lines, and the rule is the one mark this style draws.
|
|
4
130
|
|
|
5
131
|
## 0.8.0 — 2026-09-07
|
|
6
132
|
|
data/README.md
CHANGED
|
@@ -14,7 +14,7 @@ the consuming application's to set — it is not a theme with the colour left
|
|
|
14
14
|
out, it is a style whose argument is that the values are enough.
|
|
15
15
|
|
|
16
16
|
```ruby
|
|
17
|
-
gem "its-swiss", "~> 0
|
|
17
|
+
gem "its-swiss", "~> 1.0"
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
```sh
|
|
@@ -26,8 +26,8 @@ Then open `/its-swiss/specimen`.
|
|
|
26
26
|
The current specimen is also published, for anywhere that cannot run Rails:
|
|
27
27
|
**[bobbymeyer.github.io/its-swiss](https://bobbymeyer.github.io/its-swiss/)**.
|
|
28
28
|
`bin/specimen out` writes it as one static file, and a Pages workflow does
|
|
29
|
-
that on every push to `main
|
|
30
|
-
|
|
29
|
+
that on every push to `main`; the versions kept in `published/` are copied
|
|
30
|
+
alongside it at `/<version>.html` for anything that needs to pin.
|
|
31
31
|
|
|
32
32
|
## What is in the gem, and what stays in the application
|
|
33
33
|
|
|
@@ -70,6 +70,8 @@ holding all of them. Nothing here has a default the gem could pick honestly.
|
|
|
70
70
|
| `--value-chroma`, `--value-hue` | Warms the whole value scale together. Neutral as shipped |
|
|
71
71
|
| `--columns`, `--gutter` | How many fields this problem has |
|
|
72
72
|
| `--line` | The baseline: the interval everything vertical registers to |
|
|
73
|
+
| `--module` | A field's height, in lines: what divides the page down |
|
|
74
|
+
| `--measure-characters` | How many characters a line of prose holds; the grid is what it stops on |
|
|
73
75
|
| `--ratio` | A picture's aspect ratio, per figure — the library cannot read one |
|
|
74
76
|
| `--card` | How many fields a card takes, and at which widths |
|
|
75
77
|
| `--filter-label` | The column a filter's label occupies, so every register's choices start on one line |
|
|
@@ -78,120 +80,24 @@ holding all of them. Nothing here has a default the gem could pick honestly.
|
|
|
78
80
|
### The baseline
|
|
79
81
|
|
|
80
82
|
`--line` (24px) is the interval everything vertical registers to, and the
|
|
81
|
-
leading of the body text
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Every
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
been told. A caption and a paragraph can both be in step and still be out of
|
|
94
|
-
register with each other, and a page on the grid in one font is off it in the
|
|
95
|
-
next. 0.5.0 trimmed every register to its type with `text-box-trim`, which
|
|
96
|
-
registered the page in the one browser that trims and left the rest to their
|
|
97
|
-
fonts.
|
|
98
|
-
|
|
99
|
-
So the library sets every register in a face of its own. `faces.css` declares
|
|
100
|
-
the machine's grotesque three times over `src: local()`, each time with its
|
|
101
|
-
ascent set to a ratio of leading to size and its descent and line gap set to
|
|
102
|
-
nothing:
|
|
103
|
-
|
|
104
|
-
```css
|
|
105
|
-
@font-face {
|
|
106
|
-
font-family: "its-swiss-150";
|
|
107
|
-
src: local("Helvetica Neue"), local("Arial"), local("Liberation Sans"), …;
|
|
108
|
-
ascent-override: 150%;
|
|
109
|
-
descent-override: 0%;
|
|
110
|
-
line-gap-override: 0%;
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
A line box is then exactly the ascent tall, there is no half-leading for the
|
|
115
|
-
type to sit inside, and the baseline is the under edge of the line box — in
|
|
116
|
-
every line, whatever the font underneath, in a browser that honours the
|
|
117
|
-
descriptors. Chromium and Firefox do. The ladder produces three ratios and
|
|
118
|
-
there are three faces: body, subhead and page title are set on one and a half
|
|
119
|
-
times their size, the small register and the section on twice it, and the
|
|
120
|
-
subgrid puts the small register on its own size. A register is three
|
|
121
|
-
declarations, and the third is what makes the first two a grid:
|
|
122
|
-
|
|
123
|
-
```css
|
|
124
|
-
.micro { font-family: var(--face-200), var(--font-family); font-size: var(--size-1); line-height: var(--line); }
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Safari loads the faces and ignores what they say about their metrics, so
|
|
128
|
-
there every text block is also trimmed to its type: `text-box: trim-both cap
|
|
129
|
-
alphabetic` makes the block's over edge the cap of its first line and its
|
|
130
|
-
under edge the baseline of its last, and one padding rounds the cap up to the
|
|
131
|
-
block's own leading —
|
|
132
|
-
|
|
133
|
-
```css
|
|
134
|
-
padding-block-start: calc(round(up, 1cap, 1lh) - round(1cap, 1px));
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
— measured by the browser in cap and line units, so the library still never
|
|
138
|
-
has to be told the font's metrics. The cap is rounded to a pixel because that
|
|
139
|
-
is the cap WebKit trims to, and WebKit is the browser this is for. It is
|
|
140
|
-
published as `--cap-correction`: a component that puts padding above its type
|
|
141
|
-
adds it. Only where it is needed, though, and only when told: a trimmed box
|
|
142
|
-
is a 64th of a pixel short as often as not on the engine the correction is
|
|
143
|
-
written for, and half a pixel out per block on one that trims to the exact
|
|
144
|
-
cap, which down a long column is a visible drift. So one line of script ahead
|
|
145
|
-
of the stylesheets marks the document `no-metric-overrides` where the faces
|
|
146
|
-
are not honoured, and the trim steps in there and nowhere else;
|
|
147
|
-
`its_swiss_stylesheet_tags` writes it, and anything linking the stylesheets
|
|
148
|
-
by hand should too:
|
|
83
|
+
leading of the body text: one number, because that is what a baseline grid
|
|
84
|
+
is. Every leading, margin, padding and gap on the vertical axis is a whole
|
|
85
|
+
number of lines; `--space-*` is the horizontal step.
|
|
86
|
+
|
|
87
|
+
Every baseline is the under edge of its line box, two ways. The library sets
|
|
88
|
+
every register in a face of its own, the machine's grotesque declared again
|
|
89
|
+
with its ascent set to the register's ratio of leading to size and no
|
|
90
|
+
descent, which Chromium and Firefox honour. Where a browser ignores what a
|
|
91
|
+
face says about its metrics, Safari, every text block is trimmed to its type
|
|
92
|
+
instead, and one line of script ahead of the stylesheets says which is in
|
|
93
|
+
force. `its_swiss_stylesheet_tags` writes it; anything linking the
|
|
94
|
+
stylesheets by hand should too:
|
|
149
95
|
|
|
150
96
|
```html
|
|
151
97
|
<script>if (!("ascentOverride" in FontFace.prototype)) document.documentElement.classList.add("no-metric-overrides")</script>
|
|
152
98
|
```
|
|
153
99
|
|
|
154
|
-
|
|
155
|
-
in Safari in step but not registered. The faces are the mechanism and the
|
|
156
|
-
trim is the fallback. Three things follow.
|
|
157
|
-
|
|
158
|
-
Anything that changes size *inside* a line — `code`, a `small`, a
|
|
159
|
-
superscript — is given no leading at all, so it never asks the line for room;
|
|
160
|
-
its glyphs still sit on the strut's baseline, which is the grid's.
|
|
161
|
-
|
|
162
|
-
No row asks the browser to find a baseline. Every box's baselines are whole
|
|
163
|
-
lines below its own over edge, so a row that starts its items on one line has
|
|
164
|
-
put their baselines on one line; `.run` aligns on `flex-start`, the masthead
|
|
165
|
-
and the nav on `end`, a table cell on `top`, and none of them on `baseline`,
|
|
166
|
-
which is a question three kinds of box answer three ways.
|
|
167
|
-
|
|
168
|
-
Text lives in text elements. The trim is asked of headings, paragraphs,
|
|
169
|
-
terms, cells, captions, labels, list items and definitions that hold text,
|
|
170
|
-
nav links, pagination, buttons — and not of the boxes that hold those, since
|
|
171
|
-
a box that holds blocks is trimmed through its first and last child and would
|
|
172
|
-
be corrected twice. Plain text dropped straight into a `<footer>` or a `<div>`
|
|
173
|
-
is in step and, in Safari, off the baseline; put it in a paragraph. The shell
|
|
174
|
-
does, for the `:footer` slot.
|
|
175
|
-
|
|
176
|
-
A control is two lines: a line of air under the label, then the line the
|
|
177
|
-
type is set on, which the rule closes, with the rule's width taken out of the
|
|
178
|
-
first — so the type stands on its rule the way a line of handwriting stands
|
|
179
|
-
on a ruled page. A button is a box, two lines tall with
|
|
180
|
-
its label centred in it, and its label's baseline is the one baseline in the
|
|
181
|
-
library that is not on a line — on purpose, since a label set on the second
|
|
182
|
-
line of a two-line box reads as a field with a rule under it. Its keyline is
|
|
183
|
-
an inset shadow rather than a border, so the box is the label's line and two
|
|
184
|
-
paddings and nothing else.
|
|
185
|
-
|
|
186
|
-
A control's own text — an input, a select, a textarea — is the other run of
|
|
187
|
-
type the library takes off the baseline, and it does so on purpose too. A
|
|
188
|
-
browser sets that text in a box of its own, centres it there and clips it
|
|
189
|
-
there, and on a face with no descent every descender was cut off at the
|
|
190
|
-
rule. So the text is set in `--font-family` itself, with the font's own
|
|
191
|
-
metrics, on the line the rule closes: the box is on the grid, the line is
|
|
192
|
-
the ladder's, and where the baseline falls inside the line is the font's. Which means the typeface has to exist under its own name as well as
|
|
193
|
-
under the faces; `its_swiss_typeface` declares it there when given
|
|
194
|
-
`family:`, and `--font-family` names it.
|
|
100
|
+
The whole argument, and what follows from it, is in `DESIGN.md`.
|
|
195
101
|
|
|
196
102
|
#### Your own typeface
|
|
197
103
|
|
|
@@ -204,35 +110,21 @@ it:
|
|
|
204
110
|
<%= its_swiss_typeface variable: "inter.woff2", family: "Inter" %>
|
|
205
111
|
```
|
|
206
112
|
|
|
207
|
-
Put it after the library's stylesheets.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
name by order rather than by layer wants it last too. `--font-family` is only
|
|
211
|
-
what a machine with none of the faces falls through to: the page is still
|
|
212
|
-
readable and still in step, and no longer registered.
|
|
213
|
-
|
|
214
|
-
The faces are the ladder's. Re-proportion `--line` or a size and the ratios
|
|
215
|
-
move with them, and the faces have to be declared again for the ratios the new
|
|
216
|
-
ladder produces.
|
|
113
|
+
Put it after the library's stylesheets. `family:` declares the typeface under
|
|
114
|
+
its own name as well, which a control's text is set in; `--font-family` is
|
|
115
|
+
what a machine with none of the faces falls through to.
|
|
217
116
|
|
|
218
117
|
#### The one subgrid
|
|
219
118
|
|
|
220
|
-
A block of small type may sit on a half-line
|
|
221
|
-
table of figures:
|
|
119
|
+
A block of small type may sit on a half-line:
|
|
222
120
|
|
|
223
121
|
```html
|
|
224
122
|
<div class="subgrid">…</div>
|
|
225
123
|
```
|
|
226
124
|
|
|
227
125
|
It halves `--line` for the block's **children** and moves the small register
|
|
228
|
-
onto the face for its new ratio, and
|
|
229
|
-
|
|
230
|
-
margins belong to the column outside it and are owed whole lines. Set on the
|
|
231
|
-
block itself it halves the gap above it and lands the column half a line out.
|
|
232
|
-
|
|
233
|
-
A block, and only a block. An inline `<small>` shares its paragraph's line and
|
|
234
|
-
must not change it.
|
|
235
|
-
|
|
126
|
+
onto the face for its new ratio. A block, and only a block: an inline
|
|
127
|
+
`<small>` shares its paragraph's line.
|
|
236
128
|
|
|
237
129
|
### The value scale
|
|
238
130
|
|
|
@@ -294,27 +186,33 @@ yours to make where you own the picture.
|
|
|
294
186
|
The gem ships primitives and never a grid.
|
|
295
187
|
|
|
296
188
|
```css
|
|
297
|
-
.page
|
|
298
|
-
.grid
|
|
299
|
-
.measure
|
|
300
|
-
.fields
|
|
301
|
-
.
|
|
302
|
-
.
|
|
189
|
+
.page /* the one measured container: --page-max wide, --page-inset either side, and the container a field is measured in */
|
|
190
|
+
.grid /* repeat(var(--columns), minmax(0, 1fr)) with --gutter between */
|
|
191
|
+
.measure /* the measure: --measure-characters of the type, stopped on a field line */
|
|
192
|
+
.fields /* --span fields wide */
|
|
193
|
+
.modules /* --modules modules tall */
|
|
194
|
+
.run /* items on a shared baseline, a space apart, wrapping when they must */
|
|
195
|
+
.stack /* the same, turned ninety degrees */
|
|
303
196
|
```
|
|
304
197
|
|
|
305
198
|
A child of `.grid` says how many fields it takes with `--span`; a child that
|
|
306
|
-
says nothing runs the whole field
|
|
307
|
-
|
|
199
|
+
says nothing runs the whole field. `--span` is registered not to inherit, so a
|
|
200
|
+
grid inside a spanned item starts its own children on the whole field.
|
|
308
201
|
|
|
309
|
-
|
|
310
|
-
|
|
202
|
+
A field is the page's actual width, less the gutters, divided, measured in
|
|
203
|
+
container units from the `.page` the fields are laid out in:
|
|
311
204
|
|
|
312
205
|
```css
|
|
313
|
-
--field: calc((var(--
|
|
314
|
-
- var(--gutter) * (var(--columns) - 1)) / var(--columns));
|
|
315
|
-
--measure: calc(var(--field) * 3 + var(--gutter) * 2);
|
|
206
|
+
--field: calc((100cqw - var(--gutter) * (var(--columns) - 1)) / var(--columns));
|
|
316
207
|
```
|
|
317
208
|
|
|
209
|
+
The measure is a count of characters, and the grid is what it stops on:
|
|
210
|
+
`--measure-characters` (65) in the type's own font, taken up to the nearest
|
|
211
|
+
whole run of fields, and never past the page. The module is a field's height
|
|
212
|
+
in lines, `--module` (6): the columns divide the page across and the module
|
|
213
|
+
divides it down, and `.modules` and `.figure--modular` size a block or a
|
|
214
|
+
picture to whole ones.
|
|
215
|
+
|
|
318
216
|
### The page head
|
|
319
217
|
|
|
320
218
|
What a page is and what can be done to it, in one shape on every page: the
|
|
@@ -329,12 +227,36 @@ a run beside them, wrapping under the title when the page is narrow.
|
|
|
329
227
|
|
|
330
228
|
The document is titled from it unless the view has already set `:title`.
|
|
331
229
|
|
|
230
|
+
A page with several surfaces — what a thing is made of, what it wears, how it
|
|
231
|
+
leaves — names them under the title with `sections:`, each a name, a URL and
|
|
232
|
+
whether it is the one shown, and shows that one alone. A working page must
|
|
233
|
+
not scroll: what is done daily is reached from the head, in the same position
|
|
234
|
+
on every page.
|
|
235
|
+
|
|
236
|
+
```erb
|
|
237
|
+
<%= page_head @pattern.name, sections: [ [ "Compose", pattern_path(@pattern), @section == "compose" ],
|
|
238
|
+
[ "Dress", pattern_path(@pattern, section: "dress"), @section == "dress" ] ] do %>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Explanations
|
|
242
|
+
|
|
243
|
+
What a section means, behind one word. A sentence over every table is needed
|
|
244
|
+
on the first day and never again, and a tool used daily is read on every
|
|
245
|
+
other day; so `explain` writes it in the hint register, closed, and the word
|
|
246
|
+
"About" in the small register opens it. `label:` says another word.
|
|
247
|
+
|
|
248
|
+
```erb
|
|
249
|
+
<%= explain "The repeat, in order along the stripe normal." %>
|
|
250
|
+
```
|
|
251
|
+
|
|
332
252
|
### Filters and cards
|
|
333
253
|
|
|
334
254
|
What narrows a list, and the list. A search that filters as you type, and a
|
|
335
255
|
register for each other way of narrowing it — a tag, an order, a size — in the
|
|
336
256
|
same two positions every time: a quiet label, then the choices, the one in
|
|
337
|
-
force carrying `aria-current`, which the CSS
|
|
257
|
+
force carrying `aria-current`, which the CSS sets in the weight. In ink, not
|
|
258
|
+
the accent: the accent is for where you are on the site and for the one
|
|
259
|
+
thing that cannot be undone, and a page has one red.
|
|
338
260
|
|
|
339
261
|
```erb
|
|
340
262
|
<div class="filters">
|
|
@@ -389,8 +311,8 @@ application — naming the shell on the controller renders it but leaves
|
|
|
389
311
|
nowhere to fill it, so every view ends up writing the same masthead.
|
|
390
312
|
|
|
391
313
|
Note the `:head` slot links `theme.css`. The shell links the library's seven
|
|
392
|
-
stylesheets and
|
|
393
|
-
links it but this.
|
|
314
|
+
stylesheets and the module that registers its controllers, and stops; the
|
|
315
|
+
accent and the grid live in yours, and nothing links it but this.
|
|
394
316
|
|
|
395
317
|
Slots, all optional:
|
|
396
318
|
|
|
@@ -405,21 +327,23 @@ Slots, all optional:
|
|
|
405
327
|
| `:footer` | Whatever belongs after the page |
|
|
406
328
|
|
|
407
329
|
The shell writes the view transition opt-in, the seven stylesheet links, the
|
|
408
|
-
importmap tags, a skip link, and the flash. It stops there — a page layout
|
|
330
|
+
importmap tags, the library's JavaScript module, a skip link, and the flash. It stops there — a page layout
|
|
409
331
|
beyond the shell is the application's, for the same reason its grid is.
|
|
410
332
|
|
|
411
333
|
## Helpers
|
|
412
334
|
|
|
413
335
|
| | |
|
|
414
336
|
| --- | --- |
|
|
415
|
-
| `its_swiss_stylesheet_tags` | The seven links, tracked for Turbo |
|
|
337
|
+
| `its_swiss_stylesheet_tags` | The seven links, tracked for Turbo, and the metric-override mark with the page's nonce |
|
|
416
338
|
| `its_swiss_typeface(regular:, bold:)` | The application's typeface, declared under the library's face names |
|
|
417
339
|
| `nav_link_to(name, url, current:)` | A destination, with `aria-current` when you are at it |
|
|
418
340
|
| `nav_menu(label, current:) { links }` | A destination that opens into destinations, with no script |
|
|
419
341
|
| `copy_button(value)` | A value that copies itself |
|
|
420
|
-
| `its_swiss_form_with(...)` | `form_with`, already holding the library's builder |
|
|
342
|
+
| `its_swiss_form_with(...)` | `form_with`, already holding the library's builder, at the measure |
|
|
421
343
|
| `its_swiss_page_numbers(page, pages)` | Which numbers a run of them shows, elided |
|
|
422
|
-
| `page_head(title, lede:) { actions }` | The one shape every page opens with |
|
|
344
|
+
| `page_head(title, lede:, sections:) { actions }` | The one shape every page opens with |
|
|
345
|
+
| `page_sections(sections)` | The surfaces of one page, the one shown in the weight |
|
|
346
|
+
| `explain(text, label:) { }` | What a section means, behind one word |
|
|
423
347
|
| `filter_register(label, choices, name:)` | One register of a filter block |
|
|
424
348
|
| `search_form(url, frame:, keep:)` | A search that narrows a list as you type |
|
|
425
349
|
|
|
@@ -438,21 +362,12 @@ many neighbours show; `label:` names the `<nav>` for a screen reader.
|
|
|
438
362
|
|
|
439
363
|
### JavaScript
|
|
440
364
|
|
|
441
|
-
Two Stimulus controllers, pinned by the engine
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
import ItsSwissClipboardController from "its_swiss/clipboard_controller"
|
|
448
|
-
import ItsSwissLiveSearchController from "its_swiss/live_search_controller"
|
|
449
|
-
application.register("its-swiss-clipboard", ItsSwissClipboardController)
|
|
450
|
-
application.register("its-swiss-live-search", ItsSwissLiveSearchController)
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
`copy_button` and `search_form` write the `data-controller` attributes; a page
|
|
454
|
-
without the registrations still works, with the value selectable and the
|
|
455
|
-
search's button on the page.
|
|
365
|
+
Two Stimulus controllers, pinned by the engine, and a module that registers
|
|
366
|
+
them with the host's Stimulus application, which the shell imports. A host
|
|
367
|
+
has nothing to write; one that registers the two by hand still can, and
|
|
368
|
+
registering them twice is harmless. `copy_button` and `search_form` write
|
|
369
|
+
the `data-controller` attributes; a page without script still works, with
|
|
370
|
+
the value selectable and the search's button on the page.
|
|
456
371
|
|
|
457
372
|
## The form builder
|
|
458
373
|
|
|
@@ -475,7 +390,13 @@ builder wires `for`, `aria-describedby`, `aria-invalid` and `.field--invalid`
|
|
|
475
390
|
every time.
|
|
476
391
|
|
|
477
392
|
`label: false` hides the label rather than removing it — the name moves onto
|
|
478
|
-
the control as `aria-label`.
|
|
393
|
+
the control as `aria-label`. A textarea's `rows:` is how many lines tall it
|
|
394
|
+
is. `class: "form form--dense"` puts each label on its control's line of
|
|
395
|
+
air, three lines a field rather than four, for a form of many fields.
|
|
396
|
+
|
|
397
|
+
A control's rule is the strong rule at rest, ink under the hand, and the
|
|
398
|
+
accent, heavy, when the control has the focus or has been refused. The focus
|
|
399
|
+
is the rule, not a box.
|
|
479
400
|
|
|
480
401
|
## The specimen
|
|
481
402
|
|
|
@@ -539,6 +460,7 @@ ladder; the names are the library's rather than the application's.
|
|
|
539
460
|
| `--font` | `--font-family` |
|
|
540
461
|
| `--size-1..5`, `--space-N`, `--measure`, `--page-max` | unchanged |
|
|
541
462
|
| `--baseline` (8px) | **gone.** `--line` (24px) is the baseline now — see 0.4.0 |
|
|
463
|
+
| `--space-5`, `--space-13`, `--line-6` | **gone** in 1.0.0: nothing in the library used them. `--space-6`, `--space-8` and `--line-4` remain |
|
|
542
464
|
| `.masthead__nav` | `.nav` |
|
|
543
465
|
| `.channels` | `.pairs` |
|
|
544
466
|
| `.form`, `.field`, `.button*`, `.copy`, `.errors`, `.hint`, `.empty` | unchanged |
|
|
@@ -559,12 +481,11 @@ Two behavioural differences to know about:
|
|
|
559
481
|
|
|
560
482
|
## Versioning
|
|
561
483
|
|
|
562
|
-
Semver with a changelog. Consumers pin `~> 0
|
|
484
|
+
Semver with a changelog. Consumers pin `~> 1.0`.
|
|
563
485
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
upgrading, and see `RELEASING.md` for how a version gets out.
|
|
486
|
+
1.0.0 is the surface three applications settled on, and what changes it now
|
|
487
|
+
changes a major. Read `CHANGELOG.md` before upgrading, and see `RELEASING.md`
|
|
488
|
+
for how a version gets out.
|
|
568
489
|
|
|
569
490
|
## License
|
|
570
491
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Registers the library's two controllers with the host's Stimulus
|
|
2
|
+
// application. controllers/application is what stimulus-rails installs in
|
|
3
|
+
// every host, and it is the one thing this file assumes about the JavaScript
|
|
4
|
+
// around it. The shell imports this module, so a host has nothing to write;
|
|
5
|
+
// a host that registers the two by hand still can, and registers them twice
|
|
6
|
+
// harmlessly.
|
|
7
|
+
import { application } from "controllers/application"
|
|
8
|
+
import ClipboardController from "its_swiss/clipboard_controller"
|
|
9
|
+
import LiveSearchController from "its_swiss/live_search_controller"
|
|
10
|
+
|
|
11
|
+
application.register("its-swiss-clipboard", ClipboardController)
|
|
12
|
+
application.register("its-swiss-live-search", LiveSearchController)
|