@astryxdesign/core 0.7.7-canary.f9ac85f → 0.7.7
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 +104 -0
- package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts +13 -0
- package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts.map +1 -0
- package/dist/AppShell/useCloseMobileDrawerOnActivate.js +45 -0
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +79 -9
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +1 -1
- package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -1
- package/dist/BottomSheet/bottomSheetStack.js +5 -4
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +2 -1
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +7 -3
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +30 -2
- package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxList.js +7 -1
- package/dist/CheckboxList/CheckboxListContext.d.ts +6 -0
- package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +10 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +5 -2
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +13 -27
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +22 -41
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +5 -2
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +4 -3
- package/dist/Drawer/Drawer.js +0 -1
- package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
- package/dist/Drawer/useDrawerDialogPresence.js +5 -1
- package/dist/Field/PanelSearchInput.d.ts +9 -1
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +3 -1
- package/dist/InfoTip/InfoTip.d.ts +2 -2
- package/dist/InfoTip/InfoTip.js +4 -4
- package/dist/Layer/layerAnimations.stylex.d.ts +7 -8
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +25 -20
- package/dist/Layer/usePressPin.d.ts +3 -5
- package/dist/Layer/usePressPin.d.ts.map +1 -1
- package/dist/Layer/usePressPin.js +4 -6
- package/dist/MobileNav/MobileNav.js +0 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +2 -4
- package/dist/Outline/Outline.d.ts +2 -4
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +4 -52
- package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/useOutlineFromMarkdown.js +1 -0
- package/dist/Outline/useScrollSpy.js +3 -3
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +134 -179
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +5 -0
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +118 -260
- package/dist/Resizable/resizeGesture.d.ts +91 -0
- package/dist/Resizable/resizeGesture.d.ts.map +1 -0
- package/dist/Resizable/resizeGesture.js +251 -0
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +3 -9
- package/dist/Token/Token.d.ts +2 -2
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +12 -4
- package/dist/Token/TokenNamingContext.d.ts +14 -0
- package/dist/Token/TokenNamingContext.d.ts.map +1 -0
- package/dist/Token/TokenNamingContext.js +23 -0
- package/dist/Tokenizer/Tokenizer.d.ts +46 -59
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +35 -58
- package/dist/Tokenizer/TokenizerBottomSheet.d.ts +25 -28
- package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -1
- package/dist/Tokenizer/TokenizerBottomSheet.js +157 -54
- package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts.map +1 -1
- package/dist/Tokenizer/TokenizerItemRemovableContext.js +5 -3
- package/dist/Tooltip/Tooltip.d.ts +25 -30
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/Tooltip.js +24 -5
- package/dist/Tooltip/index.d.ts +1 -1
- package/dist/Tooltip/index.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +28 -29
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +20 -8
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +4 -7
- package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +4 -7
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +4 -7
- package/dist/astryx.css +5 -5
- package/dist/gestures/GestureHost.d.ts +27 -1
- package/dist/gestures/GestureHost.d.ts.map +1 -1
- package/dist/gestures/GestureHost.js +90 -8
- package/dist/hooks/useHighlightedOptionScroll.d.ts +11 -1
- package/dist/hooks/useHighlightedOptionScroll.d.ts.map +1 -1
- package/dist/hooks/useHighlightedOptionScroll.js +103 -5
- package/dist/hooks/useMenuPress.d.ts.map +1 -1
- package/dist/hooks/useMenuPress.js +4 -2
- package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.js +1 -0
- package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.js +7 -1
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +1 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +1 -0
- package/dist/internal/SheetConfirmation.d.ts +11 -0
- package/dist/internal/SheetConfirmation.d.ts.map +1 -0
- package/dist/internal/SheetConfirmation.js +92 -0
- package/dist/internal/sheetDraft.d.ts +35 -0
- package/dist/internal/sheetDraft.d.ts.map +1 -0
- package/dist/internal/sheetDraft.js +65 -0
- package/dist/internal/touch-sheet.d.ts +21 -0
- package/dist/internal/touch-sheet.d.ts.map +1 -0
- package/dist/internal/touch-sheet.js +19 -0
- package/dist/internal/useDismissSearchOnTouchDrag.d.ts +24 -0
- package/dist/internal/useDismissSearchOnTouchDrag.d.ts.map +1 -0
- package/dist/internal/useDismissSearchOnTouchDrag.js +56 -0
- package/dist/motion/reducedMotion.d.ts +24 -0
- package/dist/motion/reducedMotion.d.ts.map +1 -1
- package/dist/motion/reducedMotion.js +78 -1
- package/dist/utils/clickGuard.d.ts +8 -1
- package/dist/utils/clickGuard.d.ts.map +1 -1
- package/dist/utils/clickGuard.js +24 -1
- package/locales/en.json +4 -0
- package/locales/pseudo.json +3 -0
- package/package.json +9 -9
- package/src/AppShell/useCloseMobileDrawerOnActivate.ts +52 -0
- package/src/BottomSheet/BottomSheet.tsx +95 -10
- package/src/BottomSheet/BottomSheetPanel.tsx +7 -2
- package/src/BottomSheet/bottomSheetStack.ts +8 -4
- package/src/Breadcrumbs/BreadcrumbItem.tsx +13 -3
- package/src/Button/Button.tsx +37 -1
- package/src/CheckboxList/CheckboxList.doc.mjs +4 -2
- package/src/CheckboxList/CheckboxList.tsx +6 -0
- package/src/CheckboxList/CheckboxListContext.tsx +6 -0
- package/src/CheckboxList/CheckboxListItem.tsx +11 -2
- package/src/DateInput/DateInput.tsx +8 -2
- package/src/DateInput/MonthScroller.tsx +18 -22
- package/src/DateInput/Wheel.tsx +30 -32
- package/src/DateTimeInput/DateTimeInput.tsx +8 -2
- package/src/Dialog/Dialog.tsx +19 -4
- package/src/Drawer/Drawer.tsx +1 -1
- package/src/Drawer/useDrawerDialogPresence.ts +5 -1
- package/src/Field/PanelSearchInput.tsx +11 -0
- package/src/InfoTip/InfoTip.doc.mjs +3 -3
- package/src/InfoTip/InfoTip.tsx +5 -5
- package/src/Layer/layerAnimations.stylex.ts +24 -16
- package/src/Layer/usePressPin.ts +5 -11
- package/src/MobileNav/MobileNav.tsx +1 -1
- package/src/MultiSelector/hooks.ts +2 -4
- package/src/Outline/Outline.doc.mjs +177 -51
- package/src/Outline/Outline.tsx +5 -57
- package/src/Outline/useOutlineFromMarkdown.doc.mjs +157 -0
- package/src/Outline/useOutlineFromMarkdown.ts +1 -0
- package/src/Outline/useScrollSpy.ts +3 -3
- package/src/PowerSearch/PowerSearch.doc.mjs +3 -3
- package/src/PowerSearch/PowerSearch.tsx +196 -183
- package/src/RadioList/RadioList.doc.mjs +4 -2
- package/src/RadioList/RadioList.tsx +4 -0
- package/src/Resizable/ResizeHandle.tsx +133 -328
- package/src/Resizable/resizeGesture.ts +368 -0
- package/src/SideNav/SideNavItem.tsx +3 -7
- package/src/Token/Token.tsx +13 -4
- package/src/Token/TokenNamingContext.ts +28 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +16 -0
- package/src/Tokenizer/Tokenizer.tsx +81 -86
- package/src/Tokenizer/TokenizerBottomSheet.tsx +219 -93
- package/src/Tokenizer/TokenizerItemRemovableContext.ts +5 -3
- package/src/Tooltip/Tooltip.doc.mjs +123 -54
- package/src/Tooltip/Tooltip.tsx +36 -39
- package/src/Tooltip/index.ts +0 -1
- package/src/Tooltip/useTooltip.doc.mjs +147 -33
- package/src/Tooltip/useTooltip.tsx +39 -32
- package/src/TopNav/TopNavItem.tsx +6 -5
- package/src/TopNav/TopNavMegaMenuItem.tsx +6 -5
- package/src/TopNav/TopNavMenu.tsx +6 -5
- package/src/gestures/GestureHost.ts +105 -10
- package/src/hooks/useHighlightedOptionScroll.ts +113 -9
- package/src/hooks/useMenuPress.ts +8 -2
- package/src/i18n/generated-english/PowerSearch/PowerSearch.generated.ts +1 -0
- package/src/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.ts +7 -1
- package/src/i18n/generated-locales/en.generated.ts +1 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +1 -0
- package/src/internal/SheetConfirmation.tsx +101 -0
- package/src/internal/sheetDraft.ts +80 -0
- package/src/internal/touch-sheet.ts +21 -0
- package/src/internal/useDismissSearchOnTouchDrag.ts +69 -0
- package/src/motion/reducedMotion.ts +79 -1
- package/src/utils/clickGuard.ts +37 -1
- package/dist/internal/tokenizer-presentation.d.ts +0 -21
- package/dist/internal/tokenizer-presentation.d.ts.map +0 -1
- package/dist/internal/tokenizer-presentation.js +0 -21
- package/src/internal/tokenizer-presentation.ts +0 -25
|
@@ -34,6 +34,7 @@ import {TokenizerClearAllMessageContext} from '../Tokenizer/TokenizerClearAllMes
|
|
|
34
34
|
import {TokenizerItemRemovableContext} from '../Tokenizer/TokenizerItemRemovableContext';
|
|
35
35
|
import {TypeaheadItem} from '../Typeahead/TypeaheadItem';
|
|
36
36
|
import {Token} from '../Token';
|
|
37
|
+
import {TokenNamingContext} from '../Token/TokenNamingContext';
|
|
37
38
|
import {Avatar} from '../Avatar';
|
|
38
39
|
import {layerAnimations} from '../Layer/layerAnimations.stylex';
|
|
39
40
|
import {Icon} from '../Icon';
|
|
@@ -62,6 +63,7 @@ import {themeProps} from '../utils/themeProps';
|
|
|
62
63
|
import {truncateCharacters} from '../utils/characters';
|
|
63
64
|
import {useLocale} from '../i18n/useLocale';
|
|
64
65
|
import type {Locale} from '../i18n/types';
|
|
66
|
+
import type {SearchableItem} from '../Typeahead/types';
|
|
65
67
|
import type {
|
|
66
68
|
PowerSearchConfig,
|
|
67
69
|
PowerSearchFilter,
|
|
@@ -74,6 +76,7 @@ import type {
|
|
|
74
76
|
OperatorValue,
|
|
75
77
|
EnumItem,
|
|
76
78
|
PowerSearchComponents,
|
|
79
|
+
PowerSearchOperator,
|
|
77
80
|
} from './types';
|
|
78
81
|
|
|
79
82
|
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
@@ -157,52 +160,35 @@ function getEnumLabel(values: ReadonlyArray<EnumItem>, value: string): string {
|
|
|
157
160
|
return values.find(v => v.value === value)?.label ?? value;
|
|
158
161
|
}
|
|
159
162
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}) {
|
|
163
|
+
/**
|
|
164
|
+
* The visible text of a filter token's value. The token renders it, and the
|
|
165
|
+
* token's remove button and editor dialog are named by the same text.
|
|
166
|
+
*/
|
|
167
|
+
function tokenValueText(
|
|
168
|
+
operatorValue: OperatorValue,
|
|
169
|
+
filterValue: FilterValue,
|
|
170
|
+
maxLength: number,
|
|
171
|
+
locale: Locale,
|
|
172
|
+
): string | null {
|
|
171
173
|
switch (filterValue.type) {
|
|
172
174
|
case 'empty':
|
|
173
175
|
return null;
|
|
174
176
|
|
|
175
177
|
case 'string':
|
|
176
|
-
return (
|
|
177
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
178
|
-
{truncateString(filterValue.value, maxLength)}
|
|
179
|
-
</span>
|
|
180
|
-
);
|
|
178
|
+
return truncateString(filterValue.value, maxLength);
|
|
181
179
|
|
|
182
180
|
case 'integer':
|
|
183
181
|
case 'float':
|
|
184
|
-
return (
|
|
185
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
186
|
-
{filterValue.value}
|
|
187
|
-
</span>
|
|
188
|
-
);
|
|
182
|
+
return String(filterValue.value);
|
|
189
183
|
|
|
190
184
|
case 'enum':
|
|
191
185
|
if (operatorValue.type === 'enum') {
|
|
192
|
-
return (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
getEnumLabel(operatorValue.values, filterValue.value),
|
|
196
|
-
maxLength,
|
|
197
|
-
)}
|
|
198
|
-
</span>
|
|
186
|
+
return truncateString(
|
|
187
|
+
getEnumLabel(operatorValue.values, filterValue.value),
|
|
188
|
+
maxLength,
|
|
199
189
|
);
|
|
200
190
|
}
|
|
201
|
-
return (
|
|
202
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
203
|
-
{truncateString(filterValue.value, maxLength)}
|
|
204
|
-
</span>
|
|
205
|
-
);
|
|
191
|
+
return truncateString(filterValue.value, maxLength);
|
|
206
192
|
|
|
207
193
|
case 'string_list': {
|
|
208
194
|
const items = filterValue.value;
|
|
@@ -210,25 +196,13 @@ function PowerSearchTokenValue({
|
|
|
210
196
|
return null;
|
|
211
197
|
}
|
|
212
198
|
if (items.length === 1) {
|
|
213
|
-
return (
|
|
214
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
215
|
-
{truncateString(items[0], maxLength)}
|
|
216
|
-
</span>
|
|
217
|
-
);
|
|
199
|
+
return truncateString(items[0], maxLength);
|
|
218
200
|
}
|
|
219
201
|
const totalLength = items.reduce((sum, s) => sum + s.length, 0);
|
|
220
202
|
if (totalLength > maxLength) {
|
|
221
|
-
return
|
|
222
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
223
|
-
{items.length} items
|
|
224
|
-
</span>
|
|
225
|
-
);
|
|
203
|
+
return `${items.length} items`;
|
|
226
204
|
}
|
|
227
|
-
return (
|
|
228
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
229
|
-
{items.join(', ')}
|
|
230
|
-
</span>
|
|
231
|
-
);
|
|
205
|
+
return items.join(', ');
|
|
232
206
|
}
|
|
233
207
|
|
|
234
208
|
case 'enum_list': {
|
|
@@ -239,38 +213,18 @@ function PowerSearchTokenValue({
|
|
|
239
213
|
if (operatorValue.type === 'enum_list') {
|
|
240
214
|
const labels = items.map(v => getEnumLabel(operatorValue.values, v));
|
|
241
215
|
if (labels.length === 1) {
|
|
242
|
-
return (
|
|
243
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
244
|
-
{truncateString(labels[0], maxLength)}
|
|
245
|
-
</span>
|
|
246
|
-
);
|
|
216
|
+
return truncateString(labels[0], maxLength);
|
|
247
217
|
}
|
|
248
218
|
const totalLength = labels.reduce((sum, s) => sum + s.length, 0);
|
|
249
219
|
if (totalLength > maxLength) {
|
|
250
|
-
return
|
|
251
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
252
|
-
{labels.length} items
|
|
253
|
-
</span>
|
|
254
|
-
);
|
|
220
|
+
return `${labels.length} items`;
|
|
255
221
|
}
|
|
256
|
-
return (
|
|
257
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
258
|
-
{labels.join(', ')}
|
|
259
|
-
</span>
|
|
260
|
-
);
|
|
222
|
+
return labels.join(', ');
|
|
261
223
|
}
|
|
262
224
|
if (items.length === 1) {
|
|
263
|
-
return (
|
|
264
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
265
|
-
{truncateString(items[0], maxLength)}
|
|
266
|
-
</span>
|
|
267
|
-
);
|
|
225
|
+
return truncateString(items[0], maxLength);
|
|
268
226
|
}
|
|
269
|
-
return
|
|
270
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
271
|
-
{items.length} items
|
|
272
|
-
</span>
|
|
273
|
-
);
|
|
227
|
+
return `${items.length} items`;
|
|
274
228
|
}
|
|
275
229
|
|
|
276
230
|
case 'entity_list': {
|
|
@@ -279,80 +233,42 @@ function PowerSearchTokenValue({
|
|
|
279
233
|
return null;
|
|
280
234
|
}
|
|
281
235
|
if (entities.length === 1) {
|
|
282
|
-
return (
|
|
283
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
284
|
-
{truncateString(entities[0].label, maxLength)}
|
|
285
|
-
</span>
|
|
286
|
-
);
|
|
236
|
+
return truncateString(entities[0].label, maxLength);
|
|
287
237
|
}
|
|
288
238
|
const totalLength = entities.reduce((sum, e) => sum + e.label.length, 0);
|
|
289
239
|
if (totalLength > maxLength) {
|
|
290
|
-
return
|
|
291
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
292
|
-
{entities.length} items
|
|
293
|
-
</span>
|
|
294
|
-
);
|
|
240
|
+
return `${entities.length} items`;
|
|
295
241
|
}
|
|
296
|
-
return (
|
|
297
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
298
|
-
{entities.map(e => e.label).join(', ')}
|
|
299
|
-
</span>
|
|
300
|
-
);
|
|
242
|
+
return entities.map(e => e.label).join(', ');
|
|
301
243
|
}
|
|
302
244
|
|
|
303
245
|
case 'time':
|
|
304
|
-
return
|
|
305
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
306
|
-
{filterValue.value}
|
|
307
|
-
</span>
|
|
308
|
-
);
|
|
246
|
+
return filterValue.value;
|
|
309
247
|
|
|
310
|
-
case 'date_absolute':
|
|
311
|
-
|
|
312
|
-
filterValue.unixSeconds,
|
|
313
|
-
|
|
248
|
+
case 'date_absolute':
|
|
249
|
+
return truncateString(
|
|
250
|
+
formatDateAbsoluteCompact(filterValue.unixSeconds, locale),
|
|
251
|
+
maxLength,
|
|
314
252
|
);
|
|
315
|
-
return (
|
|
316
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
317
|
-
{truncateString(formatted, maxLength)}
|
|
318
|
-
</span>
|
|
319
|
-
);
|
|
320
|
-
}
|
|
321
253
|
|
|
322
254
|
case 'date_relative':
|
|
323
|
-
return (
|
|
324
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
325
|
-
{truncateString(filterValue.value, maxLength)}
|
|
326
|
-
</span>
|
|
327
|
-
);
|
|
255
|
+
return truncateString(filterValue.value, maxLength);
|
|
328
256
|
|
|
329
257
|
case 'date_range':
|
|
330
|
-
return
|
|
258
|
+
return 'date range';
|
|
331
259
|
|
|
332
260
|
case 'custom':
|
|
333
261
|
if (operatorValue.type === 'custom') {
|
|
334
|
-
return (
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
operatorValue.getString(filterValue.value),
|
|
338
|
-
maxLength,
|
|
339
|
-
)}
|
|
340
|
-
</span>
|
|
262
|
+
return truncateString(
|
|
263
|
+
operatorValue.getString(filterValue.value),
|
|
264
|
+
maxLength,
|
|
341
265
|
);
|
|
342
266
|
}
|
|
343
|
-
return
|
|
344
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
345
|
-
{filterValue.value}
|
|
346
|
-
</span>
|
|
347
|
-
);
|
|
267
|
+
return filterValue.value;
|
|
348
268
|
|
|
349
269
|
case 'nested': {
|
|
350
270
|
const count = filterValue.value.length;
|
|
351
|
-
return
|
|
352
|
-
<span {...stylex.props(tokenValueStyles.value)}>
|
|
353
|
-
{count === 1 ? '1 filter' : `${count} filters`}
|
|
354
|
-
</span>
|
|
355
|
-
);
|
|
271
|
+
return count === 1 ? '1 filter' : `${count} filters`;
|
|
356
272
|
}
|
|
357
273
|
|
|
358
274
|
default:
|
|
@@ -360,6 +276,10 @@ function PowerSearchTokenValue({
|
|
|
360
276
|
}
|
|
361
277
|
}
|
|
362
278
|
|
|
279
|
+
function PowerSearchTokenValue({text}: {text: string}) {
|
|
280
|
+
return <span {...stylex.props(tokenValueStyles.value)}>{text}</span>;
|
|
281
|
+
}
|
|
282
|
+
|
|
363
283
|
// =============================================================================
|
|
364
284
|
// Types
|
|
365
285
|
// =============================================================================
|
|
@@ -490,6 +410,20 @@ type PopoverState =
|
|
|
490
410
|
// Component
|
|
491
411
|
// =============================================================================
|
|
492
412
|
|
|
413
|
+
/**
|
|
414
|
+
* Whether a press on a token with this operator commits the filter instead of
|
|
415
|
+
* opening its editor: an `empty` operator with no `empty` Editor override.
|
|
416
|
+
*/
|
|
417
|
+
function commitsWithoutEditor(
|
|
418
|
+
operator: PowerSearchOperator | undefined,
|
|
419
|
+
componentOverrides: PowerSearchComponents | undefined,
|
|
420
|
+
): boolean {
|
|
421
|
+
return (
|
|
422
|
+
operator?.value.type === 'empty' &&
|
|
423
|
+
componentOverrides?.empty?.Editor == null
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
493
427
|
/**
|
|
494
428
|
* Structured filter bar where each token represents a filter (field + operator + value).
|
|
495
429
|
*
|
|
@@ -607,6 +541,47 @@ export function PowerSearch({
|
|
|
607
541
|
type: 'idle',
|
|
608
542
|
});
|
|
609
543
|
|
|
544
|
+
// A default filter token's visible text: its label (field and operator)
|
|
545
|
+
// and its value. The token's remove button and editor dialog are named by
|
|
546
|
+
// the same text.
|
|
547
|
+
const tokenText = useCallback(
|
|
548
|
+
(filter: PowerSearchFilter) => {
|
|
549
|
+
const field = config.getField(filter.field);
|
|
550
|
+
const operator = config.getOperator(filter.field, filter.operator);
|
|
551
|
+
const fieldLabel = field?.label ?? '';
|
|
552
|
+
const operatorLabel = operator ? resolveOperatorLabel(operator, t) : '';
|
|
553
|
+
const label = `${fieldLabel}: ${operatorLabel}`.trim();
|
|
554
|
+
const value = operator
|
|
555
|
+
? tokenValueText(
|
|
556
|
+
operator.value,
|
|
557
|
+
filter.value,
|
|
558
|
+
Math.max(
|
|
559
|
+
maxTokenLength - fieldLabel.length - operatorLabel.length,
|
|
560
|
+
10,
|
|
561
|
+
),
|
|
562
|
+
locale,
|
|
563
|
+
)
|
|
564
|
+
: null;
|
|
565
|
+
return {label, value, full: value != null ? `${label} ${value}` : label};
|
|
566
|
+
},
|
|
567
|
+
[config, maxTokenLength, t, locale],
|
|
568
|
+
);
|
|
569
|
+
// The built-in token being edited. A token from a `components` override
|
|
570
|
+
// names itself, so its editor keeps the plain popover.
|
|
571
|
+
const editedFilter =
|
|
572
|
+
popoverState.type === 'editing'
|
|
573
|
+
? filters[popoverState.filterIndex]
|
|
574
|
+
: undefined;
|
|
575
|
+
const editedOperator =
|
|
576
|
+
editedFilter != null
|
|
577
|
+
? config.getOperator(editedFilter.field, editedFilter.operator)
|
|
578
|
+
: undefined;
|
|
579
|
+
const editedBuiltInFilter =
|
|
580
|
+
editedOperator == null ||
|
|
581
|
+
componentOverrides?.[editedOperator.value.type]?.Token == null
|
|
582
|
+
? editedFilter
|
|
583
|
+
: undefined;
|
|
584
|
+
|
|
610
585
|
// Layer for positioning the edit popover anchored to the tokenizer
|
|
611
586
|
const handleLayerHide = useCallback(() => {
|
|
612
587
|
setPopoverStateRaw({type: 'idle'});
|
|
@@ -617,9 +592,16 @@ export function PowerSearch({
|
|
|
617
592
|
hasLightDismiss: true,
|
|
618
593
|
hasCloseButton: false,
|
|
619
594
|
hasAutoFocus: false,
|
|
620
|
-
//
|
|
621
|
-
// stays on the tokenizer input, so a
|
|
622
|
-
|
|
595
|
+
// Adding: the popup's own listbox/menu content is the exposed semantics,
|
|
596
|
+
// and focus stays on the tokenizer input, so a dialog wrapper is
|
|
597
|
+
// incorrect. Editing a token: focus moves into the editor's controls, so
|
|
598
|
+
// the editor is a non-modal dialog named by the token's visible text.
|
|
599
|
+
role: editedBuiltInFilter != null ? 'dialog' : 'none',
|
|
600
|
+
isModal: false,
|
|
601
|
+
dialogLabel:
|
|
602
|
+
editedBuiltInFilter != null
|
|
603
|
+
? tokenText(editedBuiltInFilter).full
|
|
604
|
+
: undefined,
|
|
623
605
|
});
|
|
624
606
|
|
|
625
607
|
// Wrapper that manages layer visibility and tokenizer focus alongside state
|
|
@@ -739,22 +721,38 @@ export function PowerSearch({
|
|
|
739
721
|
value: undefined,
|
|
740
722
|
},
|
|
741
723
|
});
|
|
742
|
-
} else if (change.type === 'remove'
|
|
743
|
-
const
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
724
|
+
} else if (change.type === 'remove') {
|
|
725
|
+
const keptIndices = new Set(
|
|
726
|
+
_items.map(item => item.auxiliaryData?.filterIndex),
|
|
727
|
+
);
|
|
728
|
+
const firstRemovedIndex = filters.findIndex(
|
|
729
|
+
(_, i) => !keptIndices.has(i),
|
|
730
|
+
);
|
|
731
|
+
if (firstRemovedIndex >= 0) {
|
|
732
|
+
onChange(
|
|
733
|
+
filters.filter((_, i) => keptIndices.has(i)),
|
|
734
|
+
'remove',
|
|
735
|
+
firstRemovedIndex,
|
|
747
736
|
);
|
|
748
|
-
onChange(newFilters, 'remove', auxData.filterIndex);
|
|
749
737
|
}
|
|
750
738
|
}
|
|
751
739
|
},
|
|
752
740
|
[config, filters, onChange, setPopoverState],
|
|
753
741
|
);
|
|
754
742
|
|
|
755
|
-
// Tokenizer's Backspace
|
|
756
|
-
// locks every token of a read-only
|
|
757
|
-
|
|
743
|
+
// Tokenizer's Backspace and Clear all do not go through renderToken. This
|
|
744
|
+
// predicate locks each read-only filter, and every token of a read-only
|
|
745
|
+
// field.
|
|
746
|
+
const isItemRemovable = useCallback(
|
|
747
|
+
(item: SearchableItem) => {
|
|
748
|
+
if (isReadOnly) {
|
|
749
|
+
return false;
|
|
750
|
+
}
|
|
751
|
+
const filterIndex = (item as PowerSearchItem).auxiliaryData?.filterIndex;
|
|
752
|
+
return filterIndex == null || !filters[filterIndex]?.isReadOnly;
|
|
753
|
+
},
|
|
754
|
+
[filters, isReadOnly],
|
|
755
|
+
);
|
|
758
756
|
|
|
759
757
|
// Handle clicking a token to edit
|
|
760
758
|
const handleTokenClick = useCallback(
|
|
@@ -772,10 +770,7 @@ export function PowerSearch({
|
|
|
772
770
|
// edit: commit it as that editor's save would, the way adding one does,
|
|
773
771
|
// instead of opening it. A consumer's `empty` Editor override still opens.
|
|
774
772
|
const operator = config.getOperator(filter.field, filter.operator);
|
|
775
|
-
if (
|
|
776
|
-
operator?.value.type === 'empty' &&
|
|
777
|
-
componentOverrides?.empty?.Editor == null
|
|
778
|
-
) {
|
|
773
|
+
if (commitsWithoutEditor(operator, componentOverrides)) {
|
|
779
774
|
const newFilters = [...filters];
|
|
780
775
|
newFilters[index] = {
|
|
781
776
|
field: filter.field,
|
|
@@ -880,20 +875,16 @@ export function PowerSearch({
|
|
|
880
875
|
// Default token rendering
|
|
881
876
|
const fieldLabel = field?.label ?? '';
|
|
882
877
|
const operatorLabel = operator ? resolveOperatorLabel(operator, t) : '';
|
|
883
|
-
const
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
878
|
+
const text =
|
|
879
|
+
filter != null
|
|
880
|
+
? tokenText(filter)
|
|
881
|
+
: {label: `${fieldLabel}: ${operatorLabel}`.trim(), value: null};
|
|
882
|
+
const tokenLabel = text.label;
|
|
883
|
+
const fullText =
|
|
884
|
+
text.value != null ? `${text.label} ${text.value}` : text.label;
|
|
889
885
|
const valueContent =
|
|
890
|
-
|
|
891
|
-
<PowerSearchTokenValue
|
|
892
|
-
operatorValue={operator.value}
|
|
893
|
-
filterValue={filter.value}
|
|
894
|
-
maxLength={adjustedMaxLength}
|
|
895
|
-
locale={locale}
|
|
896
|
-
/>
|
|
886
|
+
text.value != null ? (
|
|
887
|
+
<PowerSearchTokenValue text={text.value} />
|
|
897
888
|
) : undefined;
|
|
898
889
|
|
|
899
890
|
// Show entity photo as token icon for single-entity filters
|
|
@@ -907,32 +898,49 @@ export function PowerSearch({
|
|
|
907
898
|
tokenIcon = <Avatar src={entity.photo} name={entity.label} size={16} />;
|
|
908
899
|
}
|
|
909
900
|
|
|
901
|
+
// A token that opens its editor says that it opens a dialog, and the
|
|
902
|
+
// naming context names it by all its visible text.
|
|
903
|
+
const editorProps =
|
|
904
|
+
handleClick != null &&
|
|
905
|
+
!commitsWithoutEditor(operator, componentOverrides)
|
|
906
|
+
? {
|
|
907
|
+
'aria-haspopup': 'dialog' as const,
|
|
908
|
+
'aria-expanded':
|
|
909
|
+
popoverState.type === 'editing' &&
|
|
910
|
+
popoverState.filterIndex === filterIndex,
|
|
911
|
+
}
|
|
912
|
+
: null;
|
|
913
|
+
|
|
910
914
|
return (
|
|
911
|
-
<
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
915
|
+
<TokenNamingContext
|
|
916
|
+
value={{actionName: fullText, removeName: fullText}}>
|
|
917
|
+
<Token
|
|
918
|
+
label={tokenLabel}
|
|
919
|
+
size={size}
|
|
920
|
+
icon={tokenIcon}
|
|
921
|
+
{...editorProps}
|
|
922
|
+
endContent={valueContent}
|
|
923
|
+
onMouseDown={
|
|
924
|
+
handleClick
|
|
925
|
+
? e => {
|
|
926
|
+
// Keep a token press from entering Tokenizer's input-focus
|
|
927
|
+
// redirect. Click still edits/removes; Tab entry is unchanged.
|
|
928
|
+
e.preventDefault();
|
|
929
|
+
}
|
|
930
|
+
: undefined
|
|
931
|
+
}
|
|
932
|
+
onClick={
|
|
933
|
+
handleClick
|
|
934
|
+
? (e: React.MouseEvent) => {
|
|
935
|
+
e.stopPropagation();
|
|
936
|
+
handleClick();
|
|
937
|
+
}
|
|
938
|
+
: undefined
|
|
939
|
+
}
|
|
940
|
+
onRemove={handleRemove}
|
|
941
|
+
isDisabled={isDisabled}
|
|
942
|
+
/>
|
|
943
|
+
</TokenNamingContext>
|
|
936
944
|
);
|
|
937
945
|
},
|
|
938
946
|
[
|
|
@@ -940,13 +948,14 @@ export function PowerSearch({
|
|
|
940
948
|
config,
|
|
941
949
|
configProp,
|
|
942
950
|
maxTokenLength,
|
|
943
|
-
locale,
|
|
944
951
|
size,
|
|
945
952
|
isReadOnly,
|
|
946
953
|
isDisabled,
|
|
947
954
|
handleTokenClick,
|
|
948
955
|
componentOverrides,
|
|
949
956
|
t,
|
|
957
|
+
popoverState,
|
|
958
|
+
tokenText,
|
|
950
959
|
],
|
|
951
960
|
);
|
|
952
961
|
|
|
@@ -1077,9 +1086,13 @@ export function PowerSearch({
|
|
|
1077
1086
|
const announce = useAnnounce();
|
|
1078
1087
|
// PowerSearch words its Clear all as its record does; the field announces
|
|
1079
1088
|
// these words instead of Tokenizer's (component:Tokenizer AR7).
|
|
1089
|
+
const hasReadOnlyFilter = filters.some(filter => filter.isReadOnly);
|
|
1080
1090
|
const clearAllMessage = useMemo(
|
|
1081
|
-
() =>
|
|
1082
|
-
|
|
1091
|
+
() =>
|
|
1092
|
+
hasReadOnlyFilter
|
|
1093
|
+
? t('@astryx.powersearch.editableFiltersRemoved')
|
|
1094
|
+
: t('@astryx.powersearch.allFiltersRemoved'),
|
|
1095
|
+
[hasReadOnlyFilter, t],
|
|
1083
1096
|
);
|
|
1084
1097
|
const announcedResultCountRef = useRef(resultCountText);
|
|
1085
1098
|
useEffect(() => {
|
|
@@ -148,12 +148,14 @@ export const docs = {
|
|
|
148
148
|
{
|
|
149
149
|
name: 'containerClassName',
|
|
150
150
|
type: 'string',
|
|
151
|
-
description:
|
|
151
|
+
description:
|
|
152
|
+
'Class name for the field container. Same targeting as `containerXstyle`.',
|
|
152
153
|
},
|
|
153
154
|
{
|
|
154
155
|
name: 'containerStyle',
|
|
155
156
|
type: 'CSSProperties',
|
|
156
|
-
description:
|
|
157
|
+
description:
|
|
158
|
+
'Inline styles for the field container. Same targeting as `containerXstyle`.',
|
|
157
159
|
},
|
|
158
160
|
{
|
|
159
161
|
name: 'controlXstyle',
|
|
@@ -403,6 +403,10 @@ export function RadioList({
|
|
|
403
403
|
disabledMessageTooltip.ref(el);
|
|
404
404
|
}}
|
|
405
405
|
role="radiogroup"
|
|
406
|
+
// Screen readers announce the whole group as unavailable. Its dimmed
|
|
407
|
+
// label then labels a disabled control. An enabled list keeps a
|
|
408
|
+
// caller's own value.
|
|
409
|
+
aria-disabled={isDisabled || rest['aria-disabled']}
|
|
406
410
|
// A caller aria-labelledby names the group together with its label.
|
|
407
411
|
aria-labelledby={joinAriaIDs(labelID, ariaLabelledByProp)}
|
|
408
412
|
onFocus={composeEventHandlers(handleFocus, onFocus)}
|