Skip to main content

max / makenotwork

3.4 KB · 65 lines History Blame Raw
1 //! Widgets: named assemblies of things the description already says.
2 //!
3 //! The third tier, between a primitive and `Region::Bespoke`. A primitive is
4 //! drawn from scratch by every renderer and has to be something every host can
5 //! honour; a bespoke region is one app's own and carries no contents the
6 //! description knows. A widget is neither: a *name* over an assembly of members
7 //! the vocabulary already has.
8 //!
9 //! Full argument: wiki `widget-tier`.
10 //!
11 //! # What is left here
12 //!
13 //! Glue, and only glue. The widgets themselves live in `quasi-basics`, which is
14 //! where the carousel went once it had been proved against three real pages.
15 //! Each module here is an Askama entry point: it turns whatever the templates
16 //! happened to need into the widget's own types, renders the fragment, and
17 //! stops.
18 //!
19 //! A widget that has never rendered anything is a guess about what the assembly
20 //! needs, so a new one is welcome to start here and leave later. The carousel
21 //! found a missing primitive on its way through
22 //! (`makeover_layout::Image`, 0.21.0), which is the argument for proving one in
23 //! an app before it becomes shared.
24 //!
25 //! # A primitive's glue is a sibling of this directory, never a member
26 //!
27 //! Ruled by Max 2026-08-21 (`27d5e5b8`), and written here because this doc is
28 //! what gets read when someone asks where a described fragment goes.
29 //!
30 //! **A described fragment inside an Askama page is legitimate at any
31 //! granularity the vocabulary already names, primitive included.** One `Field`
32 //! qualifies; so does one `Act`. The question was whether that made a single
33 //! primitive a widget, and the answer is that it does not — it makes it a
34 //! primitive with an entry point. So the glue module sits at `src/quasi/`,
35 //! beside `rich_field.rs`, `upload_field.rs` and `export_act.rs`, and this
36 //! directory keeps meaning what the paragraphs above say it means: a name over
37 //! an assembly. The "misuses the word widget" objection is answered by
38 //! placement rather than by declining the pattern.
39 //!
40 //! What it buys is that a shared control converts at its own granularity
41 //! instead of once per parent. `export_act.rs` is the first one taken: five
42 //! Export CSV buttons in four templates, described once. The same applies to
43 //! the shared act rows — `partials/link_row.html`, `partials/tag.html`, and the
44 //! two identical delete buttons in `tabs/project_content.html` and
45 //! `tabs/project_blog.html`.
46 //!
47 //! ## What it costs, stated so it is not rediscovered
48 //!
49 //! A live visual change on a page no flag gates. The templates write
50 //! `class="btn-secondary text-sm"` and a described act emits `class="button"`,
51 //! so the control lands on the design system's button rather than the app's:
52 //! `--surface-raised` and `--bevel-raised` where `.btn-secondary` sets
53 //! `--surface-sunken`, `--shadow-raised` and its own padding and font size.
54 //! That is the swap, it is deliberate, and it wants an eyeball rather than a
55 //! test.
56 //!
57 //! It is not, any more, a loss of the design system's button altogether.
58 //! `35756077` measured that `style.css` is unlayered and outranks
59 //! `@layer makeover` at any specificity, so a bare `button { }` rule was taking
60 //! the surface, the bevel **and the tone** off every described act. Fixed by
61 //! the `revert-layer` handoff at `style.css:473`. A described act that reaches
62 //! for `Tone::Danger` gets it now, which it did not before 2026-08-21.
63
64 pub mod carousel;
65