@redseed/redseed-ui-tailwindcss 7.68.0 → 7.69.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.
@@ -61,8 +61,29 @@
61
61
  @apply sticky top-0 z-1 p-0 bg-background-secondary shrink-0 text-lg font-semibold;
62
62
  }
63
63
 
64
+ /* ---------------------------------------------------------------------------
65
+ Padding, and why it is written as three shorthands rather than @apply p-*
66
+
67
+ Each region used to pay for all four of its own sides — `p-space-md` on all
68
+ three — so the 16px below the header met the 16px above the body: 32px
69
+ between a dialog's title and its first line, 32px again before the buttons,
70
+ against 16px at the edges. The seams ended up twice the margin, which is
71
+ what you get when neighbours both pay for the gap between them.
72
+
73
+ So the two INNER edges are zeroed and the body carries them. Each region
74
+ still behaves when one of the others is absent, which matters because all
75
+ three modifiers are independent props a consumer can turn off.
76
+
77
+ The values are Material's dialog: 24 at every edge, 16 from the headline to
78
+ the supporting text, 24 from the supporting text to the buttons.
79
+
80
+ Longhand rather than Tailwind's `p-*` utilities on purpose — these are
81
+ three-value shorthands with a different value per edge, and `@apply
82
+ pt-space-lg px-space-lg pb-0` is four utilities to say what one declaration
83
+ says, with the seam buried in the last one.
84
+ --------------------------------------------------------------------------- */
64
85
  .rsui-modal__header--padded {
65
- @apply p-space-md;
86
+ padding: 1.5rem 1.5rem 0;
66
87
  }
67
88
 
68
89
  .rsui-modal__body {
@@ -71,8 +92,11 @@
71
92
  scrollbar-width: none;
72
93
  }
73
94
 
95
+ /* Carries both seams — 16px up to the header, 24px down to the footer — as well
96
+ as its own side edges. With no footer the 24px is simply the bottom of the
97
+ dialog, which is the same number, so nothing special is needed for that case. */
74
98
  .rsui-modal__body--padded {
75
- @apply p-space-md;
99
+ padding: 1rem 1.5rem 1.5rem;
76
100
  }
77
101
 
78
102
  .rsui-modal__body::-webkit-scrollbar {
@@ -85,9 +109,31 @@
85
109
  padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
86
110
  }
87
111
 
112
+ /* The footer pays for ALL FOUR of its own sides, unlike the header above.
113
+
114
+ That asymmetry is deliberate and it is about the banding. The header and body
115
+ share no visible boundary in the places it matters, so zeroing the header's
116
+ bottom edge and letting the body carry it reads as one gap. The footer does
117
+ not: it has its own background (background-secondary against the body's
118
+ primary), so the boundary is a visible edge and the buttons sit INSIDE a band
119
+ of their own. Borrowing the space above them from the body left them jammed
120
+ against the top of that band with 24px below — measured at 0 above, 24 below.
121
+
122
+ So the seam here is the body's 24px bottom plus the footer's 24px top. That is
123
+ more than the 24px between the title and the body, which is the right way
124
+ round: a button row is a different kind of thing from a paragraph, and the
125
+ band is already announcing that.
126
+
127
+ If the banding ever goes (the other half of #373), this should drop back to
128
+ `0 1.5rem 1.5rem` and let the body carry the seam, the way the header does.
129
+
130
+ The bottom keeps its safe-area floor — a footer is the last thing above the
131
+ home indicator on a phone, so the value is a minimum rather than a fixed
132
+ amount, and it rises with the padding (1rem -> 1.5rem) or a footer would sit
133
+ closer to the bottom edge than to its own buttons. */
88
134
  .rsui-modal__footer--padded {
89
- @apply p-space-md;
90
- padding-bottom: max(1rem, env(safe-area-inset-bottom));
135
+ padding: 1.5rem;
136
+ padding-bottom: max(1.5rem, env(safe-area-inset-bottom));
91
137
  }
92
138
 
93
139
  .rsui-modal__footer--start {
@@ -208,26 +208,107 @@
208
208
  @apply flex-1 flex flex-wrap gap-space-xs items-center justify-end;
209
209
  }
210
210
 
