@stapel/search-react 0.34.0 → 0.35.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.
- package/CHANGELOG.md +60 -0
- package/dist/default/FacetGroupControl.d.ts +32 -0
- package/dist/default/FacetGroupControl.d.ts.map +1 -1
- package/dist/default/FacetGroupControl.js +101 -2
- package/dist/default/FacetGroupControl.js.map +1 -1
- package/dist/default/FacetPanelPane.d.ts +25 -0
- package/dist/default/FacetPanelPane.d.ts.map +1 -1
- package/dist/default/FacetPanelPane.js +15 -5
- package/dist/default/FacetPanelPane.js.map +1 -1
- package/dist/default/SearchPage.d.ts +24 -0
- package/dist/default/SearchPage.d.ts.map +1 -1
- package/dist/default/SearchPage.js +21 -6
- package/dist/default/SearchPage.js.map +1 -1
- package/dist/default/index.d.ts +1 -1
- package/dist/default/index.d.ts.map +1 -1
- package/dist/default/index.js +1 -1
- package/dist/default/index.js.map +1 -1
- package/llms.txt +1 -1
- package/manifest.json +1 -1
- package/nav-manifest.json +1 -1
- package/package.json +4 -4
- package/src/analytics/generated/events.json +1 -1
- package/src/default/FacetGroupControl.tsx +120 -2
- package/src/default/FacetPanelPane.tsx +45 -3
- package/src/default/SearchPage.tsx +60 -2
- package/src/default/index.ts +5 -0
|
@@ -312,6 +312,14 @@ export interface SearchPageProps extends ThemeModeProp, ParseSearchStateOptions
|
|
|
312
312
|
readonly adapter: SearchParamsAdapter;
|
|
313
313
|
readonly renderCard?: SearchCardRenderer;
|
|
314
314
|
readonly categoryFeatures?: readonly FeatureDef[];
|
|
315
|
+
/**
|
|
316
|
+
* The schema is ON ITS WAY — the third state `categoryFeatures` does not
|
|
317
|
+
* have. Handed straight to the filter panel, which holds the box it already
|
|
318
|
+
* reserves rather than drawing a rail it is about to re-shape and re-order.
|
|
319
|
+
* See {@link FacetPanelPaneProps.categoryFeaturesPending} for what was
|
|
320
|
+
* measured without it (p41).
|
|
321
|
+
*/
|
|
322
|
+
readonly categoryFeaturesPending?: boolean;
|
|
315
323
|
readonly locale?: string;
|
|
316
324
|
/**
|
|
317
325
|
* Name the facet values neither the answer nor the category schema names —
|
|
@@ -431,6 +439,22 @@ export interface SearchPageProps extends ThemeModeProp, ParseSearchStateOptions
|
|
|
431
439
|
* sense that matters and not a decoration bolted on top.
|
|
432
440
|
*/
|
|
433
441
|
readonly filtersHeader?: ReactNode;
|
|
442
|
+
/**
|
|
443
|
+
* The block-size that slot will END UP at, declared before it has anything
|
|
444
|
+
* in it — a number in CSS pixels or any length (`"96px"`, `"6rem"`).
|
|
445
|
+
*
|
|
446
|
+
* For the host whose header is a SEPARATE read from the search: a category
|
|
447
|
+
* page's partition row is two chained catalogue requests behind the answer,
|
|
448
|
+
* so the rail draws its groups first and the row drops in over them a beat
|
|
449
|
+
* later, pushing every filter under it down (p41). The band is in flow from
|
|
450
|
+
* the first frame with this set — an empty box of the right height, then the
|
|
451
|
+
* control inside it — and the pair never guesses the number, because the
|
|
452
|
+
* height of a control it does not own is not the pair's to know.
|
|
453
|
+
*
|
|
454
|
+
* A FLOOR, like every other reservation here: a header taller than the
|
|
455
|
+
* declared number still takes the room it needs.
|
|
456
|
+
*/
|
|
457
|
+
readonly filtersHeaderReserve?: number | string;
|
|
434
458
|
/**
|
|
435
459
|
* The row ABOVE the chips and the results — where `<LocationSummaryLine>`
|
|
436
460
|
* goes on the phone SERP.
|
|
@@ -679,6 +703,8 @@ interface SearchPageBodyProps {
|
|
|
679
703
|
readonly dictionaryMode?: "field" | "inline" | "sheet";
|
|
680
704
|
readonly visibleGroups?: number | null;
|
|
681
705
|
readonly categoryFeatures?: readonly FeatureDef[];
|
|
706
|
+
readonly categoryFeaturesPending?: boolean;
|
|
707
|
+
readonly filtersHeaderReserve?: number | string;
|
|
682
708
|
readonly renderEmptyExits?: () => ReactNode;
|
|
683
709
|
readonly locale?: string;
|
|
684
710
|
readonly pinnedFacets?: readonly string[];
|
|
@@ -787,7 +813,13 @@ function SearchPageBody(props: SearchPageBodyProps): ReactElement {
|
|
|
787
813
|
// have called that column empty.
|
|
788
814
|
...(facets.ranges !== undefined ? { ranges: facets.ranges } : {}),
|
|
789
815
|
});
|
|
816
|
+
/* A schema still in flight makes every reading below provisional — see
|
|
817
|
+
`FacetPanelPaneProps.categoryFeaturesPending`. "Nothing to filter by" in
|
|
818
|
+
particular: the groups in hand are the ones the panel is about to redraw,
|
|
819
|
+
and a column closed on them would open again a beat later. */
|
|
820
|
+
const schemaPending = props.categoryFeaturesPending === true;
|
|
790
821
|
const filtersEmpty =
|
|
822
|
+
!schemaPending &&
|
|
791
823
|
facets.state.status === "ready" &&
|
|
792
824
|
facets.state.data.length === 0 &&
|
|
793
825
|
// `withheld` (groups the server counted and held back for covering too
|
|
@@ -806,11 +838,28 @@ function SearchPageBody(props: SearchPageBodyProps): ReactElement {
|
|
|
806
838
|
props.renderCategoryFilter === undefined)) &&
|
|
807
839
|
state.lang === undefined &&
|
|
808
840
|
(props.languages ?? []).length === 0;
|
|
809
|
-
const showFilters =
|
|
841
|
+
const showFilters =
|
|
842
|
+
filtersHeader !== undefined ||
|
|
843
|
+
props.filtersHeaderReserve !== undefined ||
|
|
844
|
+
!filtersEmpty;
|
|
810
845
|
|
|
811
846
|
const panel = (
|
|
812
847
|
<Flex vertical gap={spacing[4]}>
|
|
813
|
-
{
|
|
848
|
+
{/* THE HOST'S BAND, IN FLOW FROM THE FIRST FRAME (p41). The wrapper is
|
|
849
|
+
drawn whenever there is something to draw OR a height to hold, so a
|
|
850
|
+
header that arrives with a second read lands INTO its box rather than
|
|
851
|
+
inserting one above the groups. See `filtersHeaderReserve`. */}
|
|
852
|
+
{(filtersHeader !== undefined ||
|
|
853
|
+
props.filtersHeaderReserve !== undefined) && (
|
|
854
|
+
<div
|
|
855
|
+
data-testid="search-filters-header"
|
|
856
|
+
{...(props.filtersHeaderReserve !== undefined
|
|
857
|
+
? { style: { minBlockSize: props.filtersHeaderReserve } }
|
|
858
|
+
: {})}
|
|
859
|
+
>
|
|
860
|
+
{filtersHeader}
|
|
861
|
+
</div>
|
|
862
|
+
)}
|
|
814
863
|
{/* The facet panel is skipped entirely when the only thing it would draw
|
|
815
864
|
is its own empty state and the column is open for the host's control
|
|
816
865
|
alone — one empty-state illustration under a working filter is still
|
|
@@ -841,6 +890,9 @@ function SearchPageBody(props: SearchPageBodyProps): ReactElement {
|
|
|
841
890
|
: 16
|
|
842
891
|
}
|
|
843
892
|
{...(categoryFeatures !== undefined ? { categoryFeatures } : {})}
|
|
893
|
+
{...(props.categoryFeaturesPending !== undefined
|
|
894
|
+
? { categoryFeaturesPending: props.categoryFeaturesPending }
|
|
895
|
+
: {})}
|
|
844
896
|
{...(props.renderEmptyExits !== undefined
|
|
845
897
|
? { renderEmptyExits: props.renderEmptyExits }
|
|
846
898
|
: {})}
|
|
@@ -1094,6 +1146,7 @@ export function SearchPage(props: SearchPageProps): ReactElement {
|
|
|
1094
1146
|
adapter,
|
|
1095
1147
|
renderCard,
|
|
1096
1148
|
categoryFeatures,
|
|
1149
|
+
categoryFeaturesPending,
|
|
1097
1150
|
locale,
|
|
1098
1151
|
resolveFacetLabels,
|
|
1099
1152
|
searchBox,
|
|
@@ -1106,6 +1159,7 @@ export function SearchPage(props: SearchPageProps): ReactElement {
|
|
|
1106
1159
|
geoOffer,
|
|
1107
1160
|
footer,
|
|
1108
1161
|
filtersHeader,
|
|
1162
|
+
filtersHeaderReserve,
|
|
1109
1163
|
resultsHeader,
|
|
1110
1164
|
resultsLead,
|
|
1111
1165
|
categoryFilter,
|
|
@@ -1149,6 +1203,9 @@ export function SearchPage(props: SearchPageProps): ReactElement {
|
|
|
1149
1203
|
{...(visibleGroups !== undefined ? { visibleGroups } : {})}
|
|
1150
1204
|
{...(pinnedFacets !== undefined ? { pinnedFacets } : {})}
|
|
1151
1205
|
{...(categoryFeatures !== undefined ? { categoryFeatures } : {})}
|
|
1206
|
+
{...(categoryFeaturesPending !== undefined
|
|
1207
|
+
? { categoryFeaturesPending }
|
|
1208
|
+
: {})}
|
|
1152
1209
|
{...(locale !== undefined ? { locale } : {})}
|
|
1153
1210
|
{...(resolveFacetLabels !== undefined ? { resolveFacetLabels } : {})}
|
|
1154
1211
|
{...(searchBox !== undefined ? { searchBox } : {})}
|
|
@@ -1160,6 +1217,7 @@ export function SearchPage(props: SearchPageProps): ReactElement {
|
|
|
1160
1217
|
{...(skippedNotice !== undefined ? { skippedNotice } : {})}
|
|
1161
1218
|
{...(footer !== undefined ? { footer } : {})}
|
|
1162
1219
|
{...(filtersHeader !== undefined ? { filtersHeader } : {})}
|
|
1220
|
+
{...(filtersHeaderReserve !== undefined ? { filtersHeaderReserve } : {})}
|
|
1163
1221
|
{...(resultsHeader !== undefined ? { resultsHeader } : {})}
|
|
1164
1222
|
{...(resultsLead !== undefined ? { resultsLead } : {})}
|
|
1165
1223
|
{...(categoryFilter !== undefined ? { categoryFilter } : {})}
|
package/src/default/index.ts
CHANGED
|
@@ -122,10 +122,15 @@ export type { LocationSummaryLineProps } from "./LocationSummaryLine.js";
|
|
|
122
122
|
export {
|
|
123
123
|
FacetGroupControl,
|
|
124
124
|
facetGroupIsEmptyHeading,
|
|
125
|
+
facetGroupReservedHeight,
|
|
125
126
|
facetGroupShape,
|
|
126
127
|
facetOptionNodes,
|
|
127
128
|
isDictionaryFacet,
|
|
128
129
|
FACET_DICTIONARY_THRESHOLD,
|
|
130
|
+
FACET_HEADING_HEIGHT,
|
|
131
|
+
FACET_OPTION_ROW_HEIGHT,
|
|
132
|
+
FACET_PILLS_PER_ROW,
|
|
133
|
+
FACET_PILL_ROW_HEIGHT,
|
|
129
134
|
FACET_SHEET_PAGE,
|
|
130
135
|
FACET_VISIBLE_OPTIONS,
|
|
131
136
|
} from "./FacetGroupControl.js";
|