@stapel/search-react 0.32.6 → 0.32.8

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.
@@ -122,9 +122,34 @@ export const RESULTS_MAX_WIDTH = 1400;
122
122
  * bought went into card whitespace, not into legibility, and cost a whole
123
123
  * column of listings on the reference desktop.
124
124
  */
125
+ export const RESULTS_AUTO_FILL_COLUMNS = "repeat(auto-fill, minmax(260px, 1fr))";
126
+
125
127
  const RESULTS_GRID: CSSProperties = {
126
128
  display: "grid",
127
- gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))",
129
+ gridTemplateColumns: RESULTS_AUTO_FILL_COLUMNS,
130
+ gap: spacing[3],
131
+ alignItems: "stretch",
132
+ };
133
+
134
+ /**
135
+ * The same grid with the track declaration REMOVED, for the responsive column
136
+ * map — because an inline declaration beats a stylesheet, `!important` or not.
137
+ *
138
+ * The map's rules had nothing to win against: they were hung on a class on the
139
+ * very node that also carried `grid-template-columns: repeat(auto-fill, …)` as
140
+ * an inline style, and the browser resolves that in the inline's favour every
141
+ * time. A stand measuring `{ phone: 1, tablet: 2 }` read pure auto-fill (two
142
+ * columns at 759px, one at 448, three at 1199) — the prop was inert in a
143
+ * browser while every unit test on the emitted CSS string stayed green.
144
+ *
145
+ * A fixed count writes itself inline instead (there is one number and no
146
+ * cascade to run), so this shape is only for the map, whose base rung the
147
+ * sheet now always states — auto-fill when `phone` is left out, so "a key left
148
+ * out inherits the rung below it" still holds with nothing inline to inherit
149
+ * from.
150
+ */
151
+ const RESULTS_GRID_UNSET_COLUMNS: CSSProperties = {
152
+ display: "grid",
128
153
  gap: spacing[3],
129
154
  alignItems: "stretch",
130
155
  };
@@ -184,10 +209,18 @@ export function resultsColumnsCss(columns: ResultsColumns): string {
184
209
  if (typeof columns === "number") {
185
210
  return `${block}{grid-template-columns:${fixedColumns(columns)}}`;
186
211
  }
187
- const rules = [`${block}{container-type:inline-size}`];
188
- if (columns.phone !== undefined) {
189
- rules.push(`${block}{grid-template-columns:${fixedColumns(columns.phone)}}`);
190
- }
212
+ // The base rung is always stated, because the pane no longer writes the
213
+ // auto-fill inline when a map is in play: with nothing inline to fall back
214
+ // to, "a key left out inherits the rung below it" has to mean the default
215
+ // grid, said out loud.
216
+ const rules = [
217
+ `${block}{container-type:inline-size}`,
218
+ `${block}{grid-template-columns:${
219
+ columns.phone === undefined
220
+ ? RESULTS_AUTO_FILL_COLUMNS
221
+ : fixedColumns(columns.phone)
222
+ }}`,
223
+ ];
191
224
  for (const rung of [
192
225
  { at: breakpoints.tablet, count: columns.tablet },
193
226
  { at: breakpoints.desktop, count: columns.desktop },
@@ -322,6 +355,11 @@ export interface SearchResultsPaneProps extends ThemeModeProp {
322
355
  * against the width of this BLOCK rather than of the window, because the
323
356
  * filter rail takes 280px of that window and the cards never see it.
324
357
  *
358
+ * Whichever shape is given, the pane stops writing the auto-fill default as
359
+ * an inline style on the grid: an inline declaration beats the column sheet
360
+ * in every browser, which is how this prop shipped inert (a stand set
361
+ * `{ phone: 1, tablet: 2 }` and measured pure auto-fill).
362
+ *
325
363
  * Ignored by `layout="list"` (one row per result IS one column) and by
326
364
  * `renderResults`, which replaces the arrangement entirely.
327
365
  */
@@ -469,6 +507,24 @@ export function SearchResultsPane(props: SearchResultsPaneProps): ReactElement {
469
507
  props.columns === undefined || props.layout === "list"
470
508
  ? null
471
509
  : resultsColumnsCss(props.columns);
510
+ /**
511
+ * The tracks the NODE carries, which is the only declaration a browser
512
+ * actually resolves for it.
513
+ *
514
+ * An inline style beats a stylesheet rule at any specificity, so the pane
515
+ * must not write the auto-fill default onto the same node the column sheet
516
+ * targets: a fixed count is written inline (one number, no cascade to run)
517
+ * and a map leaves the property unset inline so its own rungs — base plus
518
+ * container queries — are the only ones in play.
519
+ */
520
+ const gridStyle: CSSProperties =
521
+ props.layout === "list"
522
+ ? RESULTS_LIST
523
+ : columnRules === null
524
+ ? RESULTS_GRID
525
+ : typeof props.columns === "number"
526
+ ? { ...RESULTS_GRID, gridTemplateColumns: fixedColumns(props.columns) }
527
+ : RESULTS_GRID_UNSET_COLUMNS;
472
528
 
473
529
  return (
474
530
  <SkinTheme
@@ -587,7 +643,7 @@ export function SearchResultsPane(props: SearchResultsPaneProps): ReactElement {
587
643
  renderResults(items)
588
644
  ) : (
589
645
  <div
590
- style={props.layout === "list" ? RESULTS_LIST : RESULTS_GRID}
646
+ style={gridStyle}
591
647
  // The class carries the host's column count; without one
592
648
  // it is absent and the `auto-fill` default is the only
593
649
  // rule in play.
@@ -46,7 +46,11 @@ export {
46
46
  RAIL_STYLE_HREF,
47
47
  railScrollbarCss,
48
48
  } from "./SearchPage.js";
49
- export type { SearchPageProps, SearchFiltersLayout } from "./SearchPage.js";
49
+ export type {
50
+ SearchPageProps,
51
+ SearchFiltersLayout,
52
+ SearchRailFrom,
53
+ } from "./SearchPage.js";
50
54
 
51
55
  export {
52
56
  OtherCategoriesLine,
@@ -66,6 +70,7 @@ export type {
66
70
  export {
67
71
  SearchResultsPane,
68
72
  RESULTS_MAX_WIDTH,
73
+ RESULTS_AUTO_FILL_COLUMNS,
69
74
  RESULTS_COLUMNS_CLASS,
70
75
  RESULTS_COLUMNS_STYLE_HREF,
71
76
  resultsColumnsCss,