211
- .rsui-page-header__meta-action {
212
- @apply flex lg:hidden;
213
- }
214
-
215
211
  .rsui-page-header__search {
216
212
  @apply w-full pt-space-xs lg:pt-0 lg:w-auto;
217
213
  }
218
214
 
219
- .rsui-page-header__meta-modal {
220
- @apply lg:hidden;
215
+ /* ---------------------------------------------------------------------------
216
+ Meta
217
+
218
+ Visible at every width. It was `hidden lg:flex`, so the facts a header exists
219
+ to carry vanished below 1024px and a modal reproduced them — on a phone, where
220
+ a reader has least context to spare and least patience for a dialog.
221
+
222
+ A grid, not a flex row, and content-width rather than full-bleed: meta reads
223
+ as one cluster beside the title rather than a band across the page. Four
224
+ columns from sm up; two on a phone, because four 16px labels in 375px is not a
225
+ grid, it is a queue.
226
+
227
+ The cap is `:nth-child` rather than a count in JS. `#meta` is a slot and every
228
+ consumer fills it with a `v-for`, so the component cannot know how many facts
229
+ there are — but CSS does not need to know. Past the fourth, they are hidden
230
+ until the toggle expands the row.
231
+ --------------------------------------------------------------------------- */
232
+ /* The region is the grid. The facts sit inside a `display: contents` wrapper so
233
+ they become direct grid items without the toggle joining their `:nth-child`
234
+ sequence — see the note in PageHeader.vue. */
235
+ .rsui-page-header__meta-region {
236
+ @apply grid w-fit max-w-full items-start;
237
+ @apply gap-x-space-lg gap-y-space-md;
238
+
239
+ /* Columns sized to content, and the SAME count in both states.
240
+
241
+ An earlier version went five columns collapsed and four expanded, so the
242
+ toggle would sit in the row rather than wrap. That moved every fact
243
+ sideways when pressed — 13.7px with `1fr`, up to 40px with `max-content`,
244
+ because both make a column's width depend on something the toggle changes.
245
+ Holding the count fixed removes the question: the toggle occupies the
246
+ fifth cell while collapsed, and the fifth fact takes it once expanded.
247
+
248
+ The width has to be FIXED, not `max-content`. Holding the count steady is
249
+ not enough on its own: `max-content` sizes each column to whatever lands in
250
+ it, and expanding puts different facts in different columns, so they still
251
+ moved — 27px, measured. A fixed track depends on neither the count nor the
252
+ content.
253
+
254
+ 6rem, against a widest-ink measurement of 90px across every label and value
255
+ in the busiest real header. Anything longer wraps inside its own cell
256
+ rather than pushing its neighbours. */
257
+ grid-template-columns: repeat(2, 6rem);
221
258
  }
222
259
 
223
- .rsui-page-header__meta-modal__body {
224
- @apply flex flex-col gap-y-space-md;
260
+ @media (min-width: 40rem) {
261
+ .rsui-page-header__meta-region {
262
+ grid-template-columns: repeat(5, 6rem);
263
+ }
225
264
  }
226
265
 
227
266
  .rsui-page-header__meta {
228
- @apply hidden lg:flex gap-x-space-xl;
267
+ display: contents;
268
+ }
269
+
270
+ /* Past the cap, hidden until expanded. `> *` rather than a component class so it
271
+ does not care what a consumer puts in the slot — MetaInfo today, something
272
+ else tomorrow. The toggle is excluded by its own rule below, which comes
273
+ later and wins. */
274
+ .rsui-page-header__meta > *:nth-child(n + 5) {
275
+ @apply hidden;
276
+ }
277
+
278
+ .rsui-page-header__meta--expanded > *:nth-child(n + 5) {
279
+ @apply block;
229
280
  }
230
281
 
282
+ /* The toggle sits where the fifth fact would be, so pressing it expands the row
283
+ around it rather than moving it. Always shown, whatever the cap is doing. */
284
+ .rsui-page-header__meta-toggle {
285
+ /* Centred against the fact beside it, not `self-start`. A fact is a two-line
286
+ unit — a 16px label over a 16px value, 36px in all — so a 20px toggle
287
+ pinned to the top reads as belonging to the LABELS rather than to the pair.
288
+ Centre also survives the expanded state, where the toggle wraps to its own
289
+ row and has no value to sit level with. */
290
+ @apply inline-flex w-fit items-center whitespace-nowrap self-center;
291
+ @apply text-sm font-semibold no-underline cursor-pointer transition-colors;
292
+ @apply text-button-tertiary hover:text-button-tertiary-hover;
293
+ @apply hover:underline underline-offset-4 decoration-2;
294
+ @apply focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-button-tertiary outline-hidden;
295
+
296
+ /* min-width, because the label changes length as it toggles — "+2 more"
297
+ against "Show fewer" — and without a floor the row shifts sideways under
298
+ the pointer mid-press. Same fix CategoryList carries (#355). */
299
+ @apply min-w-20 justify-center;
300
+
301
+ /* The negative margin pulls it back from the grid's 32px column gap to the
302
+ 16px CategoryList uses. 32px is right between two FACTS, which read as
303
+ separate label/value pairs; it is too far for an affordance trailing them,
304
+ and the two rows sit one above the other in the same header — `+4 more`
305
+ under categories and `+3 more` under meta must not be spaced differently. */
306
+ @apply -ms-space-md;
307
+ }
308
+
309
+
310
+
311
+
231
312
  .rsui-page-header__avatar {
232
313
  @apply shrink-0 size-12;
233
314
  }
@@ -439,7 +520,10 @@
439
520
  color: var(--rsui-page-header-accent, var(--rsui-page-header-ink));
440
521
  }
441
522
 
442
- .rsui-page-header--toned .rsui-page-header__meta {
523
+ /* On the REGION, not on `__meta`. The facts element is `display: contents` so it
524
+ generates no box at all — a border declared there paints nothing, and this
525
+ separator silently disappeared when the grid moved up a level. Measured. */
526
+ .rsui-page-header--toned .rsui-page-header__meta-region {
443
527
  border-top: 1px solid var(--rsui-page-header-rule);
444
528
 
445
529
  @apply mt-space-md pt-space-md;
@@ -484,3 +568,19 @@
484
568
  .rsui-page-header--toned .rsui-category-list__more {
485
569
  color: var(--rsui-page-header-ink);
486
570
  }
571
+
572
+ /* The meta toggle borrows the same tertiary green and disappears on the same dark
573
+ band — measured as near-invisible on Journey Green 800. Same fix, same reason:
574
+ an invisible control is worse than reaching for the tone's ink.
575
+
576
+ Hover included, because the hover colour is a second tertiary green and would
577
+ make the control vanish again the moment a pointer reached it. */
578
+ .rsui-page-header--toned .rsui-page-header__meta-toggle {
579
+ color: var(--rsui-page-header-ink);
580
+ }
581
+
582
+ /* Hover separately: the hover colour is a second tertiary green, so without this
583
+ the control vanishes again the moment a pointer reaches it. */
584
+ .rsui-page-header--toned .rsui-page-header__meta-toggle:hover {
585
+ color: var(--rsui-page-header-ink);
586
+ }
@@ -22,8 +22,19 @@
22
22
  @apply border-border-primary;
23
23
  }
24
24
 
25
+ /* A clickable header is a control, so it takes the library's focus ring rather
26
+ than the browser's. Without `outline-hidden` a `tabindex="0"` div falls through
27
+ to the UA default ring, which is the wrong colour and shape for this library.
28
+
29
+ Keyboard only, verified with a real click rather than a dispatched event: the
30
+ browser knows a genuine mouse press from a synthetic one, and `:focus-visible`
31
+ is false after the real thing. (A dispatched MouseEvent reports true even on a
32
+ plain <button>, so a probe built that way proves nothing.)
33
+
34
+ Same declaration CardHeader already carries for the same situation. */
25
35
  .rsui-section-header--clickable {
26
36
  @apply cursor-pointer;
37
+ @apply focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-primary outline-hidden;
27
38
  }
28
39
 
29
40
  .rsui-section-header__header {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redseed/redseed-ui-tailwindcss",
3
- "version": "7.68.0",
3
+ "version": "7.69.0",
4
4
  "description": "RedSeed UI Tailwindcss",
5
5
  "main": "index.js",
6
6
  "style": "index.css",