@stapel/search-react 0.7.0 → 0.8.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 +40 -0
- package/dist/default/FacetGroupControl.d.ts +40 -0
- package/dist/default/FacetGroupControl.d.ts.map +1 -0
- package/dist/default/FacetGroupControl.js +176 -0
- package/dist/default/FacetGroupControl.js.map +1 -0
- package/dist/default/FacetPanelPane.d.ts.map +1 -1
- package/dist/default/FacetPanelPane.js +3 -9
- package/dist/default/FacetPanelPane.js.map +1 -1
- package/dist/default/FilterChips.d.ts +28 -0
- package/dist/default/FilterChips.d.ts.map +1 -0
- package/dist/default/FilterChips.js +204 -0
- package/dist/default/FilterChips.js.map +1 -0
- package/dist/default/SearchPage.d.ts +40 -0
- package/dist/default/SearchPage.d.ts.map +1 -1
- package/dist/default/SearchPage.js +45 -9
- package/dist/default/SearchPage.js.map +1 -1
- package/dist/default/SearchResultsPane.d.ts +19 -0
- package/dist/default/SearchResultsPane.d.ts.map +1 -1
- package/dist/default/SearchResultsPane.js +15 -2
- package/dist/default/SearchResultsPane.js.map +1 -1
- package/dist/default/ViewSwitch.d.ts +66 -0
- package/dist/default/ViewSwitch.d.ts.map +1 -0
- package/dist/default/ViewSwitch.js +49 -0
- package/dist/default/ViewSwitch.js.map +1 -0
- package/dist/default/index.d.ts +6 -0
- package/dist/default/index.d.ts.map +1 -1
- package/dist/default/index.js +3 -0
- package/dist/default/index.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +8 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/keys.d.ts +20 -0
- package/dist/i18n/keys.d.ts.map +1 -1
- package/dist/i18n/keys.js +29 -0
- package/dist/i18n/keys.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +8 -0
- package/dist/i18n/ru.js.map +1 -1
- package/llms.txt +2 -1
- package/manifest.json +31 -2
- package/nav-manifest.json +1 -1
- package/package.json +6 -6
- package/src/analytics/generated/events.json +1 -1
- package/src/default/FacetGroupControl.tsx +312 -0
- package/src/default/FacetPanelPane.tsx +11 -57
- package/src/default/FilterChips.tsx +415 -0
- package/src/default/SearchPage.tsx +118 -15
- package/src/default/SearchResultsPane.tsx +39 -2
- package/src/default/ViewSwitch.tsx +147 -0
- package/src/default/index.ts +17 -0
- package/src/i18n/es.ts +9 -0
- package/src/i18n/keys.ts +31 -0
- package/src/i18n/ru.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @stapel/search-react
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 62c70ac: The classified layout, in the default skins.
|
|
8
|
+
|
|
9
|
+
Built where the doctrine says the product lives, so every future classified
|
|
10
|
+
deployment gets it rather than rebuilding it.
|
|
11
|
+
|
|
12
|
+
- `shell-react` — `NavDock`, a floating translucent island rather than a flat
|
|
13
|
+
bar: inset from every edge, real border and shadow, safe-area aware. The
|
|
14
|
+
glass is progressive enhancement, not the design — the opaque elevated fill
|
|
15
|
+
is the base and the blur is swapped in only inside an `@supports` for
|
|
16
|
+
`backdrop-filter`, so text contrast never depends on transparency being
|
|
17
|
+
available. Destinations are the first five top-level nav entries in the
|
|
18
|
+
order the manifest already declares, so there is no second selection axis.
|
|
19
|
+
Real links, `aria-current`, and the badge count folded into each link's
|
|
20
|
+
accessible name.
|
|
21
|
+
- `search-react` — a phone gets a scrollable chip row instead of one
|
|
22
|
+
"Filters" button, each chip opening its own `SkinDialog`, and chips carry
|
|
23
|
+
the CHOICE rather than the group name. A desktop gets a sticky full-height
|
|
24
|
+
rail. Both render through one `FacetGroupControl`, so the rail and the
|
|
25
|
+
sheets cannot drift into two implementations — and a group's shape is
|
|
26
|
+
derived from the schema keys the composer's editor already reads
|
|
27
|
+
(`maxSelected: 1` → pills, `hierarchical_select` → indented children)
|
|
28
|
+
rather than a new presentation flag. Plus a list/grid view switch, which is
|
|
29
|
+
not URL state because it changes how an answer is drawn and never what it
|
|
30
|
+
is.
|
|
31
|
+
- `listings-react` — the whole card is one real anchor: photo, price, title
|
|
32
|
+
and location inside it, the favourite heart a sibling button outside it so
|
|
33
|
+
the link cannot swallow it. The separate "open" control is gone and its
|
|
34
|
+
i18n key is retired. Middle-click, open-in-new-tab and crawlers still work,
|
|
35
|
+
and the anchor's accessible name is the title alone.
|
|
36
|
+
|
|
37
|
+
Parts of the reference layout that do not fit a generic contract are slots
|
|
38
|
+
with a stated reason rather than invented content: "notify me about new ones"
|
|
39
|
+
(a saved search has an owner, a schedule and a consent record this pair has
|
|
40
|
+
none of), the breadcrumb (a walk up a tree search cannot see), and map view
|
|
41
|
+
(a `SearchView` whose tiles belong to geo-react).
|
|
42
|
+
|
|
3
43
|
## 0.7.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { FacetGroup, FacetOption } from "../state/facets.js";
|
|
3
|
+
/**
|
|
4
|
+
* How many options a group shows before the rest go behind "Show all".
|
|
5
|
+
*
|
|
6
|
+
* Eight is the count at which a group stops being readable at a glance and
|
|
7
|
+
* starts being a scroll: it is two more than the six the visual pass measured
|
|
8
|
+
* as the fold on a 390px phone with the sheet's own chrome above it, which
|
|
9
|
+
* leaves a group of seven whole rather than truncated by one row.
|
|
10
|
+
*/
|
|
11
|
+
export declare const FACET_VISIBLE_OPTIONS = 8;
|
|
12
|
+
/** The three shapes a facet group takes. */
|
|
13
|
+
export type FacetGroupShape = "segmented" | "nested" | "checkbox";
|
|
14
|
+
/** The option rows of a group, already nested where the schema nests them. */
|
|
15
|
+
export interface FacetOptionNode {
|
|
16
|
+
readonly option: FacetOption;
|
|
17
|
+
/** 0 for a root option; 1+ for a child of a `hierarchical_select` tree. */
|
|
18
|
+
readonly depth: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Which of the three shapes a group takes.
|
|
22
|
+
*
|
|
23
|
+
* Order matters: a hierarchical facet is nested even when it is single-choice,
|
|
24
|
+
* because losing the tree costs more than losing the pills.
|
|
25
|
+
*/
|
|
26
|
+
export declare function facetGroupShape(group: FacetGroup): FacetGroupShape;
|
|
27
|
+
/** The group's options in render order, carrying the depth the schema gives. */
|
|
28
|
+
export declare function facetOptionNodes(group: FacetGroup): readonly FacetOptionNode[];
|
|
29
|
+
export interface FacetGroupControlProps {
|
|
30
|
+
readonly group: FacetGroup;
|
|
31
|
+
readonly onToggle: (slug: string, value: string) => void;
|
|
32
|
+
/** Draw the group's own name above its options. `false` for a surface that
|
|
33
|
+
* has already said it — a per-group sheet whose title IS the group. */
|
|
34
|
+
readonly heading?: boolean;
|
|
35
|
+
/** How many options before "Show all". Default {@link FACET_VISIBLE_OPTIONS};
|
|
36
|
+
* `null` shows every option (a sheet devoted to one group has the room). */
|
|
37
|
+
readonly visibleOptions?: number | null;
|
|
38
|
+
}
|
|
39
|
+
export declare function FacetGroupControl(props: FacetGroupControlProps): ReactElement;
|
|
40
|
+
//# sourceMappingURL=FacetGroupControl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacetGroupControl.d.ts","sourceRoot":"","sources":["../../src/default/FacetGroupControl.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAMzD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGlE;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,4CAA4C;AAC5C,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAElE,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAwCD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe,CAMlE;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,eAAe,EAAE,CAqB9E;AA6FD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD;2EACuE;IACvE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;gFAC4E;IAC5E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CAqE7E"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `<FacetGroupControl>` — ONE facet group, drawn the way its own schema says
|
|
4
|
+
* it should be drawn.
|
|
5
|
+
*
|
|
6
|
+
* Until this release every group was the same thing: a flat column of
|
|
7
|
+
* checkboxes, however many options it had and whatever the category schema
|
|
8
|
+
* said about it. That is wrong in three ways a person meets on the first
|
|
9
|
+
* screen of a real catalogue:
|
|
10
|
+
*
|
|
11
|
+
* 1. **A single-choice facet is not a checkbox list.** `maxSelected: 1` is a
|
|
12
|
+
* fact the schema already carries, and `@stapel/attributes-react`'s editor
|
|
13
|
+
* already reads it to draw a segmented control rather than a set of boxes.
|
|
14
|
+
* A filter that says "pick one" with controls that say "pick any" teaches
|
|
15
|
+
* the wrong thing before the click and surprises after it.
|
|
16
|
+
* 2. **A hierarchical facet is not flat.** `hierarchical_select` carries a
|
|
17
|
+
* TREE in `config.options`; rendering its values as one alphabetical
|
|
18
|
+
* column hides that "Sedan" is under "Cars" and puts a child next to its
|
|
19
|
+
* own parent as if they were siblings.
|
|
20
|
+
* 3. **A 60-option facet is not a list, it is a wall.** Every catalogue has
|
|
21
|
+
* one — brand, model, city — and printing all of it pushes every group
|
|
22
|
+
* under it off the screen.
|
|
23
|
+
*
|
|
24
|
+
* ── The presentation is DERIVED, never configured here ────────────────────
|
|
25
|
+
*
|
|
26
|
+
* {@link facetGroupShape} reads the same `config` keys the attributes editor
|
|
27
|
+
* reads (`maxSelected`, `type`, `options`), so a facet cannot look one way in
|
|
28
|
+
* the filter and another way in the composer that produced the value. There is
|
|
29
|
+
* no `presentation` prop on this component and there must not be one: a
|
|
30
|
+
* per-call-site override is how the two halves drift.
|
|
31
|
+
*
|
|
32
|
+
* A group with NO schema (the host passed no `categoryFeatures`, or the slug
|
|
33
|
+
* is not in it) is a flat checkbox list — the honest default, and the shape
|
|
34
|
+
* every group had before.
|
|
35
|
+
*/
|
|
36
|
+
import { useState } from "react";
|
|
37
|
+
import { Button, Checkbox, Flex, Typography } from "antd";
|
|
38
|
+
import { useT } from "@stapel/core";
|
|
39
|
+
import { radii, spacing } from "@stapel/tokens";
|
|
40
|
+
import { featureConfig, featureType } from "@stapel/attributes-react";
|
|
41
|
+
import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
|
|
42
|
+
/**
|
|
43
|
+
* How many options a group shows before the rest go behind "Show all".
|
|
44
|
+
*
|
|
45
|
+
* Eight is the count at which a group stops being readable at a glance and
|
|
46
|
+
* starts being a scroll: it is two more than the six the visual pass measured
|
|
47
|
+
* as the fold on a 390px phone with the sheet's own chrome above it, which
|
|
48
|
+
* leaves a group of seven whole rather than truncated by one row.
|
|
49
|
+
*/
|
|
50
|
+
export const FACET_VISIBLE_OPTIONS = 8;
|
|
51
|
+
function numberish(value) {
|
|
52
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The DEPTH of every value a `hierarchical_select` config declares, walked
|
|
56
|
+
* once — `{value: depth}`.
|
|
57
|
+
*
|
|
58
|
+
* The tree lives in `config.options[].children[]` (the same shape
|
|
59
|
+
* `@stapel/attributes-react`'s `Cascader` reads). The facets themselves arrive
|
|
60
|
+
* FLAT from the server, because an index term has no parent; the schema is the
|
|
61
|
+
* only thing that knows one value sits under another.
|
|
62
|
+
*/
|
|
63
|
+
function optionDepths(raw, depth = 0, into = new Map()) {
|
|
64
|
+
if (!Array.isArray(raw))
|
|
65
|
+
return into;
|
|
66
|
+
for (const option of raw) {
|
|
67
|
+
if (option === null || typeof option !== "object")
|
|
68
|
+
continue;
|
|
69
|
+
const entry = option;
|
|
70
|
+
if (entry.value !== undefined && entry.value !== null) {
|
|
71
|
+
into.set(String(entry.value), depth);
|
|
72
|
+
}
|
|
73
|
+
optionDepths(entry.children, depth + 1, into);
|
|
74
|
+
}
|
|
75
|
+
return into;
|
|
76
|
+
}
|
|
77
|
+
/** Is this feature single-choice? The schema's own answer, not a guess. */
|
|
78
|
+
function singleChoice(feature) {
|
|
79
|
+
if (feature === undefined)
|
|
80
|
+
return false;
|
|
81
|
+
// `maxSelected` ABSENT means unlimited — the engine's own default. Reading
|
|
82
|
+
// an absent key as 1 would turn every unconfigured facet into a radio group.
|
|
83
|
+
return numberish(featureConfig(feature)["maxSelected"]) === 1;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Which of the three shapes a group takes.
|
|
87
|
+
*
|
|
88
|
+
* Order matters: a hierarchical facet is nested even when it is single-choice,
|
|
89
|
+
* because losing the tree costs more than losing the pills.
|
|
90
|
+
*/
|
|
91
|
+
export function facetGroupShape(group) {
|
|
92
|
+
const feature = group.feature;
|
|
93
|
+
if (feature !== undefined && featureType(feature) === "hierarchical_select") {
|
|
94
|
+
return "nested";
|
|
95
|
+
}
|
|
96
|
+
return singleChoice(feature) ? "segmented" : "checkbox";
|
|
97
|
+
}
|
|
98
|
+
/** The group's options in render order, carrying the depth the schema gives. */
|
|
99
|
+
export function facetOptionNodes(group) {
|
|
100
|
+
if (facetGroupShape(group) !== "nested" || group.feature === undefined) {
|
|
101
|
+
return group.options.map((option) => ({ option, depth: 0 }));
|
|
102
|
+
}
|
|
103
|
+
const depths = optionDepths(featureConfig(group.feature)["options"]);
|
|
104
|
+
// Depth alone would leave children beside strangers: the options are
|
|
105
|
+
// re-ordered so each child follows its own parent, and a value the schema
|
|
106
|
+
// does not know keeps depth 0 rather than being hidden under someone.
|
|
107
|
+
const byValue = new Map(group.options.map((option) => [option.value, option]));
|
|
108
|
+
const out = [];
|
|
109
|
+
const emitted = new Set();
|
|
110
|
+
for (const [value, depth] of depths) {
|
|
111
|
+
const option = byValue.get(value);
|
|
112
|
+
if (option === undefined)
|
|
113
|
+
continue;
|
|
114
|
+
out.push({ option, depth });
|
|
115
|
+
emitted.add(value);
|
|
116
|
+
}
|
|
117
|
+
for (const option of group.options) {
|
|
118
|
+
if (!emitted.has(option.value))
|
|
119
|
+
out.push({ option, depth: 0 });
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
/** A count, or the honest "we did not count this". Never a zero standing in
|
|
124
|
+
* for an absent answer. */
|
|
125
|
+
function OptionCount(props) {
|
|
126
|
+
const t = useT();
|
|
127
|
+
return (_jsx(Typography.Text, { type: "secondary", "data-testid": `facet-count-${props.group.slug}-${props.option.value}`, children: props.option.count === null
|
|
128
|
+
? t(SEARCH_I18N_KEYS.facetsNotCounted)
|
|
129
|
+
: props.option.count }));
|
|
130
|
+
}
|
|
131
|
+
/** The indent one level of a hierarchical facet is drawn with. */
|
|
132
|
+
const NEST_STEP = spacing[5];
|
|
133
|
+
function CheckboxRow(props) {
|
|
134
|
+
const { group, node } = props;
|
|
135
|
+
return (_jsxs(Flex, { justify: "space-between", align: "center", gap: spacing[2], style: node.depth > 0
|
|
136
|
+
? { paddingInlineStart: node.depth * NEST_STEP }
|
|
137
|
+
: undefined, "data-depth": node.depth, children: [_jsx(Checkbox, { checked: node.option.selected, "data-testid": `facet-option-${group.slug}-${node.option.value}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onChange: () => {
|
|
138
|
+
props.onToggle(group.slug, node.option.value);
|
|
139
|
+
}, children: node.option.label }), _jsx(OptionCount, { group: group, option: node.option })] }));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* One pill of a single-choice group.
|
|
143
|
+
*
|
|
144
|
+
* A real `<button aria-pressed>` rather than antd's `Segmented`: the count has
|
|
145
|
+
* to sit inside the pill (a filter without its remaining count is the
|
|
146
|
+
* drill-down facet turned naive), and `Segmented` takes labels, not rows.
|
|
147
|
+
* `aria-pressed` is what makes a styled button a TOGGLE to a screen reader
|
|
148
|
+
* instead of a link-shaped thing that mysteriously changes the page.
|
|
149
|
+
*/
|
|
150
|
+
function OptionPill(props) {
|
|
151
|
+
const { group, option } = props;
|
|
152
|
+
const style = { borderRadius: radii.full };
|
|
153
|
+
return (_jsx(Button, { size: "small", shape: "round", type: option.selected ? "primary" : "default", "aria-pressed": option.selected, style: style, "data-testid": `facet-option-${group.slug}-${option.value}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
|
|
154
|
+
props.onToggle(group.slug, option.value);
|
|
155
|
+
}, children: option.count === null ? option.label : `${option.label} ${option.count}` }));
|
|
156
|
+
}
|
|
157
|
+
export function FacetGroupControl(props) {
|
|
158
|
+
const t = useT();
|
|
159
|
+
const { group } = props;
|
|
160
|
+
const [expanded, setExpanded] = useState(false);
|
|
161
|
+
const shape = facetGroupShape(group);
|
|
162
|
+
const nodes = facetOptionNodes(group);
|
|
163
|
+
const limit = props.visibleOptions === null
|
|
164
|
+
? null
|
|
165
|
+
: (props.visibleOptions ?? FACET_VISIBLE_OPTIONS);
|
|
166
|
+
// A group one row over the limit is not truncated: hiding a single option
|
|
167
|
+
// behind "Show all (9)" costs a tap to reveal exactly one thing.
|
|
168
|
+
const collapsible = limit !== null && nodes.length > limit + 1;
|
|
169
|
+
const shown = collapsible && !expanded ? nodes.slice(0, limit) : nodes;
|
|
170
|
+
return (_jsxs(Flex, { vertical: true, gap: shape === "segmented" ? spacing[2] : spacing[1], "data-testid": `facet-group-${group.slug}`, "data-counted": group.counted ? "true" : "false", "data-shape": shape, children: [props.heading !== false && (_jsx(Typography.Text, { strong: true, children: group.label })), shape === "segmented" ? (_jsx(Flex, { wrap: true, gap: spacing[2], children: shown.map((node) => (_jsx(OptionPill, { group: group, option: node.option, onToggle: props.onToggle }, node.option.value))) })) : (shown.map((node) => (_jsx(CheckboxRow, { group: group, node: node, onToggle: props.onToggle }, node.option.value)))), collapsible && (_jsx(Button, { type: "link", size: "small", style: { alignSelf: "flex-start", paddingInline: 0 }, "data-testid": `facet-more-${group.slug}`, "data-analytics": "none", "data-analytics-reason": "expanding a filter group is a read, not a flow step", onClick: () => {
|
|
171
|
+
setExpanded((was) => !was);
|
|
172
|
+
}, children: expanded
|
|
173
|
+
? t(SEARCH_I18N_KEYS.facetsShowLess)
|
|
174
|
+
: t(SEARCH_I18N_KEYS.facetsShowAll, { count: nodes.length }) }))] }));
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=FacetGroupControl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacetGroupControl.js","sourceRoot":"","sources":["../../src/default/FacetGroupControl.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FacetPanelPane.d.ts","sourceRoot":"","sources":["../../src/default/FacetPanelPane.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FacetPanelPane.d.ts","sourceRoot":"","sources":["../../src/default/FacetPanelPane.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAQjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAClD;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IACtC,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD;wCACoC;IACpC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;gFAC4E;IAC5E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,SAAS,CAAC;IAC7E;8DAC0D;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,SAAS,CAAC;IACnE,wEAAwE;IACxE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;CAC9B;AAqKD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CA4IvE"}
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Alert, Button,
|
|
2
|
+
import { Alert, Button, Divider, Flex, InputNumber, Typography, } from "antd";
|
|
3
3
|
import { SlotPlaceholder, isDevBuild, useT } from "@stapel/core";
|
|
4
4
|
import { EmptyState, ErrorAlert, LoadList, SkinTheme, } from "@stapel/tokens-antd/skin";
|
|
5
5
|
import { spacing } from "@stapel/tokens";
|
|
6
6
|
import { featureName } from "@stapel/attributes-react";
|
|
7
7
|
import { FacetPanel } from "../headless/FacetPanel.js";
|
|
8
8
|
import { useSearchState } from "../headless/SearchStateProvider.js";
|
|
9
|
+
import { FacetGroupControl } from "./FacetGroupControl.js";
|
|
9
10
|
import { buildRangeGroups } from "../state/ranges.js";
|
|
10
11
|
import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
|
|
11
12
|
import { LanguageSelect } from "./LanguageSelect.js";
|
|
12
13
|
import { RangeFilterRow } from "./RangeFilterRow.js";
|
|
13
|
-
function OptionRow(props) {
|
|
14
|
-
const t = useT();
|
|
15
|
-
const { option, group } = props;
|
|
16
|
-
return (_jsxs(Flex, { justify: "space-between", align: "center", gap: spacing[2], children: [_jsx(Checkbox, { checked: option.selected, "data-testid": `facet-option-${group.slug}-${option.value}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onChange: () => {
|
|
17
|
-
props.onToggle(group.slug, option.value);
|
|
18
|
-
}, children: option.label }), option.count === null ? (_jsx(Typography.Text, { type: "secondary", "data-testid": `facet-count-${group.slug}-${option.value}`, children: t(SEARCH_I18N_KEYS.facetsNotCounted) })) : (_jsx(Typography.Text, { type: "secondary", "data-testid": `facet-count-${group.slug}-${option.value}`, children: option.count }))] }));
|
|
19
|
-
}
|
|
20
14
|
/** The category constraint: the host's control, or the door out of it. */
|
|
21
15
|
function CategoryFilter(props) {
|
|
22
16
|
const t = useT();
|
|
@@ -127,6 +121,6 @@ export function FacetPanelPane(props) {
|
|
|
127
121
|
slugs: skippedNames(bag.skipped, props.categoryFeatures, t),
|
|
128
122
|
}) })), ranges.length > 0 && (_jsx(Flex, { vertical: true, gap: spacing[3], "data-testid": "search-ranges", children: ranges.map((group) => (_jsx(RangeFilterRow, { group: group, onApply: bag.setRange }, group.slug))) })), ranges.length > 0 && _jsx(Divider, { style: { margin: 0 } }), _jsx(LoadList, { state: bag.state, testId: "facets", skeletonRows: 4, empty: _jsx(EmptyState, { compact: true, title: t(SEARCH_I18N_KEYS.facetsEmpty), testId: "facets-empty" }), failed: (error) => (_jsx(ErrorAlert, { testId: "facets-failed", thrown: error, message: t(SEARCH_I18N_KEYS.facetsLoadFailed) })), children: (groups) => (_jsxs(Flex, { vertical: true, gap: spacing[4], children: [groups
|
|
129
123
|
.filter((group) => group.options.length > 0)
|
|
130
|
-
.map((group) => (
|
|
124
|
+
.map((group) => (_jsx(FacetGroupControl, { group: group, onToggle: bag.toggle }, group.slug))), _jsx(Typography.Text, { type: "secondary", children: t(SEARCH_I18N_KEYS.facetsDrillDownHint) })] })) })] })) }) }));
|
|
131
125
|
}
|
|
132
126
|
//# sourceMappingURL=FacetPanelPane.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FacetPanelPane.js","sourceRoot":"","sources":["../../src/default/FacetPanelPane.tsx"],"names":[],"mappings":";AAoCA,OAAO,EACL,KAAK,EACL,MAAM,EACN,
|
|
1
|
+
{"version":3,"file":"FacetPanelPane.js","sourceRoot":"","sources":["../../src/default/FacetPanelPane.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from "react";
|
|
2
|
+
import type { FeatureDef } from "@stapel/attributes-react";
|
|
3
|
+
import type { GeoFilterSlotProps } from "./FacetPanelPane.js";
|
|
4
|
+
/** The class the scroller carries, for {@link chipRowCss}. */
|
|
5
|
+
export declare const CHIP_ROW_CLASS = "stapel-filter-chips";
|
|
6
|
+
/** The `href` the hoisted chip-row stylesheet is deduplicated by. */
|
|
7
|
+
export declare const CHIP_ROW_STYLE_HREF = "stapel-search-filter-chips";
|
|
8
|
+
/**
|
|
9
|
+
* The two rules an inline style cannot express: Firefox's `scrollbar-width`
|
|
10
|
+
* and WebKit's `::-webkit-scrollbar`. Static (no theme values), so one hoisted
|
|
11
|
+
* copy serves the document.
|
|
12
|
+
*/
|
|
13
|
+
export declare function chipRowCss(): string;
|
|
14
|
+
export interface FilterChipsProps {
|
|
15
|
+
/** The category's feature schema — the source of option labels, of which
|
|
16
|
+
* slugs get a range chip, and of how each group is drawn. */
|
|
17
|
+
readonly categoryFeatures?: readonly FeatureDef[];
|
|
18
|
+
readonly locale?: string;
|
|
19
|
+
/** The location control (`geo-react`), same slot the panel takes. Without
|
|
20
|
+
* it the location chip appears only when the URL already carries a point,
|
|
21
|
+
* so a shared link can still be widened. */
|
|
22
|
+
readonly renderGeoFilter?: (slot: GeoFilterSlotProps) => ReactNode;
|
|
23
|
+
/** Open the whole panel — the leading chip's action. The page owns that
|
|
24
|
+
* sheet, because the page is the surface it covers. */
|
|
25
|
+
readonly onOpenAll: () => void;
|
|
26
|
+
}
|
|
27
|
+
export declare function FilterChips(props: FilterChipsProps): ReactElement;
|
|
28
|
+
//# sourceMappingURL=FilterChips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../src/default/FilterChips.tsx"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAS3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,8DAA8D;AAC9D,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAqBD,MAAM,WAAW,gBAAgB;IAC/B;iEAC6D;IAC7D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;gDAE4C;IAC5C,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,SAAS,CAAC;IACnE;2DACuD;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;CAChC;AAiBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA+OjE"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `<FilterChips>` — the phone's filter row: one horizontally scrolling line of
|
|
4
|
+
* chips, each of which opens its OWN picker.
|
|
5
|
+
*
|
|
6
|
+
* ## What it replaces, and why the replacement is not cosmetic
|
|
7
|
+
*
|
|
8
|
+
* The phone filter path was a single full-width "Filters (3)" button that
|
|
9
|
+
* opened the whole panel. Everything about a search — the category, the price,
|
|
10
|
+
* the brand, where — was behind one tap onto a sheet you then had to scroll,
|
|
11
|
+
* and NOTHING about what was already applied was visible on the results page
|
|
12
|
+
* itself except a number in brackets. The chips row states the filters ON the
|
|
13
|
+
* page: the ones you have set read as set, the ones you have not are one tap
|
|
14
|
+
* from their own small picker, and the whole panel is still there behind the
|
|
15
|
+
* leading chip for the person who wants all of it at once.
|
|
16
|
+
*
|
|
17
|
+
* ## The row scrolls; the PAGE does not
|
|
18
|
+
*
|
|
19
|
+
* A row of chips wider than a 390px phone is the point — it is how the row
|
|
20
|
+
* holds eight filters. What must not happen is the page's own body growing a
|
|
21
|
+
* horizontal scrollbar, which is what a `flex-wrap: nowrap` row without an
|
|
22
|
+
* `overflow-x` owner does: the chips push the document wider, every other
|
|
23
|
+
* element on the page slides, and the visitor is left rubber-banding the whole
|
|
24
|
+
* screen sideways to read a price. So the row owns its overflow
|
|
25
|
+
* (`overflow-x: auto`), contains its overscroll so a flick past the last chip
|
|
26
|
+
* does not start scrolling the page behind it, and hides the scrollbar itself
|
|
27
|
+
* (a 15px grey trough under a 32px chip is chrome nobody asked for) — through
|
|
28
|
+
* a hoisted stylesheet, because `::-webkit-scrollbar` and `scrollbar-width`
|
|
29
|
+
* cannot be written as inline style.
|
|
30
|
+
*
|
|
31
|
+
* Hiding a scrollbar is only safe because nothing here is reachable ONLY by
|
|
32
|
+
* dragging it: every chip is a real `<button>`, so Tab walks the row and the
|
|
33
|
+
* browser scrolls the focused chip into view on its own.
|
|
34
|
+
*
|
|
35
|
+
* ## Every picker is a `SkinDialog`
|
|
36
|
+
*
|
|
37
|
+
* Which means every picker is a BOTTOM SHEET on a phone and a modal above it
|
|
38
|
+
* (owner ruling 2026-08-24, enforced by `stapel/no-bare-dialog`). The chips
|
|
39
|
+
* row is a phone surface, so in practice it is always the sheet — but the
|
|
40
|
+
* component does not decide that, the substrate does, and a tablet rendering
|
|
41
|
+
* the row gets the tablet answer without this file knowing.
|
|
42
|
+
*
|
|
43
|
+
* ## The library is not inventing a classified's filters
|
|
44
|
+
*
|
|
45
|
+
* A chip exists for each facet group the SERVER returned, each numeric range
|
|
46
|
+
* the CATEGORY SCHEMA declares, and the location — plus the leading
|
|
47
|
+
* "all filters" chip. Nothing here knows what a "brand" or a "mileage" is;
|
|
48
|
+
* a deployment with three facets gets three chips and a deployment with none
|
|
49
|
+
* gets the leading chip alone.
|
|
50
|
+
*/
|
|
51
|
+
import { useState } from "react";
|
|
52
|
+
import { Button, Flex, Typography } from "antd";
|
|
53
|
+
import { SkinDialog, useDialogSurface } from "@stapel/tokens-antd/skin";
|
|
54
|
+
import { SlotPlaceholder, useT, useTPlural } from "@stapel/core";
|
|
55
|
+
import { radii, spacing } from "@stapel/tokens";
|
|
56
|
+
import { useFacetPanel } from "../headless/FacetPanel.js";
|
|
57
|
+
import { useAppliedCount } from "../headless/useAppliedCount.js";
|
|
58
|
+
import { useSearchState } from "../headless/SearchStateProvider.js";
|
|
59
|
+
import { buildRangeGroups } from "../state/ranges.js";
|
|
60
|
+
import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
|
|
61
|
+
import { FacetGroupControl } from "./FacetGroupControl.js";
|
|
62
|
+
import { RangeFilterRow } from "./RangeFilterRow.js";
|
|
63
|
+
/** The class the scroller carries, for {@link chipRowCss}. */
|
|
64
|
+
export const CHIP_ROW_CLASS = "stapel-filter-chips";
|
|
65
|
+
/** The `href` the hoisted chip-row stylesheet is deduplicated by. */
|
|
66
|
+
export const CHIP_ROW_STYLE_HREF = "stapel-search-filter-chips";
|
|
67
|
+
/**
|
|
68
|
+
* The two rules an inline style cannot express: Firefox's `scrollbar-width`
|
|
69
|
+
* and WebKit's `::-webkit-scrollbar`. Static (no theme values), so one hoisted
|
|
70
|
+
* copy serves the document.
|
|
71
|
+
*/
|
|
72
|
+
export function chipRowCss() {
|
|
73
|
+
return [
|
|
74
|
+
`.${CHIP_ROW_CLASS}{scrollbar-width:none;-ms-overflow-style:none}`,
|
|
75
|
+
`.${CHIP_ROW_CLASS}::-webkit-scrollbar{display:none}`,
|
|
76
|
+
].join("");
|
|
77
|
+
}
|
|
78
|
+
/** The scroller: one line, its own overflow, nobody else's. */
|
|
79
|
+
const ROW = {
|
|
80
|
+
display: "flex",
|
|
81
|
+
alignItems: "center",
|
|
82
|
+
gap: spacing[2],
|
|
83
|
+
flexWrap: "nowrap",
|
|
84
|
+
overflowX: "auto",
|
|
85
|
+
// A flick past the last chip must not hand the gesture to the page.
|
|
86
|
+
overscrollBehaviorInline: "contain",
|
|
87
|
+
// Room for the focus ring of the first and last chip, which a flush edge
|
|
88
|
+
// clips into invisibility.
|
|
89
|
+
paddingBlock: spacing[1],
|
|
90
|
+
};
|
|
91
|
+
const CHIP = { flex: "0 0 auto", borderRadius: radii.full };
|
|
92
|
+
/**
|
|
93
|
+
* The label a chip carries: the group's name alone when nothing is chosen,
|
|
94
|
+
* and the CHOICE when something is — "Brand" becomes "Bosch", "Brand, +2".
|
|
95
|
+
* A chip that reads "Brand" while filtering to Bosch is a lie the person can
|
|
96
|
+
* only catch by opening it.
|
|
97
|
+
*/
|
|
98
|
+
function chipLabel(group, t) {
|
|
99
|
+
const chosen = group.options.filter((option) => option.selected);
|
|
100
|
+
const first = chosen[0];
|
|
101
|
+
if (first === undefined)
|
|
102
|
+
return group.label;
|
|
103
|
+
return chosen.length === 1
|
|
104
|
+
? first.label
|
|
105
|
+
: `${first.label}${t(SEARCH_I18N_KEYS.filtersChipMore, { count: chosen.length - 1 })}`;
|
|
106
|
+
}
|
|
107
|
+
export function FilterChips(props) {
|
|
108
|
+
const t = useT();
|
|
109
|
+
const tPlural = useTPlural();
|
|
110
|
+
const { state, setGeo } = useSearchState();
|
|
111
|
+
const bag = useFacetPanel({
|
|
112
|
+
...(props.categoryFeatures !== undefined
|
|
113
|
+
? { categoryFeatures: props.categoryFeatures }
|
|
114
|
+
: {}),
|
|
115
|
+
...(props.locale !== undefined ? { locale: props.locale } : {}),
|
|
116
|
+
});
|
|
117
|
+
const applied = useAppliedCount();
|
|
118
|
+
const surface = useDialogSurface();
|
|
119
|
+
const [open, setOpen] = useState(null);
|
|
120
|
+
const ranges = buildRangeGroups({
|
|
121
|
+
state,
|
|
122
|
+
...(props.categoryFeatures !== undefined
|
|
123
|
+
? { categoryFeatures: props.categoryFeatures }
|
|
124
|
+
: {}),
|
|
125
|
+
t,
|
|
126
|
+
});
|
|
127
|
+
const groups = bag.state.status === "ready"
|
|
128
|
+
? bag.state.data.filter((group) => group.options.length > 0)
|
|
129
|
+
: [];
|
|
130
|
+
// The same sentence the panel's own commit button says, for the same reason:
|
|
131
|
+
// the results are BEHIND this sheet, so the button that closes it is the
|
|
132
|
+
// only place a person learns what their choice did.
|
|
133
|
+
const applyLabel = applied.count === null || applied.kind === "unknown"
|
|
134
|
+
? t(SEARCH_I18N_KEYS.filtersApply)
|
|
135
|
+
: tPlural(applied.kind === "at_least"
|
|
136
|
+
? SEARCH_I18N_KEYS.filtersShowCountAtLeast
|
|
137
|
+
: SEARCH_I18N_KEYS.filtersShowCount, { count: applied.count });
|
|
138
|
+
const close = () => {
|
|
139
|
+
setOpen(null);
|
|
140
|
+
};
|
|
141
|
+
const sheetFor = (id, title, body) => (_jsx(SkinDialog, { open: open === id, onClose: close, title: title, dismissLabel: t(SEARCH_I18N_KEYS.filtersDismiss), "data-testid": `filter-chip-sheet-${id}`, footer: _jsx(Button, { block: true, type: "primary", "data-testid": `filter-chip-apply-${id}`, "data-analytics": "none", "data-analytics-reason": "the filter is already applied; this closes the sheet", onClick: close, children: applyLabel }), children: body }));
|
|
142
|
+
const geo = state.geo;
|
|
143
|
+
const showGeoChip = props.renderGeoFilter !== undefined || geo !== undefined;
|
|
144
|
+
const geoLabel = geo === undefined
|
|
145
|
+
? t(SEARCH_I18N_KEYS.geoTitle)
|
|
146
|
+
: geo.kind === "bbox"
|
|
147
|
+
? t(SEARCH_I18N_KEYS.geoBox)
|
|
148
|
+
: t(SEARCH_I18N_KEYS.geoCenter, {
|
|
149
|
+
lat: geo.lat.toFixed(3),
|
|
150
|
+
lon: geo.lon.toFixed(3),
|
|
151
|
+
});
|
|
152
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { href: CHIP_ROW_STYLE_HREF, precedence: "default", children: chipRowCss() }), _jsxs("div", { className: CHIP_ROW_CLASS, style: ROW, role: "group", "aria-label": t(SEARCH_I18N_KEYS.filtersChipsLabel), "data-testid": "search-filter-chips", "data-surface": surface, children: [_jsx(Button, { shape: "circle", "aria-label": t(SEARCH_I18N_KEYS.filtersAll), icon: _jsx(SlidersGlyph, {}), style: CHIP, "data-testid": "search-filters-open", "data-active": bag.activeFilters > 0 ? "true" : "false", "data-analytics": "none", "data-analytics-reason": "opening the filter sheet is a read, not a flow step", onClick: props.onOpenAll, children: bag.activeFilters > 0 && _jsx(ActiveDot, {}) }), showGeoChip && (_jsx(Button, { style: CHIP, shape: "round", type: geo !== undefined ? "primary" : "default", "data-testid": "search-chip-geo", "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
|
|
153
|
+
setOpen("geo");
|
|
154
|
+
}, children: geoLabel })), ranges.map((group) => (_jsx(Button, { style: CHIP, shape: "round", type: group.active ? "primary" : "default", "data-testid": `search-chip-range-${group.slug}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
|
|
155
|
+
setOpen(`range:${group.slug}`);
|
|
156
|
+
}, children: group.label }, group.slug))), groups.map((group) => (_jsx(Button, { style: CHIP, shape: "round", type: group.selected.length > 0 ? "primary" : "default", "data-testid": `search-chip-${group.slug}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
|
|
157
|
+
setOpen(`facet:${group.slug}`);
|
|
158
|
+
}, children: chipLabel(group, t) }, group.slug)))] }), open?.startsWith("facet:") === true &&
|
|
159
|
+
(() => {
|
|
160
|
+
const slug = open.slice("facet:".length);
|
|
161
|
+
const group = groups.find((candidate) => candidate.slug === slug);
|
|
162
|
+
return group === undefined
|
|
163
|
+
? null
|
|
164
|
+
: sheetFor(open, group.label, _jsx(FacetGroupControl, { group: group, onToggle: bag.toggle, heading: false,
|
|
165
|
+
// A sheet devoted to ONE group has the room for all of it;
|
|
166
|
+
// "Show all" inside it would be a fold inside a fold.
|
|
167
|
+
visibleOptions: null }));
|
|
168
|
+
})(), open?.startsWith("range:") === true &&
|
|
169
|
+
(() => {
|
|
170
|
+
const slug = open.slice("range:".length);
|
|
171
|
+
const group = ranges.find((candidate) => candidate.slug === slug);
|
|
172
|
+
return group === undefined
|
|
173
|
+
? null
|
|
174
|
+
: sheetFor(open, group.label, _jsx(RangeFilterRow, { group: group, onApply: bag.setRange }));
|
|
175
|
+
})(), open === "geo" &&
|
|
176
|
+
sheetFor("geo", t(SEARCH_I18N_KEYS.geoTitle), _jsxs(Flex, { vertical: true, gap: spacing[3], children: [props.renderGeoFilter?.({
|
|
177
|
+
value: geo,
|
|
178
|
+
onChange: (next) => {
|
|
179
|
+
setGeo(next);
|
|
180
|
+
},
|
|
181
|
+
}) ?? _jsx(SlotPlaceholder, { name: "renderGeoFilter", "data-testid": "search-chip-geo-slot" }), geo !== undefined && (_jsxs(_Fragment, { children: [_jsx(Typography.Text, { type: "secondary", "data-testid": "search-chip-geo-summary", children: geoLabel }), _jsx(Button, { style: { alignSelf: "flex-start" }, "data-testid": "search-chip-geo-clear", "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
|
|
182
|
+
setGeo(null);
|
|
183
|
+
}, children: t(SEARCH_I18N_KEYS.geoClear) })] }))] }))] }));
|
|
184
|
+
}
|
|
185
|
+
/** The mark on the "all filters" chip: something is applied. Not a count —
|
|
186
|
+
* the counts are on the chips beside it, and a number inside a 32px circle is
|
|
187
|
+
* a number nobody reads. */
|
|
188
|
+
function ActiveDot() {
|
|
189
|
+
return (_jsx("span", { "aria-hidden": "true", "data-testid": "search-filters-dot", style: {
|
|
190
|
+
position: "absolute",
|
|
191
|
+
insetInlineEnd: spacing[1],
|
|
192
|
+
insetBlockStart: spacing[1],
|
|
193
|
+
width: spacing[2],
|
|
194
|
+
height: spacing[2],
|
|
195
|
+
borderRadius: radii.full,
|
|
196
|
+
background: "currentColor",
|
|
197
|
+
} }));
|
|
198
|
+
}
|
|
199
|
+
/** Sliders — the one glyph a filter control is universally drawn with. Inline
|
|
200
|
+
* SVG, like every other glyph in the fleet's skins: no icon-font dependency. */
|
|
201
|
+
function SlidersGlyph() {
|
|
202
|
+
return (_jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", role: "img", "aria-hidden": "true", children: [_jsx("path", { d: "M4 7h10M18 7h2M4 17h4M12 17h8" }), _jsx("circle", { cx: "16", cy: "7", r: "2.2" }), _jsx("circle", { cx: "10", cy: "17", r: "2.2" })] }));
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=FilterChips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterChips.js","sourceRoot":"","sources":["../../src/default/FilterChips.tsx"],"names":[],"mappings":"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"}
|