@assure-one/design-system 1.47.1 → 1.48.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/codemods/lib/entry-map.mjs +4 -0
- package/dist/{brand-scope-DwLzUrSY.d.ts → brand-scope-ObBYNT0J.d.ts} +3 -63
- package/dist/{chunk-6CXI3KRG.js → chunk-FO2WSYUA.js} +796 -336
- package/dist/chunk-FO2WSYUA.js.map +1 -0
- package/dist/{chunk-IIBDSTOG.js → chunk-HV24JSRN.js} +215 -10
- package/dist/chunk-HV24JSRN.js.map +1 -0
- package/dist/{chunk-FIRPQWYR.js → chunk-YRFLK7ER.js} +1258 -270
- package/dist/chunk-YRFLK7ER.js.map +1 -0
- package/dist/css/components.css +1 -1
- package/dist/{data-table-view-D9a1_IRF.d.ts → data-table-view-CNTfzEyS.d.ts} +769 -16
- package/dist/{design-system-provider-C6Tu1vyg.d.ts → design-system-provider-YblRtwYw.d.ts} +1 -1
- package/dist/index.d.ts +914 -392
- package/dist/index.js +3227 -340
- package/dist/index.js.map +1 -1
- package/dist/legacy/index.d.ts +4 -3
- package/dist/legacy/index.js +2 -2
- package/dist/next/index.d.ts +2 -2
- package/dist/option-izy_4w4Z.d.ts +64 -0
- package/dist/styles.css +1 -1
- package/dist/suite/index.d.ts +38 -4
- package/dist/suite/index.js +2 -2
- package/dist/{types-BTHIs2nk.d.ts → types-CKpkEBvW.d.ts} +282 -1
- package/docs/components.md +19 -7
- package/docs/components.registry.json +152 -8
- package/package.json +2 -1
- package/dist/chunk-6CXI3KRG.js.map +0 -1
- package/dist/chunk-FIRPQWYR.js.map +0 -1
- package/dist/chunk-IIBDSTOG.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
4
|
-
import {
|
|
5
|
-
export {
|
|
6
|
-
import { withPortalContainer, Backdrop, alertDialogAnatomy, OverlaySurface, OverlayTitle, OverlayDescription, Button, slot, useDsMessages, useLinkComponent, surfaceAnatomy, stateAttributes, cardAnatomy, ModalPortal, kbdAnatomy, FieldContext, fieldAnatomy, useFieldContext, MENU_SUB_TRIGGER_CHEVRON, menuSubTriggerClasses, MENU_INSET, contextMenuAnatomy, presence, menuItemClasses, MENU_ITEM_DANGER, MENU_INDICATOR_WELL, MENU_CHECK_GLYPH, menuIndicatorItemClasses, MENU_RADIO_GLYPH, menuLabelClasses, menuSeparatorClasses, useFieldControl, useMergedRefs, joinIds, Popover, PopoverTrigger, PopoverContent, FormBridge, CONTROL_SIZE_CLASSES, dialogAnatomy, DismissButton, DEFAULT_OVERLAY_MESSAGES, DISMISS_GLYPH_CLASSES, OverlayBody, headingAnatomy, deprecate, floatingSurfaceClasses, FLOATING_PADDING, FLOATING_WIDTH, labelAnatomy, warnLegacyButtonProps, resolveButtonIcons, buttonVariants, INERT_CLASSES, DISABLED_LOOK_CLASSES, inertHandlers, INERT_ATTRIBUTES, linkButtonAnatomy, useControllableState, controlChrome, mergeRefs, numberInputAnatomy, EN_MESSAGES, phoneFieldAnatomy, Input, useFieldsetContext, useFormReset2, radioGroupAnatomy, microInteractions, CONTROL_LABEL_TEXT, searchInputAnatomy, IconButton, Tooltip, TooltipTrigger, TooltipContent, codeAnatomy, textAnatomy, Slot, stackAnatomy, inlineAnatomy, statusBadgeAnatomy, useFieldsetState, FieldsetContext, fieldsetAnatomy, useFieldsetLegend, shellAnatomy, Avatar,
|
|
7
|
-
export { Avatar, Button, Checkbox, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileChip, FileUpload, IconButton, Input, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, Pressable, SPINNER_TONE_TO_INTENT, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Spinner, Textarea, ThemeScope, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, buttonVariants, iconButtonVariants, inputVariants, resolveButtonStyle, spinnerVariants, textareaVariants, useDsMessages, useFieldControl } from './chunk-
|
|
8
|
-
import { cn, ChevronDownIcon, EyeIcon, DownloadIcon, ChevronRightIcon, CheckIcon, CircleIcon, CopyIcon, CalendarIcon, XIcon, AlertTriangleIcon, ArrowRightIcon, ArrowLeftIcon, FileTextIcon, ZoomOutIcon, ZoomInIcon, lucideIcon, SquareExclamationPointIcon, TrendingUpIcon, TrendingDownIcon, SearchIcon, TableIcon, StarIcon, RowsIcon, Rows4Icon, ListChecksIcon, CheckCircleSolidIcon, HelpCircleIcon, UserIcon, SendIcon, SettingsIcon, XCircleIcon, CheckCircle2Icon, InfoIcon, ChevronLeftIcon, FolderOpenIcon, FolderClosedIcon, MinusIcon, Icon, ChartNoAxesColumnIncreasingIcon, AlertCircleIcon, PlusIcon, CircleDashedIcon, LoaderIcon, InfoCircleSolidIcon, AlertTriangleSolidIcon, XCircleSolidIcon, RotateCcwIcon, CommandIcon } from './chunk-ARCWF2S3.js';
|
|
2
|
+
import { Collapsible, CollapsibleTrigger, CollapsibleContent, PlainLink, Combobox, Sidebar, SidebarFooter, SidebarUser, Chip, useSidebarState, SidebarSection, SidebarLinkGroup, SidebarLink, SidebarLinkLabel, SidebarLinkBadge, CmdkCompatContext, Sheet, SheetContent, SheetTitle } from './chunk-FO2WSYUA.js';
|
|
3
|
+
export { BrandScope, BrandScopeProvider, Chip, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, DEFAULT_COMBOBOX_MESSAGES, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarBrand, SidebarBrandText, SidebarDrawer, SidebarFooter, SidebarLink, SidebarLinkAction, SidebarLinkBadge, SidebarLinkGroup, SidebarLinkLabel, SidebarPinButton, SidebarProvider, SidebarSection, SidebarTrigger, SidebarUser, assetPath, brandScope, chipVariants, getAssetBasePath, resolveChipStyle, setAssetBasePath, sidebarLinkBadgeVariants, useBrandScope, useSidebarPeekLock, useSidebarState } from './chunk-FO2WSYUA.js';
|
|
4
|
+
import { Skeleton, ToggleGroup, ToggleGroupItem, useOverflowTooltip, badgeVariants, DataTableBody, DataTableRow, DataTableCell, Badge, VisuallyHidden, ProgressBar, Pagination, TableBody, TableRow, TableCell, Table, TableHeader, TableHead } from './chunk-YRFLK7ER.js';
|
|
5
|
+
export { Badge, DATA_TABLE_NO_GROUPING, DataTable, DataTableBody, DataTableCell, DataTableCellDue, DataTableCellId, DataTableCellMono, DataTableCellName, DataTableCellSecondary, DataTableCheckbox, DataTableHead, DataTableHeader, DataTableHeaderMenu, DataTableLoadMore, DataTablePagination, DataTableResultsCount, DataTableRow, DataTableSearch, DataTableSpacer, DataTableSpacerRow, DataTableToolbar, DataTableView, EmptyValue, PROGRESS_LEGACY_TO_INTENT, Pagination, ProgressBar, ProgressRing, SERVICE_TONES, STATUS_DOT_TONE_TO_INTENT, SegmentedProgress, Skeleton, SkeletonCircle, SkeletonText, StatusDot, Switch, Table, TableBody, TableCaption, TableCell, TableCellSecondary, TableFooter, TableGroupRow, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, ToggleGroup, ToggleGroupItem, VisuallyHidden, badgeVariants, compareSortValues, nextSortDirection, progressBarVariants, progressRingVariants, resolveBadgeAppearance, serviceToneLabel, serviceToneStyle, statusDotVariants, useDataTable, useDataTableGrouping, useDataTableVirtualRows, useScrollRestoration } from './chunk-YRFLK7ER.js';
|
|
6
|
+
import { withPortalContainer, Backdrop, alertDialogAnatomy, OverlaySurface, OverlayTitle, OverlayDescription, Button, slot, useDsMessages, useLinkComponent, surfaceAnatomy, stateAttributes, cardAnatomy, ModalPortal, kbdAnatomy, FieldContext, fieldAnatomy, useFieldContext, MENU_SUB_TRIGGER_CHEVRON, menuSubTriggerClasses, MENU_INSET, contextMenuAnatomy, presence, menuItemClasses, MENU_ITEM_DANGER, MENU_INDICATOR_WELL, MENU_CHECK_GLYPH, menuIndicatorItemClasses, MENU_RADIO_GLYPH, menuLabelClasses, menuSeparatorClasses, useFieldControl, useMergedRefs, joinIds, Popover, PopoverTrigger, PopoverContent, FormBridge, CONTROL_SIZE_CLASSES, dialogAnatomy, DismissButton, DEFAULT_OVERLAY_MESSAGES, DISMISS_GLYPH_CLASSES, OverlayBody, headingAnatomy, deprecate, floatingSurfaceClasses, FLOATING_PADDING, FLOATING_WIDTH, labelAnatomy, warnLegacyButtonProps, resolveButtonIcons, buttonVariants, INERT_CLASSES, DISABLED_LOOK_CLASSES, inertHandlers, INERT_ATTRIBUTES, linkButtonAnatomy, useControllableState, controlChrome, mergeRefs, numberInputAnatomy, EN_MESSAGES, phoneFieldAnatomy, Input, useFieldsetContext, useFormReset2, radioGroupAnatomy, microInteractions, CONTROL_LABEL_TEXT, searchInputAnatomy, IconButton, Tooltip, TooltipTrigger, TooltipContent, codeAnatomy, textAnatomy, Slot, stackAnatomy, inlineAnatomy, statusBadgeAnatomy, useFieldsetState, FieldsetContext, fieldsetAnatomy, useFieldsetLegend, shellAnatomy, Avatar, useId as useId$1, partId, statStripAnatomy, Pressable, Spinner, DropdownMenuItem, filterChipsAnatomy, listPageAnatomy, dataTableAnatomy, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, errorOnce, isLabelable, Select, Checkbox, FIELD_PARTS, SelectRoot, SelectTrigger, SelectValue, SelectContent, SelectItem, OverlayHeader, OverlayFooter, commandAnatomy, menuShortcutClasses, useFormReset, sideDrawerAnatomy, Portal, toastAnatomy, useExitPresence, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, TooltipProvider, TOOLTIP_DEFAULT_DELAY_MS, DesignSystemContext, PortalContainerContext, ModalRoot, ModalOverlay, ModalContent, ModalTitle, ModalDescription } from './chunk-HV24JSRN.js';
|
|
7
|
+
export { Avatar, Button, Checkbox, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileChip, FileUpload, IconButton, Input, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, Pressable, SPINNER_TONE_TO_INTENT, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Spinner, Textarea, ThemeScope, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, buttonVariants, iconButtonVariants, inputVariants, resolveButtonStyle, spinnerVariants, textareaVariants, useDsMessages, useFieldControl } from './chunk-HV24JSRN.js';
|
|
8
|
+
import { cn, ChevronDownIcon, EyeIcon, DownloadIcon, ChevronRightIcon, CheckIcon, CircleIcon, CopyIcon, CalendarIcon, XIcon, AlertTriangleIcon, ArrowRightIcon, ArrowLeftIcon, FileTextIcon, ZoomOutIcon, ZoomInIcon, lucideIcon, SquareExclamationPointIcon, TrendingUpIcon, TrendingDownIcon, SearchIcon, TableIcon, StarIcon, RowsIcon, Rows4Icon, ListChecksIcon, CheckCircleSolidIcon, HelpCircleIcon, UserIcon, SendIcon, SettingsIcon, ChevronUpIcon, XCircleIcon, CheckCircle2Icon, InfoIcon, ChevronLeftIcon, FolderOpenIcon, FolderClosedIcon, MinusIcon, Icon, ChartNoAxesColumnIncreasingIcon, MoreHorizontalIcon, AlertCircleIcon, PlusIcon, CircleDashedIcon, LoaderIcon, InfoCircleSolidIcon, AlertTriangleSolidIcon, XCircleSolidIcon, RotateCcwIcon, CommandIcon, GripVerticalIcon, LockIcon, ArrowUpIcon, ArrowDownIcon } from './chunk-ARCWF2S3.js';
|
|
9
9
|
export { AlertCircleIcon, AlertTriangleIcon, AlertTriangleSolidIcon, AlignCenterIcon, AlignLeftIcon, AlignRightIcon, AppWindowIcon, ArchiveIcon, ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowRightSmallIcon, ArrowUpIcon, ArrowUpRightIcon, AtSignIcon, BanIcon, BarChartIcon, BellIcon, BellRingIcon, BoldIcon, BookTextIcon, BrainIcon, BriefcaseIcon, Building2Icon, BuildingIcon, CalculatorIcon, CalendarIcon, CameraIcon, ChartNoAxesColumnIncreasingIcon, ChatBubbleIcon, CheckCheckIcon, CheckCircle2Icon, CheckCircleSolidIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsDownUpIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpDownIcon, CircleDashedIcon, CircleDotIcon, CircleIcon, ClipboardCheckIcon, ClockAlertIcon, ClockIcon, CloseIcon, CommandIcon, CopyIcon, CornerDownLeftIcon, CreditCardIcon, DecimalsArrowLeftIcon, DecimalsArrowRightIcon, DocumentIcon, DollarSignIcon, DownloadIcon, ExternalLinkIcon, ExtractIcon, EyeIcon, EyeOffIcon, FileChartColumnIcon, FileIcon, FilePlusIcon, FileReturnIcon, FileTextIcon, FilterIcon, FlagIcon, FolderClosedIcon, FolderDownIcon, FolderOpenIcon, FolderPlusIcon, FolderUpIcon, GlobeIcon, GoogleBrandIcon, GraduationCapIcon, Grid2x2Icon, GripHorizontalIcon, GripVerticalIcon, HelpCircleIcon, HighlighterIcon, HistoryIcon, HomeIcon, InboxIcon, InfoCircleSolidIcon, InfoIcon, ItalicIcon, KanbanIcon, KeyIcon, LandmarkIcon, LayersIcon, LayoutDashboardIcon, LayoutGridIcon, LayoutListIcon, LightningIcon, Link2Icon, LinkIcon, ListChecksIcon, ListIcon, ListOrderedIcon, LoaderIcon, LockIcon, LockKeyholeIcon, LockOpenIcon, LogOutIcon, MailIcon, MapPinIcon, MaximizeIcon, MenuIcon, MessageCircleIcon, MessageCircleMoreIcon, MessageCircleWarningIcon, MicIcon, MicrosoftBrandIcon, MinimizeIcon, MinusIcon, MonitorIcon, MoonIcon, MoreHorizontalIcon, MoreVerticalIcon, MousePointer2Icon, MoveIcon, PaletteIcon, PanelLeftCloseIcon, PanelLeftIcon, PanelRightCloseIcon, PanelRightIcon, PaperclipIcon, PauseIcon, PenSignIcon, PenToolIcon, PencilIcon, PercentIcon, PhoneIcon, PinIcon, PinOffIcon, PlayIcon, PlusIcon, ReceiptIcon, RefreshCwIcon, RepeatIcon, ReplyIcon, RotateCcwIcon, Rows4Icon, RowsIcon, SaveIcon, SearchCheckIcon, SearchIcon, SendIcon, SettingsIcon, ShieldIcon, SigmaIcon, SlashIcon, SmartphoneIcon, SparkleIcon, SparklesIcon, SquareExclamationPointIcon, SquareFunctionIcon, SquareIcon, SquarePlayIcon, SquareSquareIcon, StampIcon, StarIcon, StopIcon, StrikethroughIcon, StripeBrandIcon, SunIcon, TableIcon, TagIcon, TeamIcon, ThumbsDownIcon, ThumbsUpIcon, TimerIcon, Trash2Icon, TrashIcon, TrashSolidIcon, TrendingDownIcon, TrendingUpIcon, TypeIcon, UnderlineIcon, Undo2Icon, UploadIcon, UserCircleIcon, UserIcon, UsersIcon, VideoIcon, Volume2Icon, VolumeXIcon, WorkflowIcon, XCircleIcon, XCircleSolidIcon, XIcon, ZoomInIcon, ZoomOutIcon, cn, createIcon, iconCursor, iconToSvg } from './chunk-ARCWF2S3.js';
|
|
10
10
|
export { systemTokens } from './chunk-CPOGSNXS.js';
|
|
11
11
|
import './chunk-EUHGZA6Q.js';
|
|
12
12
|
export { colors, radii, reference, shadows, spacing, surfaces, typography } from './chunk-YRHRVOLV.js';
|
|
13
13
|
import * as React30 from 'react';
|
|
14
|
-
import { forwardRef, useId, useRef, useState, useLayoutEffect, createContext, useEffect, useCallback, useMemo, useImperativeHandle, Children, isValidElement, cloneElement, useSyncExternalStore, useContext
|
|
14
|
+
import { forwardRef, useId, useRef, useState, useLayoutEffect, createContext, useEffect, useCallback, useMemo, useImperativeHandle, Children, isValidElement, cloneElement, createElement, useSyncExternalStore, useContext } from 'react';
|
|
15
15
|
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
16
16
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
17
17
|
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
18
18
|
import { cva } from 'class-variance-authority';
|
|
19
19
|
import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
|
|
20
20
|
import { DayPicker } from 'react-day-picker';
|
|
21
|
-
import { format, parse, isValid, startOfDay, startOfMonth, startOfYear, subYears, endOfMonth, endOfYear, addYears } from 'date-fns';
|
|
21
|
+
import { format, parse, isValid, startOfDay, startOfMonth, startOfYear, subYears, endOfMonth, endOfYear, addYears, subQuarters, endOfQuarter, startOfQuarter, subMonths, addDays, parseISO } from 'date-fns';
|
|
22
22
|
import { Command } from 'cmdk';
|
|
23
23
|
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
|
|
24
24
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
@@ -31,7 +31,6 @@ import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
|
31
31
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
32
32
|
import { useFormStatus } from 'react-dom';
|
|
33
33
|
import { Branch } from '@radix-ui/react-dismissable-layer';
|
|
34
|
-
import * as VisuallyHiddenPrimitive from '@radix-ui/react-visually-hidden';
|
|
35
34
|
|
|
36
35
|
var Accordion = React30.forwardRef(function Accordion2({ className, ...props }, ref) {
|
|
37
36
|
return /* @__PURE__ */ jsx(
|
|
@@ -416,9 +415,9 @@ function fileTypeFromName(fileName) {
|
|
|
416
415
|
const ext = dot >= 0 && dot < fileName.length - 1 ? fileName.slice(dot + 1) : "";
|
|
417
416
|
return normalizeFileType(ext);
|
|
418
417
|
}
|
|
419
|
-
var FileTypeBadge = forwardRef(function FileTypeBadge2({ format:
|
|
418
|
+
var FileTypeBadge = forwardRef(function FileTypeBadge2({ format: format3, type, fileName, tone = "auto", size, className, "aria-label": ariaLabel, ...props }, ref) {
|
|
420
419
|
const messages = useDsMessages("fileTypeBadge");
|
|
421
|
-
const raw =
|
|
420
|
+
const raw = format3 ?? type ?? (fileName != null ? fileTypeFromName(fileName) : void 0) ?? "FILE";
|
|
422
421
|
const code = normalizeFileType(raw);
|
|
423
422
|
const resolvedTone = tone !== "auto" ? tone : TYPE_TO_TONE[code] ?? "neutral";
|
|
424
423
|
return /* @__PURE__ */ jsx(
|
|
@@ -1059,7 +1058,7 @@ function Calendar({
|
|
|
1059
1058
|
}) {
|
|
1060
1059
|
const isRange = mode === "range";
|
|
1061
1060
|
const single = !isRange ? selected : void 0;
|
|
1062
|
-
const
|
|
1061
|
+
const range2 = isRange ? selected : void 0;
|
|
1063
1062
|
const locale = useLocale(typeof localeProp === "string" ? localeProp : void 0);
|
|
1064
1063
|
const localeObject = typeof localeProp === "object" ? localeProp : void 0;
|
|
1065
1064
|
const localeProps = React30.useMemo(
|
|
@@ -1091,8 +1090,8 @@ function Calendar({
|
|
|
1091
1090
|
if (minDate) return { before: minDate };
|
|
1092
1091
|
return { after: maxDate };
|
|
1093
1092
|
}, [minDate, maxDate]);
|
|
1094
|
-
const rangeFrom =
|
|
1095
|
-
const rangeTo =
|
|
1093
|
+
const rangeFrom = range2?.from;
|
|
1094
|
+
const rangeTo = range2?.to;
|
|
1096
1095
|
const navRange = React30.useMemo(
|
|
1097
1096
|
() => captionLayout === "label" ? void 0 : resolveCalendarNavRange({
|
|
1098
1097
|
minDate,
|
|
@@ -2700,8 +2699,8 @@ var DateRangePicker = forwardRef(
|
|
|
2700
2699
|
[onChange]
|
|
2701
2700
|
);
|
|
2702
2701
|
const handleCalendarSelect = useCallback(
|
|
2703
|
-
(
|
|
2704
|
-
if (!
|
|
2702
|
+
(range2) => {
|
|
2703
|
+
if (!range2 && draftRange?.from && draftRange.to && isSameDate(draftRange.from, draftRange.to)) {
|
|
2705
2704
|
const day = dateToIso(draftRange.from);
|
|
2706
2705
|
const next = { from: day, to: day };
|
|
2707
2706
|
if (!isControlled) setInternalValue(next);
|
|
@@ -2710,9 +2709,9 @@ var DateRangePicker = forwardRef(
|
|
|
2710
2709
|
setOpen(false);
|
|
2711
2710
|
return;
|
|
2712
2711
|
}
|
|
2713
|
-
setDraftRange(
|
|
2714
|
-
const fromIso =
|
|
2715
|
-
const toIso =
|
|
2712
|
+
setDraftRange(range2);
|
|
2713
|
+
const fromIso = range2?.from ? dateToIso(range2.from) : "";
|
|
2714
|
+
const toIso = range2?.to ? dateToIso(range2.to) : "";
|
|
2716
2715
|
if (fromIso && toIso && fromIso !== toIso) {
|
|
2717
2716
|
const next = { from: fromIso, to: toIso };
|
|
2718
2717
|
if (!isControlled) setInternalValue(next);
|
|
@@ -4402,7 +4401,7 @@ var NumberInput = forwardRef(function NumberInput2({
|
|
|
4402
4401
|
"aria-labelledby": ariaLabelledBy,
|
|
4403
4402
|
"aria-describedby": ariaDescribedBy
|
|
4404
4403
|
});
|
|
4405
|
-
const
|
|
4404
|
+
const format3 = useCallback(
|
|
4406
4405
|
(next) => formatNumber(next, locale, formatOptions),
|
|
4407
4406
|
[locale, formatOptions]
|
|
4408
4407
|
);
|
|
@@ -4410,12 +4409,12 @@ var NumberInput = forwardRef(function NumberInput2({
|
|
|
4410
4409
|
(text2) => parseNumber(text2, locale, formatOptions),
|
|
4411
4410
|
[locale, formatOptions]
|
|
4412
4411
|
);
|
|
4413
|
-
const [text, setText] = useState(() =>
|
|
4412
|
+
const [text, setText] = useState(() => format3(value));
|
|
4414
4413
|
useEffect(() => {
|
|
4415
4414
|
const typed = parse2(text);
|
|
4416
4415
|
const typedValue = typed == null || Number.isNaN(typed) ? null : typed;
|
|
4417
|
-
if (typedValue !== value) setText(
|
|
4418
|
-
}, [value,
|
|
4416
|
+
if (typedValue !== value) setText(format3(value));
|
|
4417
|
+
}, [value, format3, parse2]);
|
|
4419
4418
|
const commit = useCallback(
|
|
4420
4419
|
(next) => {
|
|
4421
4420
|
if (next == null || Number.isNaN(next)) {
|
|
@@ -4425,9 +4424,9 @@ var NumberInput = forwardRef(function NumberInput2({
|
|
|
4425
4424
|
}
|
|
4426
4425
|
const canonical = roundToFormat(clampNumber(next, min, max), locale, formatOptions);
|
|
4427
4426
|
setValue(canonical);
|
|
4428
|
-
setText(
|
|
4427
|
+
setText(format3(canonical));
|
|
4429
4428
|
},
|
|
4430
|
-
[min, max, locale, formatOptions,
|
|
4429
|
+
[min, max, locale, formatOptions, format3, setValue]
|
|
4431
4430
|
);
|
|
4432
4431
|
const stepBy = (direction, steps) => {
|
|
4433
4432
|
if (wiring.disabled || wiring.readOnly) return;
|
|
@@ -4535,7 +4534,7 @@ var NumberInput = forwardRef(function NumberInput2({
|
|
|
4535
4534
|
disabled: wiring.disabled,
|
|
4536
4535
|
onReset: () => {
|
|
4537
4536
|
setValue(defaultValue);
|
|
4538
|
-
setText(
|
|
4537
|
+
setText(format3(defaultValue));
|
|
4539
4538
|
}
|
|
4540
4539
|
}
|
|
4541
4540
|
)
|
|
@@ -7935,12 +7934,6 @@ var Code = forwardRef(function Code2({ variant = "inline", className, children,
|
|
|
7935
7934
|
);
|
|
7936
7935
|
});
|
|
7937
7936
|
Code.displayName = "Code";
|
|
7938
|
-
var VisuallyHidden = forwardRef(
|
|
7939
|
-
function VisuallyHidden2({ children, ...props }, ref) {
|
|
7940
|
-
return /* @__PURE__ */ jsx(VisuallyHiddenPrimitive.Root, { ref, ...props, children });
|
|
7941
|
-
}
|
|
7942
|
-
);
|
|
7943
|
-
VisuallyHidden.displayName = "VisuallyHidden";
|
|
7944
7937
|
var TextOverflowTooltip = forwardRef(
|
|
7945
7938
|
function TextOverflowTooltip2({ className, children, onPointerEnter, onFocus, ...props }, ref) {
|
|
7946
7939
|
const overflow = useOverflowTooltip();
|
|
@@ -8279,9 +8272,28 @@ function MultiSelect(props) {
|
|
|
8279
8272
|
return /* @__PURE__ */ jsx(Combobox, { ...props, multiple: true });
|
|
8280
8273
|
}
|
|
8281
8274
|
MultiSelect.displayName = "MultiSelect";
|
|
8275
|
+
var canMatchMedia = () => typeof window !== "undefined" && typeof window.matchMedia === "function";
|
|
8276
|
+
function useMediaQuery(query, { serverValue = false } = {}) {
|
|
8277
|
+
const subscribe3 = useCallback(
|
|
8278
|
+
(onStoreChange) => {
|
|
8279
|
+
if (!canMatchMedia()) return () => {
|
|
8280
|
+
};
|
|
8281
|
+
const list = window.matchMedia(query);
|
|
8282
|
+
list.addEventListener("change", onStoreChange);
|
|
8283
|
+
return () => list.removeEventListener("change", onStoreChange);
|
|
8284
|
+
},
|
|
8285
|
+
[query]
|
|
8286
|
+
);
|
|
8287
|
+
const getSnapshot = () => canMatchMedia() ? window.matchMedia(query).matches : serverValue;
|
|
8288
|
+
const getServerSnapshot2 = () => serverValue;
|
|
8289
|
+
return useSyncExternalStore(subscribe3, getSnapshot, getServerSnapshot2);
|
|
8290
|
+
}
|
|
8282
8291
|
|
|
8283
8292
|
// src/foundation/use-reduced-motion.ts
|
|
8284
8293
|
var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
8294
|
+
function useReducedMotion(options) {
|
|
8295
|
+
return useMediaQuery(REDUCED_MOTION_QUERY, options);
|
|
8296
|
+
}
|
|
8285
8297
|
var statusLabel = {
|
|
8286
8298
|
"not-started": "Not started",
|
|
8287
8299
|
"in-progress": "In progress",
|
|
@@ -8904,6 +8916,7 @@ function AppSidebarRow({
|
|
|
8904
8916
|
),
|
|
8905
8917
|
href: item.href,
|
|
8906
8918
|
active,
|
|
8919
|
+
activeDescendant: hasActiveDescendant(item, activeId),
|
|
8907
8920
|
defaultOpen: active || hasActiveDescendant(item, activeId),
|
|
8908
8921
|
children: item.children.map((child) => /* @__PURE__ */ jsx(AppSidebarRow, { item: child, activeId, showTitle, RouterLink }, child.id))
|
|
8909
8922
|
}
|
|
@@ -9231,10 +9244,10 @@ function Sparkline({ data, className }) {
|
|
|
9231
9244
|
const h = 28;
|
|
9232
9245
|
const min = Math.min(...data);
|
|
9233
9246
|
const max = Math.max(...data);
|
|
9234
|
-
const
|
|
9247
|
+
const range2 = max - min || 1;
|
|
9235
9248
|
const coords = data.map((d, i) => {
|
|
9236
9249
|
const x = i / (data.length - 1) * w;
|
|
9237
|
-
const y = h - (d - min) /
|
|
9250
|
+
const y = h - (d - min) / range2 * (h - 2) - 1;
|
|
9238
9251
|
return [x, y];
|
|
9239
9252
|
});
|
|
9240
9253
|
const line = coords.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
|
|
@@ -10176,13 +10189,484 @@ var FilterChip = forwardRef(function FilterChip2({ active = false, size, count,
|
|
|
10176
10189
|
);
|
|
10177
10190
|
});
|
|
10178
10191
|
FilterChip.displayName = "FilterChip";
|
|
10179
|
-
var
|
|
10192
|
+
var StatStripContext = React30.createContext({
|
|
10193
|
+
loading: false,
|
|
10194
|
+
countUp: false,
|
|
10195
|
+
highlightChanges: false
|
|
10196
|
+
});
|
|
10197
|
+
var storedFlags = /* @__PURE__ */ new Map();
|
|
10198
|
+
var storageListeners = /* @__PURE__ */ new Set();
|
|
10199
|
+
function readStoredFlag(key) {
|
|
10200
|
+
if (!storedFlags.has(key)) {
|
|
10201
|
+
let value = null;
|
|
10202
|
+
try {
|
|
10203
|
+
const raw = window.localStorage.getItem(key);
|
|
10204
|
+
value = raw === "1" ? true : raw === "0" ? false : null;
|
|
10205
|
+
} catch {
|
|
10206
|
+
}
|
|
10207
|
+
storedFlags.set(key, value);
|
|
10208
|
+
}
|
|
10209
|
+
return storedFlags.get(key) ?? null;
|
|
10210
|
+
}
|
|
10211
|
+
function writeStoredFlag(key, value) {
|
|
10212
|
+
storedFlags.set(key, value);
|
|
10213
|
+
try {
|
|
10214
|
+
window.localStorage.setItem(key, value ? "1" : "0");
|
|
10215
|
+
} catch {
|
|
10216
|
+
}
|
|
10217
|
+
for (const listener of storageListeners) listener();
|
|
10218
|
+
}
|
|
10219
|
+
function subscribeStoredFlags(listener) {
|
|
10220
|
+
storageListeners.add(listener);
|
|
10221
|
+
const onStorage = (event) => {
|
|
10222
|
+
if (event.key === null) storedFlags.clear();
|
|
10223
|
+
else storedFlags.delete(event.key);
|
|
10224
|
+
listener();
|
|
10225
|
+
};
|
|
10226
|
+
window.addEventListener("storage", onStorage);
|
|
10227
|
+
return () => {
|
|
10228
|
+
storageListeners.delete(listener);
|
|
10229
|
+
window.removeEventListener("storage", onStorage);
|
|
10230
|
+
};
|
|
10231
|
+
}
|
|
10232
|
+
var serverFlag = () => null;
|
|
10233
|
+
function useStoredFlag(key) {
|
|
10234
|
+
const getSnapshot = React30.useCallback(() => key ? readStoredFlag(key) : null, [key]);
|
|
10235
|
+
return React30.useSyncExternalStore(subscribeStoredFlags, getSnapshot, serverFlag);
|
|
10236
|
+
}
|
|
10237
|
+
function readDuration(element, property, fallback) {
|
|
10238
|
+
const raw = getComputedStyle(element).getPropertyValue(property).trim();
|
|
10239
|
+
if (raw.endsWith("ms")) return Number.parseFloat(raw) || fallback;
|
|
10240
|
+
if (raw.endsWith("s")) return (Number.parseFloat(raw) || fallback / 1e3) * 1e3;
|
|
10241
|
+
return fallback;
|
|
10242
|
+
}
|
|
10243
|
+
function useCountUp(target, enabled) {
|
|
10244
|
+
const reduced = useReducedMotion();
|
|
10245
|
+
const [shown, setShown] = React30.useState(target);
|
|
10246
|
+
const shownRef = React30.useRef(target);
|
|
10247
|
+
React30.useEffect(() => {
|
|
10248
|
+
if (!enabled || reduced || !Number.isFinite(target)) {
|
|
10249
|
+
shownRef.current = target;
|
|
10250
|
+
setShown(target);
|
|
10251
|
+
return;
|
|
10252
|
+
}
|
|
10253
|
+
const from = shownRef.current;
|
|
10254
|
+
if (from === target) return;
|
|
10255
|
+
const duration = readDuration(document.documentElement, "--motion-duration-deliberate", 400);
|
|
10256
|
+
const start = performance.now();
|
|
10257
|
+
let frame = 0;
|
|
10258
|
+
const tick = (now) => {
|
|
10259
|
+
const t = Math.min(1, (now - start) / duration);
|
|
10260
|
+
const eased = 1 - Math.pow(1 - t, 4);
|
|
10261
|
+
const next = from + (target - from) * eased;
|
|
10262
|
+
shownRef.current = next;
|
|
10263
|
+
setShown(next);
|
|
10264
|
+
if (t < 1) frame = requestAnimationFrame(tick);
|
|
10265
|
+
};
|
|
10266
|
+
frame = requestAnimationFrame(tick);
|
|
10267
|
+
return () => cancelAnimationFrame(frame);
|
|
10268
|
+
}, [target, enabled, reduced]);
|
|
10269
|
+
return enabled ? shown : target;
|
|
10270
|
+
}
|
|
10271
|
+
var GLOW_MS = 1200;
|
|
10272
|
+
function useChangeGlow(value, enabled) {
|
|
10273
|
+
const previous = React30.useRef(value);
|
|
10274
|
+
const [glowing, setGlowing] = React30.useState(false);
|
|
10275
|
+
React30.useEffect(() => {
|
|
10276
|
+
const changed = !Object.is(previous.current, value);
|
|
10277
|
+
previous.current = value;
|
|
10278
|
+
if (!enabled || !changed) {
|
|
10279
|
+
setGlowing(false);
|
|
10280
|
+
return;
|
|
10281
|
+
}
|
|
10282
|
+
setGlowing(true);
|
|
10283
|
+
const timer = setTimeout(() => setGlowing(false), GLOW_MS);
|
|
10284
|
+
return () => clearTimeout(timer);
|
|
10285
|
+
}, [value, enabled]);
|
|
10286
|
+
return enabled && glowing;
|
|
10287
|
+
}
|
|
10288
|
+
var WIDE_COLUMNS_VAR = "--ds-stat-strip-columns";
|
|
10289
|
+
var StatStrip = React30.forwardRef(function StatStrip2({
|
|
10290
|
+
children,
|
|
10291
|
+
label,
|
|
10292
|
+
columns,
|
|
10293
|
+
collapsible = false,
|
|
10294
|
+
collapsed: collapsedProp,
|
|
10295
|
+
defaultCollapsed = false,
|
|
10296
|
+
onCollapsedChange,
|
|
10297
|
+
storageKey,
|
|
10298
|
+
loading = false,
|
|
10299
|
+
countUp = false,
|
|
10300
|
+
highlightChanges = false,
|
|
10301
|
+
className,
|
|
10302
|
+
style,
|
|
10303
|
+
id: idProp,
|
|
10304
|
+
...props
|
|
10305
|
+
}, forwardedRef) {
|
|
10306
|
+
const messages = useDsMessages("statStrip");
|
|
10307
|
+
const id = useId$1(idProp, "stat-strip");
|
|
10308
|
+
const contentId = partId(id, "content");
|
|
10309
|
+
const stored = useStoredFlag(storageKey);
|
|
10310
|
+
const [uncontrolled, setUncontrolled] = React30.useState(defaultCollapsed);
|
|
10311
|
+
const collapsed = collapsible ? collapsedProp ?? stored ?? uncontrolled : false;
|
|
10312
|
+
const rootRef = React30.useRef(null);
|
|
10313
|
+
const fromHeight = React30.useRef(null);
|
|
10314
|
+
React30.useLayoutEffect(() => {
|
|
10315
|
+
const element = rootRef.current;
|
|
10316
|
+
const from = fromHeight.current;
|
|
10317
|
+
fromHeight.current = null;
|
|
10318
|
+
if (!element || from === null || typeof element.animate !== "function") return;
|
|
10319
|
+
if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return;
|
|
10320
|
+
const to = element.getBoundingClientRect().height;
|
|
10321
|
+
if (Math.abs(to - from) < 1) return;
|
|
10322
|
+
const style2 = getComputedStyle(element);
|
|
10323
|
+
element.animate([{ height: `${from}px` }, { height: `${to}px` }], {
|
|
10324
|
+
duration: readDuration(element, "--motion-duration-spatial", 250),
|
|
10325
|
+
easing: style2.getPropertyValue("--motion-ease-move").trim() || "cubic-bezier(0.4, 0, 0.2, 1)"
|
|
10326
|
+
});
|
|
10327
|
+
}, [collapsed]);
|
|
10328
|
+
const toggle = () => {
|
|
10329
|
+
const next = !collapsed;
|
|
10330
|
+
fromHeight.current = rootRef.current?.getBoundingClientRect().height ?? null;
|
|
10331
|
+
setUncontrolled(next);
|
|
10332
|
+
if (storageKey) writeStoredFlag(storageKey, next);
|
|
10333
|
+
onCollapsedChange?.(next);
|
|
10334
|
+
};
|
|
10335
|
+
const setRefs = React30.useCallback(
|
|
10336
|
+
(node) => {
|
|
10337
|
+
rootRef.current = node;
|
|
10338
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
10339
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
10340
|
+
},
|
|
10341
|
+
[forwardedRef]
|
|
10342
|
+
);
|
|
10343
|
+
const context = React30.useMemo(
|
|
10344
|
+
() => ({ loading, countUp, highlightChanges }),
|
|
10345
|
+
[loading, countUp, highlightChanges]
|
|
10346
|
+
);
|
|
10347
|
+
const toggleLabel = collapsed ? messages.expand : messages.collapse;
|
|
10348
|
+
const [content, setContent] = React30.useState(null);
|
|
10349
|
+
const [scrollable, setScrollable] = React30.useState(false);
|
|
10350
|
+
React30.useEffect(() => {
|
|
10351
|
+
if (!content || !collapsed) {
|
|
10352
|
+
setScrollable(false);
|
|
10353
|
+
return;
|
|
10354
|
+
}
|
|
10355
|
+
const measure = () => setScrollable(
|
|
10356
|
+
content.scrollWidth > content.clientWidth + 1 && !content.querySelector("button:not([disabled])")
|
|
10357
|
+
);
|
|
10358
|
+
measure();
|
|
10359
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
10360
|
+
const observer = new ResizeObserver(measure);
|
|
10361
|
+
observer.observe(content);
|
|
10362
|
+
return () => observer.disconnect();
|
|
10363
|
+
}, [content, collapsed]);
|
|
10364
|
+
return /* @__PURE__ */ jsx(StatStripContext, { value: context, children: /* @__PURE__ */ jsxs(
|
|
10365
|
+
"div",
|
|
10366
|
+
{
|
|
10367
|
+
ref: setRefs,
|
|
10368
|
+
id,
|
|
10369
|
+
role: "group",
|
|
10370
|
+
"aria-label": label ?? messages.region,
|
|
10371
|
+
"aria-busy": loading || void 0,
|
|
10372
|
+
...slot(statStripAnatomy, "root"),
|
|
10373
|
+
...stateAttributes({ state: collapsed ? "collapsed" : "expanded", loading }),
|
|
10374
|
+
"data-collapsible": collapsible ? "" : void 0,
|
|
10375
|
+
className: cn(
|
|
10376
|
+
"ds:group/stat-strip ds:@container/stat-strip ds:relative ds:overflow-hidden",
|
|
10377
|
+
"ds:rounded-card ds:border-rule ds:bg-surface ds:shadow-quiet ds:border",
|
|
10378
|
+
className
|
|
10379
|
+
),
|
|
10380
|
+
style: columns === void 0 ? style : { [WIDE_COLUMNS_VAR]: Math.max(1, Math.round(columns)), ...style },
|
|
10381
|
+
...props,
|
|
10382
|
+
children: [
|
|
10383
|
+
/* @__PURE__ */ createElement(
|
|
10384
|
+
"div",
|
|
10385
|
+
{
|
|
10386
|
+
ref: setContent,
|
|
10387
|
+
id: contentId,
|
|
10388
|
+
...slot(statStripAnatomy, "content"),
|
|
10389
|
+
...scrollable ? { tabIndex: 0, role: "region", "aria-label": label ?? messages.region } : {},
|
|
10390
|
+
className: cn(
|
|
10391
|
+
// Expanded: a grid whose hairlines are each cell's inset right and
|
|
10392
|
+
// bottom edge. The grid overhangs the card by 1px on both axes, so
|
|
10393
|
+
// the last column's and last row's edges fall under the root's
|
|
10394
|
+
// `overflow-hidden` instead of doubling the border. Unlike
|
|
10395
|
+
// `gap-px` over a rule-coloured fill, a short last row leaves
|
|
10396
|
+
// surface — not a grey block — in the empty cells.
|
|
10397
|
+
"ds:-me-px ds:-mb-px ds:grid ds:grid-cols-2 ds:@lg/stat-strip:grid-cols-3",
|
|
10398
|
+
columns === void 0 ? "ds:@4xl/stat-strip:auto-cols-fr ds:@4xl/stat-strip:grid-flow-col ds:@4xl/stat-strip:grid-cols-none" : "ds:@4xl/stat-strip:grid-cols-[repeat(var(--ds-stat-strip-columns),minmax(0,1fr))]",
|
|
10399
|
+
"ds:motion-safe:animate-in ds:motion-safe:fade-in-0 ds:duration-[var(--motion-duration-overlay)] ds:ease-[var(--motion-ease-enter)]",
|
|
10400
|
+
// Collapsed: one line of inline metrics that scrolls sideways,
|
|
10401
|
+
// leaving room on the right for the chevron.
|
|
10402
|
+
"ds:group-data-[state=collapsed]/stat-strip:flex ds:group-data-[state=collapsed]/stat-strip:items-center",
|
|
10403
|
+
"ds:group-data-[state=collapsed]/stat-strip:overflow-x-auto ds:group-data-[state=collapsed]/stat-strip:py-1",
|
|
10404
|
+
"ds:group-data-[state=collapsed]/stat-strip:m-0 ds:group-data-[state=collapsed]/stat-strip:ps-2 ds:group-data-[state=collapsed]/stat-strip:[scrollbar-width:none]",
|
|
10405
|
+
collapsible && "ds:group-data-[state=collapsed]/stat-strip:pe-10",
|
|
10406
|
+
"ds:focus-visible:outline-none ds:focus-visible:[box-shadow:inset_0_0_0_2px_var(--color-brand-ring)]"
|
|
10407
|
+
),
|
|
10408
|
+
key: collapsed ? "collapsed" : "expanded"
|
|
10409
|
+
},
|
|
10410
|
+
children
|
|
10411
|
+
),
|
|
10412
|
+
collapsible && /* @__PURE__ */ jsx(
|
|
10413
|
+
"div",
|
|
10414
|
+
{
|
|
10415
|
+
...slot(statStripAnatomy, "toggle"),
|
|
10416
|
+
className: cn(
|
|
10417
|
+
"ds:absolute ds:end-1.5 ds:top-1.5",
|
|
10418
|
+
// Collapsed: a full-height surface pad with a short fade on its
|
|
10419
|
+
// leading edge, so metrics scrolling under it dissolve instead
|
|
10420
|
+
// of colliding with the chevron.
|
|
10421
|
+
"ds:group-data-[state=collapsed]/stat-strip:inset-y-0 ds:group-data-[state=collapsed]/stat-strip:end-0",
|
|
10422
|
+
"ds:group-data-[state=collapsed]/stat-strip:flex ds:group-data-[state=collapsed]/stat-strip:items-center",
|
|
10423
|
+
"ds:group-data-[state=collapsed]/stat-strip:bg-surface ds:group-data-[state=collapsed]/stat-strip:pe-1.5",
|
|
10424
|
+
"ds:group-data-[state=collapsed]/stat-strip:before:absolute ds:group-data-[state=collapsed]/stat-strip:before:inset-y-0",
|
|
10425
|
+
"ds:group-data-[state=collapsed]/stat-strip:before:end-full ds:group-data-[state=collapsed]/stat-strip:before:w-6",
|
|
10426
|
+
"ds:group-data-[state=collapsed]/stat-strip:before:bg-linear-to-l ds:group-data-[state=collapsed]/stat-strip:before:from-surface ds:group-data-[state=collapsed]/stat-strip:before:to-transparent"
|
|
10427
|
+
),
|
|
10428
|
+
children: /* @__PURE__ */ jsx(
|
|
10429
|
+
IconButton,
|
|
10430
|
+
{
|
|
10431
|
+
variant: "ghost",
|
|
10432
|
+
size: "xs",
|
|
10433
|
+
label: toggleLabel,
|
|
10434
|
+
"aria-expanded": !collapsed,
|
|
10435
|
+
"aria-controls": contentId,
|
|
10436
|
+
onClick: toggle,
|
|
10437
|
+
icon: collapsed ? /* @__PURE__ */ jsx(ChevronDownIcon, {}) : /* @__PURE__ */ jsx(ChevronUpIcon, {})
|
|
10438
|
+
}
|
|
10439
|
+
)
|
|
10440
|
+
}
|
|
10441
|
+
)
|
|
10442
|
+
]
|
|
10443
|
+
}
|
|
10444
|
+
) });
|
|
10445
|
+
});
|
|
10446
|
+
StatStrip.displayName = "StatStrip";
|
|
10447
|
+
var SELECTED_FILL = {
|
|
10448
|
+
neutral: "ds:data-[pressed]:bg-bg-2",
|
|
10449
|
+
brand: "ds:data-[pressed]:bg-brand-bg",
|
|
10450
|
+
info: "ds:data-[pressed]:bg-info/10",
|
|
10451
|
+
success: "ds:data-[pressed]:bg-success-bg",
|
|
10452
|
+
warning: "ds:data-[pressed]:bg-warning-bg",
|
|
10453
|
+
danger: "ds:data-[pressed]:bg-danger-bg"
|
|
10454
|
+
};
|
|
10455
|
+
var SELECTED_RULE = {
|
|
10456
|
+
neutral: "ds:bg-fg-3",
|
|
10457
|
+
brand: "ds:bg-brand",
|
|
10458
|
+
info: "ds:bg-info",
|
|
10459
|
+
success: "ds:bg-success-fg",
|
|
10460
|
+
warning: "ds:bg-warning-fg",
|
|
10461
|
+
danger: "ds:bg-danger-fg"
|
|
10462
|
+
};
|
|
10463
|
+
var CAPTION_INK = {
|
|
10464
|
+
neutral: "ds:text-fg-3",
|
|
10465
|
+
brand: "ds:text-brand",
|
|
10466
|
+
info: "ds:text-info",
|
|
10467
|
+
success: "ds:text-success-fg",
|
|
10468
|
+
warning: "ds:text-warning-fg",
|
|
10469
|
+
danger: "ds:text-danger-fg"
|
|
10470
|
+
};
|
|
10471
|
+
var defaultFormat3 = (value) => Math.round(value).toLocaleString();
|
|
10472
|
+
var CELL_CLASSES = cn(
|
|
10473
|
+
"ds:relative ds:flex ds:min-w-0 ds:flex-col ds:justify-start ds:px-5 ds:py-3 ds:text-start",
|
|
10474
|
+
"ds:bg-surface ds:transition-colors ds:duration-[var(--motion-duration-deliberate)] ds:ease-[var(--motion-ease-standard)] ds:motion-reduce:transition-none",
|
|
10475
|
+
// The hairlines: the inset right and bottom edge of every cell (inset, so a
|
|
10476
|
+
// neighbour's background cannot paint over them; see the content's
|
|
10477
|
+
// overhang for the card edge).
|
|
10478
|
+
"ds:[box-shadow:inset_-1px_0_0_var(--color-rule),inset_0_-1px_0_var(--color-rule)]",
|
|
10479
|
+
// Collapsed: an inline `label value` pair with a short divider before it.
|
|
10480
|
+
"ds:group-data-[state=collapsed]/stat-strip:shrink-0 ds:group-data-[state=collapsed]/stat-strip:flex-row",
|
|
10481
|
+
"ds:group-data-[state=collapsed]/stat-strip:items-baseline ds:group-data-[state=collapsed]/stat-strip:gap-1.5",
|
|
10482
|
+
"ds:group-data-[state=collapsed]/stat-strip:rounded-btn ds:group-data-[state=collapsed]/stat-strip:px-2.5 ds:group-data-[state=collapsed]/stat-strip:py-1",
|
|
10483
|
+
"ds:group-data-[state=collapsed]/stat-strip:shadow-none",
|
|
10484
|
+
"ds:group-data-[state=collapsed]/stat-strip:not-first:before:absolute ds:group-data-[state=collapsed]/stat-strip:not-first:before:start-0",
|
|
10485
|
+
"ds:group-data-[state=collapsed]/stat-strip:not-first:before:top-1/2 ds:group-data-[state=collapsed]/stat-strip:not-first:before:h-4",
|
|
10486
|
+
"ds:group-data-[state=collapsed]/stat-strip:not-first:before:w-px ds:group-data-[state=collapsed]/stat-strip:not-first:before:-translate-y-1/2",
|
|
10487
|
+
"ds:group-data-[state=collapsed]/stat-strip:not-first:before:bg-rule"
|
|
10488
|
+
);
|
|
10489
|
+
var PRESSABLE_CELL_CLASSES = cn(
|
|
10490
|
+
"ds:cursor-pointer ds:hover:bg-surface-hover",
|
|
10491
|
+
// An inset ring: a cell on the card edge would have an outer ring clipped
|
|
10492
|
+
// by the root's overflow.
|
|
10493
|
+
"ds:focus-visible:[box-shadow:inset_0_0_0_2px_var(--color-brand-ring)]",
|
|
10494
|
+
"ds:data-[disabled]:opacity-45"
|
|
10495
|
+
);
|
|
10496
|
+
var StatStripItem = React30.forwardRef(
|
|
10497
|
+
function StatStripItem2({
|
|
10498
|
+
label,
|
|
10499
|
+
value,
|
|
10500
|
+
format: format3 = defaultFormat3,
|
|
10501
|
+
caption,
|
|
10502
|
+
progress,
|
|
10503
|
+
progressLabel,
|
|
10504
|
+
intent,
|
|
10505
|
+
tintCaption = false,
|
|
10506
|
+
pressed,
|
|
10507
|
+
onPressedChange,
|
|
10508
|
+
disabled,
|
|
10509
|
+
loading: loadingProp,
|
|
10510
|
+
countUp: countUpProp,
|
|
10511
|
+
highlightChanges: highlightProp,
|
|
10512
|
+
className,
|
|
10513
|
+
onClick,
|
|
10514
|
+
...props
|
|
10515
|
+
}, ref) {
|
|
10516
|
+
const strip = React30.use(StatStripContext);
|
|
10517
|
+
const loading = loadingProp ?? strip.loading;
|
|
10518
|
+
const numeric = typeof value === "number";
|
|
10519
|
+
const animate = numeric && (countUpProp ?? strip.countUp);
|
|
10520
|
+
const shown = useCountUp(numeric ? value : 0, animate);
|
|
10521
|
+
const glowing = useChangeGlow(value, highlightProp ?? strip.highlightChanges);
|
|
10522
|
+
const toggles = pressed !== void 0 || onPressedChange !== void 0;
|
|
10523
|
+
const resolvedIntent = intent ?? "neutral";
|
|
10524
|
+
const finalText = numeric ? format3(value) : null;
|
|
10525
|
+
const valueNode = numeric ? animate ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10526
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: format3(shown) }),
|
|
10527
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { children: finalText })
|
|
10528
|
+
] }) : finalText : value;
|
|
10529
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10530
|
+
toggles && /* @__PURE__ */ jsx(
|
|
10531
|
+
"span",
|
|
10532
|
+
{
|
|
10533
|
+
"aria-hidden": "true",
|
|
10534
|
+
className: cn(
|
|
10535
|
+
// Inside the cell rather than on its border, so the grid's
|
|
10536
|
+
// hairlines stay unbroken while the filter is on.
|
|
10537
|
+
"ds:absolute ds:inset-x-0 ds:top-0 ds:h-0.5 ds:opacity-0",
|
|
10538
|
+
"ds:transition-opacity ds:duration-[var(--motion-duration-overlay)] ds:motion-reduce:transition-none",
|
|
10539
|
+
"ds:group-data-[pressed]/stat-strip-item:opacity-100",
|
|
10540
|
+
"ds:group-data-[state=collapsed]/stat-strip:hidden",
|
|
10541
|
+
SELECTED_RULE[resolvedIntent]
|
|
10542
|
+
)
|
|
10543
|
+
}
|
|
10544
|
+
),
|
|
10545
|
+
/* @__PURE__ */ jsx(
|
|
10546
|
+
"span",
|
|
10547
|
+
{
|
|
10548
|
+
...slot(statStripAnatomy, "label"),
|
|
10549
|
+
className: "ds:text-helper ds:text-fg-3 ds:truncate ds:font-medium ds:group-data-[state=collapsed]/stat-strip:font-normal",
|
|
10550
|
+
children: label
|
|
10551
|
+
}
|
|
10552
|
+
),
|
|
10553
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { children: ": " }),
|
|
10554
|
+
/* @__PURE__ */ jsxs("span", { className: "ds:mt-1.5 ds:flex ds:min-w-0 ds:items-center ds:gap-3 ds:group-data-[state=collapsed]/stat-strip:mt-0", children: [
|
|
10555
|
+
loading ? /* @__PURE__ */ jsx(Skeleton, { className: "ds:h-7 ds:w-16 ds:group-data-[state=collapsed]/stat-strip:h-4 ds:group-data-[state=collapsed]/stat-strip:w-8" }) : /* @__PURE__ */ jsx(
|
|
10556
|
+
"span",
|
|
10557
|
+
{
|
|
10558
|
+
...slot(statStripAnatomy, "value"),
|
|
10559
|
+
className: cn(
|
|
10560
|
+
"ds:text-title-page ds:text-fg ds:shrink-0 ds:truncate ds:leading-none ds:font-semibold ds:tabular-nums",
|
|
10561
|
+
"ds:group-data-[state=collapsed]/stat-strip:text-body ds:group-data-[state=collapsed]/stat-strip:leading-normal"
|
|
10562
|
+
),
|
|
10563
|
+
children: valueNode
|
|
10564
|
+
}
|
|
10565
|
+
),
|
|
10566
|
+
progress !== void 0 && !loading && /* @__PURE__ */ jsx(
|
|
10567
|
+
ProgressBar,
|
|
10568
|
+
{
|
|
10569
|
+
value: Math.max(0, Math.min(100, progress)),
|
|
10570
|
+
max: 100,
|
|
10571
|
+
size: "xs",
|
|
10572
|
+
intent: intent ?? "brand",
|
|
10573
|
+
"aria-label": progressLabel ?? (typeof label === "string" ? label : void 0),
|
|
10574
|
+
className: "ds:min-w-0 ds:flex-1 ds:group-data-[state=collapsed]/stat-strip:hidden"
|
|
10575
|
+
}
|
|
10576
|
+
)
|
|
10577
|
+
] }),
|
|
10578
|
+
caption !== void 0 && caption !== null && /* @__PURE__ */ jsx(
|
|
10579
|
+
"span",
|
|
10580
|
+
{
|
|
10581
|
+
...slot(statStripAnatomy, "caption"),
|
|
10582
|
+
className: cn(
|
|
10583
|
+
"ds:text-helper ds:mt-2 ds:block ds:truncate ds:group-data-[state=collapsed]/stat-strip:hidden",
|
|
10584
|
+
tintCaption ? CAPTION_INK[resolvedIntent] : "ds:text-fg-3"
|
|
10585
|
+
),
|
|
10586
|
+
children: loading ? /* @__PURE__ */ jsx(Skeleton, { className: "ds:h-3 ds:w-24" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10587
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { children: ", " }),
|
|
10588
|
+
caption
|
|
10589
|
+
] })
|
|
10590
|
+
}
|
|
10591
|
+
)
|
|
10592
|
+
] });
|
|
10593
|
+
const shared = {
|
|
10594
|
+
...slot(statStripAnatomy, "item"),
|
|
10595
|
+
"data-glow": glowing ? "" : void 0,
|
|
10596
|
+
"data-intent": intent
|
|
10597
|
+
};
|
|
10598
|
+
const glowClass = "ds:data-[glow]:bg-brand-bg";
|
|
10599
|
+
if (toggles) {
|
|
10600
|
+
return /* @__PURE__ */ jsx(
|
|
10601
|
+
Pressable,
|
|
10602
|
+
{
|
|
10603
|
+
ref,
|
|
10604
|
+
pressed: pressed ?? false,
|
|
10605
|
+
disabled,
|
|
10606
|
+
onClick: (event) => {
|
|
10607
|
+
onClick?.(event);
|
|
10608
|
+
if (!event.defaultPrevented) onPressedChange?.(!(pressed ?? false));
|
|
10609
|
+
},
|
|
10610
|
+
className: cn(
|
|
10611
|
+
"ds:group/stat-strip-item",
|
|
10612
|
+
CELL_CLASSES,
|
|
10613
|
+
PRESSABLE_CELL_CLASSES,
|
|
10614
|
+
glowClass,
|
|
10615
|
+
SELECTED_FILL[resolvedIntent],
|
|
10616
|
+
className
|
|
10617
|
+
),
|
|
10618
|
+
...props,
|
|
10619
|
+
...shared,
|
|
10620
|
+
children: body
|
|
10621
|
+
}
|
|
10622
|
+
);
|
|
10623
|
+
}
|
|
10624
|
+
return /* @__PURE__ */ jsx(
|
|
10625
|
+
"div",
|
|
10626
|
+
{
|
|
10627
|
+
ref,
|
|
10628
|
+
className: cn(CELL_CLASSES, glowClass, className),
|
|
10629
|
+
...onClick ? { onClick } : {},
|
|
10630
|
+
...props,
|
|
10631
|
+
...shared,
|
|
10632
|
+
children: body
|
|
10633
|
+
}
|
|
10634
|
+
);
|
|
10635
|
+
}
|
|
10636
|
+
);
|
|
10637
|
+
StatStripItem.displayName = "StatStripItem";
|
|
10638
|
+
var BulkActionBarContext = React30.createContext({
|
|
10639
|
+
tone: "surface",
|
|
10640
|
+
unavailable: false
|
|
10641
|
+
});
|
|
10642
|
+
function useBulkLayer(openProp, defaultOpen, onOpenChange, disabled) {
|
|
10643
|
+
const { unavailable } = React30.use(BulkActionBarContext);
|
|
10644
|
+
const blocked = unavailable || disabled;
|
|
10645
|
+
const [uncontrolled, setUncontrolled] = React30.useState(defaultOpen);
|
|
10646
|
+
const open = openProp ?? uncontrolled;
|
|
10647
|
+
const setOpen = React30.useCallback(
|
|
10648
|
+
(next) => {
|
|
10649
|
+
if (next && blocked) return;
|
|
10650
|
+
setUncontrolled(next);
|
|
10651
|
+
onOpenChange?.(next);
|
|
10652
|
+
},
|
|
10653
|
+
[blocked, onOpenChange]
|
|
10654
|
+
);
|
|
10655
|
+
React30.useEffect(() => {
|
|
10656
|
+
if (blocked && open) setOpen(false);
|
|
10657
|
+
}, [blocked, open, setOpen]);
|
|
10658
|
+
return { open: open && !blocked, setOpen };
|
|
10659
|
+
}
|
|
10180
10660
|
function actionClasses(tone, destructive) {
|
|
10181
10661
|
const base = cn(
|
|
10182
|
-
"ds:inline-flex ds:h-8 ds:items-center ds:gap-1.5 ds:rounded-btn ds:px-3 ds:text-[13px] ds:font-medium",
|
|
10662
|
+
"ds:inline-flex ds:h-8 ds:shrink-0 ds:items-center ds:gap-1.5 ds:rounded-btn ds:px-3 ds:text-[13px] ds:font-medium ds:whitespace-nowrap",
|
|
10183
10663
|
"ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)]",
|
|
10184
10664
|
"ds:focus-visible:outline-none ds:focus-visible:[box-shadow:var(--shadow-focus-ring)]",
|
|
10185
|
-
"ds:disabled:pointer-events-none ds:disabled:opacity-45",
|
|
10665
|
+
"ds:disabled:pointer-events-none ds:disabled:opacity-45 ds:data-[loading]:opacity-100",
|
|
10666
|
+
// While loading, the spinner takes the leading icon's place so the row
|
|
10667
|
+
// does not shift.
|
|
10668
|
+
"ds:data-[loading]:[&>svg:first-of-type]:hidden",
|
|
10669
|
+
"ds:aria-disabled:opacity-45",
|
|
10186
10670
|
"ds:motion-reduce:transition-none",
|
|
10187
10671
|
"ds:[&_svg]:size-4 ds:[&_svg]:shrink-0"
|
|
10188
10672
|
);
|
|
@@ -10199,7 +10683,7 @@ function actionClasses(tone, destructive) {
|
|
|
10199
10683
|
destructive ? "ds:text-control-destructive-fg ds:hover:bg-control-destructive-hover-bg" : "ds:text-control-fg ds:hover:bg-control-hover-bg ds:hover:text-control-hover-fg"
|
|
10200
10684
|
);
|
|
10201
10685
|
}
|
|
10202
|
-
var BulkActionBarAction = React30.forwardRef(function BulkActionBarAction2({ asChild = false, destructive, className, type, ...props }, ref) {
|
|
10686
|
+
var BulkActionBarAction = React30.forwardRef(function BulkActionBarAction2({ asChild = false, destructive, loading, className, type, children, ...props }, ref) {
|
|
10203
10687
|
const { tone } = React30.use(BulkActionBarContext);
|
|
10204
10688
|
const Comp = asChild ? Slot : "button";
|
|
10205
10689
|
return /* @__PURE__ */ jsx(
|
|
@@ -10207,8 +10691,14 @@ var BulkActionBarAction = React30.forwardRef(function BulkActionBarAction2({ asC
|
|
|
10207
10691
|
{
|
|
10208
10692
|
ref,
|
|
10209
10693
|
type: asChild ? void 0 : type ?? "button",
|
|
10694
|
+
"aria-busy": loading || void 0,
|
|
10695
|
+
"data-loading": loading ? "" : void 0,
|
|
10210
10696
|
className: cn(actionClasses(tone, destructive), className),
|
|
10211
|
-
...props
|
|
10697
|
+
...props,
|
|
10698
|
+
children: loading && !asChild ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10699
|
+
/* @__PURE__ */ jsx(Spinner, { size: "xs", "aria-hidden": "true" }),
|
|
10700
|
+
children
|
|
10701
|
+
] }) : children
|
|
10212
10702
|
}
|
|
10213
10703
|
);
|
|
10214
10704
|
});
|
|
@@ -10228,13 +10718,116 @@ function BulkActionBarSeparator({ className }) {
|
|
|
10228
10718
|
);
|
|
10229
10719
|
}
|
|
10230
10720
|
var BAR_ENTER = "ds:motion-safe:animate-in ds:motion-safe:fade-in-0 ds:motion-safe:slide-in-from-bottom-2 ds:duration-[var(--motion-duration-overlay)] ds:ease-[var(--motion-ease-enter)]";
|
|
10721
|
+
var PRESENCE_BASE = "ds:transition-[opacity,translate] ds:motion-reduce:transition-none";
|
|
10722
|
+
var PRESENCE_SHOWN = "ds:translate-y-0 ds:opacity-100 ds:duration-[var(--motion-duration-overlay)] ds:ease-[var(--motion-ease-enter)]";
|
|
10723
|
+
var PRESENCE_HIDDEN = "ds:pointer-events-none ds:translate-y-2 ds:opacity-0 ds:duration-[var(--motion-duration-overlay-exit)] ds:ease-[var(--motion-ease-exit)]";
|
|
10724
|
+
var SURFACE_CHROME = "ds:border-rule ds:bg-surface ds:text-fg ds:border";
|
|
10725
|
+
var FLOATING_SURFACE_CHROME = "ds:border-rule ds:bg-surface-floating ds:text-fg ds:border ds:shadow-pop";
|
|
10726
|
+
var INVERSE_CHROME = "ds:bg-selection-floating-bg ds:text-selection-floating-fg ds:shadow-pop";
|
|
10727
|
+
var ESCAPE_OWNERS = "[role='dialog'],[role='alertdialog'],[role='menu'],[role='listbox'],[data-radix-popper-content-wrapper]";
|
|
10728
|
+
function useEscapeToClear(active, clear) {
|
|
10729
|
+
const latest = React30.useRef(clear);
|
|
10730
|
+
React30.useEffect(() => {
|
|
10731
|
+
latest.current = clear;
|
|
10732
|
+
});
|
|
10733
|
+
React30.useEffect(() => {
|
|
10734
|
+
if (!active) return;
|
|
10735
|
+
const onKeyDown = (event) => {
|
|
10736
|
+
if (event.key !== "Escape" || event.defaultPrevented || event.isComposing) return;
|
|
10737
|
+
if (document.querySelector(ESCAPE_OWNERS)) return;
|
|
10738
|
+
latest.current();
|
|
10739
|
+
};
|
|
10740
|
+
document.addEventListener("keydown", onKeyDown);
|
|
10741
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
10742
|
+
}, [active]);
|
|
10743
|
+
}
|
|
10744
|
+
var ITEM_SELECTOR = "button, a[href], input, select, textarea, [role='button'], [role='link']";
|
|
10745
|
+
function toolbarItems(toolbar) {
|
|
10746
|
+
return Array.from(toolbar.querySelectorAll(ITEM_SELECTOR)).filter(
|
|
10747
|
+
(element) => element.closest("[role='toolbar']") === toolbar && !element.parentElement?.closest(ITEM_SELECTOR)
|
|
10748
|
+
);
|
|
10749
|
+
}
|
|
10750
|
+
var isFocusable = (element) => !element.disabled && !element.closest("fieldset:disabled");
|
|
10751
|
+
function useRovingToolbar(toolbar) {
|
|
10752
|
+
const active = React30.useRef(null);
|
|
10753
|
+
React30.useEffect(() => {
|
|
10754
|
+
if (!toolbar) return;
|
|
10755
|
+
const sync = () => {
|
|
10756
|
+
const items = toolbarItems(toolbar);
|
|
10757
|
+
const focusable = items.filter(isFocusable);
|
|
10758
|
+
if (!active.current || !focusable.includes(active.current)) active.current = focusable[0] ?? null;
|
|
10759
|
+
for (const item of items) {
|
|
10760
|
+
const next = item === active.current ? "0" : "-1";
|
|
10761
|
+
if (item.getAttribute("tabindex") !== next) item.setAttribute("tabindex", next);
|
|
10762
|
+
}
|
|
10763
|
+
};
|
|
10764
|
+
const onFocusIn = (event) => {
|
|
10765
|
+
const item = toolbarItems(toolbar).find((candidate) => candidate.contains(event.target));
|
|
10766
|
+
if (item && item !== active.current) {
|
|
10767
|
+
active.current = item;
|
|
10768
|
+
sync();
|
|
10769
|
+
}
|
|
10770
|
+
};
|
|
10771
|
+
const onKeyDown = (event) => {
|
|
10772
|
+
if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) return;
|
|
10773
|
+
const target = event.target;
|
|
10774
|
+
if (target.matches("input, textarea, select, [contenteditable='true']")) return;
|
|
10775
|
+
const items = toolbarItems(toolbar).filter(isFocusable);
|
|
10776
|
+
const index = items.findIndex((item2) => item2.contains(target));
|
|
10777
|
+
if (index === -1) return;
|
|
10778
|
+
const rtl = getComputedStyle(toolbar).direction === "rtl";
|
|
10779
|
+
let next;
|
|
10780
|
+
switch (event.key) {
|
|
10781
|
+
case "ArrowRight":
|
|
10782
|
+
next = rtl ? index - 1 : index + 1;
|
|
10783
|
+
break;
|
|
10784
|
+
case "ArrowLeft":
|
|
10785
|
+
next = rtl ? index + 1 : index - 1;
|
|
10786
|
+
break;
|
|
10787
|
+
case "Home":
|
|
10788
|
+
next = 0;
|
|
10789
|
+
break;
|
|
10790
|
+
case "End":
|
|
10791
|
+
next = items.length - 1;
|
|
10792
|
+
break;
|
|
10793
|
+
default:
|
|
10794
|
+
return;
|
|
10795
|
+
}
|
|
10796
|
+
event.preventDefault();
|
|
10797
|
+
const item = items[(next + items.length) % items.length];
|
|
10798
|
+
if (!item) return;
|
|
10799
|
+
active.current = item;
|
|
10800
|
+
sync();
|
|
10801
|
+
item.focus();
|
|
10802
|
+
item.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
10803
|
+
};
|
|
10804
|
+
sync();
|
|
10805
|
+
const observer = new MutationObserver(sync);
|
|
10806
|
+
observer.observe(toolbar, {
|
|
10807
|
+
subtree: true,
|
|
10808
|
+
childList: true,
|
|
10809
|
+
attributes: true,
|
|
10810
|
+
attributeFilter: ["disabled"]
|
|
10811
|
+
});
|
|
10812
|
+
toolbar.addEventListener("focusin", onFocusIn);
|
|
10813
|
+
toolbar.addEventListener("keydown", onKeyDown);
|
|
10814
|
+
return () => {
|
|
10815
|
+
observer.disconnect();
|
|
10816
|
+
toolbar.removeEventListener("focusin", onFocusIn);
|
|
10817
|
+
toolbar.removeEventListener("keydown", onKeyDown);
|
|
10818
|
+
};
|
|
10819
|
+
}, [toolbar]);
|
|
10820
|
+
}
|
|
10231
10821
|
function BulkActionBarClear({
|
|
10232
|
-
|
|
10822
|
+
clearStyle,
|
|
10823
|
+
tone,
|
|
10233
10824
|
clearLabel,
|
|
10234
10825
|
clearDisabled,
|
|
10826
|
+
escapeHint,
|
|
10827
|
+
escapeKey,
|
|
10235
10828
|
onClear
|
|
10236
10829
|
}) {
|
|
10237
|
-
if (
|
|
10830
|
+
if (clearStyle === "icon") {
|
|
10238
10831
|
return /* @__PURE__ */ jsx(
|
|
10239
10832
|
"button",
|
|
10240
10833
|
{
|
|
@@ -10242,9 +10835,9 @@ function BulkActionBarClear({
|
|
|
10242
10835
|
onClick: onClear,
|
|
10243
10836
|
disabled: clearDisabled,
|
|
10244
10837
|
className: cn(
|
|
10245
|
-
"ds:
|
|
10838
|
+
"ds:ml-1 ds:inline-flex ds:size-7 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-icon",
|
|
10246
10839
|
"ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)]",
|
|
10247
|
-
"ds:hover:bg-selection-floating-hover-bg ds:hover:text-selection-floating-fg",
|
|
10840
|
+
tone === "inverse" ? "ds:text-selection-floating-muted-fg ds:hover:bg-selection-floating-hover-bg ds:hover:text-selection-floating-fg" : "ds:text-control-muted-fg ds:hover:bg-control-hover-bg ds:hover:text-control-hover-fg",
|
|
10248
10841
|
"ds:focus-visible:outline-none ds:focus-visible:[box-shadow:var(--shadow-focus-ring)]",
|
|
10249
10842
|
"ds:disabled:pointer-events-none ds:disabled:opacity-45 ds:motion-reduce:transition-none"
|
|
10250
10843
|
),
|
|
@@ -10253,68 +10846,304 @@ function BulkActionBarClear({
|
|
|
10253
10846
|
}
|
|
10254
10847
|
);
|
|
10255
10848
|
}
|
|
10256
|
-
|
|
10849
|
+
if (clearStyle === "labelled") {
|
|
10850
|
+
return /* @__PURE__ */ jsxs(
|
|
10851
|
+
BulkActionBarAction,
|
|
10852
|
+
{
|
|
10853
|
+
onClick: onClear,
|
|
10854
|
+
disabled: clearDisabled,
|
|
10855
|
+
"aria-keyshortcuts": escapeHint ? "Escape" : void 0,
|
|
10856
|
+
className: tone === "inverse" ? void 0 : "ds:text-control-muted-fg",
|
|
10857
|
+
children: [
|
|
10858
|
+
/* @__PURE__ */ jsx(XIcon, { "aria-hidden": "true" }),
|
|
10859
|
+
clearLabel,
|
|
10860
|
+
escapeHint && /* @__PURE__ */ jsx(
|
|
10861
|
+
Kbd,
|
|
10862
|
+
{
|
|
10863
|
+
variant: "flat",
|
|
10864
|
+
"aria-hidden": "true",
|
|
10865
|
+
className: tone === "inverse" ? "ds:border-selection-floating-rule ds:text-selection-floating-muted-fg ds:bg-transparent" : void 0,
|
|
10866
|
+
children: escapeKey
|
|
10867
|
+
}
|
|
10868
|
+
)
|
|
10869
|
+
]
|
|
10870
|
+
}
|
|
10871
|
+
);
|
|
10872
|
+
}
|
|
10873
|
+
return /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: onClear, disabled: clearDisabled, className: "ds:shrink-0", children: clearLabel });
|
|
10257
10874
|
}
|
|
10258
10875
|
function BulkActionBar({
|
|
10259
10876
|
variant = "table-inline",
|
|
10260
10877
|
selectedCount,
|
|
10261
10878
|
label,
|
|
10262
10879
|
children,
|
|
10880
|
+
secondaryActions,
|
|
10263
10881
|
onClear,
|
|
10264
10882
|
clearLabel: clearLabelProp,
|
|
10265
10883
|
clearDisabled,
|
|
10266
10884
|
footer,
|
|
10885
|
+
scope,
|
|
10886
|
+
toolbarLabel,
|
|
10887
|
+
escapeToClear = true,
|
|
10888
|
+
keepMounted: keepMountedProp,
|
|
10889
|
+
tone: toneProp,
|
|
10890
|
+
overflow: overflowProp,
|
|
10891
|
+
clearStyle: clearStyleProp,
|
|
10892
|
+
busy = false,
|
|
10893
|
+
returnFocusRef,
|
|
10267
10894
|
className,
|
|
10268
10895
|
...props
|
|
10269
10896
|
}) {
|
|
10270
10897
|
const messages = useDsMessages("bulkActionBar");
|
|
10271
|
-
|
|
10272
|
-
const
|
|
10273
|
-
const
|
|
10274
|
-
const tone = variant === "page-floating" ? "inverse" : "surface";
|
|
10275
|
-
const
|
|
10276
|
-
|
|
10898
|
+
const floating = variant === "floating";
|
|
10899
|
+
const responsive = Boolean(secondaryActions?.length);
|
|
10900
|
+
const keepMounted = keepMountedProp ?? floating;
|
|
10901
|
+
const tone = toneProp ?? (variant === "page-floating" ? "inverse" : "surface");
|
|
10902
|
+
const overflow = overflowProp ?? (floating || responsive ? "scroll" : "wrap");
|
|
10903
|
+
const clearStyle = clearStyleProp ?? (floating ? "labelled" : variant === "page-floating" ? "icon" : "text");
|
|
10904
|
+
const shown = selectedCount > 0;
|
|
10905
|
+
const [lastCount, setLastCount] = React30.useState(selectedCount);
|
|
10906
|
+
if (shown && selectedCount !== lastCount) setLastCount(selectedCount);
|
|
10907
|
+
const count = shown ? selectedCount : lastCount;
|
|
10908
|
+
const [toolbar, setToolbar] = React30.useState(null);
|
|
10909
|
+
useRovingToolbar(toolbar);
|
|
10910
|
+
const secondaryRef = React30.useRef(null);
|
|
10911
|
+
const measurementRef = React30.useRef(null);
|
|
10912
|
+
const [secondaryCollapsed, setSecondaryCollapsed] = React30.useState(false);
|
|
10913
|
+
const [secondaryMenuOpen, setSecondaryMenuOpen] = React30.useState(false);
|
|
10914
|
+
const transferSecondaryFocus = React30.useRef(false);
|
|
10915
|
+
React30.useLayoutEffect(() => {
|
|
10916
|
+
if (!toolbar || !responsive) return;
|
|
10917
|
+
const container = toolbar.parentElement;
|
|
10918
|
+
const measure = () => {
|
|
10919
|
+
const group = secondaryRef.current;
|
|
10920
|
+
const measurement2 = measurementRef.current;
|
|
10921
|
+
if (!container || !group || !measurement2) return;
|
|
10922
|
+
const style = getComputedStyle(toolbar);
|
|
10923
|
+
const border = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
|
|
10924
|
+
const spacer = toolbar.querySelector("[data-bulk-spacer]");
|
|
10925
|
+
const spare = spacer ? Math.max(0, spacer.getBoundingClientRect().width - parseFloat(getComputedStyle(spacer).minWidth)) : 0;
|
|
10926
|
+
const inlineWidth = toolbar.scrollWidth + border - spare - group.getBoundingClientRect().width + measurement2.getBoundingClientRect().width;
|
|
10927
|
+
const collapse = inlineWidth > container.clientWidth + 1;
|
|
10928
|
+
if (!collapse && secondaryMenuOpen) return;
|
|
10929
|
+
if (collapse !== secondaryCollapsed) {
|
|
10930
|
+
transferSecondaryFocus.current = group.contains(document.activeElement);
|
|
10931
|
+
setSecondaryCollapsed(collapse);
|
|
10932
|
+
}
|
|
10933
|
+
};
|
|
10934
|
+
measure();
|
|
10935
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
10936
|
+
const observer = new ResizeObserver(measure);
|
|
10937
|
+
observer.observe(toolbar);
|
|
10938
|
+
if (container) observer.observe(container);
|
|
10939
|
+
if (measurementRef.current) observer.observe(measurementRef.current);
|
|
10940
|
+
return () => observer.disconnect();
|
|
10941
|
+
}, [toolbar, responsive, secondaryActions, secondaryCollapsed, secondaryMenuOpen, tone]);
|
|
10942
|
+
React30.useLayoutEffect(() => {
|
|
10943
|
+
if (transferSecondaryFocus.current) {
|
|
10944
|
+
(secondaryRef.current?.querySelector("button:not(:disabled)") ?? toolbar?.querySelector("button:not(:disabled), a[href]"))?.focus();
|
|
10945
|
+
transferSecondaryFocus.current = false;
|
|
10946
|
+
}
|
|
10947
|
+
}, [secondaryCollapsed, toolbar]);
|
|
10948
|
+
const returnFocus = React30.useCallback(() => {
|
|
10949
|
+
returnFocusRef?.current?.focus();
|
|
10950
|
+
}, [returnFocusRef]);
|
|
10951
|
+
const clear = React30.useCallback(() => {
|
|
10952
|
+
onClear();
|
|
10953
|
+
returnFocus();
|
|
10954
|
+
}, [onClear, returnFocus]);
|
|
10955
|
+
useEscapeToClear(shown && escapeToClear && !clearDisabled && !busy, clear);
|
|
10956
|
+
const wasShown = React30.useRef(shown);
|
|
10957
|
+
const focusInside = React30.useRef(false);
|
|
10958
|
+
React30.useEffect(() => {
|
|
10959
|
+
if (wasShown.current && !shown && (focusInside.current || toolbar?.contains(document.activeElement))) {
|
|
10960
|
+
returnFocus();
|
|
10961
|
+
}
|
|
10962
|
+
wasShown.current = shown;
|
|
10963
|
+
}, [shown, returnFocus, toolbar]);
|
|
10964
|
+
if (!shown && !keepMounted) return null;
|
|
10965
|
+
const clearLabel = clearLabelProp ?? (clearStyle === "labelled" ? messages.clear : messages.clearSelection);
|
|
10966
|
+
const labelText = label ?? messages.selected(count);
|
|
10967
|
+
const announcement = shown ? messages.selected(selectedCount) : lastCount > 0 ? messages.cleared : "";
|
|
10968
|
+
const presence2 = keepMounted ? cn(PRESENCE_BASE, shown ? PRESENCE_SHOWN : PRESENCE_HIDDEN) : void 0;
|
|
10969
|
+
const enter = keepMounted ? void 0 : BAR_ENTER;
|
|
10970
|
+
const hiddenProps = keepMounted && !shown ? { inert: true, "aria-hidden": true } : {};
|
|
10971
|
+
const footerNode = keepMounted && !shown ? null : footer;
|
|
10972
|
+
const content = /* @__PURE__ */ jsxs(BulkActionBarContext, { value: { tone, unavailable: busy || !shown }, children: [
|
|
10973
|
+
/* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:text-sm ds:font-medium ds:tabular-nums ds:whitespace-nowrap", children: labelText }),
|
|
10974
|
+
scope !== void 0 && scope !== null && /* @__PURE__ */ jsx(
|
|
10975
|
+
"fieldset",
|
|
10976
|
+
{
|
|
10977
|
+
disabled: busy || void 0,
|
|
10978
|
+
className: "ds:m-0 ds:flex ds:shrink-0 ds:items-center ds:gap-1 ds:border-0 ds:p-0 ds:text-sm ds:whitespace-nowrap",
|
|
10979
|
+
children: scope
|
|
10980
|
+
}
|
|
10981
|
+
),
|
|
10277
10982
|
/* @__PURE__ */ jsx(BulkActionBarSeparator, {}),
|
|
10278
|
-
/* @__PURE__ */
|
|
10279
|
-
|
|
10983
|
+
/* @__PURE__ */ jsxs(
|
|
10984
|
+
"fieldset",
|
|
10985
|
+
{
|
|
10986
|
+
disabled: busy || void 0,
|
|
10987
|
+
className: cn(
|
|
10988
|
+
"ds:m-0 ds:flex ds:items-center ds:gap-1 ds:border-0 ds:p-0",
|
|
10989
|
+
overflow === "wrap" ? "ds:flex-wrap" : "ds:flex-nowrap"
|
|
10990
|
+
),
|
|
10991
|
+
children: [
|
|
10992
|
+
children,
|
|
10993
|
+
responsive && /* @__PURE__ */ jsx("span", { ref: secondaryRef, className: "ds:inline-flex ds:shrink-0 ds:items-center ds:gap-1", children: secondaryCollapsed ? /* @__PURE__ */ jsx(BulkActionBarMore, { open: secondaryMenuOpen, onOpenChange: setSecondaryMenuOpen, children: secondaryActions?.map((action) => /* @__PURE__ */ jsxs(
|
|
10994
|
+
BulkActionBarMenuItem,
|
|
10995
|
+
{
|
|
10996
|
+
disabled: Boolean(action.disabled),
|
|
10997
|
+
destructive: Boolean(action.destructive),
|
|
10998
|
+
onSelect: action.onSelect,
|
|
10999
|
+
children: [
|
|
11000
|
+
action.icon,
|
|
11001
|
+
action.label
|
|
11002
|
+
]
|
|
11003
|
+
},
|
|
11004
|
+
action.key
|
|
11005
|
+
)) }) : secondaryActions?.map((action) => /* @__PURE__ */ jsxs(
|
|
11006
|
+
BulkActionBarAction,
|
|
11007
|
+
{
|
|
11008
|
+
disabled: action.disabled,
|
|
11009
|
+
destructive: action.destructive,
|
|
11010
|
+
onClick: action.onSelect,
|
|
11011
|
+
children: [
|
|
11012
|
+
action.icon,
|
|
11013
|
+
action.label
|
|
11014
|
+
]
|
|
11015
|
+
},
|
|
11016
|
+
action.key
|
|
11017
|
+
)) })
|
|
11018
|
+
]
|
|
11019
|
+
}
|
|
11020
|
+
),
|
|
11021
|
+
/* @__PURE__ */ jsx("div", { "data-bulk-spacer": "", className: "ds:min-w-2 ds:flex-1" }),
|
|
11022
|
+
clearStyle === "labelled" && /* @__PURE__ */ jsx(BulkActionBarSeparator, {}),
|
|
10280
11023
|
/* @__PURE__ */ jsx(
|
|
10281
11024
|
BulkActionBarClear,
|
|
10282
11025
|
{
|
|
10283
|
-
|
|
11026
|
+
clearStyle,
|
|
11027
|
+
tone,
|
|
10284
11028
|
clearLabel,
|
|
10285
|
-
clearDisabled,
|
|
10286
|
-
|
|
11029
|
+
clearDisabled: clearDisabled || busy,
|
|
11030
|
+
escapeHint: escapeToClear,
|
|
11031
|
+
escapeKey: messages.escapeKey,
|
|
11032
|
+
onClear: clear
|
|
10287
11033
|
}
|
|
10288
11034
|
)
|
|
10289
11035
|
] });
|
|
11036
|
+
const measurement = responsive ? /* @__PURE__ */ jsx(
|
|
11037
|
+
"div",
|
|
11038
|
+
{
|
|
11039
|
+
ref: measurementRef,
|
|
11040
|
+
"aria-hidden": "true",
|
|
11041
|
+
className: "ds:pointer-events-none ds:invisible ds:absolute ds:flex ds:w-max ds:items-center ds:gap-1",
|
|
11042
|
+
children: secondaryActions?.map((action) => /* @__PURE__ */ jsxs("span", { className: actionClasses(tone, action.destructive), children: [
|
|
11043
|
+
action.icon,
|
|
11044
|
+
action.label
|
|
11045
|
+
] }, action.key))
|
|
11046
|
+
}
|
|
11047
|
+
) : null;
|
|
11048
|
+
const live = /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "polite", "aria-atomic": "true", children: announcement });
|
|
11049
|
+
const toolbarProps = {
|
|
11050
|
+
ref: setToolbar,
|
|
11051
|
+
...hiddenProps,
|
|
11052
|
+
role: "toolbar",
|
|
11053
|
+
"aria-label": toolbarLabel ?? messages.toolbar,
|
|
11054
|
+
"aria-orientation": "horizontal",
|
|
11055
|
+
"aria-busy": busy || void 0,
|
|
11056
|
+
"data-tone": tone,
|
|
11057
|
+
"data-overflow": overflow,
|
|
11058
|
+
// Native fieldsets do not disable anchors or custom pressables.
|
|
11059
|
+
onClickCapture: (event) => {
|
|
11060
|
+
if (busy) {
|
|
11061
|
+
event.preventDefault();
|
|
11062
|
+
event.stopPropagation();
|
|
11063
|
+
}
|
|
11064
|
+
},
|
|
11065
|
+
onPointerDownCapture: (event) => {
|
|
11066
|
+
if (busy) {
|
|
11067
|
+
event.preventDefault();
|
|
11068
|
+
event.stopPropagation();
|
|
11069
|
+
}
|
|
11070
|
+
},
|
|
11071
|
+
onKeyDownCapture: (event) => {
|
|
11072
|
+
if (busy && (event.key === "Enter" || event.key === " ")) {
|
|
11073
|
+
event.preventDefault();
|
|
11074
|
+
event.stopPropagation();
|
|
11075
|
+
}
|
|
11076
|
+
},
|
|
11077
|
+
onFocusCapture: () => {
|
|
11078
|
+
focusInside.current = true;
|
|
11079
|
+
},
|
|
11080
|
+
onBlurCapture: (event) => {
|
|
11081
|
+
focusInside.current = event.currentTarget.contains(event.relatedTarget);
|
|
11082
|
+
}
|
|
11083
|
+
};
|
|
11084
|
+
const scrollClasses = overflow === "scroll" ? "ds:flex-nowrap ds:overflow-x-auto ds:whitespace-nowrap ds:[scrollbar-width:thin]" : void 0;
|
|
10290
11085
|
if (variant === "sidebar-anchored") {
|
|
10291
11086
|
return /* @__PURE__ */ jsxs(
|
|
10292
11087
|
"div",
|
|
10293
11088
|
{
|
|
10294
11089
|
className: cn(
|
|
10295
11090
|
"ds:fixed ds:right-6 ds:bottom-6 ds:left-[calc(var(--shell-sidebar-w)+1.5rem)] ds:z-[var(--z-sticky)]",
|
|
11091
|
+
presence2,
|
|
10296
11092
|
className
|
|
10297
11093
|
),
|
|
10298
11094
|
...props,
|
|
10299
11095
|
children: [
|
|
10300
|
-
|
|
10301
|
-
|
|
11096
|
+
live,
|
|
11097
|
+
measurement,
|
|
11098
|
+
/* @__PURE__ */ jsx(
|
|
11099
|
+
"div",
|
|
11100
|
+
{
|
|
11101
|
+
...toolbarProps,
|
|
11102
|
+
className: cn(
|
|
11103
|
+
tone === "inverse" ? INVERSE_CHROME : cn(SURFACE_CHROME, "ds:shadow-card"),
|
|
11104
|
+
"ds:flex ds:items-center ds:gap-3 ds:rounded-card ds:px-6 ds:py-3",
|
|
11105
|
+
scrollClasses,
|
|
11106
|
+
enter
|
|
11107
|
+
),
|
|
11108
|
+
children: content
|
|
11109
|
+
}
|
|
11110
|
+
),
|
|
11111
|
+
footerNode
|
|
10302
11112
|
]
|
|
10303
11113
|
}
|
|
10304
11114
|
);
|
|
10305
11115
|
}
|
|
10306
|
-
if (variant === "page-floating") {
|
|
11116
|
+
if (variant === "page-floating" || floating) {
|
|
10307
11117
|
return /* @__PURE__ */ jsxs(
|
|
10308
11118
|
"div",
|
|
10309
11119
|
{
|
|
10310
11120
|
className: cn(
|
|
10311
11121
|
"ds:fixed ds:bottom-4 ds:left-1/2 ds:z-[var(--z-sticky)] ds:-translate-x-1/2",
|
|
11122
|
+
floating && "ds:max-w-[calc(100vw-2rem)]",
|
|
11123
|
+
responsive && "ds:pointer-events-none ds:flex ds:w-screen ds:max-w-[calc(100vw-2rem)] ds:flex-col ds:items-center",
|
|
11124
|
+
presence2,
|
|
10312
11125
|
className
|
|
10313
11126
|
),
|
|
10314
11127
|
...props,
|
|
10315
11128
|
children: [
|
|
10316
|
-
|
|
10317
|
-
|
|
11129
|
+
live,
|
|
11130
|
+
measurement,
|
|
11131
|
+
/* @__PURE__ */ jsx(
|
|
11132
|
+
"div",
|
|
11133
|
+
{
|
|
11134
|
+
...toolbarProps,
|
|
11135
|
+
className: cn(
|
|
11136
|
+
tone === "inverse" ? INVERSE_CHROME : FLOATING_SURFACE_CHROME,
|
|
11137
|
+
"ds:flex ds:items-center ds:gap-2 ds:rounded-card ds:px-3.5 ds:py-1.5",
|
|
11138
|
+
floating && "ds:max-w-full",
|
|
11139
|
+
responsive && "ds:pointer-events-auto ds:w-max ds:max-w-full",
|
|
11140
|
+
scrollClasses,
|
|
11141
|
+
enter
|
|
11142
|
+
),
|
|
11143
|
+
children: content
|
|
11144
|
+
}
|
|
11145
|
+
),
|
|
11146
|
+
responsive && footerNode ? /* @__PURE__ */ jsx("div", { className: "ds:pointer-events-auto", children: footerNode }) : footerNode
|
|
10318
11147
|
]
|
|
10319
11148
|
}
|
|
10320
11149
|
);
|
|
@@ -10322,92 +11151,1628 @@ function BulkActionBar({
|
|
|
10322
11151
|
return /* @__PURE__ */ jsxs(
|
|
10323
11152
|
"div",
|
|
10324
11153
|
{
|
|
10325
|
-
className: cn("ds:sticky ds:bottom-4 ds:z-[var(--z-sticky)] ds:mt-3 ds:flex ds:justify-center", className),
|
|
11154
|
+
className: cn("ds:sticky ds:bottom-4 ds:z-[var(--z-sticky)] ds:mt-3 ds:flex ds:justify-center", presence2, className),
|
|
10326
11155
|
...props,
|
|
10327
11156
|
children: [
|
|
10328
|
-
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
11157
|
+
live,
|
|
11158
|
+
measurement,
|
|
11159
|
+
/* @__PURE__ */ jsx(
|
|
11160
|
+
"div",
|
|
11161
|
+
{
|
|
11162
|
+
...toolbarProps,
|
|
11163
|
+
className: cn(
|
|
11164
|
+
tone === "inverse" ? INVERSE_CHROME : cn(SURFACE_CHROME, "ds:shadow-card"),
|
|
11165
|
+
"ds:flex ds:w-fit ds:max-w-full ds:items-center ds:gap-x-3 ds:gap-y-1.5 ds:overflow-x-auto ds:rounded-card ds:px-4 ds:py-2",
|
|
11166
|
+
overflow === "wrap" ? "ds:flex-wrap" : scrollClasses,
|
|
11167
|
+
enter
|
|
11168
|
+
),
|
|
11169
|
+
children: content
|
|
11170
|
+
}
|
|
11171
|
+
),
|
|
11172
|
+
footerNode
|
|
11173
|
+
]
|
|
11174
|
+
}
|
|
11175
|
+
);
|
|
11176
|
+
}
|
|
11177
|
+
var SubDepthContext = React30.createContext(0);
|
|
11178
|
+
function BulkActionBarMenu({
|
|
11179
|
+
label,
|
|
11180
|
+
icon,
|
|
11181
|
+
children,
|
|
11182
|
+
chevron = true,
|
|
11183
|
+
destructive,
|
|
11184
|
+
disabled,
|
|
11185
|
+
"aria-label": ariaLabel,
|
|
11186
|
+
open,
|
|
11187
|
+
defaultOpen,
|
|
11188
|
+
onOpenChange,
|
|
11189
|
+
align = "start",
|
|
11190
|
+
className,
|
|
11191
|
+
contentClassName
|
|
11192
|
+
}) {
|
|
11193
|
+
const layer = useBulkLayer(open, defaultOpen ?? false, onOpenChange, disabled);
|
|
11194
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { open: layer.open, onOpenChange: layer.setOpen, children: [
|
|
11195
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(BulkActionBarAction, { destructive, "aria-label": ariaLabel, className, children: [
|
|
11196
|
+
icon,
|
|
11197
|
+
label,
|
|
11198
|
+
chevron && /* @__PURE__ */ jsx(ChevronDownIcon, { "aria-hidden": "true", className: "ds:-me-1 ds:opacity-60" })
|
|
11199
|
+
] }) }),
|
|
11200
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align, side: "top", className: contentClassName, children: /* @__PURE__ */ jsx(SubDepthContext, { value: 0, children }) })
|
|
11201
|
+
] });
|
|
11202
|
+
}
|
|
11203
|
+
function BulkActionBarMore({ label, "aria-label": ariaLabel, ...props }) {
|
|
11204
|
+
const messages = useDsMessages("bulkActionBar");
|
|
11205
|
+
const iconOnly = label === null;
|
|
11206
|
+
return /* @__PURE__ */ jsx(
|
|
11207
|
+
BulkActionBarMenu,
|
|
11208
|
+
{
|
|
11209
|
+
...props,
|
|
11210
|
+
label: iconOnly ? null : label ?? messages.more,
|
|
11211
|
+
"aria-label": ariaLabel ?? (iconOnly ? messages.more : void 0),
|
|
11212
|
+
icon: /* @__PURE__ */ jsx(MoreHorizontalIcon, { "aria-hidden": "true" }),
|
|
11213
|
+
chevron: false,
|
|
11214
|
+
align: props.align ?? "end"
|
|
11215
|
+
}
|
|
11216
|
+
);
|
|
11217
|
+
}
|
|
11218
|
+
function Eligibility({ eligible, total }) {
|
|
11219
|
+
const messages = useDsMessages("bulkActionBar");
|
|
11220
|
+
if (eligible === void 0 || total === void 0 || eligible === total) return null;
|
|
11221
|
+
return /* @__PURE__ */ jsx("span", { className: "ds:text-fg-3 ds:ms-auto ds:ps-4 ds:text-xs ds:tabular-nums", children: messages.eligible(eligible, total) });
|
|
11222
|
+
}
|
|
11223
|
+
function Reason({ children }) {
|
|
11224
|
+
return /* @__PURE__ */ jsx("span", { className: "ds:text-fg-3 ds:block ds:text-xs ds:font-normal", children });
|
|
11225
|
+
}
|
|
11226
|
+
function sharedBulkValue(values) {
|
|
11227
|
+
if (values.length === 0) return void 0;
|
|
11228
|
+
const first = values[0];
|
|
11229
|
+
return values.every((value) => Object.is(value, first)) ? first : void 0;
|
|
11230
|
+
}
|
|
11231
|
+
function BulkActionBarMenuRadioGroup({
|
|
11232
|
+
options,
|
|
11233
|
+
selectedValues,
|
|
11234
|
+
onValueChange,
|
|
11235
|
+
total
|
|
11236
|
+
}) {
|
|
11237
|
+
const shared = sharedBulkValue(selectedValues);
|
|
11238
|
+
const denominator = total ?? selectedValues.length;
|
|
11239
|
+
return /* @__PURE__ */ jsx(DropdownMenuRadioGroup, { value: shared ?? "", onValueChange, children: options.map((option) => {
|
|
11240
|
+
const disabled = option.disabledReason !== void 0 || option.eligible === 0;
|
|
11241
|
+
return /* @__PURE__ */ jsx(DropdownMenuRadioItem, { value: option.value, disabled, className: "ds:items-start", children: /* @__PURE__ */ jsxs("span", { className: "ds:flex ds:min-w-0 ds:flex-1 ds:flex-col", children: [
|
|
11242
|
+
/* @__PURE__ */ jsxs("span", { className: "ds:flex ds:items-center", children: [
|
|
11243
|
+
option.label,
|
|
11244
|
+
/* @__PURE__ */ jsx(Eligibility, { eligible: option.eligible, total: denominator })
|
|
11245
|
+
] }),
|
|
11246
|
+
option.disabledReason !== void 0 && /* @__PURE__ */ jsx(Reason, { children: option.disabledReason })
|
|
11247
|
+
] }) }, option.value);
|
|
11248
|
+
}) });
|
|
11249
|
+
}
|
|
11250
|
+
var BulkActionBarMenuItem = React30.forwardRef(
|
|
11251
|
+
function BulkActionBarMenuItem2({ children, eligible, total, disabledReason, disabled, className, ...props }, ref) {
|
|
11252
|
+
return /* @__PURE__ */ jsx(
|
|
11253
|
+
DropdownMenuItem,
|
|
11254
|
+
{
|
|
11255
|
+
ref,
|
|
11256
|
+
disabled: disabled || disabledReason !== void 0 || eligible === 0,
|
|
11257
|
+
className: cn("ds:items-start", className),
|
|
11258
|
+
...props,
|
|
11259
|
+
children: /* @__PURE__ */ jsxs("span", { className: "ds:flex ds:min-w-0 ds:flex-1 ds:flex-col", children: [
|
|
11260
|
+
/* @__PURE__ */ jsxs("span", { className: "ds:flex ds:items-center ds:gap-2", children: [
|
|
11261
|
+
children,
|
|
11262
|
+
/* @__PURE__ */ jsx(Eligibility, { eligible, total })
|
|
11263
|
+
] }),
|
|
11264
|
+
disabledReason !== void 0 && /* @__PURE__ */ jsx(Reason, { children: disabledReason })
|
|
11265
|
+
] })
|
|
11266
|
+
}
|
|
11267
|
+
);
|
|
11268
|
+
}
|
|
11269
|
+
);
|
|
11270
|
+
BulkActionBarMenuItem.displayName = "BulkActionBarMenuItem";
|
|
11271
|
+
function BulkActionBarMenuSub({ label, children, disabled }) {
|
|
11272
|
+
const depth = React30.use(SubDepthContext);
|
|
11273
|
+
if (depth > 0) {
|
|
11274
|
+
errorOnce(
|
|
11275
|
+
"C-BULK-SUB",
|
|
11276
|
+
"nested",
|
|
11277
|
+
"BulkActionBarMenuSub: a bulk menu has at most one Sub level. Move the deeper choices into a BulkActionBarPicker."
|
|
11278
|
+
);
|
|
11279
|
+
}
|
|
11280
|
+
return /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
|
|
11281
|
+
/* @__PURE__ */ jsx(DropdownMenuSubTrigger, { disabled: disabled ?? false, children: label }),
|
|
11282
|
+
/* @__PURE__ */ jsx(DropdownMenuSubContent, { children: /* @__PURE__ */ jsx(SubDepthContext, { value: depth + 1, children }) })
|
|
11283
|
+
] });
|
|
11284
|
+
}
|
|
11285
|
+
function BulkActionBarPicker({
|
|
11286
|
+
label,
|
|
11287
|
+
icon,
|
|
11288
|
+
children,
|
|
11289
|
+
chevron = true,
|
|
11290
|
+
disabled,
|
|
11291
|
+
"aria-label": ariaLabel,
|
|
11292
|
+
open: openProp,
|
|
11293
|
+
defaultOpen = false,
|
|
11294
|
+
onOpenChange,
|
|
11295
|
+
align = "start",
|
|
11296
|
+
width = "md",
|
|
11297
|
+
padding = "sm",
|
|
11298
|
+
className,
|
|
11299
|
+
contentClassName
|
|
11300
|
+
}) {
|
|
11301
|
+
const { open, setOpen } = useBulkLayer(openProp, defaultOpen, onOpenChange, disabled);
|
|
11302
|
+
const close = React30.useCallback(() => setOpen(false), [setOpen]);
|
|
11303
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
11304
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(BulkActionBarAction, { "aria-label": ariaLabel, className, children: [
|
|
11305
|
+
icon,
|
|
11306
|
+
label,
|
|
11307
|
+
chevron && /* @__PURE__ */ jsx(ChevronDownIcon, { "aria-hidden": "true", className: "ds:-me-1 ds:opacity-60" })
|
|
11308
|
+
] }) }),
|
|
11309
|
+
/* @__PURE__ */ jsx(PopoverContent, { align, side: "top", width, padding, className: contentClassName, children: typeof children === "function" ? children({ close }) : children })
|
|
11310
|
+
] });
|
|
10333
11311
|
}
|
|
10334
11312
|
var PrimaryAction = forwardRef(
|
|
10335
11313
|
function PrimaryAction2({ arrow, iconRight, children, className, ...props }, ref) {
|
|
10336
11314
|
return /* @__PURE__ */ jsx(
|
|
10337
11315
|
Button,
|
|
10338
11316
|
{
|
|
10339
|
-
ref,
|
|
11317
|
+
ref,
|
|
11318
|
+
size: "sm",
|
|
11319
|
+
iconRight: arrow ? /* @__PURE__ */ jsx(ArrowRightIcon, { className: "ds:size-4" }) : iconRight,
|
|
11320
|
+
className: cn(className),
|
|
11321
|
+
...props,
|
|
11322
|
+
children
|
|
11323
|
+
}
|
|
11324
|
+
);
|
|
11325
|
+
}
|
|
11326
|
+
);
|
|
11327
|
+
PrimaryAction.displayName = "PrimaryAction";
|
|
11328
|
+
var SecondaryAction = forwardRef(
|
|
11329
|
+
function SecondaryAction2({ className, children, ...props }, ref) {
|
|
11330
|
+
return /* @__PURE__ */ jsx(Button, { ref, variant: "ghost", size: "sm", className: cn(className), ...props, children });
|
|
11331
|
+
}
|
|
11332
|
+
);
|
|
11333
|
+
SecondaryAction.displayName = "SecondaryAction";
|
|
11334
|
+
var DangerAction = forwardRef(function DangerAction2({ onConfirm, className, children, ...props }, ref) {
|
|
11335
|
+
return /* @__PURE__ */ jsx(
|
|
11336
|
+
Button,
|
|
11337
|
+
{
|
|
11338
|
+
ref,
|
|
11339
|
+
variant: "destructive",
|
|
11340
|
+
size: "sm",
|
|
11341
|
+
onClick: onConfirm,
|
|
11342
|
+
className: cn(className),
|
|
11343
|
+
...props,
|
|
11344
|
+
children
|
|
11345
|
+
}
|
|
11346
|
+
);
|
|
11347
|
+
});
|
|
11348
|
+
DangerAction.displayName = "DangerAction";
|
|
11349
|
+
var IconAction = forwardRef(function IconAction2({ className, children, ...props }, ref) {
|
|
11350
|
+
return /* @__PURE__ */ jsx(Button, { ref, variant: "ghost", size: "icon", className: cn(className), ...props, children });
|
|
11351
|
+
});
|
|
11352
|
+
IconAction.displayName = "IconAction";
|
|
11353
|
+
var Numeric = forwardRef(function Numeric2({ className, children, ...props }, ref) {
|
|
11354
|
+
return /* @__PURE__ */ jsx("span", { ref, className: cn("ds:tabular ds:font-mono", className), ...props, children });
|
|
11355
|
+
});
|
|
11356
|
+
Numeric.displayName = "Numeric";
|
|
11357
|
+
var MutedSpec = forwardRef(function MutedSpec2({ className, children, ...props }, ref) {
|
|
11358
|
+
return /* @__PURE__ */ jsx("span", { ref, className: cn("ds:font-spec ds:text-fg-3", className), ...props, children });
|
|
11359
|
+
});
|
|
11360
|
+
MutedSpec.displayName = "MutedSpec";
|
|
11361
|
+
var Eyebrow = forwardRef(function Eyebrow2({ numeric, className, children, ...props }, ref) {
|
|
11362
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn(numeric ? "ds:eyebrow-num" : "ds:eyebrow", className), ...props, children });
|
|
11363
|
+
});
|
|
11364
|
+
Eyebrow.displayName = "Eyebrow";
|
|
11365
|
+
var KbdHint = forwardRef(function KbdHint2(props, ref) {
|
|
11366
|
+
return /* @__PURE__ */ jsx(Kbd, { ref, variant: "flat", ...props });
|
|
11367
|
+
});
|
|
11368
|
+
KbdHint.displayName = "KbdHint";
|
|
11369
|
+
var DISPLAY_MENU_DUE_PRESETS = [
|
|
11370
|
+
"overdue",
|
|
11371
|
+
"dueToday",
|
|
11372
|
+
"dueNext7",
|
|
11373
|
+
"dueThisMonth",
|
|
11374
|
+
"noDate"
|
|
11375
|
+
];
|
|
11376
|
+
var DISPLAY_MENU_CALENDAR_PRESETS = [
|
|
11377
|
+
"today",
|
|
11378
|
+
"last7",
|
|
11379
|
+
"last30",
|
|
11380
|
+
"thisMonth",
|
|
11381
|
+
"lastMonth",
|
|
11382
|
+
"thisQuarter",
|
|
11383
|
+
"lastQuarter",
|
|
11384
|
+
"ytd"
|
|
11385
|
+
];
|
|
11386
|
+
var DISPLAY_MENU_DATE_PRESETS = [
|
|
11387
|
+
...DISPLAY_MENU_DUE_PRESETS,
|
|
11388
|
+
...DISPLAY_MENU_CALENDAR_PRESETS,
|
|
11389
|
+
"custom"
|
|
11390
|
+
];
|
|
11391
|
+
var DUE_SET = new Set(DISPLAY_MENU_DUE_PRESETS);
|
|
11392
|
+
function isDisplayMenuDuePreset(preset) {
|
|
11393
|
+
return DUE_SET.has(preset);
|
|
11394
|
+
}
|
|
11395
|
+
function toDisplayMenuIsoDate(date) {
|
|
11396
|
+
return format(date, "yyyy-MM-dd");
|
|
11397
|
+
}
|
|
11398
|
+
function toDay(value) {
|
|
11399
|
+
if (value == null || value === "") return null;
|
|
11400
|
+
const date = typeof value === "string" ? parseISO(value) : value;
|
|
11401
|
+
if (!isValid(date)) return null;
|
|
11402
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
11403
|
+
}
|
|
11404
|
+
function range(from, to) {
|
|
11405
|
+
return { from: toDisplayMenuIsoDate(from), to: toDisplayMenuIsoDate(to) };
|
|
11406
|
+
}
|
|
11407
|
+
function resolveDisplayMenuDatePreset(preset, now) {
|
|
11408
|
+
const today = toDay(now) ?? now;
|
|
11409
|
+
switch (preset) {
|
|
11410
|
+
case "dueToday":
|
|
11411
|
+
case "today":
|
|
11412
|
+
return range(today, today);
|
|
11413
|
+
case "dueNext7":
|
|
11414
|
+
return range(today, addDays(today, 7));
|
|
11415
|
+
case "dueThisMonth":
|
|
11416
|
+
return range(today, endOfMonth(today));
|
|
11417
|
+
case "last7":
|
|
11418
|
+
return range(addDays(today, -6), today);
|
|
11419
|
+
case "last30":
|
|
11420
|
+
return range(addDays(today, -29), today);
|
|
11421
|
+
case "thisMonth":
|
|
11422
|
+
return range(startOfMonth(today), endOfMonth(today));
|
|
11423
|
+
case "lastMonth": {
|
|
11424
|
+
const last = subMonths(today, 1);
|
|
11425
|
+
return range(startOfMonth(last), endOfMonth(last));
|
|
11426
|
+
}
|
|
11427
|
+
case "thisQuarter":
|
|
11428
|
+
return range(startOfQuarter(today), endOfQuarter(today));
|
|
11429
|
+
case "lastQuarter": {
|
|
11430
|
+
const last = subQuarters(today, 1);
|
|
11431
|
+
return range(startOfQuarter(last), endOfQuarter(last));
|
|
11432
|
+
}
|
|
11433
|
+
case "ytd":
|
|
11434
|
+
return range(startOfYear(today), today);
|
|
11435
|
+
default:
|
|
11436
|
+
return void 0;
|
|
11437
|
+
}
|
|
11438
|
+
}
|
|
11439
|
+
function detectDisplayMenuDatePreset(value, now, presets = DISPLAY_MENU_DATE_PRESETS) {
|
|
11440
|
+
if (!value || !value.from && !value.to) return "custom";
|
|
11441
|
+
for (const preset of presets) {
|
|
11442
|
+
const resolved = resolveDisplayMenuDatePreset(preset, now);
|
|
11443
|
+
if (resolved && resolved.from === value.from && resolved.to === value.to) return preset;
|
|
11444
|
+
}
|
|
11445
|
+
return "custom";
|
|
11446
|
+
}
|
|
11447
|
+
function effectiveDisplayMenuDatePreset(value, now, presets) {
|
|
11448
|
+
if (!value) return null;
|
|
11449
|
+
if (value.preset !== "custom") return value.preset;
|
|
11450
|
+
return detectDisplayMenuDatePreset(value.range, now, presets);
|
|
11451
|
+
}
|
|
11452
|
+
function matchesDisplayMenuDate(value, filter, now) {
|
|
11453
|
+
if (!filter) return true;
|
|
11454
|
+
const day = toDay(value);
|
|
11455
|
+
if (filter.preset === "noDate") return day === null;
|
|
11456
|
+
if (day === null) return false;
|
|
11457
|
+
const today = toDay(now) ?? now;
|
|
11458
|
+
if (filter.preset === "overdue") return day.getTime() < today.getTime();
|
|
11459
|
+
const bounds = filter.preset === "custom" ? filter.range : resolveDisplayMenuDatePreset(filter.preset, now);
|
|
11460
|
+
if (!bounds) return true;
|
|
11461
|
+
const from = toDay(bounds.from);
|
|
11462
|
+
const to = toDay(bounds.to);
|
|
11463
|
+
if (from && day.getTime() < from.getTime()) return false;
|
|
11464
|
+
if (to && day.getTime() > to.getTime()) return false;
|
|
11465
|
+
return true;
|
|
11466
|
+
}
|
|
11467
|
+
var NUMBER_PATTERN = /^-?\d*\.?\d+$|^-?\d+\.$/;
|
|
11468
|
+
function parseDisplayMenuNumber(input) {
|
|
11469
|
+
let text = input.replace(/\s+/g, "");
|
|
11470
|
+
if (!text) return null;
|
|
11471
|
+
let negative = false;
|
|
11472
|
+
if (text.startsWith("(") && text.endsWith(")")) {
|
|
11473
|
+
negative = true;
|
|
11474
|
+
text = text.slice(1, -1);
|
|
11475
|
+
} else if (text.includes("(") || text.includes(")")) {
|
|
11476
|
+
return null;
|
|
11477
|
+
}
|
|
11478
|
+
if (text.startsWith("-")) {
|
|
11479
|
+
if (negative) return null;
|
|
11480
|
+
negative = true;
|
|
11481
|
+
text = text.slice(1);
|
|
11482
|
+
}
|
|
11483
|
+
text = text.replace(/^\$/, "");
|
|
11484
|
+
if (text.startsWith("-")) {
|
|
11485
|
+
if (negative) return null;
|
|
11486
|
+
negative = true;
|
|
11487
|
+
text = text.slice(1);
|
|
11488
|
+
}
|
|
11489
|
+
if (text.includes(",")) {
|
|
11490
|
+
if (!/^\d{1,3}(,\d{3})+(\.\d*)?$/.test(text)) return null;
|
|
11491
|
+
text = text.replace(/,/g, "");
|
|
11492
|
+
}
|
|
11493
|
+
if (!NUMBER_PATTERN.test(text)) return null;
|
|
11494
|
+
const value = Number(text);
|
|
11495
|
+
if (!Number.isFinite(value)) return null;
|
|
11496
|
+
return negative ? -value : value;
|
|
11497
|
+
}
|
|
11498
|
+
function matchesDisplayMenuNumber(value, filter) {
|
|
11499
|
+
if (!filter || filter.value === null) return true;
|
|
11500
|
+
if (value == null || Number.isNaN(value)) return false;
|
|
11501
|
+
const target = filter.value;
|
|
11502
|
+
switch (filter.operator) {
|
|
11503
|
+
case "eq":
|
|
11504
|
+
return value === target;
|
|
11505
|
+
case "ne":
|
|
11506
|
+
return value !== target;
|
|
11507
|
+
case "lt":
|
|
11508
|
+
return value < target;
|
|
11509
|
+
case "lte":
|
|
11510
|
+
return value <= target;
|
|
11511
|
+
case "gt":
|
|
11512
|
+
return value > target;
|
|
11513
|
+
case "gte":
|
|
11514
|
+
return value >= target;
|
|
11515
|
+
case "between": {
|
|
11516
|
+
const upper = filter.to ?? null;
|
|
11517
|
+
const low = upper === null ? target : Math.min(target, upper);
|
|
11518
|
+
const high = upper === null ? Infinity : Math.max(target, upper);
|
|
11519
|
+
return value >= low && value <= high;
|
|
11520
|
+
}
|
|
11521
|
+
default:
|
|
11522
|
+
return true;
|
|
11523
|
+
}
|
|
11524
|
+
}
|
|
11525
|
+
function formatDisplayMenuNumber(value, formatKind = "number", locale) {
|
|
11526
|
+
if (formatKind === "currency") {
|
|
11527
|
+
return new Intl.NumberFormat(locale ?? "en-US", {
|
|
11528
|
+
style: "currency",
|
|
11529
|
+
currency: "USD",
|
|
11530
|
+
maximumFractionDigits: Number.isInteger(value) ? 0 : 2
|
|
11531
|
+
}).format(value);
|
|
11532
|
+
}
|
|
11533
|
+
return new Intl.NumberFormat(locale ?? "en-US", { maximumFractionDigits: 6 }).format(value);
|
|
11534
|
+
}
|
|
11535
|
+
var DISPLAY_MENU_NUMBER_SYMBOLS = {
|
|
11536
|
+
eq: "=",
|
|
11537
|
+
ne: "\u2260",
|
|
11538
|
+
lt: "<",
|
|
11539
|
+
lte: "\u2264",
|
|
11540
|
+
gt: ">",
|
|
11541
|
+
gte: "\u2265",
|
|
11542
|
+
between: "\u2194"
|
|
11543
|
+
};
|
|
11544
|
+
function matchesDisplayMenuText(value, filter) {
|
|
11545
|
+
const needle = filter?.text.trim().toLowerCase() ?? "";
|
|
11546
|
+
if (!filter || !needle) return true;
|
|
11547
|
+
const haystack = (value ?? "").trim().toLowerCase();
|
|
11548
|
+
return filter.operator === "startsWith" ? haystack.startsWith(needle) : haystack.includes(needle);
|
|
11549
|
+
}
|
|
11550
|
+
function toList(values) {
|
|
11551
|
+
if (values == null || values === "") return [];
|
|
11552
|
+
return typeof values === "string" ? [values] : values;
|
|
11553
|
+
}
|
|
11554
|
+
function matchesDisplayMenuOperator(rowValues, selected, operator = "isAnyOf") {
|
|
11555
|
+
const values = toList(rowValues);
|
|
11556
|
+
if (operator === "isEmpty") return values.length === 0;
|
|
11557
|
+
if (operator === "isNotEmpty") return values.length > 0;
|
|
11558
|
+
if (selected.size === 0) return true;
|
|
11559
|
+
const hit = values.some((value) => selected.has(value));
|
|
11560
|
+
return operator === "isNot" || operator === "isNoneOf" ? !hit : hit;
|
|
11561
|
+
}
|
|
11562
|
+
function matchesDisplayMenuTags(rowTags, selected, match = "any") {
|
|
11563
|
+
if (selected.size === 0) return true;
|
|
11564
|
+
const tags = new Set(rowTags ?? []);
|
|
11565
|
+
if (match === "all") {
|
|
11566
|
+
for (const tag of selected) if (!tags.has(tag)) return false;
|
|
11567
|
+
return true;
|
|
11568
|
+
}
|
|
11569
|
+
for (const tag of selected) if (tags.has(tag)) return true;
|
|
11570
|
+
return false;
|
|
11571
|
+
}
|
|
11572
|
+
function visibleDisplayMenuOptions(section, query = "", pinnedKeys = []) {
|
|
11573
|
+
const q = query.trim().toLowerCase();
|
|
11574
|
+
const pinnedSet = new Set(pinnedKeys);
|
|
11575
|
+
const isPinned = (o) => Boolean(o.pinned) || pinnedSet.has(o.key);
|
|
11576
|
+
const keep = (o) => !section.hideZero || o.count !== 0 || section.selected.has(o.key) || isPinned(o);
|
|
11577
|
+
const pinned = pinnedKeys.map((key) => section.options.find((o) => o.key === key)).filter((o) => o !== void 0);
|
|
11578
|
+
for (const o of section.options) if (o.pinned && !pinnedSet.has(o.key)) pinned.push(o);
|
|
11579
|
+
const rest = section.options.filter(
|
|
11580
|
+
(o) => !isPinned(o) && keep(o) && (!q || o.label.toLowerCase().includes(q))
|
|
11581
|
+
);
|
|
11582
|
+
return [...pinned, ...rest];
|
|
11583
|
+
}
|
|
11584
|
+
function displayMenuSectionOperator(section) {
|
|
11585
|
+
return section.operator ?? section.operators?.[0];
|
|
11586
|
+
}
|
|
11587
|
+
function isDisplayMenuSectionActive(section) {
|
|
11588
|
+
const spec = section.spec;
|
|
11589
|
+
if (spec) {
|
|
11590
|
+
switch (spec.kind) {
|
|
11591
|
+
case "sort":
|
|
11592
|
+
case "columns":
|
|
11593
|
+
return false;
|
|
11594
|
+
case "date":
|
|
11595
|
+
case "number":
|
|
11596
|
+
return spec.value !== null && (spec.kind === "date" || spec.value.value !== null);
|
|
11597
|
+
case "text":
|
|
11598
|
+
return spec.value !== null && spec.value.text.trim() !== "";
|
|
11599
|
+
case "boolean":
|
|
11600
|
+
return spec.value !== null;
|
|
11601
|
+
}
|
|
11602
|
+
}
|
|
11603
|
+
const operator = displayMenuSectionOperator(section);
|
|
11604
|
+
if (operator === "isEmpty" || operator === "isNotEmpty") return true;
|
|
11605
|
+
if (section.mode === "multi" || section.mode === "toggle") return section.selected.size > 0;
|
|
11606
|
+
return false;
|
|
11607
|
+
}
|
|
11608
|
+
function displayMenuOperatorLabel(operator, messages) {
|
|
11609
|
+
switch (operator) {
|
|
11610
|
+
case "is":
|
|
11611
|
+
return messages.operatorIs;
|
|
11612
|
+
case "isNot":
|
|
11613
|
+
return messages.operatorIsNot;
|
|
11614
|
+
case "isAnyOf":
|
|
11615
|
+
return messages.operatorIsAnyOf;
|
|
11616
|
+
case "isNoneOf":
|
|
11617
|
+
return messages.operatorIsNoneOf;
|
|
11618
|
+
case "isEmpty":
|
|
11619
|
+
return messages.operatorIsEmpty;
|
|
11620
|
+
case "isNotEmpty":
|
|
11621
|
+
return messages.operatorIsNotEmpty;
|
|
11622
|
+
}
|
|
11623
|
+
}
|
|
11624
|
+
function displayMenuDatePresetLabel(preset, messages) {
|
|
11625
|
+
return messages[preset];
|
|
11626
|
+
}
|
|
11627
|
+
function displayMenuNumberOperatorLabel(operator, messages) {
|
|
11628
|
+
const key = `number${operator.charAt(0).toUpperCase()}${operator.slice(1)}`;
|
|
11629
|
+
return messages[key];
|
|
11630
|
+
}
|
|
11631
|
+
function displayMenuOptionLabel(section, option, messages) {
|
|
11632
|
+
if (section.spec?.kind === "person") {
|
|
11633
|
+
if (option.key === section.spec.meKey) return messages.me;
|
|
11634
|
+
if (option.key === section.spec.unassignedKey) return messages.unassigned;
|
|
11635
|
+
}
|
|
11636
|
+
return option.label;
|
|
11637
|
+
}
|
|
11638
|
+
function joinDisplayMenuLabels(labels, messages, max = 2) {
|
|
11639
|
+
if (labels.length <= max) return labels.join(", ");
|
|
11640
|
+
return `${labels.slice(0, max).join(", ")} ${messages.more(labels.length - max)}`;
|
|
11641
|
+
}
|
|
11642
|
+
function formatDay(iso, locale) {
|
|
11643
|
+
const day = toDay(iso);
|
|
11644
|
+
if (!day) return iso;
|
|
11645
|
+
return new Intl.DateTimeFormat(locale ?? "en-US", {
|
|
11646
|
+
month: "short",
|
|
11647
|
+
day: "numeric",
|
|
11648
|
+
year: "numeric"
|
|
11649
|
+
}).format(day);
|
|
11650
|
+
}
|
|
11651
|
+
function summarizeDisplayMenuSection(section, messages, options = {}) {
|
|
11652
|
+
const { locale } = options;
|
|
11653
|
+
const spec = section.spec;
|
|
11654
|
+
if (spec?.kind === "sort") {
|
|
11655
|
+
if (spec.value.length === 0) return null;
|
|
11656
|
+
const labels2 = spec.value.map(
|
|
11657
|
+
(key) => spec.fields.find((field) => field.key === key.key)?.label ?? key.key
|
|
11658
|
+
);
|
|
11659
|
+
return messages.sortSummary(labels2.join(", "));
|
|
11660
|
+
}
|
|
11661
|
+
if (!isDisplayMenuSectionActive(section)) return null;
|
|
11662
|
+
if (spec) {
|
|
11663
|
+
switch (spec.kind) {
|
|
11664
|
+
case "date": {
|
|
11665
|
+
const value = spec.value;
|
|
11666
|
+
if (!value) return null;
|
|
11667
|
+
const now = options.now ?? spec.now ?? /* @__PURE__ */ new Date();
|
|
11668
|
+
const preset = effectiveDisplayMenuDatePreset(value, now, spec.presets);
|
|
11669
|
+
if (preset && preset !== "custom") return displayMenuDatePresetLabel(preset, messages);
|
|
11670
|
+
const from = value.range?.from;
|
|
11671
|
+
const to = value.range?.to;
|
|
11672
|
+
if (from && to) return messages.dateBetween(formatDay(from, locale), formatDay(to, locale));
|
|
11673
|
+
if (from) return messages.dateOnOrAfter(formatDay(from, locale));
|
|
11674
|
+
if (to) return messages.dateOnOrBefore(formatDay(to, locale));
|
|
11675
|
+
return messages.custom;
|
|
11676
|
+
}
|
|
11677
|
+
case "number": {
|
|
11678
|
+
const value = spec.value;
|
|
11679
|
+
if (!value || value.value === null) return null;
|
|
11680
|
+
const fmt = (n) => formatDisplayMenuNumber(n, spec.format ?? "number", locale);
|
|
11681
|
+
if (value.operator === "between") {
|
|
11682
|
+
return value.to == null ? `${DISPLAY_MENU_NUMBER_SYMBOLS.gte} ${fmt(value.value)}` : messages.numberBetweenSummary(fmt(value.value), fmt(value.to));
|
|
11683
|
+
}
|
|
11684
|
+
return `${DISPLAY_MENU_NUMBER_SYMBOLS[value.operator]} ${fmt(value.value)}`;
|
|
11685
|
+
}
|
|
11686
|
+
case "text": {
|
|
11687
|
+
const value = spec.value;
|
|
11688
|
+
if (!value) return null;
|
|
11689
|
+
const text = value.text.trim();
|
|
11690
|
+
return value.operator === "startsWith" ? messages.textStartsWithSummary(text) : messages.textContainsSummary(text);
|
|
11691
|
+
}
|
|
11692
|
+
case "boolean":
|
|
11693
|
+
return spec.value ? spec.trueLabel ?? messages.booleanTrue : spec.falseLabel ?? messages.booleanFalse;
|
|
11694
|
+
}
|
|
11695
|
+
}
|
|
11696
|
+
if (section.mode === "toggle") return section.options[0]?.label ?? null;
|
|
11697
|
+
const operator = displayMenuSectionOperator(section);
|
|
11698
|
+
if (operator === "isEmpty" || operator === "isNotEmpty") {
|
|
11699
|
+
return displayMenuOperatorLabel(operator, messages);
|
|
11700
|
+
}
|
|
11701
|
+
const labels = section.options.filter((option) => section.selected.has(option.key)).map((option) => displayMenuOptionLabel(section, option, messages));
|
|
11702
|
+
const joined = joinDisplayMenuLabels(labels, messages);
|
|
11703
|
+
if (spec?.kind === "tags" && spec.tagMatch === "all" && labels.length > 1) {
|
|
11704
|
+
return messages.tagMatchAllSummary(joined);
|
|
11705
|
+
}
|
|
11706
|
+
if (!section.operators || !operator) return joined;
|
|
11707
|
+
return `${displayMenuOperatorLabel(operator, messages)} ${joined}`;
|
|
11708
|
+
}
|
|
11709
|
+
var ITEM_ROLE = {
|
|
11710
|
+
item: "menuitem",
|
|
11711
|
+
checkbox: "menuitemcheckbox",
|
|
11712
|
+
radio: "menuitemradio",
|
|
11713
|
+
list: "menu"
|
|
11714
|
+
};
|
|
11715
|
+
var DISPLAY_MENU_ROW_CLASSES = "ds:flex ds:w-full ds:items-center ds:gap-2 ds:rounded-md ds:px-2 ds:py-1.5 ds:text-left ds:text-(length:--control-font-size-sm) ds:text-fg ds:transition-colors ds:hover:bg-surface-hover/60 ds:focus-visible:bg-bg-2/60 ds:focus-visible:shadow-none ds:focus-visible:outline-none ds:motion-reduce:transition-none";
|
|
11716
|
+
var DisplayMenuItem = forwardRef(
|
|
11717
|
+
function DisplayMenuItem2({ kind, checked, trailing, indicator, bare = false, className, children, ...props }, ref) {
|
|
11718
|
+
const isChecked = Boolean(checked);
|
|
11719
|
+
return /* @__PURE__ */ jsxs(
|
|
11720
|
+
Pressable,
|
|
11721
|
+
{
|
|
11722
|
+
ref,
|
|
11723
|
+
role: ITEM_ROLE[kind],
|
|
11724
|
+
"aria-checked": kind === "item" ? void 0 : isChecked,
|
|
11725
|
+
className: cn(DISPLAY_MENU_ROW_CLASSES, className),
|
|
11726
|
+
...props,
|
|
11727
|
+
children: [
|
|
11728
|
+
kind === "checkbox" && indicator !== "check" && /* @__PURE__ */ jsx(
|
|
11729
|
+
"span",
|
|
11730
|
+
{
|
|
11731
|
+
"aria-hidden": "true",
|
|
11732
|
+
className: cn(
|
|
11733
|
+
"ds:flex ds:size-3.5 ds:shrink-0 ds:items-center ds:justify-center ds:rounded ds:border ds:transition-colors ds:motion-reduce:transition-none",
|
|
11734
|
+
isChecked ? "ds:border-brand ds:bg-brand ds:text-fg-on-brand" : "ds:border-rule"
|
|
11735
|
+
),
|
|
11736
|
+
children: isChecked && /* @__PURE__ */ jsx(CheckIcon, { size: 10 })
|
|
11737
|
+
}
|
|
11738
|
+
),
|
|
11739
|
+
bare ? children : /* @__PURE__ */ jsx("span", { className: "ds:min-w-0 ds:flex-1 ds:truncate", children }),
|
|
11740
|
+
trailing,
|
|
11741
|
+
(kind === "radio" || indicator === "check") && kind !== "item" && isChecked && /* @__PURE__ */ jsx(CheckIcon, { size: 14, "aria-hidden": "true", className: "ds:shrink-0 ds:text-brand" })
|
|
11742
|
+
]
|
|
11743
|
+
}
|
|
11744
|
+
);
|
|
11745
|
+
}
|
|
11746
|
+
);
|
|
11747
|
+
DisplayMenuItem.displayName = "DisplayMenuItem";
|
|
11748
|
+
var DisplayMenuList = forwardRef(
|
|
11749
|
+
function DisplayMenuList2({ className, ...props }, ref) {
|
|
11750
|
+
return /* @__PURE__ */ jsx("div", { ref, role: ITEM_ROLE.list, className: cn("ds:p-1", className), ...props });
|
|
11751
|
+
}
|
|
11752
|
+
);
|
|
11753
|
+
DisplayMenuList.displayName = "DisplayMenuList";
|
|
11754
|
+
function DisplayMenuCount({ value }) {
|
|
11755
|
+
return /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:ps-2 ds:text-(length:--text-caption) ds:text-fg-3 ds:tabular-nums", children: value.toLocaleString() });
|
|
11756
|
+
}
|
|
11757
|
+
function useFilterMessages() {
|
|
11758
|
+
return useDsMessages("displayMenuFilters");
|
|
11759
|
+
}
|
|
11760
|
+
function PanelHeading({ id, children }) {
|
|
11761
|
+
return /* @__PURE__ */ jsx(
|
|
11762
|
+
"p",
|
|
11763
|
+
{
|
|
11764
|
+
id,
|
|
11765
|
+
className: "ds:px-2 ds:pt-2 ds:pb-1 ds:text-(length:--text-overline) ds:font-medium ds:uppercase ds:tracking-wide ds:text-fg-4",
|
|
11766
|
+
children
|
|
11767
|
+
}
|
|
11768
|
+
);
|
|
11769
|
+
}
|
|
11770
|
+
function useAnnouncer() {
|
|
11771
|
+
const [text, setText] = useState("");
|
|
11772
|
+
const announce = useCallback((next) => {
|
|
11773
|
+
setText("");
|
|
11774
|
+
const raf = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
|
|
11775
|
+
raf(() => setText(next));
|
|
11776
|
+
}, []);
|
|
11777
|
+
const region = /* @__PURE__ */ jsx(VisuallyHidden, { role: "status", "aria-live": "polite", children: text });
|
|
11778
|
+
return [region, announce];
|
|
11779
|
+
}
|
|
11780
|
+
function onListArrowKeys(event) {
|
|
11781
|
+
const keys = ["ArrowDown", "ArrowUp", "Home", "End"];
|
|
11782
|
+
if (!keys.includes(event.key)) return;
|
|
11783
|
+
const target = event.target;
|
|
11784
|
+
if (target.tagName === "INPUT") return;
|
|
11785
|
+
const items = Array.from(
|
|
11786
|
+
event.currentTarget.querySelectorAll("[data-dm-nav]:not([disabled])")
|
|
11787
|
+
);
|
|
11788
|
+
if (items.length === 0) return;
|
|
11789
|
+
const index = items.indexOf(target);
|
|
11790
|
+
if (index === -1) return;
|
|
11791
|
+
event.preventDefault();
|
|
11792
|
+
event.stopPropagation();
|
|
11793
|
+
const next = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : event.key === "ArrowDown" ? Math.min(items.length - 1, index + 1) : Math.max(0, index - 1);
|
|
11794
|
+
items[next]?.focus();
|
|
11795
|
+
}
|
|
11796
|
+
function keepTypingInField(event) {
|
|
11797
|
+
if (event.key.length === 1 || event.key === "Backspace" || event.key === "Delete") {
|
|
11798
|
+
event.stopPropagation();
|
|
11799
|
+
}
|
|
11800
|
+
}
|
|
11801
|
+
function CheckOptionRow({
|
|
11802
|
+
checked,
|
|
11803
|
+
onToggle,
|
|
11804
|
+
label,
|
|
11805
|
+
icon,
|
|
11806
|
+
count,
|
|
11807
|
+
disabled
|
|
11808
|
+
}) {
|
|
11809
|
+
const id = useId();
|
|
11810
|
+
return /* @__PURE__ */ jsxs(
|
|
11811
|
+
"div",
|
|
11812
|
+
{
|
|
11813
|
+
className: cn(
|
|
11814
|
+
"ds:flex ds:items-center ds:gap-2 ds:rounded-md ds:px-2 ds:py-1.5",
|
|
11815
|
+
"ds:transition-colors ds:hover:bg-surface-hover/60 ds:motion-reduce:transition-none"
|
|
11816
|
+
),
|
|
11817
|
+
children: [
|
|
11818
|
+
/* @__PURE__ */ jsx(
|
|
11819
|
+
Checkbox,
|
|
11820
|
+
{
|
|
11821
|
+
id,
|
|
11822
|
+
"data-dm-nav": "",
|
|
11823
|
+
checked,
|
|
11824
|
+
disabled,
|
|
11825
|
+
onCheckedChange: onToggle
|
|
11826
|
+
}
|
|
11827
|
+
),
|
|
11828
|
+
/* @__PURE__ */ jsxs(
|
|
11829
|
+
Label2,
|
|
11830
|
+
{
|
|
11831
|
+
htmlFor: id,
|
|
11832
|
+
className: cn(
|
|
11833
|
+
"ds:flex ds:min-w-0 ds:flex-1 ds:cursor-pointer ds:items-center ds:gap-2 ds:font-normal",
|
|
11834
|
+
"ds:text-(length:--control-font-size-sm)",
|
|
11835
|
+
checked ? "ds:text-fg" : "ds:text-fg-2"
|
|
11836
|
+
),
|
|
11837
|
+
children: [
|
|
11838
|
+
icon && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ds:inline-flex ds:shrink-0", children: icon }),
|
|
11839
|
+
/* @__PURE__ */ jsx("span", { className: "ds:truncate", children: label })
|
|
11840
|
+
]
|
|
11841
|
+
}
|
|
11842
|
+
),
|
|
11843
|
+
typeof count === "number" && /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:text-(length:--text-helper) ds:tabular-nums ds:text-fg-3", children: count })
|
|
11844
|
+
]
|
|
11845
|
+
}
|
|
11846
|
+
);
|
|
11847
|
+
}
|
|
11848
|
+
function PanelSearch({
|
|
11849
|
+
value,
|
|
11850
|
+
onChange,
|
|
11851
|
+
label,
|
|
11852
|
+
onArrowDown
|
|
11853
|
+
}) {
|
|
11854
|
+
const messages = useFilterMessages();
|
|
11855
|
+
return /* @__PURE__ */ jsx("div", { className: "ds:p-1", children: /* @__PURE__ */ jsx(
|
|
11856
|
+
Input,
|
|
11857
|
+
{
|
|
11858
|
+
type: "search",
|
|
11859
|
+
size: "sm",
|
|
11860
|
+
value,
|
|
11861
|
+
onChange: (event) => onChange(event.target.value),
|
|
11862
|
+
onKeyDown: (event) => {
|
|
11863
|
+
keepTypingInField(event);
|
|
11864
|
+
if (event.key === "ArrowDown" && onArrowDown) {
|
|
11865
|
+
event.preventDefault();
|
|
11866
|
+
onArrowDown();
|
|
11867
|
+
}
|
|
11868
|
+
},
|
|
11869
|
+
"aria-label": label,
|
|
11870
|
+
placeholder: messages.searchPlaceholder,
|
|
11871
|
+
prefixIcon: /* @__PURE__ */ jsx(SearchIcon, { "aria-hidden": "true" })
|
|
11872
|
+
}
|
|
11873
|
+
) });
|
|
11874
|
+
}
|
|
11875
|
+
function PanelEmpty({ children }) {
|
|
11876
|
+
return /* @__PURE__ */ jsx("p", { className: "ds:px-2 ds:py-3 ds:text-center ds:text-(length:--text-helper) ds:text-fg-3", children });
|
|
11877
|
+
}
|
|
11878
|
+
function ChoiceList({
|
|
11879
|
+
label,
|
|
11880
|
+
labelledBy,
|
|
11881
|
+
choices,
|
|
11882
|
+
value,
|
|
11883
|
+
onChange,
|
|
11884
|
+
inline = false,
|
|
11885
|
+
className
|
|
11886
|
+
}) {
|
|
11887
|
+
return /* @__PURE__ */ jsx(
|
|
11888
|
+
RadioGroup2,
|
|
11889
|
+
{
|
|
11890
|
+
"aria-label": labelledBy ? void 0 : label,
|
|
11891
|
+
"aria-labelledby": labelledBy,
|
|
11892
|
+
orientation: inline ? "horizontal" : "vertical",
|
|
11893
|
+
value: value ?? "",
|
|
11894
|
+
onValueChange: (next) => onChange(next),
|
|
11895
|
+
onKeyDown: (event) => {
|
|
11896
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") event.stopPropagation();
|
|
11897
|
+
},
|
|
11898
|
+
className: cn(
|
|
11899
|
+
inline ? "ds:flex ds:flex-wrap ds:gap-x-3 ds:gap-y-1.5 ds:px-2 ds:py-1.5" : "ds:flex ds:flex-col ds:gap-1.5 ds:px-2 ds:py-1",
|
|
11900
|
+
className
|
|
11901
|
+
),
|
|
11902
|
+
children: choices.map((choice) => /* @__PURE__ */ jsx(RadioGroupItem, { value: choice.value, label: choice.label }, choice.value))
|
|
11903
|
+
}
|
|
11904
|
+
);
|
|
11905
|
+
}
|
|
11906
|
+
function SortPanel({ spec }) {
|
|
11907
|
+
const messages = useFilterMessages();
|
|
11908
|
+
const [region, announce] = useAnnouncer();
|
|
11909
|
+
const [picking, setPicking] = useState(null);
|
|
11910
|
+
const maxKeys = spec.maxKeys ?? 2;
|
|
11911
|
+
const labelOf2 = (key) => spec.fields.find((f) => f.key === key)?.label ?? key;
|
|
11912
|
+
const used = new Set(spec.value.map((k) => k.key));
|
|
11913
|
+
const update = (next) => {
|
|
11914
|
+
spec.onChange(next);
|
|
11915
|
+
announce(
|
|
11916
|
+
next.length === 0 ? messages.sortChanged("\u2014") : messages.sortChanged(next.map((k) => labelOf2(k.key)).join(", "))
|
|
11917
|
+
);
|
|
11918
|
+
};
|
|
11919
|
+
const setField = (index, key) => {
|
|
11920
|
+
const field = spec.fields.find((f) => f.key === key);
|
|
11921
|
+
const next = [...spec.value];
|
|
11922
|
+
const direction = field?.defaultDirection ?? "asc";
|
|
11923
|
+
if (index >= next.length) next.push({ key, direction });
|
|
11924
|
+
else next[index] = { key, direction: next[index]?.direction ?? direction };
|
|
11925
|
+
setPicking(null);
|
|
11926
|
+
update(next);
|
|
11927
|
+
};
|
|
11928
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:p-1", children: [
|
|
11929
|
+
region,
|
|
11930
|
+
/* @__PURE__ */ jsx("ol", { "aria-label": messages.sortBy, className: "ds:flex ds:flex-col ds:gap-1", children: spec.value.map((sortKey, index) => {
|
|
11931
|
+
const label = labelOf2(sortKey.key);
|
|
11932
|
+
const position = index === 0 ? messages.sortBy : messages.sortThenBy;
|
|
11933
|
+
return /* @__PURE__ */ jsxs("li", { className: "ds:flex ds:flex-col ds:gap-0.5", children: [
|
|
11934
|
+
/* @__PURE__ */ jsx(PanelHeading, { children: position }),
|
|
11935
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:items-center ds:gap-1 ds:px-1", children: [
|
|
11936
|
+
/* @__PURE__ */ jsx(
|
|
11937
|
+
Button,
|
|
11938
|
+
{
|
|
11939
|
+
variant: "outline",
|
|
11940
|
+
size: "sm",
|
|
11941
|
+
"aria-label": `${messages.sortField(position)}: ${label}`,
|
|
11942
|
+
"aria-expanded": picking === index,
|
|
11943
|
+
onClick: () => setPicking(picking === index ? null : index),
|
|
11944
|
+
className: "ds:h-7 ds:min-w-0 ds:flex-1 ds:justify-start ds:px-2",
|
|
11945
|
+
children: /* @__PURE__ */ jsx("span", { className: "ds:truncate", children: label })
|
|
11946
|
+
}
|
|
11947
|
+
),
|
|
11948
|
+
/* @__PURE__ */ jsx(
|
|
11949
|
+
IconButton,
|
|
11950
|
+
{
|
|
11951
|
+
variant: "ghost",
|
|
11952
|
+
intent: "neutral",
|
|
11953
|
+
size: "xs",
|
|
11954
|
+
tooltip: false,
|
|
11955
|
+
label: `${messages.sortDirection(label)}: ${sortKey.direction === "asc" ? messages.ascending : messages.descending}`,
|
|
11956
|
+
icon: sortKey.direction === "asc" ? /* @__PURE__ */ jsx(ArrowUpIcon, {}) : /* @__PURE__ */ jsx(ArrowDownIcon, {}),
|
|
11957
|
+
onClick: () => update(
|
|
11958
|
+
spec.value.map(
|
|
11959
|
+
(k, i) => i === index ? { ...k, direction: k.direction === "asc" ? "desc" : "asc" } : k
|
|
11960
|
+
)
|
|
11961
|
+
)
|
|
11962
|
+
}
|
|
11963
|
+
),
|
|
11964
|
+
index > 0 && /* @__PURE__ */ jsx(
|
|
11965
|
+
IconButton,
|
|
11966
|
+
{
|
|
11967
|
+
variant: "ghost",
|
|
11968
|
+
intent: "neutral",
|
|
11969
|
+
size: "xs",
|
|
11970
|
+
tooltip: false,
|
|
11971
|
+
label: messages.makePrimary(label),
|
|
11972
|
+
icon: /* @__PURE__ */ jsx(ArrowUpIcon, {}),
|
|
11973
|
+
onClick: () => {
|
|
11974
|
+
const next = [...spec.value];
|
|
11975
|
+
const [moved] = next.splice(index, 1);
|
|
11976
|
+
if (moved) next.unshift(moved);
|
|
11977
|
+
update(next);
|
|
11978
|
+
}
|
|
11979
|
+
}
|
|
11980
|
+
),
|
|
11981
|
+
/* @__PURE__ */ jsx(
|
|
11982
|
+
IconButton,
|
|
11983
|
+
{
|
|
11984
|
+
variant: "ghost",
|
|
11985
|
+
intent: "neutral",
|
|
11986
|
+
size: "xs",
|
|
11987
|
+
tooltip: false,
|
|
11988
|
+
label: messages.removeSort(label),
|
|
11989
|
+
icon: /* @__PURE__ */ jsx(XIcon, {}),
|
|
11990
|
+
onClick: () => update(spec.value.filter((_, i) => i !== index))
|
|
11991
|
+
}
|
|
11992
|
+
)
|
|
11993
|
+
] }),
|
|
11994
|
+
picking === index && /* @__PURE__ */ jsx(
|
|
11995
|
+
FieldPicker,
|
|
11996
|
+
{
|
|
11997
|
+
fields: spec.fields.filter((f) => f.key === sortKey.key || !used.has(f.key)),
|
|
11998
|
+
selected: sortKey.key,
|
|
11999
|
+
label: messages.chooseField,
|
|
12000
|
+
onPick: (key) => setField(index, key)
|
|
12001
|
+
}
|
|
12002
|
+
)
|
|
12003
|
+
] }, sortKey.key);
|
|
12004
|
+
}) }),
|
|
12005
|
+
spec.value.length < maxKeys && spec.fields.some((f) => !used.has(f.key)) && /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:px-1 ds:pt-1", children: [
|
|
12006
|
+
/* @__PURE__ */ jsxs(
|
|
12007
|
+
Button,
|
|
12008
|
+
{
|
|
12009
|
+
variant: "ghost",
|
|
12010
|
+
size: "sm",
|
|
12011
|
+
"aria-expanded": picking === spec.value.length,
|
|
12012
|
+
onClick: () => setPicking(picking === spec.value.length ? null : spec.value.length),
|
|
12013
|
+
className: "ds:h-7 ds:justify-start ds:gap-1.5 ds:px-2 ds:text-fg-3 ds:hover:text-fg",
|
|
12014
|
+
children: [
|
|
12015
|
+
/* @__PURE__ */ jsx(PlusIcon, { size: 13, "aria-hidden": "true" }),
|
|
12016
|
+
messages.addSort
|
|
12017
|
+
]
|
|
12018
|
+
}
|
|
12019
|
+
),
|
|
12020
|
+
picking === spec.value.length && /* @__PURE__ */ jsx(
|
|
12021
|
+
FieldPicker,
|
|
12022
|
+
{
|
|
12023
|
+
fields: spec.fields.filter((f) => !used.has(f.key)),
|
|
12024
|
+
label: messages.chooseField,
|
|
12025
|
+
onPick: (key) => setField(spec.value.length, key)
|
|
12026
|
+
}
|
|
12027
|
+
)
|
|
12028
|
+
] })
|
|
12029
|
+
] });
|
|
12030
|
+
}
|
|
12031
|
+
function FieldPicker({
|
|
12032
|
+
fields,
|
|
12033
|
+
selected,
|
|
12034
|
+
label,
|
|
12035
|
+
onPick
|
|
12036
|
+
}) {
|
|
12037
|
+
return /* @__PURE__ */ jsx("div", { className: "ds:mx-1 ds:mt-1 ds:max-h-48 ds:overflow-y-auto ds:rounded-input ds:border ds:border-rule", children: /* @__PURE__ */ jsx(
|
|
12038
|
+
ChoiceList,
|
|
12039
|
+
{
|
|
12040
|
+
label,
|
|
12041
|
+
choices: fields.map((f) => ({ value: f.key, label: f.label })),
|
|
12042
|
+
value: selected ?? null,
|
|
12043
|
+
onChange: onPick
|
|
12044
|
+
}
|
|
12045
|
+
) });
|
|
12046
|
+
}
|
|
12047
|
+
function resolveColumnOrder(columns, order) {
|
|
12048
|
+
const known = new Set(columns.map((c) => c.key));
|
|
12049
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12050
|
+
const out = [];
|
|
12051
|
+
for (const key of order) {
|
|
12052
|
+
if (!known.has(key) || seen.has(key)) continue;
|
|
12053
|
+
seen.add(key);
|
|
12054
|
+
out.push(key);
|
|
12055
|
+
}
|
|
12056
|
+
for (const c of columns) if (!seen.has(c.key)) out.push(c.key);
|
|
12057
|
+
return out;
|
|
12058
|
+
}
|
|
12059
|
+
function moveColumn(order, key, delta, isLocked) {
|
|
12060
|
+
const from = order.indexOf(key);
|
|
12061
|
+
const to = from + delta;
|
|
12062
|
+
if (from === -1 || isLocked(key) || to < 0 || to >= order.length) return null;
|
|
12063
|
+
const step = delta > 0 ? 1 : -1;
|
|
12064
|
+
for (let i = from + step; i !== to + step; i += step) {
|
|
12065
|
+
const passed = order[i];
|
|
12066
|
+
if (passed !== void 0 && isLocked(passed)) return null;
|
|
12067
|
+
}
|
|
12068
|
+
const next = [...order];
|
|
12069
|
+
next.splice(from, 1);
|
|
12070
|
+
next.splice(to, 0, key);
|
|
12071
|
+
return next;
|
|
12072
|
+
}
|
|
12073
|
+
function ColumnsPanel({ spec }) {
|
|
12074
|
+
const messages = useFilterMessages();
|
|
12075
|
+
const [region, announce] = useAnnouncer();
|
|
12076
|
+
const [dragging, setDragging] = useState(null);
|
|
12077
|
+
const rowRefs = useRef(/* @__PURE__ */ new Map());
|
|
12078
|
+
const order = resolveColumnOrder(spec.columns, spec.order);
|
|
12079
|
+
const byKey = new Map(spec.columns.map((c) => [c.key, c]));
|
|
12080
|
+
const isLocked = (key) => Boolean(byKey.get(key)?.locked);
|
|
12081
|
+
const move = (key, delta, refocus = true) => {
|
|
12082
|
+
const next = moveColumn(order, key, delta, isLocked);
|
|
12083
|
+
if (!next) return;
|
|
12084
|
+
spec.onOrderChange(next);
|
|
12085
|
+
announce(messages.columnMoved(byKey.get(key)?.label ?? key, next.indexOf(key) + 1, next.length));
|
|
12086
|
+
if (refocus) requestAnimationFrame(() => rowRefs.current.get(key)?.focus());
|
|
12087
|
+
};
|
|
12088
|
+
const toggleHidden = (key) => {
|
|
12089
|
+
const next = new Set(spec.hidden);
|
|
12090
|
+
const label = byKey.get(key)?.label ?? key;
|
|
12091
|
+
if (next.has(key)) {
|
|
12092
|
+
next.delete(key);
|
|
12093
|
+
announce(messages.columnShown(label));
|
|
12094
|
+
} else {
|
|
12095
|
+
next.add(key);
|
|
12096
|
+
announce(messages.columnHidden(label));
|
|
12097
|
+
}
|
|
12098
|
+
spec.onHiddenChange(next);
|
|
12099
|
+
};
|
|
12100
|
+
const onDrop = (event, target) => {
|
|
12101
|
+
event.preventDefault();
|
|
12102
|
+
if (!dragging || dragging === target) return;
|
|
12103
|
+
const delta = order.indexOf(target) - order.indexOf(dragging);
|
|
12104
|
+
move(dragging, delta, false);
|
|
12105
|
+
setDragging(null);
|
|
12106
|
+
};
|
|
12107
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col", children: [
|
|
12108
|
+
region,
|
|
12109
|
+
/* @__PURE__ */ jsx("ul", { "aria-label": messages.columnsList, className: "ds:flex ds:flex-col ds:p-1", children: order.map((key, index) => {
|
|
12110
|
+
const column = byKey.get(key);
|
|
12111
|
+
if (!column) return null;
|
|
12112
|
+
const locked = Boolean(column.locked);
|
|
12113
|
+
const hideable = !locked && column.hideable !== false;
|
|
12114
|
+
const canUp = moveColumn(order, key, -1, isLocked) !== null;
|
|
12115
|
+
const canDown = moveColumn(order, key, 1, isLocked) !== null;
|
|
12116
|
+
return (
|
|
12117
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- Alt+Arrow reorder and drop target on the focusable row; the checkbox and move buttons are the named controls
|
|
12118
|
+
/* @__PURE__ */ jsxs(
|
|
12119
|
+
"li",
|
|
12120
|
+
{
|
|
12121
|
+
ref: (el) => {
|
|
12122
|
+
if (el) rowRefs.current.set(key, el);
|
|
12123
|
+
else rowRefs.current.delete(key);
|
|
12124
|
+
},
|
|
12125
|
+
tabIndex: -1,
|
|
12126
|
+
"aria-label": `${column.label}, ${index + 1} / ${order.length}${locked ? `, ${messages.locked}` : ""}`,
|
|
12127
|
+
onDragStart: (event) => {
|
|
12128
|
+
if (!event.target.closest("[data-dm-grip]")) {
|
|
12129
|
+
event.preventDefault();
|
|
12130
|
+
return;
|
|
12131
|
+
}
|
|
12132
|
+
event.dataTransfer.effectAllowed = "move";
|
|
12133
|
+
setDragging(key);
|
|
12134
|
+
},
|
|
12135
|
+
onDragEnd: () => setDragging(null),
|
|
12136
|
+
onDragOver: (event) => {
|
|
12137
|
+
if (dragging && !locked) event.preventDefault();
|
|
12138
|
+
},
|
|
12139
|
+
onDrop: (event) => onDrop(event, key),
|
|
12140
|
+
onKeyDown: (event) => {
|
|
12141
|
+
if (event.altKey && (event.key === "ArrowUp" || event.key === "ArrowDown")) {
|
|
12142
|
+
event.preventDefault();
|
|
12143
|
+
event.stopPropagation();
|
|
12144
|
+
move(key, event.key === "ArrowUp" ? -1 : 1);
|
|
12145
|
+
}
|
|
12146
|
+
},
|
|
12147
|
+
className: cn(
|
|
12148
|
+
"ds:flex ds:items-center ds:gap-1.5 ds:rounded-md ds:px-1 ds:py-1",
|
|
12149
|
+
"ds:transition-colors ds:hover:bg-surface-hover/60 ds:motion-reduce:transition-none",
|
|
12150
|
+
"ds:focus-visible:outline-none ds:focus-visible:[box-shadow:var(--shadow-focus-ring)]",
|
|
12151
|
+
dragging === key && "ds:opacity-50"
|
|
12152
|
+
),
|
|
12153
|
+
children: [
|
|
12154
|
+
/* @__PURE__ */ jsx(
|
|
12155
|
+
"span",
|
|
12156
|
+
{
|
|
12157
|
+
"data-dm-grip": "",
|
|
12158
|
+
draggable: !locked,
|
|
12159
|
+
"aria-hidden": "true",
|
|
12160
|
+
className: cn(
|
|
12161
|
+
"ds:inline-flex ds:shrink-0 ds:text-fg-4",
|
|
12162
|
+
locked ? "ds:invisible" : "ds:cursor-grab"
|
|
12163
|
+
),
|
|
12164
|
+
children: /* @__PURE__ */ jsx(GripVerticalIcon, { size: 14 })
|
|
12165
|
+
}
|
|
12166
|
+
),
|
|
12167
|
+
/* @__PURE__ */ jsx(
|
|
12168
|
+
Checkbox,
|
|
12169
|
+
{
|
|
12170
|
+
checked: !spec.hidden.has(key),
|
|
12171
|
+
disabled: !hideable,
|
|
12172
|
+
"aria-label": messages.showColumn(column.label),
|
|
12173
|
+
onCheckedChange: () => toggleHidden(key),
|
|
12174
|
+
onKeyDown: (event) => {
|
|
12175
|
+
if (event.altKey && (event.key === "ArrowUp" || event.key === "ArrowDown")) {
|
|
12176
|
+
event.preventDefault();
|
|
12177
|
+
event.stopPropagation();
|
|
12178
|
+
move(key, event.key === "ArrowUp" ? -1 : 1);
|
|
12179
|
+
}
|
|
12180
|
+
}
|
|
12181
|
+
}
|
|
12182
|
+
),
|
|
12183
|
+
/* @__PURE__ */ jsx("span", { className: "ds:min-w-0 ds:flex-1 ds:truncate ds:text-(length:--control-font-size-sm) ds:text-fg", children: column.label }),
|
|
12184
|
+
locked ? /* @__PURE__ */ jsx(LockIcon, { size: 13, "aria-label": messages.locked, className: "ds:shrink-0 ds:text-fg-4" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12185
|
+
/* @__PURE__ */ jsx(
|
|
12186
|
+
IconButton,
|
|
12187
|
+
{
|
|
12188
|
+
variant: "ghost",
|
|
12189
|
+
intent: "neutral",
|
|
12190
|
+
size: "xs",
|
|
12191
|
+
tooltip: false,
|
|
12192
|
+
label: messages.moveUp(column.label),
|
|
12193
|
+
icon: /* @__PURE__ */ jsx(ArrowUpIcon, {}),
|
|
12194
|
+
disabled: !canUp,
|
|
12195
|
+
onClick: () => move(key, -1)
|
|
12196
|
+
}
|
|
12197
|
+
),
|
|
12198
|
+
/* @__PURE__ */ jsx(
|
|
12199
|
+
IconButton,
|
|
12200
|
+
{
|
|
12201
|
+
variant: "ghost",
|
|
12202
|
+
intent: "neutral",
|
|
12203
|
+
size: "xs",
|
|
12204
|
+
tooltip: false,
|
|
12205
|
+
label: messages.moveDown(column.label),
|
|
12206
|
+
icon: /* @__PURE__ */ jsx(ArrowDownIcon, {}),
|
|
12207
|
+
disabled: !canDown,
|
|
12208
|
+
onClick: () => move(key, 1)
|
|
12209
|
+
}
|
|
12210
|
+
)
|
|
12211
|
+
] })
|
|
12212
|
+
]
|
|
12213
|
+
},
|
|
12214
|
+
key
|
|
12215
|
+
)
|
|
12216
|
+
);
|
|
12217
|
+
}) }),
|
|
12218
|
+
spec.onReset && /* @__PURE__ */ jsx("div", { className: "ds:flex ds:justify-end ds:border-t ds:border-rule ds:p-1", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: spec.onReset, className: "ds:h-6 ds:px-2 ds:text-fg-3", children: messages.resetColumns }) })
|
|
12219
|
+
] });
|
|
12220
|
+
}
|
|
12221
|
+
var SEARCH_THRESHOLD = 8;
|
|
12222
|
+
function DisplayMenuOperatorPicker({ section }) {
|
|
12223
|
+
const messages = useFilterMessages();
|
|
12224
|
+
const operators = section.operators ?? [];
|
|
12225
|
+
const current = displayMenuSectionOperator(section) ?? null;
|
|
12226
|
+
if (operators.length < 2) return null;
|
|
12227
|
+
return /* @__PURE__ */ jsx("div", { className: "ds:shrink-0 ds:border-b ds:border-rule", children: /* @__PURE__ */ jsx(
|
|
12228
|
+
ChoiceList,
|
|
12229
|
+
{
|
|
12230
|
+
inline: true,
|
|
12231
|
+
label: messages.operator,
|
|
12232
|
+
choices: operators.map((op) => ({ value: op, label: displayMenuOperatorLabel(op, messages) })),
|
|
12233
|
+
value: current,
|
|
12234
|
+
onChange: (op) => section.onOperatorChange?.(op)
|
|
12235
|
+
}
|
|
12236
|
+
) });
|
|
12237
|
+
}
|
|
12238
|
+
function DisplayMenuSpecPanel({ section, onDone }) {
|
|
12239
|
+
const spec = section.spec;
|
|
12240
|
+
if (!spec) return null;
|
|
12241
|
+
switch (spec.kind) {
|
|
12242
|
+
case "person":
|
|
12243
|
+
case "tags":
|
|
12244
|
+
return /* @__PURE__ */ jsx(ValueListPanel, { section, spec });
|
|
12245
|
+
case "date":
|
|
12246
|
+
return /* @__PURE__ */ jsx(DatePanel, { spec });
|
|
12247
|
+
case "number":
|
|
12248
|
+
return /* @__PURE__ */ jsx(NumberPanel, { spec });
|
|
12249
|
+
case "text":
|
|
12250
|
+
return /* @__PURE__ */ jsx(TextPanel, { spec, label: section.label });
|
|
12251
|
+
case "boolean":
|
|
12252
|
+
return /* @__PURE__ */ jsx(BooleanPanel, { spec, label: section.label, onDone });
|
|
12253
|
+
case "sort":
|
|
12254
|
+
return /* @__PURE__ */ jsx(SortPanel, { spec });
|
|
12255
|
+
case "columns":
|
|
12256
|
+
return /* @__PURE__ */ jsx(ColumnsPanel, { spec });
|
|
12257
|
+
default:
|
|
12258
|
+
return null;
|
|
12259
|
+
}
|
|
12260
|
+
}
|
|
12261
|
+
function ValueListPanel({
|
|
12262
|
+
section,
|
|
12263
|
+
spec
|
|
12264
|
+
}) {
|
|
12265
|
+
const messages = useFilterMessages();
|
|
12266
|
+
const [query, setQuery] = useState("");
|
|
12267
|
+
const listRef = useRef(null);
|
|
12268
|
+
const operator = displayMenuSectionOperator(section);
|
|
12269
|
+
const emptiness = operator === "isEmpty" || operator === "isNotEmpty";
|
|
12270
|
+
const pinnedKeys = spec.kind === "person" ? [spec.meKey, spec.unassignedKey].filter((k) => k !== void 0) : [];
|
|
12271
|
+
const options = visibleDisplayMenuOptions(section, query, pinnedKeys);
|
|
12272
|
+
const searchable = section.searchable ?? section.options.length > SEARCH_THRESHOLD;
|
|
12273
|
+
const matchId = useId();
|
|
12274
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col", children: [
|
|
12275
|
+
spec.kind === "tags" && /* @__PURE__ */ jsxs("div", { className: "ds:border-b ds:border-rule ds:pb-1", children: [
|
|
12276
|
+
/* @__PURE__ */ jsx(PanelHeading, { id: matchId, children: messages.tagMatch }),
|
|
12277
|
+
/* @__PURE__ */ jsx(
|
|
12278
|
+
ChoiceList,
|
|
12279
|
+
{
|
|
12280
|
+
inline: true,
|
|
12281
|
+
labelledBy: matchId,
|
|
12282
|
+
choices: [
|
|
12283
|
+
{ value: "any", label: messages.tagMatchAny },
|
|
12284
|
+
{ value: "all", label: messages.tagMatchAll }
|
|
12285
|
+
],
|
|
12286
|
+
value: spec.tagMatch,
|
|
12287
|
+
onChange: spec.onTagMatchChange
|
|
12288
|
+
}
|
|
12289
|
+
)
|
|
12290
|
+
] }),
|
|
12291
|
+
!emptiness && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12292
|
+
searchable && /* @__PURE__ */ jsx(
|
|
12293
|
+
PanelSearch,
|
|
12294
|
+
{
|
|
12295
|
+
value: query,
|
|
12296
|
+
onChange: setQuery,
|
|
12297
|
+
label: messages.search(section.label),
|
|
12298
|
+
onArrowDown: () => listRef.current?.querySelector("[data-dm-nav]")?.focus()
|
|
12299
|
+
}
|
|
12300
|
+
),
|
|
12301
|
+
/* @__PURE__ */ jsx("div", { ref: listRef, onKeyDown: onListArrowKeys, className: "ds:p-1", children: options.length === 0 ? /* @__PURE__ */ jsx(PanelEmpty, { children: messages.noMatches }) : options.map((option) => /* @__PURE__ */ jsx(
|
|
12302
|
+
CheckOptionRow,
|
|
12303
|
+
{
|
|
12304
|
+
checked: section.selected.has(option.key),
|
|
12305
|
+
onToggle: () => section.onSelect(option.key),
|
|
12306
|
+
label: displayMenuOptionLabel(section, option, messages),
|
|
12307
|
+
icon: option.icon,
|
|
12308
|
+
count: option.count
|
|
12309
|
+
},
|
|
12310
|
+
option.key
|
|
12311
|
+
)) }),
|
|
12312
|
+
section.onClear && section.selected.size > 0 && /* @__PURE__ */ jsx(PanelFooter, { children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: section.onClear, className: "ds:h-6 ds:px-2 ds:text-fg-3", children: messages.clear }) })
|
|
12313
|
+
] })
|
|
12314
|
+
] });
|
|
12315
|
+
}
|
|
12316
|
+
function PanelFooter({ children }) {
|
|
12317
|
+
return /* @__PURE__ */ jsx("div", { className: "ds:flex ds:items-center ds:justify-end ds:gap-1 ds:border-t ds:border-rule ds:p-1", children });
|
|
12318
|
+
}
|
|
12319
|
+
function DatePanel({ spec }) {
|
|
12320
|
+
const messages = useFilterMessages();
|
|
12321
|
+
const now = spec.now ?? /* @__PURE__ */ new Date();
|
|
12322
|
+
const presets = spec.presets ?? DISPLAY_MENU_DATE_PRESETS;
|
|
12323
|
+
const active = effectiveDisplayMenuDatePreset(spec.value, now, presets);
|
|
12324
|
+
const [showCustom, setShowCustom] = useState(active === "custom");
|
|
12325
|
+
const dueId = useId();
|
|
12326
|
+
const calendarId = useId();
|
|
12327
|
+
const fromId = useId();
|
|
12328
|
+
const toId = useId();
|
|
12329
|
+
const due = presets.filter((p) => isDisplayMenuDuePreset(p));
|
|
12330
|
+
const calendar = presets.filter(
|
|
12331
|
+
(p) => p !== "custom" && DISPLAY_MENU_CALENDAR_PRESETS.includes(p)
|
|
12332
|
+
);
|
|
12333
|
+
const offersCustom = presets.includes("custom");
|
|
12334
|
+
const choose = (preset) => {
|
|
12335
|
+
if (preset === "custom") {
|
|
12336
|
+
setShowCustom(true);
|
|
12337
|
+
spec.onChange({ preset: "custom", range: spec.value?.range });
|
|
12338
|
+
return;
|
|
12339
|
+
}
|
|
12340
|
+
setShowCustom(false);
|
|
12341
|
+
spec.onChange({ preset, range: resolveDisplayMenuDatePreset(preset, now) });
|
|
12342
|
+
};
|
|
12343
|
+
const toChoices = (list) => list.map((p) => ({ value: p, label: displayMenuDatePresetLabel(p, messages) }));
|
|
12344
|
+
const range2 = spec.value?.range ?? {};
|
|
12345
|
+
const setRange = (next) => spec.onChange({ preset: "custom", range: { ...range2, ...next } });
|
|
12346
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:p-1", children: [
|
|
12347
|
+
due.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12348
|
+
/* @__PURE__ */ jsx(PanelHeading, { id: dueId, children: messages.dateDue }),
|
|
12349
|
+
/* @__PURE__ */ jsx(ChoiceList, { labelledBy: dueId, choices: toChoices(due), value: active, onChange: choose })
|
|
12350
|
+
] }),
|
|
12351
|
+
(calendar.length > 0 || offersCustom) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12352
|
+
/* @__PURE__ */ jsx(PanelHeading, { id: calendarId, children: messages.dateCalendar }),
|
|
12353
|
+
/* @__PURE__ */ jsx(
|
|
12354
|
+
ChoiceList,
|
|
12355
|
+
{
|
|
12356
|
+
labelledBy: calendarId,
|
|
12357
|
+
choices: toChoices(offersCustom ? [...calendar, "custom"] : calendar),
|
|
12358
|
+
value: showCustom ? "custom" : active,
|
|
12359
|
+
onChange: choose
|
|
12360
|
+
}
|
|
12361
|
+
)
|
|
12362
|
+
] }),
|
|
12363
|
+
showCustom && /* @__PURE__ */ jsxs("div", { className: "ds:grid ds:grid-cols-2 ds:gap-2 ds:px-2 ds:pt-2 ds:pb-1", children: [
|
|
12364
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:gap-1", children: [
|
|
12365
|
+
/* @__PURE__ */ jsx(Label2, { htmlFor: fromId, className: "ds:text-(length:--text-helper) ds:text-fg-3", children: messages.dateFrom }),
|
|
12366
|
+
/* @__PURE__ */ jsx(
|
|
12367
|
+
Input,
|
|
12368
|
+
{
|
|
12369
|
+
id: fromId,
|
|
12370
|
+
type: "date",
|
|
12371
|
+
size: "sm",
|
|
12372
|
+
value: range2.from ?? "",
|
|
12373
|
+
max: range2.to,
|
|
12374
|
+
onKeyDown: keepTypingInField,
|
|
12375
|
+
onChange: (e) => setRange({ from: e.target.value || void 0 })
|
|
12376
|
+
}
|
|
12377
|
+
)
|
|
12378
|
+
] }),
|
|
12379
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:gap-1", children: [
|
|
12380
|
+
/* @__PURE__ */ jsx(Label2, { htmlFor: toId, className: "ds:text-(length:--text-helper) ds:text-fg-3", children: messages.dateTo }),
|
|
12381
|
+
/* @__PURE__ */ jsx(
|
|
12382
|
+
Input,
|
|
12383
|
+
{
|
|
12384
|
+
id: toId,
|
|
12385
|
+
type: "date",
|
|
12386
|
+
size: "sm",
|
|
12387
|
+
value: range2.to ?? "",
|
|
12388
|
+
min: range2.from,
|
|
12389
|
+
onKeyDown: keepTypingInField,
|
|
12390
|
+
onChange: (e) => setRange({ to: e.target.value || void 0 })
|
|
12391
|
+
}
|
|
12392
|
+
)
|
|
12393
|
+
] })
|
|
12394
|
+
] }),
|
|
12395
|
+
spec.value && /* @__PURE__ */ jsx(PanelFooter, { children: /* @__PURE__ */ jsx(
|
|
12396
|
+
Button,
|
|
12397
|
+
{
|
|
12398
|
+
variant: "ghost",
|
|
10340
12399
|
size: "sm",
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
12400
|
+
onClick: () => {
|
|
12401
|
+
setShowCustom(false);
|
|
12402
|
+
spec.onChange(null);
|
|
12403
|
+
},
|
|
12404
|
+
className: "ds:h-6 ds:px-2 ds:text-fg-3",
|
|
12405
|
+
children: messages.clear
|
|
10345
12406
|
}
|
|
12407
|
+
) })
|
|
12408
|
+
] });
|
|
12409
|
+
}
|
|
12410
|
+
var NUMBER_OPERATORS = ["eq", "ne", "lt", "lte", "gt", "gte", "between"];
|
|
12411
|
+
function NumberPanel({ spec }) {
|
|
12412
|
+
const messages = useFilterMessages();
|
|
12413
|
+
const operator = spec.value?.operator ?? "gt";
|
|
12414
|
+
const show = (n) => n === null || n === void 0 ? "" : formatDisplayMenuNumber(n, spec.format ?? "number");
|
|
12415
|
+
const [draft, setDraft] = useState({ value: show(spec.value?.value), to: show(spec.value?.to) });
|
|
12416
|
+
const [invalid, setInvalid] = useState({ value: false, to: false });
|
|
12417
|
+
const valueId = useId();
|
|
12418
|
+
const toId = useId();
|
|
12419
|
+
const errorId = useId();
|
|
12420
|
+
const commit = (nextOperator, nextDraft = draft) => {
|
|
12421
|
+
const value = nextDraft.value.trim() === "" ? null : parseDisplayMenuNumber(nextDraft.value);
|
|
12422
|
+
const to = nextDraft.to.trim() === "" ? null : parseDisplayMenuNumber(nextDraft.to);
|
|
12423
|
+
const bad = {
|
|
12424
|
+
value: nextDraft.value.trim() !== "" && value === null,
|
|
12425
|
+
to: nextOperator === "between" && nextDraft.to.trim() !== "" && to === null
|
|
12426
|
+
};
|
|
12427
|
+
setInvalid(bad);
|
|
12428
|
+
if (bad.value || bad.to) return;
|
|
12429
|
+
if (value === null) {
|
|
12430
|
+
spec.onChange(null);
|
|
12431
|
+
return;
|
|
12432
|
+
}
|
|
12433
|
+
spec.onChange(
|
|
12434
|
+
nextOperator === "between" ? { operator: nextOperator, value, to } : { operator: nextOperator, value }
|
|
10346
12435
|
);
|
|
10347
|
-
}
|
|
10348
|
-
)
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
12436
|
+
};
|
|
12437
|
+
const field = (key, id, label) => /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:gap-1", children: [
|
|
12438
|
+
/* @__PURE__ */ jsx(Label2, { htmlFor: id, className: "ds:text-(length:--text-helper) ds:text-fg-3", children: label }),
|
|
12439
|
+
/* @__PURE__ */ jsx(
|
|
12440
|
+
Input,
|
|
12441
|
+
{
|
|
12442
|
+
id,
|
|
12443
|
+
size: "sm",
|
|
12444
|
+
inputMode: "decimal",
|
|
12445
|
+
value: draft[key],
|
|
12446
|
+
"aria-invalid": invalid[key] || void 0,
|
|
12447
|
+
"aria-describedby": invalid[key] ? errorId : void 0,
|
|
12448
|
+
onChange: (e) => setDraft((d) => ({ ...d, [key]: e.target.value })),
|
|
12449
|
+
onBlur: () => commit(operator),
|
|
12450
|
+
onKeyDown: (e) => {
|
|
12451
|
+
keepTypingInField(e);
|
|
12452
|
+
if (e.key === "Enter") {
|
|
12453
|
+
e.preventDefault();
|
|
12454
|
+
commit(operator);
|
|
12455
|
+
}
|
|
12456
|
+
}
|
|
12457
|
+
}
|
|
12458
|
+
)
|
|
12459
|
+
] });
|
|
12460
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:p-1", children: [
|
|
12461
|
+
/* @__PURE__ */ jsx(
|
|
12462
|
+
ChoiceList,
|
|
12463
|
+
{
|
|
12464
|
+
inline: true,
|
|
12465
|
+
label: messages.operator,
|
|
12466
|
+
choices: NUMBER_OPERATORS.map((op) => ({ value: op, label: displayMenuNumberOperatorLabel(op, messages) })),
|
|
12467
|
+
value: operator,
|
|
12468
|
+
onChange: (op) => commit(op)
|
|
12469
|
+
}
|
|
12470
|
+
),
|
|
12471
|
+
/* @__PURE__ */ jsxs("div", { className: cn("ds:grid ds:gap-2 ds:px-1 ds:pt-1 ds:pb-1", operator === "between" ? "ds:grid-cols-2" : "ds:grid-cols-1"), children: [
|
|
12472
|
+
field("value", valueId, operator === "between" ? messages.numberMin : messages.numberValue),
|
|
12473
|
+
operator === "between" && field("to", toId, messages.numberMax)
|
|
12474
|
+
] }),
|
|
12475
|
+
(invalid.value || invalid.to) && /* @__PURE__ */ jsx("p", { id: errorId, className: "ds:px-2 ds:pb-1 ds:text-(length:--text-helper) ds:text-danger-fg", children: messages.numberInvalid }),
|
|
12476
|
+
spec.value && /* @__PURE__ */ jsx(PanelFooter, { children: /* @__PURE__ */ jsx(
|
|
12477
|
+
Button,
|
|
12478
|
+
{
|
|
12479
|
+
variant: "ghost",
|
|
12480
|
+
size: "sm",
|
|
12481
|
+
onClick: () => {
|
|
12482
|
+
setDraft({ value: "", to: "" });
|
|
12483
|
+
setInvalid({ value: false, to: false });
|
|
12484
|
+
spec.onChange(null);
|
|
12485
|
+
},
|
|
12486
|
+
className: "ds:h-6 ds:px-2 ds:text-fg-3",
|
|
12487
|
+
children: messages.clear
|
|
12488
|
+
}
|
|
12489
|
+
) })
|
|
12490
|
+
] });
|
|
12491
|
+
}
|
|
12492
|
+
function TextPanel({
|
|
12493
|
+
spec,
|
|
12494
|
+
label
|
|
12495
|
+
}) {
|
|
12496
|
+
const messages = useFilterMessages();
|
|
12497
|
+
const operator = spec.value?.operator ?? "contains";
|
|
12498
|
+
const text = spec.value?.text ?? "";
|
|
12499
|
+
const set = (next) => {
|
|
12500
|
+
const value = { operator: next.operator ?? operator, text: next.text ?? text };
|
|
12501
|
+
spec.onChange(value.text === "" ? next.operator ? { ...value } : null : value);
|
|
12502
|
+
};
|
|
12503
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:flex-col ds:p-1", children: [
|
|
12504
|
+
/* @__PURE__ */ jsx(
|
|
12505
|
+
ChoiceList,
|
|
12506
|
+
{
|
|
12507
|
+
inline: true,
|
|
12508
|
+
label: messages.operator,
|
|
12509
|
+
choices: [
|
|
12510
|
+
{ value: "contains", label: messages.textContains },
|
|
12511
|
+
{ value: "startsWith", label: messages.textStartsWith }
|
|
12512
|
+
],
|
|
12513
|
+
value: operator,
|
|
12514
|
+
onChange: (op) => set({ operator: op })
|
|
12515
|
+
}
|
|
12516
|
+
),
|
|
12517
|
+
/* @__PURE__ */ jsx("div", { className: "ds:px-1 ds:pt-1 ds:pb-1", children: /* @__PURE__ */ jsx(
|
|
12518
|
+
Input,
|
|
12519
|
+
{
|
|
12520
|
+
size: "sm",
|
|
12521
|
+
value: text,
|
|
12522
|
+
"aria-label": `${label}, ${messages.textValue}`,
|
|
12523
|
+
placeholder: spec.placeholder,
|
|
12524
|
+
onKeyDown: keepTypingInField,
|
|
12525
|
+
onChange: (e) => set({ text: e.target.value })
|
|
12526
|
+
}
|
|
12527
|
+
) })
|
|
12528
|
+
] });
|
|
12529
|
+
}
|
|
12530
|
+
function BooleanPanel({
|
|
12531
|
+
spec,
|
|
12532
|
+
label,
|
|
12533
|
+
onDone
|
|
12534
|
+
}) {
|
|
12535
|
+
const messages = useFilterMessages();
|
|
12536
|
+
const value = spec.value === null ? "any" : spec.value ? "true" : "false";
|
|
12537
|
+
return /* @__PURE__ */ jsx("div", { className: "ds:p-1", children: /* @__PURE__ */ jsx(
|
|
12538
|
+
ChoiceList,
|
|
10359
12539
|
{
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
12540
|
+
label,
|
|
12541
|
+
choices: [
|
|
12542
|
+
{ value: "any", label: messages.booleanAny },
|
|
12543
|
+
{ value: "true", label: spec.trueLabel ?? messages.booleanTrue },
|
|
12544
|
+
{ value: "false", label: spec.falseLabel ?? messages.booleanFalse }
|
|
12545
|
+
],
|
|
12546
|
+
value,
|
|
12547
|
+
onChange: (next) => {
|
|
12548
|
+
spec.onChange(next === "any" ? null : next === "true");
|
|
12549
|
+
if (typeof window !== "undefined" && window.event instanceof MouseEvent) onDone?.();
|
|
12550
|
+
}
|
|
10367
12551
|
}
|
|
12552
|
+
) });
|
|
12553
|
+
}
|
|
12554
|
+
var MENU_ITEM_SELECTOR = '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]';
|
|
12555
|
+
var FOCUSABLE_SELECTOR = 'input:not([disabled]),button:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
12556
|
+
var TYPEAHEAD_RESET_MS = 500;
|
|
12557
|
+
function menuItems(container) {
|
|
12558
|
+
return Array.from(container.querySelectorAll(MENU_ITEM_SELECTOR)).filter(
|
|
12559
|
+
(item) => !item.hasAttribute("disabled") && item.getAttribute("aria-disabled") !== "true" && item.getAttribute("data-disabled") === null
|
|
10368
12560
|
);
|
|
10369
|
-
}
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
return
|
|
10381
|
-
}
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
12561
|
+
}
|
|
12562
|
+
function labelOf(item) {
|
|
12563
|
+
return (item.getAttribute("data-typeahead") ?? item.textContent ?? "").trim().toLowerCase();
|
|
12564
|
+
}
|
|
12565
|
+
function typeaheadMatch(items, from, query) {
|
|
12566
|
+
if (items.length === 0 || !query) return void 0;
|
|
12567
|
+
const start = query.length === 1 ? from + 1 : Math.max(from, 0);
|
|
12568
|
+
for (let offset = 0; offset < items.length; offset += 1) {
|
|
12569
|
+
const item = items[(start + offset + items.length) % items.length];
|
|
12570
|
+
if (item && labelOf(item).startsWith(query)) return item;
|
|
12571
|
+
}
|
|
12572
|
+
return void 0;
|
|
12573
|
+
}
|
|
12574
|
+
function useRovingMenu() {
|
|
12575
|
+
const buffer = useRef("");
|
|
12576
|
+
const timer = useRef(null);
|
|
12577
|
+
useEffect(
|
|
12578
|
+
() => () => {
|
|
12579
|
+
if (timer.current) clearTimeout(timer.current);
|
|
12580
|
+
},
|
|
12581
|
+
[]
|
|
12582
|
+
);
|
|
12583
|
+
return useCallback((event) => {
|
|
12584
|
+
if (event.defaultPrevented) return;
|
|
12585
|
+
const target = event.target;
|
|
12586
|
+
if (target.closest("input, textarea, select, [contenteditable='true']")) return;
|
|
12587
|
+
const items = menuItems(event.currentTarget);
|
|
12588
|
+
if (items.length === 0) return;
|
|
12589
|
+
const current = target.closest(MENU_ITEM_SELECTOR);
|
|
12590
|
+
const index = current ? items.indexOf(current) : -1;
|
|
12591
|
+
let next;
|
|
12592
|
+
switch (event.key) {
|
|
12593
|
+
case "ArrowDown":
|
|
12594
|
+
next = items[(index + 1) % items.length];
|
|
12595
|
+
break;
|
|
12596
|
+
case "ArrowUp":
|
|
12597
|
+
next = items[index <= 0 ? items.length - 1 : index - 1];
|
|
12598
|
+
break;
|
|
12599
|
+
case "Home":
|
|
12600
|
+
next = items[0];
|
|
12601
|
+
break;
|
|
12602
|
+
case "End":
|
|
12603
|
+
next = items[items.length - 1];
|
|
12604
|
+
break;
|
|
12605
|
+
default: {
|
|
12606
|
+
const printable = event.key.length === 1 && event.key !== " " && !event.ctrlKey && !event.metaKey && !event.altKey;
|
|
12607
|
+
if (!printable) return;
|
|
12608
|
+
if (timer.current) clearTimeout(timer.current);
|
|
12609
|
+
buffer.current += event.key.toLowerCase();
|
|
12610
|
+
timer.current = setTimeout(() => {
|
|
12611
|
+
buffer.current = "";
|
|
12612
|
+
}, TYPEAHEAD_RESET_MS);
|
|
12613
|
+
next = typeaheadMatch(items, index, buffer.current);
|
|
12614
|
+
}
|
|
12615
|
+
}
|
|
12616
|
+
if (next) {
|
|
12617
|
+
event.preventDefault();
|
|
12618
|
+
next.focus();
|
|
12619
|
+
}
|
|
12620
|
+
}, []);
|
|
12621
|
+
}
|
|
12622
|
+
function DisplayMenuViewsBar({
|
|
12623
|
+
views,
|
|
12624
|
+
messages,
|
|
12625
|
+
onAnnounce,
|
|
12626
|
+
listOpen,
|
|
12627
|
+
onListOpenChange: setListOpen
|
|
12628
|
+
}) {
|
|
12629
|
+
const listId = useId();
|
|
12630
|
+
const roving = useRovingMenu();
|
|
12631
|
+
const active = views.items.find((v) => v.key === views.activeKey);
|
|
12632
|
+
const activeLabel = active?.label ?? messages.noView;
|
|
12633
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:border-b ds:border-rule", children: [
|
|
12634
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:items-center ds:gap-1 ds:px-1.5 ds:py-1", children: [
|
|
12635
|
+
/* @__PURE__ */ jsxs(
|
|
12636
|
+
Button,
|
|
12637
|
+
{
|
|
12638
|
+
variant: "ghost",
|
|
12639
|
+
size: "sm",
|
|
12640
|
+
"aria-haspopup": "menu",
|
|
12641
|
+
"aria-expanded": listOpen,
|
|
12642
|
+
"aria-controls": listOpen ? listId : void 0,
|
|
12643
|
+
onClick: () => setListOpen(!listOpen),
|
|
12644
|
+
onKeyDown: (event) => {
|
|
12645
|
+
if (event.key === "ArrowDown") {
|
|
12646
|
+
event.preventDefault();
|
|
12647
|
+
setListOpen(true);
|
|
12648
|
+
requestAnimationFrame(
|
|
12649
|
+
() => document.getElementById(listId)?.querySelector('[aria-checked="true"], [role="menuitemradio"]')?.focus()
|
|
12650
|
+
);
|
|
12651
|
+
}
|
|
12652
|
+
},
|
|
12653
|
+
className: "ds:h-7 ds:min-w-0 ds:flex-1 ds:justify-start ds:gap-1.5 ds:px-2",
|
|
12654
|
+
children: [
|
|
12655
|
+
/* @__PURE__ */ jsx("span", { className: "ds:text-fg-3", children: messages.views }),
|
|
12656
|
+
/* @__PURE__ */ jsx("span", { className: "ds:min-w-0 ds:truncate ds:text-fg", children: activeLabel }),
|
|
12657
|
+
views.dirty && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12658
|
+
/* @__PURE__ */ jsx(
|
|
12659
|
+
"span",
|
|
12660
|
+
{
|
|
12661
|
+
"data-dirty": "",
|
|
12662
|
+
"aria-hidden": "true",
|
|
12663
|
+
className: "ds:size-1.5 ds:shrink-0 ds:rounded-full ds:bg-brand"
|
|
12664
|
+
}
|
|
12665
|
+
),
|
|
12666
|
+
/* @__PURE__ */ jsxs(VisuallyHidden, { children: [
|
|
12667
|
+
", ",
|
|
12668
|
+
messages.unsavedChanges
|
|
12669
|
+
] })
|
|
12670
|
+
] }),
|
|
12671
|
+
/* @__PURE__ */ jsx(
|
|
12672
|
+
ChevronDownIcon,
|
|
12673
|
+
{
|
|
12674
|
+
size: 13,
|
|
12675
|
+
"aria-hidden": "true",
|
|
12676
|
+
className: cn(
|
|
12677
|
+
"ds:ms-auto ds:shrink-0 ds:text-fg-3 ds:transition-transform ds:motion-reduce:transition-none",
|
|
12678
|
+
listOpen && "ds:rotate-180"
|
|
12679
|
+
)
|
|
12680
|
+
}
|
|
12681
|
+
)
|
|
12682
|
+
]
|
|
12683
|
+
}
|
|
12684
|
+
),
|
|
12685
|
+
views.onSave && /* @__PURE__ */ jsx(
|
|
12686
|
+
Button,
|
|
12687
|
+
{
|
|
12688
|
+
variant: "ghost",
|
|
12689
|
+
size: "sm",
|
|
12690
|
+
onClick: views.onSave,
|
|
12691
|
+
className: "ds:h-7 ds:shrink-0 ds:px-2 ds:text-fg-3 ds:hover:text-fg",
|
|
12692
|
+
children: messages.saveView
|
|
12693
|
+
}
|
|
12694
|
+
)
|
|
12695
|
+
] }),
|
|
12696
|
+
listOpen && /* @__PURE__ */ jsx(
|
|
12697
|
+
DisplayMenuList,
|
|
12698
|
+
{
|
|
12699
|
+
id: listId,
|
|
12700
|
+
"aria-label": messages.views,
|
|
12701
|
+
onKeyDown: roving,
|
|
12702
|
+
className: "ds:max-h-48 ds:overflow-y-auto ds:pt-0",
|
|
12703
|
+
children: views.items.map((view) => /* @__PURE__ */ jsxs(
|
|
12704
|
+
DisplayMenuItem,
|
|
12705
|
+
{
|
|
12706
|
+
kind: "radio",
|
|
12707
|
+
checked: view.key === views.activeKey,
|
|
12708
|
+
onClick: () => {
|
|
12709
|
+
views.onSelect(view.key);
|
|
12710
|
+
onAnnounce(messages.announceView(view.label));
|
|
12711
|
+
setListOpen(false);
|
|
12712
|
+
},
|
|
12713
|
+
children: [
|
|
12714
|
+
view.label,
|
|
12715
|
+
view.description && /* @__PURE__ */ jsx("span", { className: "ds:block ds:truncate ds:text-(length:--text-caption) ds:text-fg-3", children: view.description })
|
|
12716
|
+
]
|
|
12717
|
+
},
|
|
12718
|
+
view.key
|
|
12719
|
+
))
|
|
12720
|
+
}
|
|
12721
|
+
)
|
|
12722
|
+
] });
|
|
12723
|
+
}
|
|
12724
|
+
var SEARCH_THRESHOLD2 = 8;
|
|
10392
12725
|
var HOVER_OPEN_MS = 90;
|
|
10393
12726
|
var HOVER_CLOSE_MS = 220;
|
|
10394
12727
|
var FLYOUT_WIDTH = 224;
|
|
12728
|
+
var WIDE_FLYOUT_WIDTH = 288;
|
|
12729
|
+
var WIDE_KINDS = /* @__PURE__ */ new Set(["date", "number", "text", "sort", "columns"]);
|
|
10395
12730
|
var MIN_FLYOUT_HEIGHT = 120;
|
|
10396
12731
|
var VIEWPORT_MARGIN = 24;
|
|
10397
12732
|
var COLLISION_PADDING_PX = 12;
|
|
12733
|
+
function flyoutWidthFor(section) {
|
|
12734
|
+
return section?.spec && WIDE_KINDS.has(section.spec.kind) ? WIDE_FLYOUT_WIDTH : FLYOUT_WIDTH;
|
|
12735
|
+
}
|
|
12736
|
+
function usesFilterSummary(section) {
|
|
12737
|
+
return section.spec !== void 0 || section.operators !== void 0;
|
|
12738
|
+
}
|
|
10398
12739
|
function DisplayMenu({
|
|
10399
12740
|
sections,
|
|
10400
12741
|
onReset,
|
|
10401
12742
|
isAtDefault,
|
|
10402
|
-
tooltip
|
|
12743
|
+
tooltip: tooltipProp,
|
|
10403
12744
|
dataTour,
|
|
10404
12745
|
triggerIcon,
|
|
10405
|
-
triggerLabel
|
|
12746
|
+
triggerLabel: triggerLabelProp,
|
|
10406
12747
|
className,
|
|
10407
|
-
flyoutSide = "auto"
|
|
12748
|
+
flyoutSide = "auto",
|
|
12749
|
+
activeCount,
|
|
12750
|
+
match,
|
|
12751
|
+
onMatchChange,
|
|
12752
|
+
density,
|
|
12753
|
+
onDensityChange,
|
|
12754
|
+
views,
|
|
12755
|
+
open: openProp,
|
|
12756
|
+
defaultOpen = false,
|
|
12757
|
+
onOpenChange,
|
|
12758
|
+
openSection: openSectionProp,
|
|
12759
|
+
onOpenSectionChange,
|
|
12760
|
+
messages: messagesProp
|
|
10408
12761
|
}) {
|
|
10409
|
-
const
|
|
10410
|
-
const
|
|
12762
|
+
const messages = useDsMessages("displayMenu", messagesProp);
|
|
12763
|
+
const filterMessages = useDsMessages("displayMenuFilters");
|
|
12764
|
+
const triggerLabel = triggerLabelProp ?? messages.trigger;
|
|
12765
|
+
const tooltip = tooltipProp ?? messages.tooltip;
|
|
12766
|
+
const [open, setOpen] = useControllableState({
|
|
12767
|
+
prop: openProp,
|
|
12768
|
+
defaultProp: defaultOpen,
|
|
12769
|
+
onChange: onOpenChange
|
|
12770
|
+
});
|
|
12771
|
+
const [openKey, setOpenKeyState] = useControllableState({
|
|
12772
|
+
prop: openSectionProp,
|
|
12773
|
+
defaultProp: null,
|
|
12774
|
+
onChange: onOpenSectionChange
|
|
12775
|
+
});
|
|
10411
12776
|
const [flyout, setFlyout] = useState({
|
|
10412
12777
|
top: 0,
|
|
10413
12778
|
side: "left",
|
|
@@ -10415,6 +12780,11 @@ function DisplayMenu({
|
|
|
10415
12780
|
});
|
|
10416
12781
|
const [rootQuery, setRootQuery] = useState("");
|
|
10417
12782
|
const [sectionQuery, setSectionQuery] = useState("");
|
|
12783
|
+
const [viewsOpen, setViewsOpen] = useState(false);
|
|
12784
|
+
const [announcer, announce] = useAnnouncer();
|
|
12785
|
+
const headingId = useId();
|
|
12786
|
+
const rootRoving = useRovingMenu();
|
|
12787
|
+
const flyoutRoving = useRovingMenu();
|
|
10418
12788
|
const panelRef = useRef(null);
|
|
10419
12789
|
const rowRefs = useRef(/* @__PURE__ */ new Map());
|
|
10420
12790
|
const openTimer = useRef(null);
|
|
@@ -10427,30 +12797,39 @@ function DisplayMenu({
|
|
|
10427
12797
|
closeTimer.current = null;
|
|
10428
12798
|
}, []);
|
|
10429
12799
|
useEffect(() => clearTimers, [clearTimers]);
|
|
10430
|
-
const
|
|
10431
|
-
|
|
10432
|
-
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
|
|
12800
|
+
const sectionFor = useCallback(
|
|
12801
|
+
(key) => key === null ? void 0 : sections.find((s) => s.key === key),
|
|
12802
|
+
[sections]
|
|
12803
|
+
);
|
|
12804
|
+
const positionFor = useCallback(
|
|
12805
|
+
(key) => {
|
|
12806
|
+
const panel = panelRef.current;
|
|
12807
|
+
const row = rowRefs.current.get(key);
|
|
12808
|
+
if (!panel || !row) return;
|
|
12809
|
+
const panelRect = panel.getBoundingClientRect();
|
|
12810
|
+
const rowRect = row.getBoundingClientRect();
|
|
12811
|
+
const width = flyoutWidthFor(sectionFor(key));
|
|
12812
|
+
const maxTop = Math.max(0, window.innerHeight - panelRect.top - VIEWPORT_MARGIN - MIN_FLYOUT_HEIGHT);
|
|
12813
|
+
const top = Math.min(Math.max(rowRect.top - panelRect.top - 4, 0), maxTop);
|
|
12814
|
+
const maxHeight = Math.max(
|
|
12815
|
+
MIN_FLYOUT_HEIGHT,
|
|
12816
|
+
window.innerHeight - (panelRect.top + top) - VIEWPORT_MARGIN
|
|
12817
|
+
);
|
|
12818
|
+
const side = flyoutSide === "auto" ? panelRect.left >= width + 16 ? "left" : "right" : flyoutSide;
|
|
12819
|
+
setFlyout({ top, side, maxHeight });
|
|
12820
|
+
},
|
|
12821
|
+
[flyoutSide, sectionFor]
|
|
12822
|
+
);
|
|
10445
12823
|
const openSection = useCallback(
|
|
10446
12824
|
(key) => {
|
|
10447
12825
|
clearTimers();
|
|
10448
12826
|
positionFor(key);
|
|
10449
|
-
|
|
12827
|
+
setOpenKeyState(key);
|
|
10450
12828
|
setSectionQuery("");
|
|
10451
12829
|
},
|
|
10452
|
-
[clearTimers, positionFor]
|
|
12830
|
+
[clearTimers, positionFor, setOpenKeyState]
|
|
10453
12831
|
);
|
|
12832
|
+
const closeSection = useCallback(() => setOpenKeyState(null), [setOpenKeyState]);
|
|
10454
12833
|
const scheduleOpen = useCallback(
|
|
10455
12834
|
(key) => {
|
|
10456
12835
|
clearTimers();
|
|
@@ -10465,20 +12844,23 @@ function DisplayMenu({
|
|
|
10465
12844
|
);
|
|
10466
12845
|
const scheduleClose = useCallback(() => {
|
|
10467
12846
|
clearTimers();
|
|
10468
|
-
closeTimer.current = setTimeout(
|
|
10469
|
-
}, [clearTimers]);
|
|
12847
|
+
closeTimer.current = setTimeout(closeSection, HOVER_CLOSE_MS);
|
|
12848
|
+
}, [clearTimers, closeSection]);
|
|
10470
12849
|
useEffect(() => {
|
|
10471
12850
|
if (!open) {
|
|
10472
12851
|
clearTimers();
|
|
10473
|
-
|
|
12852
|
+
if (openSectionProp === void 0) setOpenKeyState(null);
|
|
10474
12853
|
setRootQuery("");
|
|
10475
12854
|
setSectionQuery("");
|
|
12855
|
+
setViewsOpen(false);
|
|
10476
12856
|
}
|
|
10477
|
-
}, [open, clearTimers]);
|
|
10478
|
-
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
12857
|
+
}, [open, clearTimers, openSectionProp, setOpenKeyState]);
|
|
12858
|
+
useLayoutEffect(() => {
|
|
12859
|
+
if (!open || openKey === null) return;
|
|
12860
|
+
const frame = requestAnimationFrame(() => positionFor(openKey));
|
|
12861
|
+
return () => cancelAnimationFrame(frame);
|
|
12862
|
+
}, [open, openKey, positionFor]);
|
|
12863
|
+
const activeSection = useMemo(() => sectionFor(openKey) ?? null, [sectionFor, openKey]);
|
|
10482
12864
|
const rootRows = useMemo(() => {
|
|
10483
12865
|
const q = rootQuery.trim().toLowerCase();
|
|
10484
12866
|
if (!q) return sections.map((section) => ({ kind: "section", section }));
|
|
@@ -10487,7 +12869,8 @@ function DisplayMenu({
|
|
|
10487
12869
|
if (section.label.toLowerCase().includes(q)) rows.push({ kind: "section", section });
|
|
10488
12870
|
}
|
|
10489
12871
|
for (const section of sections) {
|
|
10490
|
-
if (section.content) continue;
|
|
12872
|
+
if (section.content || section.mode === "toggle") continue;
|
|
12873
|
+
if (section.spec && section.spec.kind !== "person" && section.spec.kind !== "tags") continue;
|
|
10491
12874
|
for (const option of section.options) {
|
|
10492
12875
|
if (option.label.toLowerCase().includes(q)) rows.push({ kind: "option", section, option });
|
|
10493
12876
|
}
|
|
@@ -10496,12 +12879,192 @@ function DisplayMenu({
|
|
|
10496
12879
|
}, [sections, rootQuery]);
|
|
10497
12880
|
const sectionRows = useMemo(() => {
|
|
10498
12881
|
if (!activeSection) return [];
|
|
12882
|
+
if (activeSection.hideZero || activeSection.options.some((o) => o.pinned)) {
|
|
12883
|
+
return visibleDisplayMenuOptions(activeSection, sectionQuery);
|
|
12884
|
+
}
|
|
10499
12885
|
const q = sectionQuery.trim().toLowerCase();
|
|
10500
12886
|
return q ? activeSection.options.filter((o) => o.label.toLowerCase().includes(q)) : activeSection.options;
|
|
10501
12887
|
}, [activeSection, sectionQuery]);
|
|
10502
|
-
const
|
|
12888
|
+
const activeOperator = activeSection ? displayMenuSectionOperator(activeSection) : void 0;
|
|
12889
|
+
const emptinessOperator = activeOperator === "isEmpty" || activeOperator === "isNotEmpty";
|
|
12890
|
+
const showFlyoutSearch = !!activeSection && !activeSection.content && !activeSection.spec && !emptinessOperator && (activeSection.searchable ?? activeSection.options.length > SEARCH_THRESHOLD2);
|
|
10503
12891
|
const anySelected = sections.some((s) => s.mode === "multi" && s.selected.size > 0);
|
|
10504
|
-
const showDot = !isAtDefault || anySelected;
|
|
12892
|
+
const showDot = activeCount !== void 0 ? activeCount > 0 : !isAtDefault || anySelected;
|
|
12893
|
+
const triggerName = activeCount !== void 0 && activeCount > 0 ? messages.activeFilters(triggerLabel, activeCount) : showDot ? messages.triggerCustomised(triggerLabel) : triggerLabel;
|
|
12894
|
+
const grouped = sections.some((s) => s.group !== void 0);
|
|
12895
|
+
const selectOption = (section, option) => {
|
|
12896
|
+
const wasSelected = section.selected.has(option.key);
|
|
12897
|
+
section.onSelect(option.key);
|
|
12898
|
+
const label = displayMenuOptionLabel(section, option, filterMessages);
|
|
12899
|
+
announce(
|
|
12900
|
+
wasSelected && section.mode !== "single" ? messages.announceDeselected(section.label, label) : messages.announceSelected(section.label, label)
|
|
12901
|
+
);
|
|
12902
|
+
};
|
|
12903
|
+
const focusFlyout = () => requestAnimationFrame(() => {
|
|
12904
|
+
const root = flyoutRef.current;
|
|
12905
|
+
if (!root) return;
|
|
12906
|
+
const target = root.querySelector('[role="radio"][tabindex="0"], [aria-checked="true"]') ?? root.querySelector(`input, ${MENU_ITEM_SELECTOR}, ${FOCUSABLE_SELECTOR}`);
|
|
12907
|
+
target?.focus();
|
|
12908
|
+
});
|
|
12909
|
+
const focusRow = (key) => rowRefs.current.get(key)?.querySelector("button")?.focus();
|
|
12910
|
+
const renderSectionRow = (section) => {
|
|
12911
|
+
if (section.mode === "toggle") {
|
|
12912
|
+
const option = section.options[0];
|
|
12913
|
+
if (!option) return null;
|
|
12914
|
+
const checked = section.selected.has(option.key);
|
|
12915
|
+
return /* @__PURE__ */ jsxs(
|
|
12916
|
+
DisplayMenuItem,
|
|
12917
|
+
{
|
|
12918
|
+
kind: "checkbox",
|
|
12919
|
+
checked,
|
|
12920
|
+
"data-typeahead": section.label,
|
|
12921
|
+
onMouseEnter: () => {
|
|
12922
|
+
clearTimers();
|
|
12923
|
+
closeSection();
|
|
12924
|
+
},
|
|
12925
|
+
onClick: () => selectOption(section, option),
|
|
12926
|
+
trailing: typeof option.count === "number" ? /* @__PURE__ */ jsx(DisplayMenuCount, { value: option.count }) : null,
|
|
12927
|
+
children: [
|
|
12928
|
+
section.icon && /* @__PURE__ */ jsx("span", { className: "ds:me-1.5 ds:inline-flex ds:text-fg-3", "aria-hidden": "true", children: section.icon }),
|
|
12929
|
+
option.label || section.label
|
|
12930
|
+
]
|
|
12931
|
+
},
|
|
12932
|
+
section.key
|
|
12933
|
+
);
|
|
12934
|
+
}
|
|
12935
|
+
const count = section.selected.size;
|
|
12936
|
+
const filterSummary = usesFilterSummary(section) ? summarizeDisplayMenuSection(section, filterMessages) : null;
|
|
12937
|
+
const valueLabel = section.summary ?? filterSummary ?? (section.mode === "single" ? section.options.find((o) => section.selected.has(o.key))?.label ?? "" : "");
|
|
12938
|
+
const shownValue = valueLabel || (section.emptyLabel && !isDisplayMenuSectionActive(section) ? section.emptyLabel : "");
|
|
12939
|
+
const showCountBadge = section.mode === "multi" && count > 0 && !usesFilterSummary(section);
|
|
12940
|
+
const isOpen = section.key === openKey;
|
|
12941
|
+
return (
|
|
12942
|
+
/* Hover handlers sit on the wrapper so the cursor can cross
|
|
12943
|
+
* the gap to `section.trailing` without closing the flyout.
|
|
12944
|
+
* The wrapper is not itself a control — the button inside is,
|
|
12945
|
+
* and it carries the keyboard equivalent (ArrowRight / Enter /
|
|
12946
|
+
* Space open the same flyout). Nothing here is mouse-only. */
|
|
12947
|
+
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
12948
|
+
/* @__PURE__ */ jsxs(
|
|
12949
|
+
"div",
|
|
12950
|
+
{
|
|
12951
|
+
ref: (el) => {
|
|
12952
|
+
if (el) rowRefs.current.set(section.key, el);
|
|
12953
|
+
else rowRefs.current.delete(section.key);
|
|
12954
|
+
},
|
|
12955
|
+
className: "ds:flex ds:items-center ds:gap-0.5",
|
|
12956
|
+
onMouseEnter: () => scheduleOpen(section.key),
|
|
12957
|
+
onMouseLeave: scheduleClose,
|
|
12958
|
+
children: [
|
|
12959
|
+
/* @__PURE__ */ jsxs(
|
|
12960
|
+
DisplayMenuItem,
|
|
12961
|
+
{
|
|
12962
|
+
kind: "item",
|
|
12963
|
+
bare: true,
|
|
12964
|
+
"aria-haspopup": "menu",
|
|
12965
|
+
"aria-expanded": isOpen,
|
|
12966
|
+
"data-typeahead": section.label,
|
|
12967
|
+
onClick: () => openSection(section.key),
|
|
12968
|
+
onKeyDown: (e) => {
|
|
12969
|
+
if (e.key === "ArrowRight" || e.key === "Enter" || e.key === " ") {
|
|
12970
|
+
e.preventDefault();
|
|
12971
|
+
openSection(section.key);
|
|
12972
|
+
focusFlyout();
|
|
12973
|
+
}
|
|
12974
|
+
},
|
|
12975
|
+
className: cn(
|
|
12976
|
+
"ds:min-w-0 ds:flex-1",
|
|
12977
|
+
isOpen && "ds:bg-bg-2/60"
|
|
12978
|
+
),
|
|
12979
|
+
children: [
|
|
12980
|
+
section.icon && /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:text-fg-3", "aria-hidden": "true", children: section.icon }),
|
|
12981
|
+
/* @__PURE__ */ jsx("span", { className: "ds:flex-1 ds:truncate", children: section.label }),
|
|
12982
|
+
showCountBadge && /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:rounded-full ds:bg-brand-bg ds:px-1.5 ds:text-(length:--text-caption) ds:font-medium ds:text-brand", children: count }),
|
|
12983
|
+
!showCountBadge && shownValue && /* @__PURE__ */ jsx("span", { className: "ds:max-w-24 ds:shrink-0 ds:truncate ds:text-fg-3", children: shownValue }),
|
|
12984
|
+
/* @__PURE__ */ jsx(ChevronRightIcon, { size: 13, className: "ds:shrink-0 ds:text-fg-3" })
|
|
12985
|
+
]
|
|
12986
|
+
}
|
|
12987
|
+
),
|
|
12988
|
+
section.trailing
|
|
12989
|
+
]
|
|
12990
|
+
},
|
|
12991
|
+
section.key
|
|
12992
|
+
)
|
|
12993
|
+
);
|
|
12994
|
+
};
|
|
12995
|
+
const renderRootRows = () => {
|
|
12996
|
+
if (rootRows.length === 0) return /* @__PURE__ */ jsx(EmptyRow, { label: messages.noMatches });
|
|
12997
|
+
if (rootQuery.trim() || !grouped) return rootRows.map(renderRootRow);
|
|
12998
|
+
const order = ["filter", "arrange"];
|
|
12999
|
+
const buckets = order.map((group) => ({
|
|
13000
|
+
group,
|
|
13001
|
+
rows: sections.filter((s) => (s.group ?? "filter") === group)
|
|
13002
|
+
}));
|
|
13003
|
+
return buckets.filter((b) => b.rows.length > 0).map(({ group, rows }) => /* @__PURE__ */ jsxs(
|
|
13004
|
+
"div",
|
|
13005
|
+
{
|
|
13006
|
+
role: "group",
|
|
13007
|
+
"aria-labelledby": `${headingId}-${group}`,
|
|
13008
|
+
className: "ds:not-first:mt-1 ds:not-first:border-t ds:not-first:border-rule ds:not-first:pt-1",
|
|
13009
|
+
children: [
|
|
13010
|
+
/* @__PURE__ */ jsx(
|
|
13011
|
+
"p",
|
|
13012
|
+
{
|
|
13013
|
+
id: `${headingId}-${group}`,
|
|
13014
|
+
className: "ds:px-2 ds:pt-1 ds:pb-0.5 ds:text-(length:--text-caption) ds:font-medium ds:uppercase ds:tracking-wide ds:text-fg-4",
|
|
13015
|
+
children: group === "filter" ? messages.groupFilter : messages.groupArrange
|
|
13016
|
+
}
|
|
13017
|
+
),
|
|
13018
|
+
rows.map(renderSectionRow)
|
|
13019
|
+
]
|
|
13020
|
+
},
|
|
13021
|
+
group
|
|
13022
|
+
));
|
|
13023
|
+
};
|
|
13024
|
+
const renderRootRow = (row) => {
|
|
13025
|
+
if (row.kind === "option") {
|
|
13026
|
+
const { section, option } = row;
|
|
13027
|
+
const isActive = section.selected.has(option.key);
|
|
13028
|
+
const isMulti = section.mode === "multi";
|
|
13029
|
+
return /* @__PURE__ */ jsxs(
|
|
13030
|
+
DisplayMenuItem,
|
|
13031
|
+
{
|
|
13032
|
+
kind: isMulti ? "checkbox" : "radio",
|
|
13033
|
+
indicator: "check",
|
|
13034
|
+
bare: true,
|
|
13035
|
+
checked: isActive,
|
|
13036
|
+
onMouseEnter: () => {
|
|
13037
|
+
clearTimers();
|
|
13038
|
+
closeSection();
|
|
13039
|
+
},
|
|
13040
|
+
onClick: () => selectOption(section, option),
|
|
13041
|
+
className: "ds:gap-1.5",
|
|
13042
|
+
children: [
|
|
13043
|
+
section.icon && /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:text-fg-3", "aria-hidden": "true", children: section.icon }),
|
|
13044
|
+
/* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:truncate ds:text-fg-3", children: section.label }),
|
|
13045
|
+
/* @__PURE__ */ jsx(ChevronRightIcon, { size: 12, className: "ds:shrink-0 ds:text-fg-3", "aria-hidden": "true" }),
|
|
13046
|
+
/* @__PURE__ */ jsx("span", { className: "ds:flex-1 ds:truncate ds:text-fg", children: displayMenuOptionLabel(section, option, filterMessages) })
|
|
13047
|
+
]
|
|
13048
|
+
},
|
|
13049
|
+
`${section.key}:${option.key}`
|
|
13050
|
+
);
|
|
13051
|
+
}
|
|
13052
|
+
return renderSectionRow(row.section);
|
|
13053
|
+
};
|
|
13054
|
+
const onEscapeKeyDown = (e) => {
|
|
13055
|
+
if (viewsOpen) {
|
|
13056
|
+
e.preventDefault();
|
|
13057
|
+
setViewsOpen(false);
|
|
13058
|
+
return;
|
|
13059
|
+
}
|
|
13060
|
+
if (openKey) {
|
|
13061
|
+
e.preventDefault();
|
|
13062
|
+
const key = openKey;
|
|
13063
|
+
const fromFlyout = flyoutRef.current?.contains(e.target);
|
|
13064
|
+
closeSection();
|
|
13065
|
+
if (fromFlyout) focusRow(key);
|
|
13066
|
+
}
|
|
13067
|
+
};
|
|
10505
13068
|
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
10506
13069
|
/* @__PURE__ */ jsxs(Tooltip, { delayMs: 300, children: [
|
|
10507
13070
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
@@ -10509,7 +13072,7 @@ function DisplayMenu({
|
|
|
10509
13072
|
{
|
|
10510
13073
|
variant: "outline",
|
|
10511
13074
|
size: "sm",
|
|
10512
|
-
"aria-label":
|
|
13075
|
+
"aria-label": triggerName,
|
|
10513
13076
|
"data-tour": dataTour,
|
|
10514
13077
|
className: cn("ds:relative ds:shrink-0", className),
|
|
10515
13078
|
children: [
|
|
@@ -10531,17 +13094,22 @@ function DisplayMenu({
|
|
|
10531
13094
|
PopoverContent,
|
|
10532
13095
|
{
|
|
10533
13096
|
align: "end",
|
|
10534
|
-
sideOffset: 6,
|
|
10535
|
-
collisionPadding: COLLISION_PADDING_PX,
|
|
10536
|
-
className: "ds:w-64 ds:overflow-visible ds:p-0",
|
|
10537
|
-
|
|
10538
|
-
if (e.key === "Escape" && openKey) {
|
|
10539
|
-
e.preventDefault();
|
|
10540
|
-
e.stopPropagation();
|
|
10541
|
-
setOpenKey(null);
|
|
10542
|
-
}
|
|
10543
|
-
},
|
|
13097
|
+
sideOffset: 6,
|
|
13098
|
+
collisionPadding: COLLISION_PADDING_PX,
|
|
13099
|
+
className: "ds:w-64 ds:overflow-visible ds:p-0",
|
|
13100
|
+
onEscapeKeyDown,
|
|
10544
13101
|
children: /* @__PURE__ */ jsxs("div", { ref: panelRef, className: "ds:relative ds:isolate", children: [
|
|
13102
|
+
announcer,
|
|
13103
|
+
views && /* @__PURE__ */ jsx(
|
|
13104
|
+
DisplayMenuViewsBar,
|
|
13105
|
+
{
|
|
13106
|
+
views,
|
|
13107
|
+
messages,
|
|
13108
|
+
onAnnounce: announce,
|
|
13109
|
+
listOpen: viewsOpen,
|
|
13110
|
+
onListOpenChange: setViewsOpen
|
|
13111
|
+
}
|
|
13112
|
+
),
|
|
10545
13113
|
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:items-center ds:gap-1.5 ds:border-b ds:border-rule ds:px-2.5 ds:py-1.5", children: [
|
|
10546
13114
|
/* @__PURE__ */ jsx(SearchIcon, { size: 13, className: "ds:shrink-0 ds:text-fg-3", "aria-hidden": "true" }),
|
|
10547
13115
|
/* @__PURE__ */ jsx(
|
|
@@ -10550,139 +13118,82 @@ function DisplayMenu({
|
|
|
10550
13118
|
type: "text",
|
|
10551
13119
|
value: rootQuery,
|
|
10552
13120
|
onChange: (e) => setRootQuery(e.target.value),
|
|
10553
|
-
|
|
10554
|
-
|
|
13121
|
+
onKeyDown: (e) => {
|
|
13122
|
+
if (e.key === "ArrowDown") {
|
|
13123
|
+
e.preventDefault();
|
|
13124
|
+
panelRef.current?.querySelector(`[data-dm-root] :is(${MENU_ITEM_SELECTOR})`)?.focus();
|
|
13125
|
+
}
|
|
13126
|
+
},
|
|
13127
|
+
placeholder: messages.rootSearchPlaceholder,
|
|
13128
|
+
"aria-label": messages.rootSearchLabel,
|
|
10555
13129
|
className: "ds:h-6 ds:w-full ds:bg-transparent ds:text-[13px] ds:text-fg ds:outline-none ds:placeholder:text-fg-3"
|
|
10556
13130
|
}
|
|
10557
13131
|
)
|
|
10558
13132
|
] }),
|
|
13133
|
+
match !== void 0 && onMatchChange && sections.some((s) => (s.group ?? "filter") === "filter") && /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:items-center ds:justify-between ds:gap-2 ds:border-b ds:border-rule ds:px-2.5 ds:py-1", children: [
|
|
13134
|
+
/* @__PURE__ */ jsx("span", { className: "ds:text-(length:--text-helper) ds:text-fg-3", id: `${headingId}-match`, children: messages.matchLabel }),
|
|
13135
|
+
/* @__PURE__ */ jsxs(
|
|
13136
|
+
ToggleGroup,
|
|
13137
|
+
{
|
|
13138
|
+
type: "single",
|
|
13139
|
+
variant: "segmented",
|
|
13140
|
+
size: "xs",
|
|
13141
|
+
value: match,
|
|
13142
|
+
"aria-labelledby": `${headingId}-match`,
|
|
13143
|
+
onValueChange: (next) => {
|
|
13144
|
+
if (next === "all" || next === "any") onMatchChange(next);
|
|
13145
|
+
},
|
|
13146
|
+
children: [
|
|
13147
|
+
/* @__PURE__ */ jsx(ToggleGroupItem, { value: "all", className: "ds:px-2 ds:text-(length:--text-helper)", children: messages.matchAll }),
|
|
13148
|
+
/* @__PURE__ */ jsx(ToggleGroupItem, { value: "any", className: "ds:px-2 ds:text-(length:--text-helper)", children: messages.matchAny })
|
|
13149
|
+
]
|
|
13150
|
+
}
|
|
13151
|
+
)
|
|
13152
|
+
] }),
|
|
10559
13153
|
/* @__PURE__ */ jsx(
|
|
10560
13154
|
"div",
|
|
10561
13155
|
{
|
|
10562
13156
|
role: "menu",
|
|
10563
13157
|
"aria-label": triggerLabel,
|
|
13158
|
+
"data-dm-root": "",
|
|
13159
|
+
onKeyDown: rootRoving,
|
|
10564
13160
|
className: "ds:scrollbar-thin ds:max-h-[min(32rem,70vh)] ds:overflow-y-auto ds:p-1",
|
|
10565
|
-
children:
|
|
10566
|
-
if (row.kind === "option") {
|
|
10567
|
-
const { section: section2, option } = row;
|
|
10568
|
-
const isActive = section2.selected.has(option.key);
|
|
10569
|
-
const isMulti = section2.mode === "multi";
|
|
10570
|
-
return /* @__PURE__ */ jsxs(
|
|
10571
|
-
"button",
|
|
10572
|
-
{
|
|
10573
|
-
type: "button",
|
|
10574
|
-
role: isMulti ? "menuitemcheckbox" : "menuitemradio",
|
|
10575
|
-
"aria-checked": isActive,
|
|
10576
|
-
onMouseEnter: () => {
|
|
10577
|
-
clearTimers();
|
|
10578
|
-
setOpenKey(null);
|
|
10579
|
-
},
|
|
10580
|
-
onClick: () => section2.onSelect(option.key),
|
|
10581
|
-
className: "ds:flex ds:w-full ds:items-center ds:gap-1.5 ds:rounded-md ds:px-2 ds:py-1.5 ds:text-left ds:text-[13px] ds:transition-colors ds:hover:bg-surface-hover/60 ds:focus-visible:bg-bg-2/60 ds:focus-visible:outline-none ds:motion-reduce:transition-none",
|
|
10582
|
-
children: [
|
|
10583
|
-
section2.icon && /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:text-fg-3", "aria-hidden": "true", children: section2.icon }),
|
|
10584
|
-
/* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:truncate ds:text-fg-3", children: section2.label }),
|
|
10585
|
-
/* @__PURE__ */ jsx(
|
|
10586
|
-
ChevronRightIcon,
|
|
10587
|
-
{
|
|
10588
|
-
size: 12,
|
|
10589
|
-
className: "ds:shrink-0 ds:text-fg-3",
|
|
10590
|
-
"aria-hidden": "true"
|
|
10591
|
-
}
|
|
10592
|
-
),
|
|
10593
|
-
/* @__PURE__ */ jsx("span", { className: "ds:flex-1 ds:truncate ds:text-fg", children: option.label }),
|
|
10594
|
-
isActive && /* @__PURE__ */ jsx(CheckIcon, { size: 14, className: "ds:shrink-0 ds:text-brand" })
|
|
10595
|
-
]
|
|
10596
|
-
},
|
|
10597
|
-
`${section2.key}:${option.key}`
|
|
10598
|
-
);
|
|
10599
|
-
}
|
|
10600
|
-
const { section } = row;
|
|
10601
|
-
const count = section.selected.size;
|
|
10602
|
-
const valueLabel = section.summary ?? (section.mode === "single" ? section.options.find((o) => section.selected.has(o.key))?.label ?? "" : "");
|
|
10603
|
-
const isOpen = section.key === openKey;
|
|
10604
|
-
return (
|
|
10605
|
-
/* Hover handlers sit on the wrapper so the cursor can cross
|
|
10606
|
-
* the gap to `section.trailing` without closing the flyout.
|
|
10607
|
-
* The wrapper is not itself a control — the button inside is,
|
|
10608
|
-
* and it carries the keyboard equivalent (ArrowRight / Enter /
|
|
10609
|
-
* Space open the same flyout). Nothing here is mouse-only. */
|
|
10610
|
-
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
10611
|
-
/* @__PURE__ */ jsxs(
|
|
10612
|
-
"div",
|
|
10613
|
-
{
|
|
10614
|
-
ref: (el) => {
|
|
10615
|
-
if (el) rowRefs.current.set(section.key, el);
|
|
10616
|
-
else rowRefs.current.delete(section.key);
|
|
10617
|
-
},
|
|
10618
|
-
className: "ds:flex ds:items-center ds:gap-0.5",
|
|
10619
|
-
onMouseEnter: () => scheduleOpen(section.key),
|
|
10620
|
-
onMouseLeave: scheduleClose,
|
|
10621
|
-
children: [
|
|
10622
|
-
/* @__PURE__ */ jsxs(
|
|
10623
|
-
"button",
|
|
10624
|
-
{
|
|
10625
|
-
type: "button",
|
|
10626
|
-
role: "menuitem",
|
|
10627
|
-
"aria-haspopup": "menu",
|
|
10628
|
-
"aria-expanded": isOpen,
|
|
10629
|
-
onClick: () => openSection(section.key),
|
|
10630
|
-
onKeyDown: (e) => {
|
|
10631
|
-
if (e.key === "ArrowRight" || e.key === "Enter" || e.key === " ") {
|
|
10632
|
-
e.preventDefault();
|
|
10633
|
-
openSection(section.key);
|
|
10634
|
-
requestAnimationFrame(
|
|
10635
|
-
() => flyoutRef.current?.querySelector("input, [role='menuitemcheckbox'], [role='menuitemradio']")?.focus()
|
|
10636
|
-
);
|
|
10637
|
-
}
|
|
10638
|
-
},
|
|
10639
|
-
className: cn(
|
|
10640
|
-
"ds:flex ds:min-w-0 ds:flex-1 ds:items-center ds:gap-2 ds:rounded-md ds:px-2 ds:py-1.5 ds:text-left ds:text-[13px] ds:text-fg ds:transition-colors ds:hover:bg-surface-hover/60 ds:focus-visible:bg-bg-2/60 ds:focus-visible:outline-none ds:motion-reduce:transition-none",
|
|
10641
|
-
isOpen && "ds:bg-bg-2/60"
|
|
10642
|
-
),
|
|
10643
|
-
children: [
|
|
10644
|
-
section.icon && /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:text-fg-3", "aria-hidden": "true", children: section.icon }),
|
|
10645
|
-
/* @__PURE__ */ jsx("span", { className: "ds:flex-1 ds:truncate", children: section.label }),
|
|
10646
|
-
section.mode === "multi" && count > 0 && /* @__PURE__ */ jsx("span", { className: "ds:shrink-0 ds:rounded-full ds:bg-brand-bg ds:px-1.5 ds:text-[11px] ds:font-medium ds:text-brand", children: count }),
|
|
10647
|
-
section.mode !== "multi" && valueLabel && /* @__PURE__ */ jsx("span", { className: "ds:max-w-24 ds:shrink-0 ds:truncate ds:text-[13px] ds:text-fg-3", children: valueLabel }),
|
|
10648
|
-
/* @__PURE__ */ jsx(ChevronRightIcon, { size: 13, className: "ds:shrink-0 ds:text-fg-3" })
|
|
10649
|
-
]
|
|
10650
|
-
}
|
|
10651
|
-
),
|
|
10652
|
-
section.trailing
|
|
10653
|
-
]
|
|
10654
|
-
},
|
|
10655
|
-
section.key
|
|
10656
|
-
)
|
|
10657
|
-
);
|
|
10658
|
-
})
|
|
13161
|
+
children: renderRootRows()
|
|
10659
13162
|
}
|
|
10660
13163
|
),
|
|
10661
|
-
/* @__PURE__ */
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
13164
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:items-center ds:gap-1 ds:border-t ds:border-rule ds:p-1", children: [
|
|
13165
|
+
/* @__PURE__ */ jsxs(
|
|
13166
|
+
Button,
|
|
13167
|
+
{
|
|
13168
|
+
variant: "ghost",
|
|
13169
|
+
size: "sm",
|
|
13170
|
+
onClick: () => {
|
|
13171
|
+
onReset();
|
|
13172
|
+
announce(messages.announceReset);
|
|
13173
|
+
},
|
|
13174
|
+
disabled: isAtDefault,
|
|
13175
|
+
className: "ds:h-7 ds:flex-1 ds:justify-start ds:gap-1.5 ds:px-2 ds:text-xs ds:text-fg-3 ds:hover:text-fg",
|
|
13176
|
+
children: [
|
|
13177
|
+
/* @__PURE__ */ jsx(RotateCcwIcon, { size: 13 }),
|
|
13178
|
+
messages.reset
|
|
13179
|
+
]
|
|
13180
|
+
}
|
|
13181
|
+
),
|
|
13182
|
+
density !== void 0 && onDensityChange && /* @__PURE__ */ jsx(TableDensityToggle, { size: "xs", value: density, onValueChange: onDensityChange })
|
|
13183
|
+
] }),
|
|
13184
|
+
activeSection && // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- delegated ArrowLeft/hover for the controls inside; the flyout is a surface, not a control
|
|
13185
|
+
/* @__PURE__ */ jsxs(
|
|
10676
13186
|
"div",
|
|
10677
13187
|
{
|
|
10678
13188
|
ref: flyoutRef,
|
|
10679
13189
|
tabIndex: -1,
|
|
10680
13190
|
"data-ds-presence": "floating",
|
|
10681
13191
|
"data-state": "open",
|
|
13192
|
+
"data-kind": activeSection.spec?.kind,
|
|
10682
13193
|
style: {
|
|
10683
13194
|
top: flyout.top,
|
|
10684
|
-
width:
|
|
10685
|
-
maxHeight: flyout.maxHeight,
|
|
13195
|
+
width: flyoutWidthFor(activeSection),
|
|
13196
|
+
maxHeight: flyout.maxHeight || void 0,
|
|
10686
13197
|
transformOrigin: flyout.side === "left" ? "right top" : "left top"
|
|
10687
13198
|
},
|
|
10688
13199
|
className: cn(
|
|
@@ -10696,7 +13207,17 @@ function DisplayMenu({
|
|
|
10696
13207
|
),
|
|
10697
13208
|
onMouseEnter: clearTimers,
|
|
10698
13209
|
onMouseLeave: scheduleClose,
|
|
13210
|
+
onKeyDown: (e) => {
|
|
13211
|
+
const inField = e.target.closest("input, textarea");
|
|
13212
|
+
if (e.key === "ArrowLeft" && !inField && !e.defaultPrevented) {
|
|
13213
|
+
e.preventDefault();
|
|
13214
|
+
const key = activeSection.key;
|
|
13215
|
+
closeSection();
|
|
13216
|
+
focusRow(key);
|
|
13217
|
+
}
|
|
13218
|
+
},
|
|
10699
13219
|
children: [
|
|
13220
|
+
activeSection.operators && /* @__PURE__ */ jsx(DisplayMenuOperatorPicker, { section: activeSection }),
|
|
10700
13221
|
showFlyoutSearch && /* @__PURE__ */ jsxs("div", { className: "ds:flex ds:shrink-0 ds:items-center ds:gap-1.5 ds:border-b ds:border-rule ds:px-2.5 ds:py-1.5", children: [
|
|
10701
13222
|
/* @__PURE__ */ jsx(SearchIcon, { size: 13, className: "ds:shrink-0 ds:text-fg-3", "aria-hidden": "true" }),
|
|
10702
13223
|
/* @__PURE__ */ jsx(
|
|
@@ -10705,85 +13226,98 @@ function DisplayMenu({
|
|
|
10705
13226
|
type: "text",
|
|
10706
13227
|
value: sectionQuery,
|
|
10707
13228
|
onChange: (e) => setSectionQuery(e.target.value),
|
|
10708
|
-
placeholder:
|
|
10709
|
-
"aria-label":
|
|
13229
|
+
placeholder: messages.sectionSearchPlaceholder(activeSection.label),
|
|
13230
|
+
"aria-label": messages.sectionSearchLabel(activeSection.label),
|
|
10710
13231
|
className: "ds:h-6 ds:w-full ds:bg-transparent ds:text-[13px] ds:text-fg ds:outline-none ds:placeholder:text-fg-3"
|
|
10711
13232
|
}
|
|
10712
13233
|
)
|
|
10713
13234
|
] }),
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
"
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
13235
|
+
activeSection.spec ? (
|
|
13236
|
+
/* Typed panels own inputs and radio groups — a menu may only own
|
|
13237
|
+
* items, so this container is a labelled group instead. */
|
|
13238
|
+
/* @__PURE__ */ jsx(
|
|
13239
|
+
"div",
|
|
13240
|
+
{
|
|
13241
|
+
role: "group",
|
|
13242
|
+
"aria-label": activeSection.label,
|
|
13243
|
+
className: "ds:scrollbar-thin ds:min-h-0 ds:flex-1 ds:overflow-y-auto",
|
|
13244
|
+
children: /* @__PURE__ */ jsx(DisplayMenuSpecPanel, { section: activeSection, onDone: closeSection })
|
|
13245
|
+
}
|
|
13246
|
+
)
|
|
13247
|
+
) : emptinessOperator ? null : (
|
|
13248
|
+
/* The menu is the option list alone: the search box above and
|
|
13249
|
+
* the Clear action below are not menu items, so they sit
|
|
13250
|
+
* outside it (a menu may only own items, G10). */
|
|
13251
|
+
/* @__PURE__ */ jsx(
|
|
13252
|
+
"div",
|
|
13253
|
+
{
|
|
13254
|
+
role: "menu",
|
|
13255
|
+
"aria-label": activeSection.label,
|
|
13256
|
+
onKeyDown: flyoutRoving,
|
|
13257
|
+
className: "ds:scrollbar-thin ds:min-h-0 ds:flex-1 ds:max-h-[min(24rem,60vh)] ds:overflow-y-auto ds:p-1",
|
|
13258
|
+
children: activeSection.content ? (
|
|
13259
|
+
/* Consumer-supplied controls (date range, numeric bound).
|
|
13260
|
+
* Rendered raw — the section owns its own labelling and
|
|
13261
|
+
* layout; the flyout only provides the surface. */
|
|
13262
|
+
/* @__PURE__ */ jsx("div", { className: "ds:p-1.5", children: activeSection.content })
|
|
13263
|
+
) : sectionRows.length === 0 ? /* @__PURE__ */ jsx(
|
|
13264
|
+
EmptyRow,
|
|
10735
13265
|
{
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
isMulti && /* @__PURE__ */ jsx(
|
|
10756
|
-
"span",
|
|
10757
|
-
{
|
|
10758
|
-
"aria-hidden": "true",
|
|
10759
|
-
className: cn(
|
|
10760
|
-
"ds:flex ds:size-3.5 ds:shrink-0 ds:items-center ds:justify-center ds:rounded ds:border ds:transition-colors",
|
|
10761
|
-
isActive ? "ds:border-brand ds:bg-brand ds:text-fg-on-brand" : "ds:border-rule"
|
|
10762
|
-
),
|
|
10763
|
-
children: isActive && /* @__PURE__ */ jsx(CheckIcon, { size: 10 })
|
|
10764
|
-
}
|
|
13266
|
+
label: activeSection.options.length === 0 ? messages.nothingToFilter : messages.noMatches
|
|
13267
|
+
}
|
|
13268
|
+
) : sectionRows.map((option) => {
|
|
13269
|
+
const isActive = activeSection.selected.has(option.key);
|
|
13270
|
+
const isMulti = activeSection.mode === "multi";
|
|
13271
|
+
return /* @__PURE__ */ jsxs(
|
|
13272
|
+
"button",
|
|
13273
|
+
{
|
|
13274
|
+
type: "button",
|
|
13275
|
+
role: isMulti ? "menuitemcheckbox" : "menuitemradio",
|
|
13276
|
+
"aria-checked": isActive,
|
|
13277
|
+
"data-typeahead": option.label,
|
|
13278
|
+
onClick: () => {
|
|
13279
|
+
selectOption(activeSection, option);
|
|
13280
|
+
if (!isMulti) closeSection();
|
|
13281
|
+
},
|
|
13282
|
+
className: cn(
|
|
13283
|
+
"ds:flex ds:w-full ds:items-center ds:gap-2 ds:rounded-md ds:px-2 ds:py-1.5 ds:text-left ds:text-[13px] ds:transition-colors ds:hover:bg-surface-hover/60 ds:focus-visible:bg-bg-2/60 ds:focus-visible:outline-none ds:motion-reduce:transition-none",
|
|
13284
|
+
isActive ? "ds:text-fg" : "ds:text-fg-3 ds:hover:text-fg"
|
|
10765
13285
|
),
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
13286
|
+
children: [
|
|
13287
|
+
isMulti && /* @__PURE__ */ jsx(
|
|
13288
|
+
"span",
|
|
13289
|
+
{
|
|
13290
|
+
"aria-hidden": "true",
|
|
13291
|
+
className: cn(
|
|
13292
|
+
"ds:flex ds:size-3.5 ds:shrink-0 ds:items-center ds:justify-center ds:rounded ds:border ds:transition-colors",
|
|
13293
|
+
isActive ? "ds:border-brand ds:bg-brand ds:text-fg-on-brand" : "ds:border-rule"
|
|
13294
|
+
),
|
|
13295
|
+
children: isActive && /* @__PURE__ */ jsx(CheckIcon, { size: 10 })
|
|
13296
|
+
}
|
|
13297
|
+
),
|
|
13298
|
+
option.icon && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ds:inline-flex ds:shrink-0", children: option.icon }),
|
|
13299
|
+
/* @__PURE__ */ jsx("span", { className: "ds:flex-1 ds:truncate", children: option.label }),
|
|
13300
|
+
typeof option.count === "number" && /* @__PURE__ */ jsx(DisplayMenuCount, { value: option.count }),
|
|
13301
|
+
!isMulti && isActive && /* @__PURE__ */ jsx(CheckIcon, { size: 14, className: "ds:shrink-0 ds:text-brand" })
|
|
13302
|
+
]
|
|
13303
|
+
},
|
|
13304
|
+
option.key
|
|
13305
|
+
);
|
|
13306
|
+
})
|
|
13307
|
+
}
|
|
13308
|
+
)
|
|
10774
13309
|
),
|
|
10775
|
-
activeSection.mode === "multi" && activeSection.selected.size > 0 && activeSection.onClear && /* @__PURE__ */ jsx("div", { className: "ds:shrink-0 ds:border-t ds:border-rule ds:p-1", children: /* @__PURE__ */
|
|
13310
|
+
!activeSection.spec && activeSection.mode === "multi" && activeSection.selected.size > 0 && activeSection.onClear && /* @__PURE__ */ jsx("div", { className: "ds:shrink-0 ds:border-t ds:border-rule ds:p-1", children: /* @__PURE__ */ jsx(
|
|
10776
13311
|
Button,
|
|
10777
13312
|
{
|
|
10778
13313
|
variant: "ghost",
|
|
10779
13314
|
size: "sm",
|
|
10780
|
-
onClick:
|
|
13315
|
+
onClick: () => {
|
|
13316
|
+
activeSection.onClear?.();
|
|
13317
|
+
announce(messages.announceCleared(activeSection.label));
|
|
13318
|
+
},
|
|
10781
13319
|
className: "ds:h-6 ds:w-full ds:justify-start ds:px-2 ds:text-[11px] ds:text-fg-3 ds:hover:text-fg",
|
|
10782
|
-
children:
|
|
10783
|
-
"Clear ",
|
|
10784
|
-
activeSection.selected.size,
|
|
10785
|
-
" selected"
|
|
10786
|
-
]
|
|
13320
|
+
children: messages.clearSelected(activeSection.selected.size)
|
|
10787
13321
|
}
|
|
10788
13322
|
) })
|
|
10789
13323
|
]
|
|
@@ -10794,9 +13328,220 @@ function DisplayMenu({
|
|
|
10794
13328
|
)
|
|
10795
13329
|
] });
|
|
10796
13330
|
}
|
|
10797
|
-
function EmptyRow({ label
|
|
13331
|
+
function EmptyRow({ label }) {
|
|
10798
13332
|
return /* @__PURE__ */ jsx("p", { className: "ds:px-2 ds:py-3 ds:text-center ds:text-[11px] ds:text-fg-3", children: label });
|
|
10799
13333
|
}
|
|
13334
|
+
function facetSummary(facet) {
|
|
13335
|
+
return facet.summary ?? (facet.values ?? []).map((v) => v.label).join(", ");
|
|
13336
|
+
}
|
|
13337
|
+
var FilterChips = forwardRef(function FilterChips2({
|
|
13338
|
+
facets,
|
|
13339
|
+
onEdit,
|
|
13340
|
+
onRemove,
|
|
13341
|
+
onRemoveValue,
|
|
13342
|
+
onClearAll,
|
|
13343
|
+
maxVisible = 3,
|
|
13344
|
+
size = "sm",
|
|
13345
|
+
trailing,
|
|
13346
|
+
messages: messagesProp,
|
|
13347
|
+
className,
|
|
13348
|
+
...props
|
|
13349
|
+
}, ref) {
|
|
13350
|
+
const messages = useDsMessages("filterChips", messagesProp);
|
|
13351
|
+
const [panelOpen, setPanelOpen] = useState(false);
|
|
13352
|
+
if (facets.length === 0) return null;
|
|
13353
|
+
const limit = Math.max(1, maxVisible);
|
|
13354
|
+
const collapse = facets.length > limit + 1;
|
|
13355
|
+
const visible = collapse ? facets.slice(0, limit) : facets;
|
|
13356
|
+
const hidden = collapse ? facets.slice(limit) : [];
|
|
13357
|
+
return /* @__PURE__ */ jsxs(
|
|
13358
|
+
"div",
|
|
13359
|
+
{
|
|
13360
|
+
ref,
|
|
13361
|
+
role: "group",
|
|
13362
|
+
"aria-label": messages.region,
|
|
13363
|
+
...slot(filterChipsAnatomy, "root"),
|
|
13364
|
+
className: cn("ds:flex ds:min-w-0 ds:flex-wrap ds:items-center ds:gap-1.5", className),
|
|
13365
|
+
...props,
|
|
13366
|
+
children: [
|
|
13367
|
+
visible.map((facet) => {
|
|
13368
|
+
const text = messages.facet(facet.label, facetSummary(facet));
|
|
13369
|
+
return /* @__PURE__ */ jsx(
|
|
13370
|
+
Chip,
|
|
13371
|
+
{
|
|
13372
|
+
size,
|
|
13373
|
+
"data-facet": facet.key,
|
|
13374
|
+
...slot(filterChipsAnatomy, "chip"),
|
|
13375
|
+
...onEdit ? { onClick: () => onEdit(facet.key) } : {},
|
|
13376
|
+
onRemove: () => onRemove(facet.key),
|
|
13377
|
+
removeLabel: messages.remove(facet.label),
|
|
13378
|
+
className: "ds:max-w-72 ds:[&_[data-slot=chip-label]]:truncate",
|
|
13379
|
+
title: text,
|
|
13380
|
+
children: text
|
|
13381
|
+
},
|
|
13382
|
+
facet.key
|
|
13383
|
+
);
|
|
13384
|
+
}),
|
|
13385
|
+
hidden.length > 0 && /* @__PURE__ */ jsxs(Popover, { open: panelOpen, onOpenChange: setPanelOpen, children: [
|
|
13386
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
13387
|
+
Chip,
|
|
13388
|
+
{
|
|
13389
|
+
size,
|
|
13390
|
+
...slot(filterChipsAnatomy, "overflow"),
|
|
13391
|
+
"aria-label": messages.moreLabel(hidden.length),
|
|
13392
|
+
"aria-haspopup": "dialog",
|
|
13393
|
+
"aria-expanded": panelOpen,
|
|
13394
|
+
onClick: () => setPanelOpen((open) => !open),
|
|
13395
|
+
children: messages.more(hidden.length)
|
|
13396
|
+
}
|
|
13397
|
+
) }),
|
|
13398
|
+
/* @__PURE__ */ jsxs(
|
|
13399
|
+
PopoverContent,
|
|
13400
|
+
{
|
|
13401
|
+
align: "start",
|
|
13402
|
+
sideOffset: 6,
|
|
13403
|
+
padding: "none",
|
|
13404
|
+
"aria-label": messages.panelTitle(facets.length),
|
|
13405
|
+
...slot(filterChipsAnatomy, "overflow-panel"),
|
|
13406
|
+
children: [
|
|
13407
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:items-center ds:justify-between ds:gap-2 ds:border-b ds:border-rule ds:px-3 ds:py-2", children: [
|
|
13408
|
+
/* @__PURE__ */ jsx("p", { className: "ds:text-xs ds:font-semibold ds:text-fg", children: messages.panelTitle(facets.length) }),
|
|
13409
|
+
onClearAll && /* @__PURE__ */ jsx(
|
|
13410
|
+
Button,
|
|
13411
|
+
{
|
|
13412
|
+
variant: "ghost",
|
|
13413
|
+
size: "sm",
|
|
13414
|
+
onClick: () => {
|
|
13415
|
+
onClearAll();
|
|
13416
|
+
setPanelOpen(false);
|
|
13417
|
+
},
|
|
13418
|
+
children: messages.clearFilters
|
|
13419
|
+
}
|
|
13420
|
+
)
|
|
13421
|
+
] }),
|
|
13422
|
+
/* @__PURE__ */ jsx("ul", { className: "ds:scrollbar-thin ds:max-h-72 ds:space-y-3 ds:overflow-y-auto ds:p-3", children: facets.map((facet) => /* @__PURE__ */ jsxs("li", { ...slot(filterChipsAnatomy, "overflow-facet"), children: [
|
|
13423
|
+
/* @__PURE__ */ jsx("p", { className: "ds:mb-1 ds:text-xs ds:font-medium ds:text-fg-3", children: facet.label }),
|
|
13424
|
+
/* @__PURE__ */ jsx("ul", { className: "ds:space-y-0.5", children: onRemoveValue && facet.values && facet.values.length > 0 ? facet.values.map((value) => /* @__PURE__ */ jsx(
|
|
13425
|
+
ValueRow,
|
|
13426
|
+
{
|
|
13427
|
+
label: value.label,
|
|
13428
|
+
removeLabel: messages.removeValue(facet.label, value.label),
|
|
13429
|
+
onRemove: () => onRemoveValue(facet.key, value.key)
|
|
13430
|
+
},
|
|
13431
|
+
value.key
|
|
13432
|
+
)) : /* @__PURE__ */ jsx(
|
|
13433
|
+
ValueRow,
|
|
13434
|
+
{
|
|
13435
|
+
label: facetSummary(facet),
|
|
13436
|
+
removeLabel: messages.remove(facet.label),
|
|
13437
|
+
onRemove: () => onRemove(facet.key)
|
|
13438
|
+
}
|
|
13439
|
+
) })
|
|
13440
|
+
] }, facet.key)) })
|
|
13441
|
+
]
|
|
13442
|
+
}
|
|
13443
|
+
)
|
|
13444
|
+
] }),
|
|
13445
|
+
trailing,
|
|
13446
|
+
onClearAll && /* @__PURE__ */ jsx(
|
|
13447
|
+
Button,
|
|
13448
|
+
{
|
|
13449
|
+
variant: "ghost",
|
|
13450
|
+
size: "sm",
|
|
13451
|
+
onClick: onClearAll,
|
|
13452
|
+
...slot(filterChipsAnatomy, "clear"),
|
|
13453
|
+
className: "ds:text-fg-3 ds:hover:text-fg",
|
|
13454
|
+
children: messages.clearAll
|
|
13455
|
+
}
|
|
13456
|
+
)
|
|
13457
|
+
]
|
|
13458
|
+
}
|
|
13459
|
+
);
|
|
13460
|
+
});
|
|
13461
|
+
FilterChips.displayName = "FilterChips";
|
|
13462
|
+
function ValueRow({
|
|
13463
|
+
label,
|
|
13464
|
+
removeLabel,
|
|
13465
|
+
onRemove
|
|
13466
|
+
}) {
|
|
13467
|
+
return /* @__PURE__ */ jsxs(
|
|
13468
|
+
"li",
|
|
13469
|
+
{
|
|
13470
|
+
...slot(filterChipsAnatomy, "overflow-value"),
|
|
13471
|
+
className: "ds:flex ds:items-center ds:justify-between ds:gap-2 ds:rounded-input ds:py-0.5 ds:ps-1 ds:pe-0.5 ds:transition-colors ds:duration-[var(--duration-fast)] ds:hover:bg-surface-hover ds:motion-reduce:transition-none",
|
|
13472
|
+
children: [
|
|
13473
|
+
/* @__PURE__ */ jsx("span", { className: "ds:min-w-0 ds:truncate ds:text-sm ds:text-fg", children: label }),
|
|
13474
|
+
/* @__PURE__ */ jsx(
|
|
13475
|
+
IconButton,
|
|
13476
|
+
{
|
|
13477
|
+
variant: "ghost",
|
|
13478
|
+
intent: "neutral",
|
|
13479
|
+
size: "xs",
|
|
13480
|
+
label: removeLabel,
|
|
13481
|
+
tooltip: false,
|
|
13482
|
+
icon: /* @__PURE__ */ jsx(XIcon, {}),
|
|
13483
|
+
onClick: onRemove
|
|
13484
|
+
}
|
|
13485
|
+
)
|
|
13486
|
+
]
|
|
13487
|
+
}
|
|
13488
|
+
);
|
|
13489
|
+
}
|
|
13490
|
+
function clearSection(section) {
|
|
13491
|
+
const spec = section.spec;
|
|
13492
|
+
if (spec && "onChange" in spec && spec.kind !== "sort") {
|
|
13493
|
+
spec.onChange(null);
|
|
13494
|
+
return;
|
|
13495
|
+
}
|
|
13496
|
+
if (section.operator === "isEmpty" || section.operator === "isNotEmpty") {
|
|
13497
|
+
const fallback = section.operators?.find((op) => op !== "isEmpty" && op !== "isNotEmpty");
|
|
13498
|
+
if (fallback) section.onOperatorChange?.(fallback);
|
|
13499
|
+
}
|
|
13500
|
+
if (section.onClear) {
|
|
13501
|
+
section.onClear();
|
|
13502
|
+
return;
|
|
13503
|
+
}
|
|
13504
|
+
for (const key of section.selected) section.onSelect(key);
|
|
13505
|
+
}
|
|
13506
|
+
function useDisplayMenuFilterChips(sections, options) {
|
|
13507
|
+
const filterMessages = useDsMessages("displayMenuFilters");
|
|
13508
|
+
const group = options?.group;
|
|
13509
|
+
const now = options?.now;
|
|
13510
|
+
return useMemo(() => {
|
|
13511
|
+
const grouped = sections.some((s) => s.group !== void 0);
|
|
13512
|
+
const eligible = sections.filter((section) => {
|
|
13513
|
+
if (section.spec?.kind === "sort" || section.spec?.kind === "columns") return false;
|
|
13514
|
+
if (group === "all" || !group && !grouped) return true;
|
|
13515
|
+
return section.group === (group ?? "filter");
|
|
13516
|
+
});
|
|
13517
|
+
const active = eligible.filter((section) => isDisplayMenuSectionActive(section));
|
|
13518
|
+
const byKey = new Map(active.map((s) => [s.key, s]));
|
|
13519
|
+
const facets = active.map((section) => {
|
|
13520
|
+
const valueList = !section.spec || section.spec.kind === "person" || section.spec.kind === "tags";
|
|
13521
|
+
const values = valueList && section.operator !== "isEmpty" && section.operator !== "isNotEmpty" ? section.options.filter((o) => section.selected.has(o.key)).map((o) => ({ key: o.key, label: o.label })) : void 0;
|
|
13522
|
+
return {
|
|
13523
|
+
key: section.key,
|
|
13524
|
+
label: section.label,
|
|
13525
|
+
summary: summarizeDisplayMenuSection(section, filterMessages, now ? { now } : void 0) ?? void 0,
|
|
13526
|
+
values
|
|
13527
|
+
};
|
|
13528
|
+
});
|
|
13529
|
+
return {
|
|
13530
|
+
facets,
|
|
13531
|
+
onRemove: (key) => {
|
|
13532
|
+
const section = byKey.get(key);
|
|
13533
|
+
if (section) clearSection(section);
|
|
13534
|
+
},
|
|
13535
|
+
onRemoveValue: (key, valueKey) => {
|
|
13536
|
+
const section = byKey.get(key);
|
|
13537
|
+
if (section?.selected.has(valueKey)) section.onSelect(valueKey);
|
|
13538
|
+
},
|
|
13539
|
+
onClearAll: () => {
|
|
13540
|
+
for (const section of active) clearSection(section);
|
|
13541
|
+
}
|
|
13542
|
+
};
|
|
13543
|
+
}, [sections, group, now, filterMessages]);
|
|
13544
|
+
}
|
|
10800
13545
|
var StickyStackContext = React30.createContext(null);
|
|
10801
13546
|
function StickyStack({
|
|
10802
13547
|
layers,
|
|
@@ -10965,6 +13710,148 @@ var StickyStackSectionHeader = React30.forwardRef(function StickyStackSectionHea
|
|
|
10965
13710
|
return /* @__PURE__ */ jsx(StickyStackSticky, { ref, "data-sticky-stack-section-header": "", ...props });
|
|
10966
13711
|
});
|
|
10967
13712
|
StickyStackSectionHeader.displayName = "StickyStackSectionHeader";
|
|
13713
|
+
var ListPage = forwardRef(function ListPage2({ stats, toolbar, bulkBar, children, className, ...props }, ref) {
|
|
13714
|
+
return /* @__PURE__ */ jsxs(
|
|
13715
|
+
"div",
|
|
13716
|
+
{
|
|
13717
|
+
ref,
|
|
13718
|
+
...slot(listPageAnatomy, "root"),
|
|
13719
|
+
className: cn(
|
|
13720
|
+
"ds:flex ds:h-full ds:min-h-0 ds:flex-col ds:gap-3 ds:overflow-hidden",
|
|
13721
|
+
className
|
|
13722
|
+
),
|
|
13723
|
+
...props,
|
|
13724
|
+
children: [
|
|
13725
|
+
stats != null && /* @__PURE__ */ jsx("div", { ...slot(listPageAnatomy, "stats"), className: "ds:shrink-0", children: stats }),
|
|
13726
|
+
toolbar,
|
|
13727
|
+
children,
|
|
13728
|
+
bulkBar != null && /* @__PURE__ */ jsx("div", { ...slot(listPageAnatomy, "bulk-bar"), className: "ds:shrink-0", children: bulkBar })
|
|
13729
|
+
]
|
|
13730
|
+
}
|
|
13731
|
+
);
|
|
13732
|
+
});
|
|
13733
|
+
ListPage.displayName = "ListPage";
|
|
13734
|
+
var ListPageToolbar = forwardRef(
|
|
13735
|
+
function ListPageToolbar2({ search, chips, count, actions, children, className, ...props }, ref) {
|
|
13736
|
+
return /* @__PURE__ */ jsxs(
|
|
13737
|
+
"div",
|
|
13738
|
+
{
|
|
13739
|
+
ref,
|
|
13740
|
+
...slot(listPageAnatomy, "toolbar"),
|
|
13741
|
+
className: cn("ds:flex ds:shrink-0 ds:flex-wrap ds:items-center ds:gap-2", className),
|
|
13742
|
+
...props,
|
|
13743
|
+
children: [
|
|
13744
|
+
search != null && /* @__PURE__ */ jsx("div", { ...slot(listPageAnatomy, "search"), className: "ds:flex ds:min-w-0 ds:shrink-0", children: search }),
|
|
13745
|
+
chips != null && /* @__PURE__ */ jsx("div", { ...slot(listPageAnatomy, "chips"), className: "ds:flex ds:min-w-0 ds:items-center", children: chips }),
|
|
13746
|
+
children,
|
|
13747
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ds:flex-1" }),
|
|
13748
|
+
count != null && /* @__PURE__ */ jsx("div", { ...slot(listPageAnatomy, "count"), className: "ds:flex ds:shrink-0 ds:items-center", children: count }),
|
|
13749
|
+
actions != null && /* @__PURE__ */ jsx(
|
|
13750
|
+
"div",
|
|
13751
|
+
{
|
|
13752
|
+
...slot(listPageAnatomy, "actions"),
|
|
13753
|
+
className: "ds:flex ds:shrink-0 ds:items-center ds:gap-2",
|
|
13754
|
+
children: actions
|
|
13755
|
+
}
|
|
13756
|
+
)
|
|
13757
|
+
]
|
|
13758
|
+
}
|
|
13759
|
+
);
|
|
13760
|
+
}
|
|
13761
|
+
);
|
|
13762
|
+
ListPageToolbar.displayName = "ListPageToolbar";
|
|
13763
|
+
var ListPageResultCount = forwardRef(
|
|
13764
|
+
function ListPageResultCount2({ total, start, end, loaded, locale, messages: messagesProp, className, ...props }, ref) {
|
|
13765
|
+
const messages = useDsMessages("listPage", messagesProp);
|
|
13766
|
+
const format3 = (n) => n.toLocaleString(locale);
|
|
13767
|
+
const text = loaded !== void 0 ? messages.loaded(format3(loaded), format3(total)) : start !== void 0 && end !== void 0 && total > 0 ? messages.range(format3(start), format3(end), format3(total)) : messages.total(format3(total));
|
|
13768
|
+
return /* @__PURE__ */ jsx(
|
|
13769
|
+
"span",
|
|
13770
|
+
{
|
|
13771
|
+
ref,
|
|
13772
|
+
role: "status",
|
|
13773
|
+
"aria-live": "polite",
|
|
13774
|
+
...slot(listPageAnatomy, "result-count"),
|
|
13775
|
+
className: cn(
|
|
13776
|
+
"ds:text-xs ds:whitespace-nowrap ds:text-fg-3 ds:tabular-nums",
|
|
13777
|
+
className
|
|
13778
|
+
),
|
|
13779
|
+
...props,
|
|
13780
|
+
children: text
|
|
13781
|
+
}
|
|
13782
|
+
);
|
|
13783
|
+
}
|
|
13784
|
+
);
|
|
13785
|
+
ListPageResultCount.displayName = "ListPageResultCount";
|
|
13786
|
+
var SCROLL_CHILD = cn(
|
|
13787
|
+
"ds:[&>[data-slot=table-wrapper]]:min-h-0 ds:[&>[data-slot=table-wrapper]]:flex-initial ds:[&>[data-slot=table-wrapper]]:overflow-auto",
|
|
13788
|
+
"ds:[&>[data-slot=table-wrapper]]:rounded-none ds:[&>[data-slot=table-wrapper]]:border-0 ds:[&>[data-slot=table-wrapper]]:shadow-none",
|
|
13789
|
+
"ds:[&>[data-slot=data-table]]:min-h-0 ds:[&>[data-slot=data-table]]:flex-initial ds:[&>[data-slot=data-table]]:overflow-auto",
|
|
13790
|
+
"ds:[&>[data-slot=data-table]]:rounded-none ds:[&>[data-slot=data-table]]:border-0 ds:[&>[data-slot=data-table]]:shadow-none"
|
|
13791
|
+
);
|
|
13792
|
+
var ListPageTable = forwardRef(function ListPageTable2({ footer, className, children, ...props }, ref) {
|
|
13793
|
+
return /* @__PURE__ */ jsxs(
|
|
13794
|
+
"div",
|
|
13795
|
+
{
|
|
13796
|
+
ref,
|
|
13797
|
+
...slot(listPageAnatomy, "table"),
|
|
13798
|
+
className: cn(
|
|
13799
|
+
"ds:flex ds:min-h-0 ds:min-w-0 ds:flex-initial ds:flex-col ds:overflow-hidden",
|
|
13800
|
+
"ds:rounded-surface-sm ds:border ds:border-rule-strong ds:bg-surface ds:shadow-quiet",
|
|
13801
|
+
SCROLL_CHILD,
|
|
13802
|
+
className
|
|
13803
|
+
),
|
|
13804
|
+
...props,
|
|
13805
|
+
children: [
|
|
13806
|
+
children,
|
|
13807
|
+
footer != null && /* @__PURE__ */ jsx(
|
|
13808
|
+
"div",
|
|
13809
|
+
{
|
|
13810
|
+
...slot(listPageAnatomy, "footer"),
|
|
13811
|
+
className: "ds:shrink-0 ds:border-t ds:border-rule ds:bg-surface ds:px-(--table-cell-padding-x) ds:py-3 ds:empty:hidden ds:[&>[data-slot=pagination]]:mt-0",
|
|
13812
|
+
children: footer
|
|
13813
|
+
}
|
|
13814
|
+
)
|
|
13815
|
+
]
|
|
13816
|
+
}
|
|
13817
|
+
);
|
|
13818
|
+
});
|
|
13819
|
+
ListPageTable.displayName = "ListPageTable";
|
|
13820
|
+
var ListPageScroll = forwardRef(
|
|
13821
|
+
function ListPageScroll2({ messages: messagesProp, className, ...props }, ref) {
|
|
13822
|
+
const messages = useDsMessages("listPage", messagesProp);
|
|
13823
|
+
const localRef = useRef(null);
|
|
13824
|
+
const mergedRef = useMergedRefs(ref, localRef);
|
|
13825
|
+
const [overflowing, setOverflowing] = useState(false);
|
|
13826
|
+
useEffect(() => {
|
|
13827
|
+
const element = localRef.current;
|
|
13828
|
+
if (!element || typeof ResizeObserver === "undefined") return;
|
|
13829
|
+
const measure = () => setOverflowing(
|
|
13830
|
+
element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1
|
|
13831
|
+
);
|
|
13832
|
+
measure();
|
|
13833
|
+
const observer = new ResizeObserver(measure);
|
|
13834
|
+
observer.observe(element);
|
|
13835
|
+
for (const child of Array.from(element.children)) observer.observe(child);
|
|
13836
|
+
return () => observer.disconnect();
|
|
13837
|
+
}, []);
|
|
13838
|
+
return /* @__PURE__ */ jsx(
|
|
13839
|
+
"div",
|
|
13840
|
+
{
|
|
13841
|
+
ref: mergedRef,
|
|
13842
|
+
...slot(listPageAnatomy, "scroll"),
|
|
13843
|
+
...overflowing ? { role: "region", "aria-label": props["aria-label"] ?? messages.tableRegion, tabIndex: 0 } : {},
|
|
13844
|
+
className: cn(
|
|
13845
|
+
"ds:min-h-0 ds:flex-initial ds:overflow-auto",
|
|
13846
|
+
overflowing && "ds:focus-visible:outline-none ds:focus-visible:[box-shadow:var(--shadow-focus-ring)]",
|
|
13847
|
+
className
|
|
13848
|
+
),
|
|
13849
|
+
...props
|
|
13850
|
+
}
|
|
13851
|
+
);
|
|
13852
|
+
}
|
|
13853
|
+
);
|
|
13854
|
+
ListPageScroll.displayName = "ListPageScroll";
|
|
10968
13855
|
|
|
10969
13856
|
// src/foundation/status-map.ts
|
|
10970
13857
|
function defineStatusMap(map) {
|
|
@@ -11698,6 +14585,6 @@ function useTableDensity(options) {
|
|
|
11698
14585
|
return { density, setDensity };
|
|
11699
14586
|
}
|
|
11700
14587
|
|
|
11701
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityEventItem, ActivityItem, ActivityList, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppHeader, AppHeaderActions, AppHeaderBreadcrumb, AppHeaderSearch, AppHeaderTitle, AppSidebar, AppSidebarNav, AreaChart, AspectRatio, AttachmentChip, AvatarGroup, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BulkActionBar, BulkActionBarAction, BulkActionBarSeparator, COUNTRY_CODES, Calendar, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Code, CommandPalette, ConfirmActionButton, ConfirmDialog, ConfirmHost, Content6 as Content, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CountryFlag2 as CountryFlag, CountrySelect, DATE_DISPLAY_PLACEHOLDER, DEFAULT_PHONE_FIELD_MESSAGES, DangerAction, DataItem, DataTablePattern, DatePicker, DateRangePicker, DesignSystemProvider, DetailGrid, DetailMain, DetailSpine, DetailSpineHeader, DetailSpineSection, DetailSpineStats, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DismissibleChip, DisplayMenu, DonutChart, EmptyState, ErrorState, Eyebrow, Field, FieldControl, FieldDescription, FieldError, Fieldset, FieldsetLegend, FileTypeBadge, FilterChip, FolderTree, FormError, FormSection, FormSuccess, Heading, HoverCard, HoverCardContent, HoverCardPortal, HoverCardTrigger, ICON_TILE_TONE_TO_INTENT, IconAction, IconTile, InfoHint, Inline, Kanban, KanbanCard, KanbanColumn, Kbd, KbdHint, KeyboardShortcutsDialog, KpiCard, Label2 as Label, LinkAction, LinkButton, LoadingRows, Main, MasterDetailLayout, MessageBubble, MessageBubbleAction, MessageBubbleTombstone, MessageComposer, MetadataGrid, MultiFilterPill, MultiSelect, MultiSelectField, MutedSpec, NotificationFilter, NotificationItem, NotificationList, NotificationPanel, NotificationPanelFooter, NotificationPanelHeader, NumberInput, Numeric, OTPInput, PageHeader, PageHeaderSep, PageHeaderSpec, PdfPreview, PeoplePicker, PhoneCountryInput, PhoneField, PhoneInput, PrimaryAction, PriorityIcon, QuestionnairePanel, RadioGroup2 as RadioGroup, RadioGroupItem, RankedBars, ResponsiveDialog, RouteTransition, ScrollArea, ScrollBar, SearchInput, SearchSelect, SecondaryAction, SectionCard, SegmentedControl, SelectableKpiCard, Separator2 as Separator, Shell, SideDrawer, Slider, SpreadsheetPreview, Stack, StackedBarChart, StarRating, StatusBadge, StatusIcon, Stepper, StickyActionBar, StickyStack, StickyStackLayer, StickyStackSectionHeader, StickyStackSticky, SubmitButton, SuiteProgress, Surface, TableDensityToggle, TableEmpty, TableError, TableLoading, Text, ToastProvider, Toolbar,
|
|
14588
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityEventItem, ActivityItem, ActivityList, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppHeader, AppHeaderActions, AppHeaderBreadcrumb, AppHeaderSearch, AppHeaderTitle, AppSidebar, AppSidebarNav, AreaChart, AspectRatio, AttachmentChip, AvatarGroup, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BulkActionBar, BulkActionBarAction, BulkActionBarMenu, BulkActionBarMenuItem, BulkActionBarMenuRadioGroup, BulkActionBarMenuSub, BulkActionBarMore, BulkActionBarPicker, BulkActionBarSeparator, COUNTRY_CODES, Calendar, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Code, CommandPalette, ConfirmActionButton, ConfirmDialog, ConfirmHost, Content6 as Content, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CountryFlag2 as CountryFlag, CountrySelect, DATE_DISPLAY_PLACEHOLDER, DEFAULT_PHONE_FIELD_MESSAGES, DangerAction, DataItem, DataTablePattern, DatePicker, DateRangePicker, DesignSystemProvider, DetailGrid, DetailMain, DetailSpine, DetailSpineHeader, DetailSpineSection, DetailSpineStats, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DismissibleChip, DisplayMenu, DonutChart, EmptyState, ErrorState, Eyebrow, Field, FieldControl, FieldDescription, FieldError, Fieldset, FieldsetLegend, FileTypeBadge, FilterChip, FilterChips, FolderTree, FormError, FormSection, FormSuccess, Heading, HoverCard, HoverCardContent, HoverCardPortal, HoverCardTrigger, ICON_TILE_TONE_TO_INTENT, IconAction, IconTile, InfoHint, Inline, Kanban, KanbanCard, KanbanColumn, Kbd, KbdHint, KeyboardShortcutsDialog, KpiCard, Label2 as Label, LinkAction, LinkButton, ListPage, ListPageResultCount, ListPageScroll, ListPageTable, ListPageToolbar, LoadingRows, Main, MasterDetailLayout, MessageBubble, MessageBubbleAction, MessageBubbleTombstone, MessageComposer, MetadataGrid, MultiFilterPill, MultiSelect, MultiSelectField, MutedSpec, NotificationFilter, NotificationItem, NotificationList, NotificationPanel, NotificationPanelFooter, NotificationPanelHeader, NumberInput, Numeric, OTPInput, PageHeader, PageHeaderSep, PageHeaderSpec, PdfPreview, PeoplePicker, PhoneCountryInput, PhoneField, PhoneInput, PrimaryAction, PriorityIcon, QuestionnairePanel, RadioGroup2 as RadioGroup, RadioGroupItem, RankedBars, ResponsiveDialog, RouteTransition, ScrollArea, ScrollBar, SearchInput, SearchSelect, SecondaryAction, SectionCard, SegmentedControl, SelectableKpiCard, Separator2 as Separator, Shell, SideDrawer, Slider, SpreadsheetPreview, Stack, StackedBarChart, StarRating, StatStrip, StatStripItem, StatusBadge, StatusIcon, Stepper, StickyActionBar, StickyStack, StickyStackLayer, StickyStackSectionHeader, StickyStackSticky, SubmitButton, SuiteProgress, Surface, TableDensityToggle, TableEmpty, TableError, TableLoading, Text, ToastProvider, Toolbar, YEAR_DISPLAY_PLACEHOLDER, alertVariants, applyMask, applyYearMask, attachmentChipVariants, cardVariants, dateToIso, defineStatusMap, detectDisplayMenuDatePreset, displayToIso, fileTypeBadgeVariants, fileTypeFromName, filterChipVariants, getFlagEmoji, resolveIconTileVariants as iconTileVariants, isDisplayMenuSectionActive, isoToDate, isoToDisplay, isoToYear, labelVariants, matchesDisplayMenuDate, matchesDisplayMenuNumber, matchesDisplayMenuOperator, matchesDisplayMenuTags, matchesDisplayMenuText, parseDisplayMenuNumber, parsePhoneForEditing, resolveDisplayMenuDatePreset, searchInputVariants, sharedBulkValue, starRatingVariants, suiteProgressFillVariants, summarizeDisplayMenuSection, useConfirm, useDisplayMenuFilterChips, usePrompt, useTableDensity, useToast, yearToIso };
|
|
11702
14589
|
//# sourceMappingURL=index.js.map
|
|
11703
14590
|
//# sourceMappingURL=index.js.map
|