its-swiss 0.8.0 → 0.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -0
- data/README.md +28 -2
- data/app/assets/stylesheets/its_swiss/components.css +77 -10
- data/app/assets/stylesheets/its_swiss/type.css +7 -2
- data/app/helpers/its_swiss/application_helper.rb +32 -2
- data/app/views/its_swiss/specimen/_filters.html.erb +2 -2
- data/app/views/its_swiss/specimen/_page_head.html.erb +18 -0
- data/lib/its_swiss/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7ab6df97c9cfca52b616b05f5e985aa37df4253563fd1b1177c9c67890706cad
|
|
4
|
+
data.tar.gz: 6e9d6316b70b2670b7b307b33ec64955e88d562d085c95a86e07836e635d1a97
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5a3f8671a25c996f2883add93ead145a89244a8a5bbec670022c0b3d49d587d19dd1b5a664eb94bd49908b1d8a4b28877e66b180ac49d3b653b47b0493cf7d02
|
|
7
|
+
data.tar.gz: 286de25b2203d9928f9a4cbf596341aa8d450c3cfaecf016cafff44737586df4d4cd65d98271d102f2dcf2af9e8f9e058413ead233ad86602a3e242a5f471a4d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
Semver. Consumers pin `~> 0.1`.
|
|
4
4
|
|
|
5
|
+
## 0.9.1 — 2026-09-07
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **The suite, and so the release, under json 3.0.0.** json 3.0.0 came out
|
|
10
|
+
twenty minutes after 0.9.0's pull request went green and changed the
|
|
11
|
+
signature of `JSON.parse`; Active Support 8.1.3.1 still calls it the old
|
|
12
|
+
way when it reads a signed cookie, so the session and the flash raised on
|
|
13
|
+
every request and the release of 0.9.0 stopped at its own tests. The
|
|
14
|
+
Gemfile holds json below 3 until a Rails that takes it. Nothing in the
|
|
15
|
+
library changed; 0.9.1 is 0.9.0 released.
|
|
16
|
+
|
|
17
|
+
## 0.9.0 — 2026-09-07
|
|
18
|
+
|
|
19
|
+
A day of use, and what a day asks of a style: less talk and one red.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Sections.** `page_head(title, sections:)` names the surfaces of one
|
|
24
|
+
page under its title — what a thing is made of, what it wears, how it
|
|
25
|
+
leaves — the one shown in the weight, and a page shows that one alone.
|
|
26
|
+
A working page must not scroll: what is done daily is reached from the
|
|
27
|
+
head, in the same position on every page, never by scrolling past what
|
|
28
|
+
was done yesterday. `page_sections(sections)` writes the nav on its own.
|
|
29
|
+
|
|
30
|
+
- **Explanations.** `explain(text)` puts what a section means behind one
|
|
31
|
+
mark: a question mark on the line, closed, and the text in the hint
|
|
32
|
+
register under it when it is asked for. A sentence over every table is
|
|
33
|
+
needed on the first day and never again.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **One red per page.** The chosen filter and a current menu are in the
|
|
38
|
+
weight, in ink. The accent is for where you are on the site — the nav,
|
|
39
|
+
the subnav, the page numbers — and for the one thing that cannot be
|
|
40
|
+
undone. A page that said "this one" in red five times above the fold
|
|
41
|
+
had no signal left.
|
|
42
|
+
|
|
43
|
+
- **Hints are prose.** `.hint` is set at body size. The small size is for
|
|
44
|
+
labels and metadata, and a hint set in it at a body line's leading read
|
|
45
|
+
as a list of afterthoughts. Table headings go the other way: the label
|
|
46
|
+
register, bold, on the line.
|
|
47
|
+
|
|
48
|
+
- **The filter block is ruled once, below.** The rule above it was a third
|
|
49
|
+
rule in ten lines, and the rule is the one mark this style draws.
|
|
50
|
+
|
|
5
51
|
## 0.8.0 — 2026-09-07
|
|
6
52
|
|
|
7
53
|
The third consumer, and what it and the second found in common.
|
data/README.md
CHANGED
|
@@ -329,12 +329,36 @@ a run beside them, wrapping under the title when the page is narrow.
|
|
|
329
329
|
|
|
330
330
|
The document is titled from it unless the view has already set `:title`.
|
|
331
331
|
|
|
332
|
+
A page with several surfaces — what a thing is made of, what it wears, how it
|
|
333
|
+
leaves — names them under the title with `sections:`, each a name, a URL and
|
|
334
|
+
whether it is the one shown, and shows that one alone. A working page must
|
|
335
|
+
not scroll: what is done daily is reached from the head, in the same position
|
|
336
|
+
on every page.
|
|
337
|
+
|
|
338
|
+
```erb
|
|
339
|
+
<%= page_head @pattern.name, sections: [ [ "Compose", pattern_path(@pattern), @section == "compose" ],
|
|
340
|
+
[ "Dress", pattern_path(@pattern, section: "dress"), @section == "dress" ] ] do %>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Explanations
|
|
344
|
+
|
|
345
|
+
What a section means, behind one mark. A sentence over every table is needed
|
|
346
|
+
on the first day and never again, and a tool used daily is read on every
|
|
347
|
+
other day; so `explain` writes it in the hint register, closed, and a
|
|
348
|
+
question mark on the line opens it.
|
|
349
|
+
|
|
350
|
+
```erb
|
|
351
|
+
<%= explain "The repeat, in order along the stripe normal." %>
|
|
352
|
+
```
|
|
353
|
+
|
|
332
354
|
### Filters and cards
|
|
333
355
|
|
|
334
356
|
What narrows a list, and the list. A search that filters as you type, and a
|
|
335
357
|
register for each other way of narrowing it — a tag, an order, a size — in the
|
|
336
358
|
same two positions every time: a quiet label, then the choices, the one in
|
|
337
|
-
force carrying `aria-current`, which the CSS
|
|
359
|
+
force carrying `aria-current`, which the CSS sets in the weight. In ink, not
|
|
360
|
+
the accent: the accent is for where you are on the site and for the one
|
|
361
|
+
thing that cannot be undone, and a page has one red.
|
|
338
362
|
|
|
339
363
|
```erb
|
|
340
364
|
<div class="filters">
|
|
@@ -419,7 +443,9 @@ beyond the shell is the application's, for the same reason its grid is.
|
|
|
419
443
|
| `copy_button(value)` | A value that copies itself |
|
|
420
444
|
| `its_swiss_form_with(...)` | `form_with`, already holding the library's builder |
|
|
421
445
|
| `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 |
|
|
446
|
+
| `page_head(title, lede:, sections:) { actions }` | The one shape every page opens with |
|
|
447
|
+
| `page_sections(sections)` | The surfaces of one page, the one shown in the weight |
|
|
448
|
+
| `explain(text) { }` | What a section means, behind one mark |
|
|
423
449
|
| `filter_register(label, choices, name:)` | One register of a filter block |
|
|
424
450
|
| `search_form(url, frame:, keep:)` | A search that narrows a list as you type |
|
|
425
451
|
|
|
@@ -95,10 +95,11 @@
|
|
|
95
95
|
.menu > summary:hover,
|
|
96
96
|
.menu[open] > summary { color: var(--ink); }
|
|
97
97
|
|
|
98
|
-
/* Where you are, when where you are is inside the menu:
|
|
99
|
-
|
|
98
|
+
/* Where you are, when where you are is inside the menu: the weight, in
|
|
99
|
+
ink. Not the accent — a page has one red, and the subnav under a menu
|
|
100
|
+
that is current already names the place in it. */
|
|
100
101
|
.menu--current > summary {
|
|
101
|
-
color: var(--
|
|
102
|
+
color: var(--ink);
|
|
102
103
|
font-weight: 700;
|
|
103
104
|
}
|
|
104
105
|
|
|
@@ -206,6 +207,62 @@
|
|
|
206
207
|
than holding their one-line width and pushing a phone's page sideways. */
|
|
207
208
|
.page-head__actions { flex: 0 1 auto; }
|
|
208
209
|
|
|
210
|
+
/* --- Sections -----------------------------------------------------------
|
|
211
|
+
One page, several surfaces: what a thing is made of, what it wears,
|
|
212
|
+
how it leaves. A run of names under the title, the one you are on in
|
|
213
|
+
the weight, and the surface below it the only thing on the page. A
|
|
214
|
+
working page must not scroll: what is done every day is reached from
|
|
215
|
+
the head, in the same position on every page, and never by scrolling
|
|
216
|
+
past what was done yesterday. */
|
|
217
|
+
.sections {
|
|
218
|
+
display: flex;
|
|
219
|
+
flex-wrap: wrap;
|
|
220
|
+
gap: var(--line) var(--space-3);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* Its own row in the head, under the title and the actions. */
|
|
224
|
+
.page-head > .sections { flex-basis: 100%; }
|
|
225
|
+
|
|
226
|
+
.sections a {
|
|
227
|
+
display: inline-block;
|
|
228
|
+
color: var(--ink-quiet);
|
|
229
|
+
text-decoration: none;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.sections a:hover { color: var(--ink); }
|
|
233
|
+
|
|
234
|
+
/* Where you are, in the weight. Ink, not the accent: the accent is for
|
|
235
|
+
where you are on the site, and this is where you are on the page. */
|
|
236
|
+
.sections [aria-current] {
|
|
237
|
+
color: var(--ink);
|
|
238
|
+
font-weight: 700;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* --- Explanations -------------------------------------------------------
|
|
242
|
+
What a section means, behind one mark, for the day it is first read.
|
|
243
|
+
A sentence over every table is needed on the first day and never
|
|
244
|
+
again, and a tool used daily is read on every other day. So the
|
|
245
|
+
explanation is there, in the hint register, and closed: a question
|
|
246
|
+
mark on the line, and the text under it when it is asked for. A
|
|
247
|
+
details element, so it opens with no script. */
|
|
248
|
+
/* A block as wide as its one character, so the line it sits on is whole
|
|
249
|
+
and the target is the mark and not the row. */
|
|
250
|
+
.explain > summary {
|
|
251
|
+
list-style: none;
|
|
252
|
+
display: block;
|
|
253
|
+
width: max-content;
|
|
254
|
+
cursor: pointer;
|
|
255
|
+
color: var(--ink-quiet);
|
|
256
|
+
font-weight: 700;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.explain > summary::-webkit-details-marker { display: none; }
|
|
260
|
+
|
|
261
|
+
.explain > summary:hover,
|
|
262
|
+
.explain[open] > summary { color: var(--ink); }
|
|
263
|
+
|
|
264
|
+
.explain__body { margin-block-start: var(--line); }
|
|
265
|
+
|
|
209
266
|
/* --- Rules --------------------------------------------------------------
|
|
210
267
|
The one horizontal mark in the style, at the two weights tokens.css
|
|
211
268
|
declares. */
|
|
@@ -301,9 +358,15 @@
|
|
|
301
358
|
vertical-align: top;
|
|
302
359
|
}
|
|
303
360
|
|
|
361
|
+
/* A heading is a label: the label register, bold, on the line. Body size
|
|
362
|
+
made it a second row of values. */
|
|
304
363
|
.table th {
|
|
364
|
+
font-family: var(--face-200), var(--font-family);
|
|
365
|
+
font-size: var(--size-1);
|
|
366
|
+
line-height: var(--line);
|
|
305
367
|
color: var(--ink-quiet);
|
|
306
368
|
font-weight: 700;
|
|
369
|
+
letter-spacing: 0.01em;
|
|
307
370
|
}
|
|
308
371
|
|
|
309
372
|
.table thead th { border-bottom-color: var(--ink); }
|
|
@@ -613,17 +676,19 @@
|
|
|
613
676
|
control: pick one of a handful. A register is a quiet label and then
|
|
614
677
|
the choices, in the same two positions every time, so filtering and
|
|
615
678
|
ordering read as the registers they are rather than as two rows of
|
|
616
|
-
identical words. Ruled
|
|
617
|
-
under it,
|
|
679
|
+
identical words. Ruled below, once: the block belongs to the list
|
|
680
|
+
under it, and the space above it is the page head's. A second rule
|
|
681
|
+
above it was a third rule in ten lines, and the rule is the one mark
|
|
682
|
+
this style draws, so it has to be rare. */
|
|
618
683
|
|
|
619
684
|
.filters {
|
|
620
685
|
display: flex;
|
|
621
686
|
flex-wrap: wrap;
|
|
622
687
|
align-items: flex-start;
|
|
623
688
|
gap: var(--line) var(--space-3);
|
|
624
|
-
/* The
|
|
625
|
-
padding-block: calc(var(--line) - var(--rule-hair));
|
|
626
|
-
border-block: var(--rule-hair) solid var(--rule);
|
|
689
|
+
/* The rule is drawn inside the box, so the block stays whole lines. */
|
|
690
|
+
padding-block-end: calc(var(--line) - var(--rule-hair));
|
|
691
|
+
border-block-end: var(--rule-hair) solid var(--rule);
|
|
627
692
|
margin-block-end: var(--line);
|
|
628
693
|
}
|
|
629
694
|
|
|
@@ -659,9 +724,11 @@
|
|
|
659
724
|
|
|
660
725
|
.filter__choices a:hover { color: var(--ink); }
|
|
661
726
|
|
|
662
|
-
/* Which one is chosen
|
|
727
|
+
/* Which one is chosen: the weight, in ink. The accent is for where you
|
|
728
|
+
are on the site and for the one thing that cannot be undone; a page
|
|
729
|
+
with four registers each saying "this one" in red has no signal left. */
|
|
663
730
|
.filter__choices [aria-current] {
|
|
664
|
-
color: var(--
|
|
731
|
+
color: var(--ink);
|
|
665
732
|
font-weight: 700;
|
|
666
733
|
}
|
|
667
734
|
|
|
@@ -106,9 +106,12 @@
|
|
|
106
106
|
.button--danger,
|
|
107
107
|
.link-quiet { color: var(--ink-quiet); }
|
|
108
108
|
|
|
109
|
+
/* A hint is prose — a sentence about the thing beside it — and prose is
|
|
110
|
+
read at body size. The small size is for labels and metadata, and a
|
|
111
|
+
hint set in it read as a list of afterthoughts. */
|
|
109
112
|
.hint {
|
|
110
|
-
font-family: var(--face-
|
|
111
|
-
font-size: var(--size-
|
|
113
|
+
font-family: var(--face-150), var(--font-family);
|
|
114
|
+
font-size: var(--size-2);
|
|
112
115
|
line-height: var(--line);
|
|
113
116
|
max-width: var(--measure);
|
|
114
117
|
}
|
|
@@ -232,8 +235,10 @@
|
|
|
232
235
|
dd:not(:has(> :is(p, ul, ol, dl, div, figure, table, pre, blockquote))),
|
|
233
236
|
.micro, .hint, .lede, .empty, .masthead__mark, .field__error, .errors__title,
|
|
234
237
|
.filter__label, .card__name, .card__meta,
|
|
238
|
+
.explain > summary,
|
|
235
239
|
/* Flex items are blockified, so the text in a row is trimmable too. */
|
|
236
240
|
.nav a,
|
|
241
|
+
.sections a,
|
|
237
242
|
.menu > summary,
|
|
238
243
|
.menu__list a,
|
|
239
244
|
.subnav a,
|
|
@@ -155,7 +155,13 @@ module ItsSwiss
|
|
|
155
155
|
# <%= page_head "Palettes", lede: "Every palette in the library." do %>
|
|
156
156
|
# <%= link_to "New palette", new_palette_path, class: "button button--primary" %>
|
|
157
157
|
# <% end %>
|
|
158
|
-
|
|
158
|
+
#
|
|
159
|
+
# A page with several surfaces names them under the title, and the one
|
|
160
|
+
# you are on carries the weight:
|
|
161
|
+
#
|
|
162
|
+
# <%= page_head @pattern.name, sections: [ [ "Compose", pattern_path(@pattern), true ],
|
|
163
|
+
# [ "Dress", pattern_path(@pattern, section: "dress"), false ] ] do %>
|
|
164
|
+
def page_head(title, lede: nil, sections: nil, &block)
|
|
159
165
|
content_for(:title, strip_tags(title.to_s)) unless content_for?(:title)
|
|
160
166
|
actions = capture(&block) if block
|
|
161
167
|
|
|
@@ -164,11 +170,35 @@ module ItsSwiss
|
|
|
164
170
|
tag.div(class: "page-head__title") do
|
|
165
171
|
safe_join([ tag.h1(title, class: "page-title"), (tag.p(lede, class: "lede") if lede) ].compact)
|
|
166
172
|
end,
|
|
167
|
-
(tag.div(actions, class: "page-head__actions run") if actions.present?)
|
|
173
|
+
(tag.div(actions, class: "page-head__actions run") if actions.present?),
|
|
174
|
+
(page_sections(sections) if sections.present?)
|
|
168
175
|
].compact)
|
|
169
176
|
end
|
|
170
177
|
end
|
|
171
178
|
|
|
179
|
+
# The surfaces of one page: a name, a URL and whether it is the one
|
|
180
|
+
# shown, each a whole navigation so it survives a reload and can be
|
|
181
|
+
# sent to somebody. The page head places it; on its own it is a nav.
|
|
182
|
+
def page_sections(sections, label: "Sections")
|
|
183
|
+
tag.nav(class: "sections", aria: { label: label }) do
|
|
184
|
+
safe_join(sections.map { |text, url, current| link_to(text, url, aria: { current: ("page" if current) }) })
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# What a section means, behind one mark. The explanation is written in
|
|
189
|
+
# the hint register and closed: a page used daily is read on every day
|
|
190
|
+
# but the first, and a sentence over every table is for the first.
|
|
191
|
+
#
|
|
192
|
+
# <%= explain "The repeat, in order along the stripe normal." %>
|
|
193
|
+
# <%= explain do %><p class="hint">…</p><% end %>
|
|
194
|
+
def explain(text = nil, label: "Explain", &block)
|
|
195
|
+
body = block ? capture(&block) : tag.p(text, class: "hint")
|
|
196
|
+
|
|
197
|
+
tag.details(class: "explain") do
|
|
198
|
+
safe_join([ tag.summary("?", aria: { label: label }), tag.div(body, class: "explain__body") ])
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
172
202
|
# One register of a filter block: a quiet label, then the choices, each
|
|
173
203
|
# a name, a URL and whether it is the one in force. Filtering and
|
|
174
204
|
# ordering are the same kind of control — pick one of a handful — so
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
What narrows a list, and the list. A search that filters as you type, and
|
|
5
5
|
a register for each other way of narrowing it: the same two positions
|
|
6
6
|
every time, a quiet label and the choices, the one in force carrying the
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
weight. Under it, cards on the page's own fields — this page says a card
|
|
8
|
+
is two fields wide.
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<div class="filters">
|
|
@@ -12,4 +12,22 @@
|
|
|
12
12
|
<a href="#page-head" class="button">New from this</a>
|
|
13
13
|
<a href="#page-head" class="button button--danger">Delete palette</a>
|
|
14
14
|
<% end %>
|
|
15
|
+
|
|
16
|
+
<h4>Sections</h4>
|
|
17
|
+
<p class="hint">
|
|
18
|
+
A page with several surfaces names them under the title, the one shown
|
|
19
|
+
in the weight, and shows that one alone. What is done daily is reached
|
|
20
|
+
from the head, never by scrolling past what was done yesterday.
|
|
21
|
+
</p>
|
|
22
|
+
<%= page_head "Deck Chair", sections: [ [ "Compose", "#page-head", true ], [ "Dress", "#page-head", false ], [ "Export", "#page-head", false ] ] do %>
|
|
23
|
+
<a href="#page-head" class="button button--primary">Dress this pattern</a>
|
|
24
|
+
<a href="#page-head" class="button button--quiet">Rename</a>
|
|
25
|
+
<% end %>
|
|
26
|
+
|
|
27
|
+
<h4>Explanations</h4>
|
|
28
|
+
<p class="hint">
|
|
29
|
+
What a section means, behind one mark, for the day it is first read.
|
|
30
|
+
Closed, in the hint register, and there when it is asked for.
|
|
31
|
+
</p>
|
|
32
|
+
<%= explain "The repeat, in order along the stripe normal. Widths sum to one." %>
|
|
15
33
|
</section>
|
data/lib/its_swiss/version.rb
CHANGED