@leta-io/components 0.5.1 → 0.6.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.
Binary file
Binary file
Binary file
Binary file
package/dist/index.d.ts CHANGED
@@ -1527,8 +1527,10 @@ interface BreadcrumbsProps extends React.HTMLAttributes<HTMLElement> {
1527
1527
  * dropdown (the overlay itself is a separate component); for `global-client`
1528
1528
  * it optionally navigates to the client home. When omitted, the
1529
1529
  * `global-client` root renders as a non-interactive label (matching Figma).
1530
+ * Receives the click event: anchor a switcher to `e.currentTarget` (Safari does
1531
+ * not focus buttons on click, so `document.activeElement` is unreliable).
1530
1532
  */
1531
- onClientClick?: () => void;
1533
+ onClientClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
1532
1534
  }
1533
1535
  /**
1534
1536
  * Breadcrumbs — a horizontal trail showing the user's location in a hierarchy,
@@ -2533,8 +2535,12 @@ interface ToastProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'
2533
2535
  /** Renders a trailing dismiss (×) button and is the dismiss handler. */
2534
2536
  onDismiss?: () => void;
2535
2537
  /**
2536
- * Auto-dismiss delay in ms. When set together with `onDismiss`, the toast
2537
- * fires `onDismiss` after this delay. LETA toasts persist ~7000ms.
2538
+ * Auto-dismiss delay in ms. With `onDismiss`, the toast shows a **progress bar**
2539
+ * along its top edge that runs from full to empty over this time, then fires
2540
+ * `onDismiss`. Hovering the toast, or focusing anything in it, pauses both, and
2541
+ * leaving resumes from where it stopped (Figma `68:36772`, 2026-10-27). LETA uses
2542
+ * 6000ms, or 8000ms when the toast carries an action (Doc 3 §4). Read when the
2543
+ * toast mounts.
2538
2544
  */
2539
2545
  duration?: number;
2540
2546
  /** Optional trailing CTA (a `<Button>`), shown when `showCTA`. */
@@ -2545,11 +2551,13 @@ interface ToastProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'
2545
2551
  /**
2546
2552
  * Desktop Toast — a transient, auto-dismissing notification confirming the
2547
2553
  * outcome of an action. Per Doc 3 §4, the consumer's toast container places
2548
- * these top-right (stacking downward, newest on top) and persists them 6s by
2549
- * default / 8s when a CTA is present (set `duration`); positioning/stacking is
2550
- * owned by that container, this component is the visual surface. `type="error"`
2551
- * (a destructive outcome) renders `role="alert"`/`aria-live="assertive"`
2552
- * instead of `role="status"`/`polite`. Figma `68:36772`.
2554
+ * these at the window's **bottom-left** (newest at the bottom, nearest the
2555
+ * corner) and persists them 6s by default / 8s when a CTA is present (set
2556
+ * `duration`); positioning and stacking are the container's, this component is
2557
+ * the visual surface and owns the countdown — a 4px progress bar across its top
2558
+ * edge, paused while hovered or focused. `type="error"` (a destructive outcome)
2559
+ * renders `role="alert"`/`aria-live="assertive"` instead of `role="status"`/
2560
+ * `polite`. Figma `68:36772`.
2553
2561
  */
2554
2562
  declare const Toast: React.ForwardRefExoticComponent<ToastProps & React.RefAttributes<HTMLDivElement>>;
2555
2563
 
@@ -2824,7 +2832,7 @@ interface TruncatedIdTextProps {
2824
2832
  */
2825
2833
  declare function TruncatedIdText({ id, className, color, style }: TruncatedIdTextProps): React.ReactElement;
2826
2834
 
2827
- type EmptyStateType = 'no-results' | 'no-reviews' | 'no-broadcast-logs' | 'image-upload' | 'file-upload' | 'no-suspensions' | 'no-items' | 'no-orders' | 'no-network' | 'new-update' | 'no-data' | 'no-trips' | 'no-drivers' | 'no-products' | 'error' | 'comments' | 'notifications' | 'calendar' | 'recording';
2835
+ type EmptyStateType = 'no-results' | 'no-reviews' | 'no-broadcast-logs' | 'image-upload' | 'file-upload' | 'no-suspensions' | 'no-items' | 'no-orders' | 'no-network' | 'new-update' | 'no-data' | 'no-trips' | 'no-drivers' | 'no-products' | 'error' | 'comments' | 'notifications' | 'calendar' | 'recording' | 'check';
2828
2836
  type EmptyStateSize = 'mobile' | 'desktop';
2829
2837
  interface EmptyStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
2830
2838
  /** Preset scenario — sets the illustration + default copy. Default `no-orders`. */
@@ -3277,6 +3285,18 @@ interface MapSearchResultGroup {
3277
3285
  /** The group's rows — `DesktopMenuOptions type="dropdown-advanced"`, 4px apart. */
3278
3286
  children: React.ReactNode;
3279
3287
  }
3288
+ /**
3289
+ * Which keyboard hints the footer shows (Doc 11 §11 — only the ones that work
3290
+ * right now). Each field overrides the state's default.
3291
+ */
3292
+ interface MapSearchFooterHints {
3293
+ /** "↑ ↓ to select" — there is at least one item to highlight. */
3294
+ select?: boolean;
3295
+ /** "Tab to switch filter" — chips are showing. */
3296
+ switchFilter?: boolean;
3297
+ /** "↵ to open / to view / to search", by what is highlighted; `null` hides it. */
3298
+ enter?: 'open' | 'view' | 'search' | null;
3299
+ }
3280
3300
  interface MapSearchInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
3281
3301
  /** Panel state. `idle` = field only; the rest attach a results panel. Default `active-results`. */
3282
3302
  state?: MapSearchState;
@@ -3317,6 +3337,28 @@ interface MapSearchInputProps extends Omit<React.InputHTMLAttributes<HTMLInputEl
3317
3337
  /** Replaces the panel body (the recent-search list or the result groups). */
3318
3338
  children?: React.ReactNode;
3319
3339
  disabled?: boolean;
3340
+ /** A search is running: a spinner sits beside the × (Doc 11 §6). */
3341
+ loading?: boolean;
3342
+ /** The ×'s accessible name. Default "Clear Search"; the global overlay, whose × closes it, passes "Close search". */
3343
+ clearLabel?: string;
3344
+ /** Override the footer's per-state hints (see {@link MapSearchFooterHints}). */
3345
+ footerHints?: MapSearchFooterHints;
3346
+ /**
3347
+ * `active-results` only: start at 360 and grow with the results up to 480, then
3348
+ * scroll the body (Doc 11 §3). Default false — a fixed 480.
3349
+ */
3350
+ fitHeight?: boolean;
3351
+ /**
3352
+ * Whether the filter chips are in the tab order. Default true. A consumer that
3353
+ * keeps focus in the input and moves between chips with Tab itself (the Search
3354
+ * Overlay, Doc 3 §15) passes false: the chips leave the tab order and a click on
3355
+ * one doesn't take focus from the input.
3356
+ */
3357
+ filtersTabbable?: boolean;
3358
+ /** Ref to the scrolling body (`active-history` / `active-results`) — for scroll-into-view and load-more. */
3359
+ bodyRef?: React.Ref<HTMLDivElement>;
3360
+ /** Props for the scrolling body, e.g. `role="listbox"` and an `id` for `aria-controls`. */
3361
+ bodyProps?: React.HTMLAttributes<HTMLDivElement>;
3320
3362
  }
3321
3363
  /**
3322
3364
  * Overlay search — the `Search Input` type of Data Entry `38:42`, **Overlay** variant.
@@ -3534,6 +3576,26 @@ interface DesktopMenuOptionsProps extends Omit<React.HTMLAttributes<HTMLDivEleme
3534
3576
  subtext?: string;
3535
3577
  /** dropdown-advanced: full content override (else a flat title + subtext + chevron is built from label/subtext). */
3536
3578
  content?: React.ReactNode;
3579
+ /**
3580
+ * dropdown-advanced: the Library's **Leading Content** SLOT — replaces the
3581
+ * built-in icon + title + subtext with caller content (e.g. a title carrying a
3582
+ * status badge and bold match text, as the Search Overlay's result rows do).
3583
+ * Fills the row; the Trailing Content slot keeps its place beside it.
3584
+ */
3585
+ leadingContent?: React.ReactNode;
3586
+ /**
3587
+ * dropdown-advanced: the Library's **Trailing Content** SLOT — e.g. the arrow a
3588
+ * search result shows on hover, or (Search Overlay v2) its actions button.
3589
+ * Replaces the chevron.
3590
+ */
3591
+ trailingContent?: React.ReactNode;
3592
+ /**
3593
+ * Draw the row in its Hover look without the pointer on it — a **keyboard
3594
+ * highlight** (a listbox's active option). When this prop is passed at all, the
3595
+ * row stops tracking its own hover: highlight is then the caller's alone, so a
3596
+ * pointer resting on one row and arrow keys on another never light up two rows.
3597
+ */
3598
+ highlighted?: boolean;
3537
3599
  /**
3538
3600
  * filter-group: how many options are currently selected in the List section.
3539
3601
  * Drives the single "{n} selected" chip shown beneath the label; the chip is
@@ -3728,7 +3790,7 @@ interface DesktopDropdownsProps extends Omit<React.HTMLAttributes<HTMLDivElement
3728
3790
  /**
3729
3791
  * Override the empty-state message for the `combobox-empty` / `combobox-search-empty`
3730
3792
  * variants (e.g. "No depots found"). Defaults to the `no-results` preset copy
3731
- * ("Try adjusting your search.").
3793
+ * ("Check the spelling or adjust your filters").
3732
3794
  */
3733
3795
  emptyDescription?: string;
3734
3796
  /** User Menu display name. */
@@ -4941,8 +5003,12 @@ interface TopBarProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'
4941
5003
  };
4942
5004
  /** Fired when the notification bell is clicked. */
4943
5005
  onNotificationsClick?: () => void;
4944
- /** Fired when the User-Menu is clicked. */
4945
- onUserMenuClick?: () => void;
5006
+ /**
5007
+ * Fired when the User-Menu is clicked, with the click event — anchor the menu to
5008
+ * `e.currentTarget`, not `document.activeElement` (Safari doesn't focus buttons
5009
+ * on click, so `activeElement` is `<body>` and the menu lands at 0,0).
5010
+ */
5011
+ onUserMenuClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
4946
5012
  /**
4947
5013
  * Show the global search field in the centre of the bar (Figma 2026-10-06 — it
4948
5014
  * moved here from the Side Bar). Default `true`.
@@ -5446,4 +5512,4 @@ interface ExtraLargeModalProps extends Omit<React.HTMLAttributes<HTMLDivElement>
5446
5512
  */
5447
5513
  declare const ExtraLargeModal: React.ForwardRefExoticComponent<ExtraLargeModalProps & React.RefAttributes<HTMLDivElement>>;
5448
5514
 
5449
- export { ALL_ORDER_COLUMNS, AVATAR_PHOTOS, AccordionChevron, AccordionContent, AccordionHeader, type AccordionHeaderProps, AlertDialog, type AlertDialogProps, type AlertDialogVariant, Avatar, type AvatarProps, type AvatarSize, type AvatarTone, BROADCASTED_ORDER_COLUMNS, Badge, type BadgeColor, type BadgeProps, type BreadcrumbCrumb, Breadcrumbs, type BreadcrumbsProps, type BreadcrumbsType, Button, type ButtonPlatform, type ButtonProps, type ButtonSize, type ButtonVariant, CANCELLED_ORDER_COLUMNS, CARET_SIDE, CREATED_BY_COLUMN, Calendar, type CalendarProps, type CaretAlign, type CaretSide, CarouselPagination, type CarouselPaginationProps, Cell, type CellProps, type CellState, type CellType, Checkbox, type CheckboxProps, Chip, type ChipProps, CollapsedSidebarLogo, type CollapsedSidebarLogoProps, ConfigurationCard, type ConfigurationCardProps, type ConfigurationCardState, ConfigurationContainer, type ConfigurationContainerProps, ContentCard, type ContentCardProps, ContentPrimitives, type ContentPrimitivesProps, type ContentPrimitivesType, DEFAULT_SORT_OPTIONS, DIALOG_OVERLAY_DEFAULT_TIER, DOORSTEP_DELIVERY_IMAGE, type DataRowCell, DataRows, type DataRowsProps, type DataRowsState, type DataRowsVariant, DateTimePicker, type DateTimePickerProps, type DateTimePickerType, type DesktopDropdownVariant, DesktopDropdowns, type DesktopDropdownsProps, type DesktopMenuOptionState, type DesktopMenuOptionType, DesktopMenuOptions, type DesktopMenuOptionsProps, DesktopMetricCard, type DesktopMetricCardProps, DesktopProgressIndicator, type DesktopProgressIndicatorProps, type DesktopProgressIndicatorVariant, DesktopSegmentControl, type DesktopSegmentControlItem, type DesktopSegmentControlProps, type DesktopSegmentControlVariant, DialogOverlay, type DialogOverlayHelpers, type DialogOverlayProps, DurationLabel, type DurationLabelProps, type DurationLabelStatus, type DurationLabelVariant, EmptyState, type EmptyStateProps, type EmptyStateSize, type EmptyStateType, ExtraLargeModal, type ExtraLargeModalProps, FeaturedIcon, type FeaturedIconColor, type FeaturedIconProps, type FeaturedIconSize, FileUpload, FileUploadCard, type FileUploadCardProps, type FileUploadCardStatus, type FileUploadProps, type FilterGroupDimension, Flag, type FlagProps, FloatingToolbar, type FloatingToolbarActionsProps, type FloatingToolbarContextProps, type FloatingToolbarPlacement, type FloatingToolbarProps, FooterFrame, type FooterFrameProps, type FooterFrameVariant, FormDemarcator, GroupedInput, type GroupedInputProps, type GroupedInputVariant, HoverTip, type HoverTipProps, InputField, type InputFieldProps, type InputFieldVariant, InputGroup, type InputGroupProps, InputSection, type InputSectionProps, LAST_UPDATED_COLUMN, LargeModal, type LargeModalProps, type LargeModalVariant, LeadingInputFieldElement, type LeadingInputFieldElementProps, type LeadingInputFieldElementVariant, LetaLogo, type LetaLogoProps, ListGroup, type ListGroupProps, type ListItemData, ListSection, type ListSectionProps, LoadingOverlay, type LoadingOverlayProps, MAP_ROUTE_DRIVEN, MAP_ROUTE_PLANNED, MapIcon, type MapIconProps, type MapIconVariant, MapLegend, type MapLegendEntry, type MapLegendProps, MapSearchInput, type MapSearchInputProps, type MapSearchResultGroup, type MapSearchState, MapView, type MapViewProps, MapZoomControl, type MapZoomControlProps, MenuDivider, MenuFlyout, type MenuFlyoutProps, MenuPanel, type MenuPanelProps, type MetricCardState, type MetricVariance, MobileBadge, type MobileBadgeColor, type MobileBadgeProps, type MobileBadgeVariant, MobileChip, type MobileChipProps, MobileDropdown, type MobileDropdownOption, type MobileDropdownProps, MobileFeaturedIcon, type MobileFeaturedIconColor, type MobileFeaturedIconProps, type MobileFeaturedIconSize, type MobileFeaturedIconVariant, MobileFileUpload, type MobileFileUploadImage, type MobileFileUploadProps, MobileMapSearchInput, type MobileMapSearchInputProps, type MobileMenuOptionState, type MobileMenuOptionType, MobileMenuOptions, type MobileMenuOptionsProps, MobileNavTab, type MobileNavTabProps, MobileSearchInput, type MobileSearchInputProps, MobileSegment, type MobileSegmentProps, ModalDialog, type ModalDialogProps, type ModalDialogVariant, ModalHeaders, type ModalHeadersProps, type ModalHeadersVariant, ModalShell, type ModalShellProps, NotificationBanner, type NotificationBannerProps, type NotificationBannerType, type NotificationBannerVariant, ORDER_TABLE_COLUMNS, ORDER_TABLE_COLUMNS_FINISHED, OptionCard, type OptionCardProps, type OptionCardState, Page, type PageProps, PageTab, type PageTabProps, PageTabsControl, type PageTabsControlItem, type PageTabsControlProps, type PageTabsControlVariant, type PageVariant, Pagination, type PaginationProps, type PaginationVariant, Placeholder, type PlaceholderProps, Popover, type PopoverPlacement, type PopoverProps, ProgressTracker, type ProgressTrackerProps, RadioButton, type RadioButtonProps, SCHEDULED_ORDER_COLUMNS, SIGNATURE_IMAGE, type ScrollEdges, SearchInput, type SearchInputProps, SegmentSwitcherTab, type SegmentSwitcherTabProps, Select, type SelectProps, type SelectedFilterChip, SelectedFilterControl, type SelectedFilterControlProps, SelectionControl, type SelectionControlProps, type SelectionControlVariant, Shortcut, ShortcutHint, type ShortcutHintProps, type ShortcutKey, type ShortcutProps, SideBar, type SideBarGroup, type SideBarItem, type SideBarProps, type SideBarVariant, Sidetab, type SidetabItem, type SidetabProps, Skeleton, type SkeletonProps, type SortOption, StackedCards, type StackedCardsProps, Stepper, StepperInput, type StepperInputProps, type StepperProps, type StepperVariant, type SurroundingTheme, Table, type TableColumn, type TableColumnRole, TableContainer, type TableContainerProps, type TableContainerVariant, TableDataControl, type TableDataControlProps, type TableDataControlVariant, type TableProps, type TableRow, TableSection, type TableSectionProps, Tag, type TagProps, TextArea, type TextAreaBasicProps, type TextAreaProps, type TextAreaRichProps, type TextAreaVariant, Title, type TitleProps, type TitleVariant, Toast, type ToastProps, type ToastType, Toggle, ToggleButton, type ToggleButtonProps, type ToggleProps, Tooltip, type TooltipPlatform, type TooltipPosition, type TooltipPositionInput, type TooltipProps, type TooltipRect, type TooltipSide, type TooltipVariant, TopBar, type TopBarProps, type TopBarVariant, TopFilter, type TopFilterProps, TopFilterSection, type TopFilterSectionItem, type TopFilterSectionProps, TrailingInputFieldElement, type TrailingInputFieldElementProps, type TrailingInputFieldElementVariant, TruncatedIdText, type TruncatedIdTextProps, TruncatedText, type TruncatedTextProps, UNASSIGNED_ORDER_COLUMNS, UserMenu, type UserMenuProps, type UserMenuState, ViewSwitcherTab, type ViewSwitcherTabProps, WizardTab, type WizardTabProps, abbreviateId, animateScrollTop, computeTooltipPosition, downloadFile, htmlToPlainText, inverseTheme, sanitizeRichText, sortLabelFor, useAccordion, useEscapeLayer, useRovingFocus, useScrollEdges, useScrollShadow, useSurroundingTheme };
5515
+ export { ALL_ORDER_COLUMNS, AVATAR_PHOTOS, AccordionChevron, AccordionContent, AccordionHeader, type AccordionHeaderProps, AlertDialog, type AlertDialogProps, type AlertDialogVariant, Avatar, type AvatarProps, type AvatarSize, type AvatarTone, BROADCASTED_ORDER_COLUMNS, Badge, type BadgeColor, type BadgeProps, type BreadcrumbCrumb, Breadcrumbs, type BreadcrumbsProps, type BreadcrumbsType, Button, type ButtonPlatform, type ButtonProps, type ButtonSize, type ButtonVariant, CANCELLED_ORDER_COLUMNS, CARET_SIDE, CREATED_BY_COLUMN, Calendar, type CalendarProps, type CaretAlign, type CaretSide, CarouselPagination, type CarouselPaginationProps, Cell, type CellProps, type CellState, type CellType, Checkbox, type CheckboxProps, Chip, type ChipProps, CollapsedSidebarLogo, type CollapsedSidebarLogoProps, ConfigurationCard, type ConfigurationCardProps, type ConfigurationCardState, ConfigurationContainer, type ConfigurationContainerProps, ContentCard, type ContentCardProps, ContentPrimitives, type ContentPrimitivesProps, type ContentPrimitivesType, DEFAULT_SORT_OPTIONS, DIALOG_OVERLAY_DEFAULT_TIER, DOORSTEP_DELIVERY_IMAGE, type DataRowCell, DataRows, type DataRowsProps, type DataRowsState, type DataRowsVariant, DateTimePicker, type DateTimePickerProps, type DateTimePickerType, type DesktopDropdownVariant, DesktopDropdowns, type DesktopDropdownsProps, type DesktopMenuOptionState, type DesktopMenuOptionType, DesktopMenuOptions, type DesktopMenuOptionsProps, DesktopMetricCard, type DesktopMetricCardProps, DesktopProgressIndicator, type DesktopProgressIndicatorProps, type DesktopProgressIndicatorVariant, DesktopSegmentControl, type DesktopSegmentControlItem, type DesktopSegmentControlProps, type DesktopSegmentControlVariant, DialogOverlay, type DialogOverlayHelpers, type DialogOverlayProps, DurationLabel, type DurationLabelProps, type DurationLabelStatus, type DurationLabelVariant, EmptyState, type EmptyStateProps, type EmptyStateSize, type EmptyStateType, ExtraLargeModal, type ExtraLargeModalProps, FeaturedIcon, type FeaturedIconColor, type FeaturedIconProps, type FeaturedIconSize, FileUpload, FileUploadCard, type FileUploadCardProps, type FileUploadCardStatus, type FileUploadProps, type FilterGroupDimension, Flag, type FlagProps, FloatingToolbar, type FloatingToolbarActionsProps, type FloatingToolbarContextProps, type FloatingToolbarPlacement, type FloatingToolbarProps, FooterFrame, type FooterFrameProps, type FooterFrameVariant, FormDemarcator, GroupedInput, type GroupedInputProps, type GroupedInputVariant, HoverTip, type HoverTipProps, InputField, type InputFieldProps, type InputFieldVariant, InputGroup, type InputGroupProps, InputSection, type InputSectionProps, LAST_UPDATED_COLUMN, LargeModal, type LargeModalProps, type LargeModalVariant, LeadingInputFieldElement, type LeadingInputFieldElementProps, type LeadingInputFieldElementVariant, LetaLogo, type LetaLogoProps, ListGroup, type ListGroupProps, type ListItemData, ListSection, type ListSectionProps, LoadingOverlay, type LoadingOverlayProps, MAP_ROUTE_DRIVEN, MAP_ROUTE_PLANNED, MapIcon, type MapIconProps, type MapIconVariant, MapLegend, type MapLegendEntry, type MapLegendProps, type MapSearchFooterHints, MapSearchInput, type MapSearchInputProps, type MapSearchResultGroup, type MapSearchState, MapView, type MapViewProps, MapZoomControl, type MapZoomControlProps, MenuDivider, MenuFlyout, type MenuFlyoutProps, MenuPanel, type MenuPanelProps, type MetricCardState, type MetricVariance, MobileBadge, type MobileBadgeColor, type MobileBadgeProps, type MobileBadgeVariant, MobileChip, type MobileChipProps, MobileDropdown, type MobileDropdownOption, type MobileDropdownProps, MobileFeaturedIcon, type MobileFeaturedIconColor, type MobileFeaturedIconProps, type MobileFeaturedIconSize, type MobileFeaturedIconVariant, MobileFileUpload, type MobileFileUploadImage, type MobileFileUploadProps, MobileMapSearchInput, type MobileMapSearchInputProps, type MobileMenuOptionState, type MobileMenuOptionType, MobileMenuOptions, type MobileMenuOptionsProps, MobileNavTab, type MobileNavTabProps, MobileSearchInput, type MobileSearchInputProps, MobileSegment, type MobileSegmentProps, ModalDialog, type ModalDialogProps, type ModalDialogVariant, ModalHeaders, type ModalHeadersProps, type ModalHeadersVariant, ModalShell, type ModalShellProps, NotificationBanner, type NotificationBannerProps, type NotificationBannerType, type NotificationBannerVariant, ORDER_TABLE_COLUMNS, ORDER_TABLE_COLUMNS_FINISHED, OptionCard, type OptionCardProps, type OptionCardState, Page, type PageProps, PageTab, type PageTabProps, PageTabsControl, type PageTabsControlItem, type PageTabsControlProps, type PageTabsControlVariant, type PageVariant, Pagination, type PaginationProps, type PaginationVariant, Placeholder, type PlaceholderProps, Popover, type PopoverPlacement, type PopoverProps, ProgressTracker, type ProgressTrackerProps, RadioButton, type RadioButtonProps, SCHEDULED_ORDER_COLUMNS, SIGNATURE_IMAGE, type ScrollEdges, SearchInput, type SearchInputProps, SegmentSwitcherTab, type SegmentSwitcherTabProps, Select, type SelectProps, type SelectedFilterChip, SelectedFilterControl, type SelectedFilterControlProps, SelectionControl, type SelectionControlProps, type SelectionControlVariant, Shortcut, ShortcutHint, type ShortcutHintProps, type ShortcutKey, type ShortcutProps, SideBar, type SideBarGroup, type SideBarItem, type SideBarProps, type SideBarVariant, Sidetab, type SidetabItem, type SidetabProps, Skeleton, type SkeletonProps, type SortOption, StackedCards, type StackedCardsProps, Stepper, StepperInput, type StepperInputProps, type StepperProps, type StepperVariant, type SurroundingTheme, Table, type TableColumn, type TableColumnRole, TableContainer, type TableContainerProps, type TableContainerVariant, TableDataControl, type TableDataControlProps, type TableDataControlVariant, type TableProps, type TableRow, TableSection, type TableSectionProps, Tag, type TagProps, TextArea, type TextAreaBasicProps, type TextAreaProps, type TextAreaRichProps, type TextAreaVariant, Title, type TitleProps, type TitleVariant, Toast, type ToastProps, type ToastType, Toggle, ToggleButton, type ToggleButtonProps, type ToggleProps, Tooltip, type TooltipPlatform, type TooltipPosition, type TooltipPositionInput, type TooltipProps, type TooltipRect, type TooltipSide, type TooltipVariant, TopBar, type TopBarProps, type TopBarVariant, TopFilter, type TopFilterProps, TopFilterSection, type TopFilterSectionItem, type TopFilterSectionProps, TrailingInputFieldElement, type TrailingInputFieldElementProps, type TrailingInputFieldElementVariant, TruncatedIdText, type TruncatedIdTextProps, TruncatedText, type TruncatedTextProps, UNASSIGNED_ORDER_COLUMNS, UserMenu, type UserMenuProps, type UserMenuState, ViewSwitcherTab, type ViewSwitcherTabProps, WizardTab, type WizardTabProps, abbreviateId, animateScrollTop, computeTooltipPosition, downloadFile, htmlToPlainText, inverseTheme, sanitizeRichText, sortLabelFor, useAccordion, useEscapeLayer, useRovingFocus, useScrollEdges, useScrollShadow, useSurroundingTheme };
package/dist/index.js CHANGED
@@ -836,11 +836,17 @@ var BUTTON_STYLES = `
836
836
  }
837
837
  /* Plain underline spans the whole content row (icons + label), not just the
838
838
  text run \u2014 text-decoration:underline only underlines inline text, leaving
839
- the flex-item icons un-underlined. A bottom border on the flex container
840
- draws one continuous line under the leading icon, label, gap, and trailing
841
- icon, matching Figma. currentColor tracks --leta-btn-text across states. */
839
+ the flex-item icons un-underlined. A 1px line painted across the bottom of
840
+ the flex container runs under the leading icon, label, gap and trailing
841
+ icon. It is painted INSIDE the box (Figma's Underline is a zero-height
842
+ vector at the bottom of the 20/16px box), so it adds no height: a
843
+ border-bottom made Medium 21 and Small 17 (fixed 2026-10-21).
844
+ currentColor tracks --leta-btn-text across states. */
842
845
  .leta-btn--plain.leta-btn--underline {
843
- border-bottom: 1px solid currentColor;
846
+ background-image: linear-gradient(currentColor, currentColor);
847
+ background-size: 100% var(--stroke-xs);
848
+ background-position: 0 100%;
849
+ background-repeat: no-repeat;
844
850
  }
845
851
  `;
846
852
  function ensureStylesInjected2() {
@@ -3198,7 +3204,14 @@ var STYLES4 = `
3198
3204
  .leta-search-field__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
3199
3205
  .leta-search-field__input:disabled { cursor: not-allowed; }
3200
3206
  .leta-search-field__input:disabled::placeholder { color: var(--text-disabled-placeholder-disabled); }
3207
+ @keyframes leta-search-field-spin { to { transform: rotate(360deg); } }
3208
+ .leta-search-field__spinner { display: flex; animation: leta-search-field-spin 0.9s linear infinite; }
3209
+ @media (prefers-reduced-motion: reduce) { .leta-search-field__spinner { animation: none; } }
3201
3210
  `;
3211
+ function SearchFieldSpinner() {
3212
+ ensureStyles9();
3213
+ return /* @__PURE__ */ jsx31("span", { className: "leta-search-field__spinner", role: "status", "aria-label": "Searching", style: { flexShrink: 0, color: "var(--icons-neutral-idle)" }, children: /* @__PURE__ */ jsx31(Icon16, { name: "Loading", size: 16 }) });
3214
+ }
3202
3215
  function ensureStyles9() {
3203
3216
  if (typeof document === "undefined") return;
3204
3217
  if (document.getElementById(STYLE_ID12)) return;
@@ -3222,6 +3235,11 @@ var SearchField = /* @__PURE__ */ React31.forwardRef(function SearchField2({
3222
3235
  onChange,
3223
3236
  className,
3224
3237
  style,
3238
+ trailing,
3239
+ clearLabel = "Clear Search",
3240
+ clearVariant = "glyph",
3241
+ onFocus,
3242
+ onBlur,
3225
3243
  ...inputProps
3226
3244
  }, ref) {
3227
3245
  ensureStyles9();
@@ -3278,22 +3296,35 @@ var SearchField = /* @__PURE__ */ React31.forwardRef(function SearchField2({
3278
3296
  },
3279
3297
  onFocus: (e) => {
3280
3298
  setFocused(true);
3281
- inputProps.onFocus?.(e);
3299
+ onFocus?.(e);
3282
3300
  },
3283
3301
  onBlur: (e) => {
3284
3302
  setFocused(false);
3285
- inputProps.onBlur?.(e);
3303
+ onBlur?.(e);
3286
3304
  },
3287
3305
  style: { color: disabled ? "var(--text-disabled-placeholder-disabled)" : "var(--text-default-label)" },
3288
3306
  ...inputProps
3289
3307
  }
3290
3308
  ),
3291
- clearVisible && /* @__PURE__ */ jsx31(
3309
+ trailing,
3310
+ clearVisible && clearVariant === "ghost" && // Figma's open Overlay: Extra Small Ghost icon-only (24×24), 16 from the value.
3311
+ /* @__PURE__ */ jsx31(
3312
+ Button,
3313
+ {
3314
+ variant: "ghost",
3315
+ size: "extra-small",
3316
+ iconOnly: "Cancel",
3317
+ "aria-label": clearLabel,
3318
+ onClick: handleClear,
3319
+ style: { flexShrink: 0, marginLeft: "calc(var(--spacing-16px) - var(--spacing-8px))" }
3320
+ }
3321
+ ),
3322
+ clearVisible && clearVariant === "glyph" && /* @__PURE__ */ jsx31(
3292
3323
  "button",
3293
3324
  {
3294
3325
  type: "button",
3295
3326
  onClick: handleClear,
3296
- "aria-label": "Clear Search",
3327
+ "aria-label": clearLabel,
3297
3328
  style: { flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center", border: 0, background: "transparent", padding: 0, cursor: "pointer", color: "var(--icons-neutral-default)" },
3298
3329
  children: /* @__PURE__ */ jsx31(Icon16, { name: "Cancel", size: 16 })
3299
3330
  }
@@ -3594,8 +3625,9 @@ function surfaceVar(type, eff, active, selected, disabled) {
3594
3625
  return `--surface-neutral-sidetab-navigation-${eff}`;
3595
3626
  }
3596
3627
  }
3597
- function borderVar(type, active, disabled) {
3628
+ function borderVar(type, active, disabled, eff = "idle") {
3598
3629
  if (disabled) return null;
3630
+ if (type === "dropdown-advanced" && eff !== "idle") return `--border-neutral-dropdown-advanced-${eff}`;
3599
3631
  if (type === "filter-group") return active ? "--border-secondary-filter-group-active" : "--border-neutral-filter-group-idle";
3600
3632
  if (active && (type === "sidebar-main" || type === "sidebar-main-icon")) return "--border-neutral-sidebar-main-navigation-active";
3601
3633
  if (active && type === "sidebar-sub") return "--border-neutral-sidebar-sub-navigation-active";
@@ -3666,12 +3698,19 @@ var DesktopMenuOptions = /* @__PURE__ */ React35.forwardRef(function DesktopMenu
3666
3698
  showChevron,
3667
3699
  subtext,
3668
3700
  content,
3701
+ leadingContent,
3702
+ trailingContent,
3703
+ highlighted,
3669
3704
  selectedCount,
3670
3705
  onDeselectAll,
3671
3706
  onSelect,
3672
3707
  className,
3673
3708
  style,
3674
3709
  role,
3710
+ onMouseEnter,
3711
+ onMouseLeave,
3712
+ onMouseDown,
3713
+ onMouseUp,
3675
3714
  ...rest
3676
3715
  }, ref) {
3677
3716
  ensureStyles10();
@@ -3681,9 +3720,9 @@ var DesktopMenuOptions = /* @__PURE__ */ React35.forwardRef(function DesktopMenu
3681
3720
  const disabled = state ? state === "disabled" || state === "disabled-selected" : disabledProp;
3682
3721
  const active = state ? state === "active" || state === "active-selected" : activeProp;
3683
3722
  const selected = state ? state.endsWith("-selected") : selectedProp;
3684
- const eff = disabled ? "idle" : state ? state.startsWith("hover") ? "hover" : state.startsWith("pressed") ? "pressed" : "idle" : press ? "pressed" : hover ? "hover" : "idle";
3723
+ const eff = disabled ? "idle" : state ? state.startsWith("hover") ? "hover" : state.startsWith("pressed") ? "pressed" : "idle" : press ? "pressed" : (highlighted !== void 0 ? highlighted : hover) ? "hover" : "idle";
3685
3724
  const bg = surfaceVar(type, eff, active, selected, disabled);
3686
- const bd = borderVar(type, active, disabled);
3725
+ const bd = borderVar(type, active, disabled, eff);
3687
3726
  const txtVar = textVar(type, active, disabled);
3688
3727
  const txtClass = textClass(type, active);
3689
3728
  const fire = () => {
@@ -3740,7 +3779,15 @@ var DesktopMenuOptions = /* @__PURE__ */ React35.forwardRef(function DesktopMenu
3740
3779
  }
3741
3780
  case "dropdown-advanced": {
3742
3781
  const advChevron = showChevron ?? false;
3743
- inner = content ?? /* @__PURE__ */ jsxs25("div", { style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "var(--spacing-20px)", width: "100%" }, children: [
3782
+ const usesSlots = leadingContent !== void 0 || trailingContent !== void 0;
3783
+ inner = content ?? (usesSlots ? (
3784
+ // The Library's two SLOTs (Leading Content, gap 12 inside; Trailing Content
3785
+ // hugging its content), 20 apart.
3786
+ /* @__PURE__ */ jsxs25("div", { style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "var(--spacing-20px)", width: "100%", minWidth: 0 }, children: [
3787
+ /* @__PURE__ */ jsx35("div", { style: { display: "flex", flexDirection: "row", alignItems: "flex-start", gap: "var(--spacing-12px)", flex: 1, minWidth: 0 }, children: leadingContent }),
3788
+ trailingContent != null && /* @__PURE__ */ jsx35("div", { style: { display: "flex", alignItems: "center", justifyContent: "flex-end", flexShrink: 0 }, children: trailingContent })
3789
+ ] })
3790
+ ) : /* @__PURE__ */ jsxs25("div", { style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "var(--spacing-20px)", width: "100%" }, children: [
3744
3791
  /* @__PURE__ */ jsxs25("div", { style: { display: "flex", flexDirection: "row", alignItems: "flex-start", gap: "var(--spacing-12px)", flex: 1, minWidth: 0 }, children: [
3745
3792
  leadingIcon && // Figma `Leading Icon` frame: 20×22, padding-top 2 — the glyph sits
3746
3793
  // on the title's line.
@@ -3750,8 +3797,22 @@ var DesktopMenuOptions = /* @__PURE__ */ React35.forwardRef(function DesktopMenu
3750
3797
  subtext != null && /* @__PURE__ */ jsx35("span", { className: "text-body-s-regular", style: { color: "var(--text-default-sub-body)" }, children: subtext })
3751
3798
  ] })
3752
3799
  ] }),
3753
- advChevron && chevron("right", 20)
3754
- ] });
3800
+ advChevron ? chevron("right", 20) : /* @__PURE__ */ jsx35(
3801
+ "span",
3802
+ {
3803
+ "aria-hidden": true,
3804
+ style: {
3805
+ display: "flex",
3806
+ flexShrink: 0,
3807
+ width: 20,
3808
+ height: 20,
3809
+ color: "var(--icons-neutral-default)",
3810
+ visibility: eff === "idle" ? "hidden" : "visible"
3811
+ },
3812
+ children: /* @__PURE__ */ jsx35(Icon20, { name: "Enter", size: 20 })
3813
+ }
3814
+ )
3815
+ ] }));
3755
3816
  break;
3756
3817
  }
3757
3818
  case "checkbox-selection":
@@ -3845,13 +3906,23 @@ var DesktopMenuOptions = /* @__PURE__ */ React35.forwardRef(function DesktopMenu
3845
3906
  fire();
3846
3907
  }
3847
3908
  },
3848
- onMouseEnter: () => setHover(true),
3849
- onMouseLeave: () => {
3909
+ onMouseEnter: (e) => {
3910
+ setHover(true);
3911
+ onMouseEnter?.(e);
3912
+ },
3913
+ onMouseLeave: (e) => {
3850
3914
  setHover(false);
3851
3915
  setPress(false);
3916
+ onMouseLeave?.(e);
3917
+ },
3918
+ onMouseDown: (e) => {
3919
+ setPress(true);
3920
+ onMouseDown?.(e);
3921
+ },
3922
+ onMouseUp: (e) => {
3923
+ setPress(false);
3924
+ onMouseUp?.(e);
3852
3925
  },
3853
- onMouseDown: () => setPress(true),
3854
- onMouseUp: () => setPress(false),
3855
3926
  style: container,
3856
3927
  ...rest,
3857
3928
  children: inner
@@ -4315,6 +4386,11 @@ var SideBar = /* @__PURE__ */ React38.forwardRef(function SideBar2({
4315
4386
  return "0:0";
4316
4387
  }, [groups]);
4317
4388
  const [activeKey, setActiveKey] = React38.useState(seedActive);
4389
+ const [prevSeed, setPrevSeed] = React38.useState(seedActive);
4390
+ if (seedActive !== prevSeed) {
4391
+ setPrevSeed(seedActive);
4392
+ setActiveKey(seedActive);
4393
+ }
4318
4394
  const width = collapsed ? 72 : 240;
4319
4395
  const toggle = () => {
4320
4396
  setCollapsed((c) => {
@@ -4638,7 +4714,10 @@ var UserMenu = /* @__PURE__ */ React40.forwardRef(function UserMenu2({ name, ava
4638
4714
  border: "none",
4639
4715
  cursor: "pointer",
4640
4716
  backgroundColor: SURFACE2[eff],
4641
- boxShadow: `inset 0 0 0 var(--stroke-xs) ${BORDER2[eff]}`,
4717
+ // Figma 2026-10-21: a 1px ring OUTSIDE the 68×40 pill (an outer spread, so
4718
+ // the box doesn't grow). At Idle the ring matches the surface and is meant
4719
+ // to be invisible; Hover/Pressed show it.
4720
+ boxShadow: `0 0 0 var(--stroke-xs) ${BORDER2[eff]}`,
4642
4721
  ...style
4643
4722
  },
4644
4723
  onMouseEnter: (e) => {
@@ -7241,6 +7320,7 @@ var TopFilter = /* @__PURE__ */ React57.forwardRef(
7241
7320
  const pressed = forcedState ? forcedState === "pressed" : pressedLive;
7242
7321
  const split = advanced && !!onChevronClick;
7243
7322
  const stateSurface = pressed ? "var(--surface-neutral-top-filter-tab-pressed)" : hovered ? "var(--surface-neutral-top-filter-tab-hover)" : "var(--surface-neutral-top-filter-tab-idle)";
7323
+ const selectedSurface = pressed || hovered ? stateSurface : "var(--surface-neutral-top-filter-tab-active)";
7244
7324
  const stateBorder = pressed ? "var(--border-neutral-top-filter-tab-pressed)" : hovered ? "var(--border-neutral-top-filter-tab-hover)" : "var(--border-neutral-top-filter-tab-idle)";
7245
7325
  const selectedRing = `inset 0 0 0 var(--stroke-sm) var(--border-secondary-top-filter-tab-active)`;
7246
7326
  const hoverHandlers = {
@@ -7288,11 +7368,9 @@ var TopFilter = /* @__PURE__ */ React57.forwardRef(
7288
7368
  height: 40,
7289
7369
  padding: "var(--padding-8px) var(--padding-12px)",
7290
7370
  borderRadius: "var(--rounding-lg)",
7291
- // Selection is carried by the 1.5px ring alone: Idle-Selected sits on the
7292
- // idle surface (Library 2026-10-18 — `Surface/neutral/top-filter-tab-active`
7293
- // was deleted; Advanced rebinds to idle, Basic still points at the deleted
7294
- // variable, reported as Figma hygiene).
7295
- backgroundColor: stateSurface,
7371
+ // Selected → the 1.5px ring plus the selected surface (`top-filter-tab-active`
7372
+ // at Idle-Selected; hover/pressed surfaces otherwise).
7373
+ backgroundColor: selected ? selectedSurface : stateSurface,
7296
7374
  color: "var(--text-default-label)",
7297
7375
  // 1px unselected, 1.5px selected (all six of each in Figma).
7298
7376
  boxShadow: selected ? selectedRing : `inset 0 0 0 var(--stroke-xs) ${stateBorder}`,
@@ -7334,7 +7412,7 @@ var TopFilter = /* @__PURE__ */ React57.forwardRef(
7334
7412
  height: 40,
7335
7413
  padding: 0,
7336
7414
  borderRadius: "var(--rounding-lg)",
7337
- backgroundColor: selected ? stateSurface : "transparent",
7415
+ backgroundColor: selected ? selectedSurface : "transparent",
7338
7416
  color: "var(--text-default-label)",
7339
7417
  border: "none",
7340
7418
  cursor: "pointer",
@@ -7909,6 +7987,7 @@ var EMPTY_STATE_ILLUSTRATIONS = {
7909
7987
  "no-notifications": new URL("./assets/no-notifications.png", import.meta.url).href,
7910
7988
  calendar: new URL("./assets/calendar.png", import.meta.url).href,
7911
7989
  recordings: new URL("./assets/recordings.png", import.meta.url).href,
7990
+ check: new URL("./assets/check.png", import.meta.url).href,
7912
7991
  "error": new URL("./assets/error.png", import.meta.url).href
7913
7992
  };
7914
7993
  var EMPTY_STATE_ILLUSTRATIONS_WEBP = {
@@ -7929,6 +8008,7 @@ var EMPTY_STATE_ILLUSTRATIONS_WEBP = {
7929
8008
  "no-notifications": new URL("./assets/no-notifications.webp", import.meta.url).href,
7930
8009
  calendar: new URL("./assets/calendar.webp", import.meta.url).href,
7931
8010
  recordings: new URL("./assets/recordings.webp", import.meta.url).href,
8011
+ check: new URL("./assets/check.webp", import.meta.url).href,
7932
8012
  "error": new URL("./assets/error.webp", import.meta.url).href
7933
8013
  };
7934
8014
 
@@ -7943,31 +8023,36 @@ function ensureIllustrationStyles() {
7943
8023
  document.head.appendChild(el);
7944
8024
  }
7945
8025
  var PRESET = {
7946
- "no-results": { illustration: "no-results", heading: "No matching results", description: "Try adjusting your search." },
7947
- "no-reviews": { illustration: "no-reviews", heading: "No reviews", description: "All reviews will be displayed here" },
7948
- "no-broadcast-logs": { illustration: "no-broadcast-logs", heading: "No broadcast logs", description: "All info will be displayed here" },
7949
- "image-upload": { illustration: "image-upload", heading: "Select image to upload", description: "Or drag and drop here" },
7950
- "file-upload": { illustration: "file-upload", heading: "Select file to upload", description: "Or drag and drop here" },
8026
+ // Every description ends with a full stop (ruled 2026-10-27 — Figma had them on
8027
+ // most Desktop variants and the code had dropped them all).
8028
+ // Copy per Figma (2026-10-21): the No Results variants read "Check the spelling or
8029
+ // adjust your filters." Surfaces with their own ruled copy pass `description`.
8030
+ "no-results": { illustration: "no-results", heading: "No matching results", description: "Check the spelling or adjust your filters." },
8031
+ "no-reviews": { illustration: "no-reviews", heading: "No reviews", description: "All reviews will be displayed here." },
8032
+ "no-broadcast-logs": { illustration: "no-broadcast-logs", heading: "No broadcast logs", description: "All info will be displayed here." },
8033
+ "image-upload": { illustration: "image-upload", heading: "Select image to upload", description: "Or drag and drop here." },
8034
+ "file-upload": { illustration: "file-upload", heading: "Select file to upload", description: "Or drag and drop here." },
7951
8035
  "no-suspensions": { illustration: "no-suspensions", heading: "No suspensions", description: "You are currently eligible to receive order broadcasts from partner companies." },
7952
- "no-items": { illustration: "no-items", heading: "No items", description: "You have no returnables" },
7953
- "no-orders": { illustration: "no-orders", heading: "No orders yet", description: "All orders will be displayed here" },
8036
+ "no-items": { illustration: "no-items", heading: "No items", description: "You have no returnables." },
8037
+ "no-orders": { illustration: "no-orders", heading: "No orders yet", description: "All orders will be displayed here." },
7954
8038
  "no-network": { illustration: "no-network", heading: "Check your connection", description: "Could not connect to the internet. Please check your network." },
7955
8039
  "new-update": { illustration: "new-update", heading: "Get the new update", description: "Update to the latest version with bug fixes and improvements." },
7956
- "no-data": { illustration: "no-data", heading: "No data yet", description: "All data will be displayed here" },
7957
- "no-trips": { illustration: "no-trips", heading: "No trips yet", description: "All trips will be displayed here" },
7958
- "no-drivers": { illustration: "no-drivers", heading: "No drivers", description: "All drivers will be displayed here" },
8040
+ "no-data": { illustration: "no-data", heading: "No data yet", description: "All data will be displayed here." },
8041
+ "no-trips": { illustration: "no-trips", heading: "No trips yet", description: "All trips will be displayed here." },
8042
+ "no-drivers": { illustration: "no-drivers", heading: "No drivers", description: "All drivers will be displayed here." },
7959
8043
  "no-products": { illustration: "no-items", heading: "No products", description: "No products have been added." },
7960
8044
  "error": { illustration: "error", heading: "Oops, something went wrong", description: "We couldn't load your content. Reload the page." },
7961
- // Added 2026-08-26 (Figma `Type=Comments` / `Type=Notifications`). Copy verbatim
7962
- // from the component set; both illustrations ship at the same 150×150 render size
7963
- // as every other type.
7964
- "comments": { illustration: "no-comments", heading: "No comments yet", description: "All comments will be displayed here" },
7965
- "notifications": { illustration: "no-notifications", heading: "No notifications yet", description: "New notifications will be displayed here" },
8045
+ // Added 2026-08-26 (Figma `Type=Comments` / `Type=Notifications`). Both
8046
+ // illustrations ship at the same 150×150 render size as every other type.
8047
+ "comments": { illustration: "no-comments", heading: "No comments yet", description: "All comments will be displayed here." },
8048
+ "notifications": { illustration: "no-notifications", heading: "No notifications yet", description: "New notifications will be displayed here." },
7966
8049
  // Added 2026-10-06 (Figma `Type=Calendar`, desktop). Figma reads "No Schedule";
7967
8050
  // sentence-cased like every other preset title (2026-10-02 ruling).
7968
- "calendar": { illustration: "calendar", heading: "No schedule", description: "All schedules will be displayed here" },
8051
+ "calendar": { illustration: "calendar", heading: "No schedule", description: "All schedules will be displayed here." },
7969
8052
  // Added 2026-10-21 (Figma `Type=Recording`, Desktop + Mobile — same copy in both).
7970
- "recording": { illustration: "recordings", heading: "No recordings", description: "All recordings will be displayed here" }
8053
+ "recording": { illustration: "recordings", heading: "No recordings", description: "All recordings will be displayed here." },
8054
+ // Added 2026-10-27 (Figma `Type=Check`, Desktop + Mobile) — nothing left to do.
8055
+ "check": { illustration: "check", heading: "You\u2019re all good", description: "Any pending tasks will be displayed here." }
7971
8056
  };
7972
8057
  var ILLUSTRATION_SIZE = 150;
7973
8058
  var HEADING_CLASS = {
@@ -7996,7 +8081,10 @@ var EmptyState = /* @__PURE__ */ React62.forwardRef(function EmptyState2({
7996
8081
  display: "flex",
7997
8082
  flexDirection: "column",
7998
8083
  alignItems: "center",
7999
- gap: "var(--spacing-20px)",
8084
+ // Desktop keeps 20 between illustration, copy and CTA; Mobile packs them
8085
+ // tight (Figma Container gap 0, 2026-10-27 — the illustration's own
8086
+ // whitespace does the separating).
8087
+ gap: size === "mobile" ? 0 : "var(--spacing-20px)",
8000
8088
  width: 300,
8001
8089
  padding: "var(--padding-16px)",
8002
8090
  boxSizing: "border-box",
@@ -9106,6 +9194,7 @@ var FooterFrame = /* @__PURE__ */ React72.forwardRef(
9106
9194
  const isCard = variant === "card";
9107
9195
  const itemGap = variant === "search-overlay" ? "var(--spacing-16px)" : "var(--spacing-8px)";
9108
9196
  const hasLeading = leading != null && leading !== false;
9197
+ const wraps = variant === "search-overlay";
9109
9198
  return /* @__PURE__ */ jsxs52(
9110
9199
  "div",
9111
9200
  {
@@ -9119,7 +9208,7 @@ var FooterFrame = /* @__PURE__ */ React72.forwardRef(
9119
9208
  // the trailing buttons' own gap is 8px (handled on the inner flex).
9120
9209
  gap: 10,
9121
9210
  width: "100%",
9122
- height: HEIGHT[variant],
9211
+ ...wraps ? { minHeight: HEIGHT[variant], flexWrap: "wrap", rowGap: "var(--spacing-8px)" } : { height: HEIGHT[variant] },
9123
9212
  padding: isCard ? 0 : "var(--padding-16px)",
9124
9213
  backgroundColor: isCard ? "transparent" : "var(--surface-neutral-bg-default)",
9125
9214
  // No top border (Figma removed the footer's top outline across all
@@ -9146,8 +9235,8 @@ var FooterFrame = /* @__PURE__ */ React72.forwardRef(
9146
9235
  },
9147
9236
  ...rest,
9148
9237
  children: [
9149
- hasLeading && /* @__PURE__ */ jsx71("div", { style: { display: "flex", alignItems: "center", gap: itemGap, minWidth: 0 }, children: leading }),
9150
- /* @__PURE__ */ jsx71("div", { style: { display: "flex", alignItems: "center", gap: itemGap, flexShrink: 0 }, children })
9238
+ hasLeading && /* @__PURE__ */ jsx71("div", { style: { display: "flex", alignItems: "center", gap: itemGap, minWidth: 0, ...wraps ? { flexWrap: "wrap", rowGap: "var(--spacing-8px)" } : null }, children: leading }),
9239
+ /* @__PURE__ */ jsx71("div", { style: { display: "flex", alignItems: "center", gap: itemGap, flexShrink: 0, ...wraps ? { flexWrap: "wrap", rowGap: "var(--spacing-8px)" } : null }, children })
9151
9240
  ]
9152
9241
  }
9153
9242
  );
@@ -10575,6 +10664,23 @@ var InputSection = /* @__PURE__ */ React87.forwardRef(function InputSection2({ t
10575
10664
  import * as React88 from "react";
10576
10665
  import { Icon as Icon38 } from "@leta-io/icons";
10577
10666
  import { jsx as jsx83, jsxs as jsxs60 } from "react/jsx-runtime";
10667
+ var STYLE_ID27 = "leta-toast-styles";
10668
+ var STYLES18 = `
10669
+ @keyframes leta-toast-progress { from { transform: scaleX(1); } to { transform: scaleX(0); } }
10670
+ .leta-toast-progress {
10671
+ transform-origin: left center;
10672
+ animation-name: leta-toast-progress;
10673
+ animation-timing-function: linear;
10674
+ animation-fill-mode: forwards;
10675
+ }
10676
+ `;
10677
+ function ensureStyles24() {
10678
+ if (typeof document === "undefined" || document.getElementById(STYLE_ID27)) return;
10679
+ const el = document.createElement("style");
10680
+ el.id = STYLE_ID27;
10681
+ el.textContent = STYLES18;
10682
+ document.head.appendChild(el);
10683
+ }
10578
10684
  var TYPE_CONFIG2 = {
10579
10685
  success: { icon: "Check-Circle", iconColor: "var(--icons-success-default)" },
10580
10686
  warning: { icon: "Warning", iconColor: "var(--icons-warning-default)" },
@@ -10590,17 +10696,38 @@ var Toast = /* @__PURE__ */ React88.forwardRef(function Toast2({
10590
10696
  duration,
10591
10697
  children,
10592
10698
  showCTA = false,
10699
+ className,
10593
10700
  style,
10701
+ onMouseEnter,
10702
+ onMouseLeave,
10703
+ onFocus,
10704
+ onBlur,
10594
10705
  ...rest
10595
10706
  }, ref) {
10707
+ ensureStyles24();
10596
10708
  const config = TYPE_CONFIG2[type];
10597
10709
  const isDestructive = type === "error";
10710
+ const autoDismiss = Boolean(duration && onDismiss);
10711
+ const [hovered, setHovered] = React88.useState(false);
10712
+ const [focused, setFocused] = React88.useState(false);
10713
+ const paused = hovered || focused;
10714
+ const remaining = React88.useRef(duration ?? 0);
10715
+ const dismiss = React88.useRef(onDismiss);
10716
+ React88.useEffect(() => {
10717
+ dismiss.current = onDismiss;
10718
+ });
10598
10719
  React88.useEffect(() => {
10599
- if (!duration || !onDismiss) return;
10600
- const t = setTimeout(onDismiss, duration);
10601
- return () => clearTimeout(t);
10602
- }, [duration, onDismiss]);
10720
+ if (!autoDismiss || paused) return;
10721
+ const started = Date.now();
10722
+ const id = setTimeout(() => dismiss.current?.(), remaining.current);
10723
+ return () => {
10724
+ clearTimeout(id);
10725
+ remaining.current = Math.max(0, remaining.current - (Date.now() - started));
10726
+ };
10727
+ }, [autoDismiss, paused]);
10603
10728
  const rootStyle = {
10729
+ position: "relative",
10730
+ overflow: "hidden",
10604
10731
  display: "flex",
10605
10732
  flexDirection: "row",
10606
10733
  alignItems: "center",
@@ -10621,12 +10748,41 @@ var Toast = /* @__PURE__ */ React88.forwardRef(function Toast2({
10621
10748
  ref,
10622
10749
  role: isDestructive ? "alert" : "status",
10623
10750
  "aria-live": isDestructive ? "assertive" : "polite",
10751
+ className: ["leta-toast", className].filter(Boolean).join(" "),
10624
10752
  style: rootStyle,
10753
+ onMouseEnter: (e) => {
10754
+ setHovered(true);
10755
+ onMouseEnter?.(e);
10756
+ },
10757
+ onMouseLeave: (e) => {
10758
+ setHovered(false);
10759
+ onMouseLeave?.(e);
10760
+ },
10761
+ onFocus: (e) => {
10762
+ setFocused(true);
10763
+ onFocus?.(e);
10764
+ },
10765
+ onBlur: (e) => {
10766
+ if (!e.currentTarget.contains(e.relatedTarget)) setFocused(false);
10767
+ onBlur?.(e);
10768
+ },
10625
10769
  ...rest,
10626
10770
  children: [
10627
- /* @__PURE__ */ jsxs60("div", { style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "var(--spacing-12px)", minWidth: 0 }, children: [
10628
- /* @__PURE__ */ jsx83("div", { style: { flexShrink: 0, width: 24, height: 24, color: config.iconColor }, children: /* @__PURE__ */ jsx83(Icon38, { name: config.icon, outlined: false, size: 24 }) }),
10629
- /* @__PURE__ */ jsxs60("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-2px)", minWidth: 0 }, children: [
10771
+ autoDismiss && /* @__PURE__ */ jsx83("div", { "aria-hidden": true, style: { position: "absolute", top: 0, left: 0, right: 0, height: 4, backgroundColor: "var(--surface-neutral-bg-default)" }, children: /* @__PURE__ */ jsx83(
10772
+ "div",
10773
+ {
10774
+ className: "leta-toast-progress",
10775
+ style: {
10776
+ height: "100%",
10777
+ backgroundColor: "var(--surface-success-task-progress-bar)",
10778
+ animationDuration: `${duration}ms`,
10779
+ animationPlayState: paused ? "paused" : "running"
10780
+ }
10781
+ }
10782
+ ) }),
10783
+ /* @__PURE__ */ jsxs60("div", { style: { display: "flex", flexDirection: "row", alignItems: "flex-start", gap: "var(--spacing-12px)", minWidth: 0 }, children: [
10784
+ /* @__PURE__ */ jsx83("div", { style: { flexShrink: 0, width: 24, height: 24, paddingTop: "var(--padding-2px)", color: config.iconColor }, children: /* @__PURE__ */ jsx83(Icon38, { name: config.icon, outlined: false, size: 24 }) }),
10785
+ /* @__PURE__ */ jsxs60("div", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
10630
10786
  showTitle && title && /* @__PURE__ */ jsx83("span", { className: "text-body-l-medium", style: { color: "var(--text-default-heading)" }, children: title }),
10631
10787
  showSubtitle && subtitle && /* @__PURE__ */ jsx83("span", { className: "text-body-m-regular", style: { color: "var(--text-default-sub-body)" }, children: subtitle })
10632
10788
  ] })
@@ -10662,18 +10818,18 @@ import "@leta-io/icons";
10662
10818
  import * as React89 from "react";
10663
10819
  import { Icon as Icon39 } from "@leta-io/icons";
10664
10820
  import { Fragment as Fragment19, jsx as jsx84, jsxs as jsxs61 } from "react/jsx-runtime";
10665
- var STYLE_ID27 = "leta-mmo-styles";
10666
- var STYLES18 = `
10821
+ var STYLE_ID28 = "leta-mmo-styles";
10822
+ var STYLES19 = `
10667
10823
  .leta-mmo { cursor: pointer; }
10668
10824
  .leta-mmo[aria-disabled="true"] { cursor: not-allowed; }
10669
10825
  .leta-mmo:focus-visible { outline: var(--stroke-sm) solid var(--border-secondary-component-focus); outline-offset: 2px; }
10670
10826
  `;
10671
- function ensureStyles24() {
10827
+ function ensureStyles25() {
10672
10828
  if (typeof document === "undefined") return;
10673
- if (document.getElementById(STYLE_ID27)) return;
10829
+ if (document.getElementById(STYLE_ID28)) return;
10674
10830
  const el = document.createElement("style");
10675
- el.id = STYLE_ID27;
10676
- el.textContent = STYLES18;
10831
+ el.id = STYLE_ID28;
10832
+ el.textContent = STYLES19;
10677
10833
  document.head.appendChild(el);
10678
10834
  }
10679
10835
  function surfaceVar3(type, press, active, disabled) {
@@ -10711,7 +10867,7 @@ function borderVar3(type, press, active, disabled) {
10711
10867
  }
10712
10868
  }
10713
10869
  var MobileMenuOptions = /* @__PURE__ */ React89.forwardRef(function MobileMenuOptions2({ type = "combobox", label = "Insert Text", leadingIcon, showLeadingIcon = false, active = false, selected = false, disabled = false, state, onSelect, className, style, role, ...rest }, ref) {
10714
- ensureStyles24();
10870
+ ensureStyles25();
10715
10871
  const [press, setPress] = React89.useState(false);
10716
10872
  const isCell = type === "mobile-day-cell";
10717
10873
  const isSel = type === "checkbox-selection" || type === "radio-selection";
@@ -11622,8 +11778,8 @@ function cleanStickyMarker(marker) {
11622
11778
 
11623
11779
  // src/TextArea/TextArea.tsx
11624
11780
  import { Fragment as Fragment22, jsx as jsx87, jsxs as jsxs64 } from "react/jsx-runtime";
11625
- var STYLE_ID28 = "leta-textarea-styles";
11626
- var STYLES19 = `
11781
+ var STYLE_ID29 = "leta-textarea-styles";
11782
+ var STYLES20 = `
11627
11783
  .leta-textarea__input {
11628
11784
  border: 0;
11629
11785
  outline: none;
@@ -11646,12 +11802,12 @@ var STYLES19 = `
11646
11802
  }
11647
11803
  .leta-textarea__rich-input:empty::before { content: ''; }
11648
11804
  `;
11649
- function ensureStyles25() {
11805
+ function ensureStyles26() {
11650
11806
  if (typeof document === "undefined") return;
11651
- if (document.getElementById(STYLE_ID28)) return;
11807
+ if (document.getElementById(STYLE_ID29)) return;
11652
11808
  const el = document.createElement("style");
11653
- el.id = STYLE_ID28;
11654
- el.textContent = STYLES19;
11809
+ el.id = STYLE_ID29;
11810
+ el.textContent = STYLES20;
11655
11811
  document.head.appendChild(el);
11656
11812
  }
11657
11813
  function LabelSection({
@@ -12095,7 +12251,7 @@ var RichField = /* @__PURE__ */ React92.forwardRef(function RichField2({ props,
12095
12251
  ] });
12096
12252
  });
12097
12253
  var TextArea = /* @__PURE__ */ React92.forwardRef(function TextArea2(props, ref) {
12098
- ensureStyles25();
12254
+ ensureStyles26();
12099
12255
  const [focused, setFocused] = React92.useState(false);
12100
12256
  const borderColor = borderColorFor(props.disabled, props.error, focused);
12101
12257
  return /* @__PURE__ */ jsxs64(
@@ -12155,6 +12311,56 @@ var OPEN_HEIGHT = {
12155
12311
  "active-results": 480
12156
12312
  };
12157
12313
  var Demarcator2 = () => /* @__PURE__ */ jsx89("div", { "aria-hidden": true, style: { height: 0, flexShrink: 0, borderTop: "var(--stroke-xs) solid var(--border-neutral-default)" } });
12314
+ var CHIP_FADE = 24;
12315
+ function FilterChipRow({
12316
+ filters,
12317
+ activeFilter,
12318
+ onFilterChange,
12319
+ tabbable
12320
+ }) {
12321
+ const scrollRef = React94.useRef(null);
12322
+ const edges = useScrollEdges(scrollRef);
12323
+ React94.useEffect(() => {
12324
+ const el = scrollRef.current?.children[activeFilter];
12325
+ el?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
12326
+ }, [activeFilter]);
12327
+ return /* @__PURE__ */ jsx89("div", { style: { display: "flex", padding: "0 var(--padding-12px) var(--padding-12px)", marginTop: "calc(var(--spacing-16px) - var(--padding-12px))", minWidth: 0 }, children: /* @__PURE__ */ jsx89(
12328
+ "div",
12329
+ {
12330
+ ref: scrollRef,
12331
+ role: "group",
12332
+ "aria-label": "Filters",
12333
+ className: "scroll-hidden",
12334
+ style: {
12335
+ display: "flex",
12336
+ alignItems: "center",
12337
+ gap: "var(--spacing-8px)",
12338
+ flex: 1,
12339
+ minWidth: 0,
12340
+ overflowX: "auto",
12341
+ overscrollBehavior: "contain",
12342
+ scrollbarWidth: "none",
12343
+ // Room for the chips' focus rings, which the scroller would clip.
12344
+ padding: "6px",
12345
+ margin: "-6px",
12346
+ maskImage: `linear-gradient(to right, ${edges.atStart ? "#000" : "transparent"} 0, #000 ${CHIP_FADE}px, #000 calc(100% - ${CHIP_FADE}px), ${edges.atEnd ? "#000" : "transparent"} 100%)`
12347
+ },
12348
+ children: filters.map((f, i) => /* @__PURE__ */ jsx89(
12349
+ Chip,
12350
+ {
12351
+ label: f,
12352
+ active: i === activeFilter,
12353
+ "aria-pressed": i === activeFilter,
12354
+ tabIndex: tabbable ? void 0 : -1,
12355
+ onMouseDown: tabbable ? void 0 : (e) => e.preventDefault(),
12356
+ onClick: onFilterChange ? () => onFilterChange(i) : void 0,
12357
+ style: { flexShrink: 0 }
12358
+ },
12359
+ i
12360
+ ))
12361
+ }
12362
+ ) });
12363
+ }
12158
12364
  var SAMPLE_GROUPS = ["Group Name", "Group Name"].map((title) => ({
12159
12365
  title,
12160
12366
  children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx89(DesktopMenuOptions, { type: "dropdown-advanced", label: "Title", subtext: "Enter description here" }, i))
@@ -12178,6 +12384,13 @@ var MapSearchInput = /* @__PURE__ */ React94.forwardRef(function MapSearchInput2
12178
12384
  showFooter = true,
12179
12385
  children,
12180
12386
  disabled = false,
12387
+ loading = false,
12388
+ clearLabel,
12389
+ footerHints,
12390
+ fitHeight = false,
12391
+ filtersTabbable = true,
12392
+ bodyRef,
12393
+ bodyProps,
12181
12394
  value,
12182
12395
  defaultValue,
12183
12396
  onChange,
@@ -12197,6 +12410,9 @@ var MapSearchInput = /* @__PURE__ */ React94.forwardRef(function MapSearchInput2
12197
12410
  placeholder,
12198
12411
  onClear,
12199
12412
  showClear: open,
12413
+ clearLabel,
12414
+ clearVariant: open ? "ghost" : "glyph",
12415
+ trailing: open && loading ? /* @__PURE__ */ jsx89(SearchFieldSpinner, {}) : void 0,
12200
12416
  disabled,
12201
12417
  value,
12202
12418
  defaultValue,
@@ -12228,7 +12444,7 @@ var MapSearchInput = /* @__PURE__ */ React94.forwardRef(function MapSearchInput2
12228
12444
  },
12229
12445
  children: [
12230
12446
  field,
12231
- state === "active-results" && /* @__PURE__ */ jsx89("div", { role: "group", "aria-label": "Filters", style: { display: "flex", alignItems: "center", gap: "var(--spacing-8px)", flexWrap: "wrap", padding: "0 var(--padding-12px) var(--padding-12px)", marginTop: "calc(var(--spacing-16px) - var(--padding-12px))" }, children: filters.map((f, i) => /* @__PURE__ */ jsx89(Chip, { label: f, active: i === activeFilter, onClick: onFilterChange ? () => onFilterChange(i) : void 0 }, i)) })
12447
+ state === "active-results" && /* @__PURE__ */ jsx89(FilterChipRow, { filters, activeFilter, onFilterChange, tabbable: filtersTabbable })
12232
12448
  ]
12233
12449
  }
12234
12450
  );
@@ -12247,10 +12463,22 @@ var MapSearchInput = /* @__PURE__ */ React94.forwardRef(function MapSearchInput2
12247
12463
  /* @__PURE__ */ jsx89("span", { className: "text-body-m-regular", style: { color: "var(--text-default-sub-body)", textWrap: "pretty" }, children: noHistoryText })
12248
12464
  ] }) });
12249
12465
  } else if (state === "active-history") {
12250
- body = /* @__PURE__ */ jsxs66("div", { style: { ...bodyStyle, gap: "var(--spacing-8px)", padding: "var(--padding-16px)", overflowY: "auto", overscrollBehavior: "contain" }, children: [
12466
+ body = /* @__PURE__ */ jsxs66("div", { ref: bodyRef, ...bodyProps, className: ["scroll-slim", bodyProps?.className].filter(Boolean).join(" "), style: { ...bodyStyle, gap: "var(--spacing-8px)", padding: "var(--padding-16px)", overflowY: "auto", overscrollBehavior: "contain", ...bodyProps?.style }, children: [
12251
12467
  /* @__PURE__ */ jsxs66("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "var(--spacing-8px)" }, children: [
12252
12468
  /* @__PURE__ */ jsx89("span", { className: "text-body-s-medium", style: { color: "var(--text-default-sub-heading)" }, children: recentTitle }),
12253
- /* @__PURE__ */ jsx89(Button, { variant: "plain", size: "small", iconLeft: "Cancel", showUnderline: false, onClick: onClearHistory, children: "Clear All" })
12469
+ /* @__PURE__ */ jsx89(
12470
+ Button,
12471
+ {
12472
+ variant: "plain",
12473
+ size: "small",
12474
+ iconLeft: "Cancel",
12475
+ showUnderline: false,
12476
+ onClick: onClearHistory,
12477
+ tabIndex: filtersTabbable ? void 0 : -1,
12478
+ onMouseDown: filtersTabbable ? void 0 : (e) => e.preventDefault(),
12479
+ children: "Clear All"
12480
+ }
12481
+ )
12254
12482
  ] }),
12255
12483
  children ?? /* @__PURE__ */ jsx89("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-4px)" }, children: ["LTA-ID-001", "LTA-ID-002", "Michael", "Kitisuru"].map((l) => /* @__PURE__ */ jsx89(DesktopMenuOptions, { type: "dropdown-basic", label: l, leadingIcon: "History", showLeadingIcon: true, showChevron: false }, l)) })
12256
12484
  ] });
@@ -12258,15 +12486,27 @@ var MapSearchInput = /* @__PURE__ */ React94.forwardRef(function MapSearchInput2
12258
12486
  body = /* @__PURE__ */ jsx89("div", { style: { ...bodyStyle, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx89("div", { style: { width: 480, maxWidth: "100%", padding: "var(--padding-12px) var(--padding-16px)", boxSizing: "border-box" }, children: /* @__PURE__ */ jsx89(EmptyState, { type: "no-results", size: "desktop", showIcon: false, heading: noResultsTitle, description: noResultsText, style: { width: "100%" } }) }) });
12259
12487
  } else {
12260
12488
  const list = groups ?? SAMPLE_GROUPS;
12261
- body = /* @__PURE__ */ jsx89("div", { style: { ...bodyStyle, overflowY: "auto", overscrollBehavior: "contain" }, children: /* @__PURE__ */ jsx89("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-16px)", padding: "var(--padding-12px) var(--padding-16px)" }, children: children ?? list.map((g, i) => /* @__PURE__ */ jsxs66(React94.Fragment, { children: [
12262
- i > 0 && /* @__PURE__ */ jsx89(Demarcator2, {}),
12263
- /* @__PURE__ */ jsxs66("div", { role: "group", "aria-label": g.title, style: { display: "flex", flexDirection: "column", gap: "var(--spacing-8px)" }, children: [
12264
- /* @__PURE__ */ jsx89("span", { className: "text-body-s-medium", style: { color: "var(--text-default-sub-heading)" }, children: g.title }),
12265
- /* @__PURE__ */ jsx89("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-4px)" }, children: g.children })
12266
- ] })
12267
- ] }, i)) }) });
12489
+ body = /* @__PURE__ */ jsx89(
12490
+ "div",
12491
+ {
12492
+ ref: bodyRef,
12493
+ ...bodyProps,
12494
+ className: ["scroll-slim", bodyProps?.className].filter(Boolean).join(" "),
12495
+ style: { ...bodyStyle, ...fitHeight ? { flex: "1 1 auto" } : null, overflowY: "auto", overscrollBehavior: "contain", ...bodyProps?.style },
12496
+ children: /* @__PURE__ */ jsx89("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-16px)", padding: "var(--padding-12px) var(--padding-16px)" }, children: children ?? list.map((g, i) => /* @__PURE__ */ jsxs66(React94.Fragment, { children: [
12497
+ i > 0 && /* @__PURE__ */ jsx89(Demarcator2, {}),
12498
+ /* @__PURE__ */ jsxs66("div", { role: "group", "aria-label": g.title, style: { display: "flex", flexDirection: "column", gap: "var(--spacing-8px)" }, children: [
12499
+ /* @__PURE__ */ jsx89("span", { className: "text-body-s-medium", style: { color: "var(--text-default-sub-heading)" }, children: g.title }),
12500
+ /* @__PURE__ */ jsx89("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-4px)" }, children: g.children })
12501
+ ] })
12502
+ ] }, i)) })
12503
+ }
12504
+ );
12268
12505
  }
12269
12506
  const hasRows = state === "active-history" || state === "active-results";
12507
+ const hintSelect = footerHints?.select ?? hasRows;
12508
+ const hintSwitch = footerHints?.switchFilter ?? state === "active-results";
12509
+ const hintEnter = footerHints && "enter" in footerHints ? footerHints.enter : hasRows ? "open" : null;
12270
12510
  const footer = showFooter && /* @__PURE__ */ jsxs66(
12271
12511
  FooterFrame,
12272
12512
  {
@@ -12274,11 +12514,11 @@ var MapSearchInput = /* @__PURE__ */ React94.forwardRef(function MapSearchInput2
12274
12514
  style: { boxShadow: "inset 0 var(--stroke-xs) 0 var(--border-neutral-input-field)", flexShrink: 0 },
12275
12515
  leading: /* @__PURE__ */ jsxs66(Fragment24, { children: [
12276
12516
  /* @__PURE__ */ jsx89(ShortcutHint, { keys: ["Esc"], action: "to close" }),
12277
- hasRows && /* @__PURE__ */ jsx89(ShortcutHint, { keys: [{ icon: "Up-Arrow", label: "Up arrow" }, { icon: "Down-Arrow", label: "Down arrow" }], action: "to select" })
12517
+ hintSelect && /* @__PURE__ */ jsx89(ShortcutHint, { keys: [{ icon: "Up-Arrow", label: "Up arrow" }, { icon: "Down-Arrow", label: "Down arrow" }], action: "to select" })
12278
12518
  ] }),
12279
12519
  children: [
12280
- state === "active-results" && /* @__PURE__ */ jsx89(ShortcutHint, { keys: ["Tab"], action: "to switch filter" }),
12281
- hasRows && /* @__PURE__ */ jsx89(ShortcutHint, { keys: [{ icon: "Enter", label: "Enter" }], action: "to open" })
12520
+ hintSwitch && /* @__PURE__ */ jsx89(ShortcutHint, { keys: ["Tab"], action: "to switch filter" }),
12521
+ hintEnter && /* @__PURE__ */ jsx89(ShortcutHint, { keys: [{ icon: "Enter", label: "Enter" }], action: `to ${hintEnter}` })
12282
12522
  ]
12283
12523
  }
12284
12524
  );
@@ -12297,7 +12537,7 @@ var MapSearchInput = /* @__PURE__ */ React94.forwardRef(function MapSearchInput2
12297
12537
  flexDirection: "column",
12298
12538
  width: OPEN_WIDTH,
12299
12539
  maxWidth: "100%",
12300
- height: OPEN_HEIGHT[state],
12540
+ ...fitHeight && state === "active-results" ? { minHeight: OPEN_HEIGHT["no-history"], maxHeight: OPEN_HEIGHT["active-results"] } : { height: OPEN_HEIGHT[state] },
12301
12541
  boxSizing: "border-box",
12302
12542
  borderRadius: "var(--rounding-xl)",
12303
12543
  overflow: "hidden",
@@ -12545,20 +12785,20 @@ var FileUploadCard = /* @__PURE__ */ React98.forwardRef(function FileUploadCard2
12545
12785
  import * as React99 from "react";
12546
12786
  import { Icon as Icon45 } from "@leta-io/icons";
12547
12787
  import { jsx as jsx94, jsxs as jsxs70 } from "react/jsx-runtime";
12548
- var STYLE_ID29 = "leta-mobile-file-upload-styles";
12549
- var STYLES20 = `
12788
+ var STYLE_ID30 = "leta-mobile-file-upload-styles";
12789
+ var STYLES21 = `
12550
12790
  .leta-mfu__add, .leta-mfu__delete { cursor: pointer; }
12551
12791
  .leta-mfu__add:focus-visible, .leta-mfu__delete:focus-visible {
12552
12792
  outline: var(--stroke-sm) solid var(--border-secondary-component-focus);
12553
12793
  outline-offset: 4px;
12554
12794
  }
12555
12795
  `;
12556
- function ensureStyles26() {
12796
+ function ensureStyles27() {
12557
12797
  if (typeof document === "undefined") return;
12558
- if (document.getElementById(STYLE_ID29)) return;
12798
+ if (document.getElementById(STYLE_ID30)) return;
12559
12799
  const el = document.createElement("style");
12560
- el.id = STYLE_ID29;
12561
- el.textContent = STYLES20;
12800
+ el.id = STYLE_ID30;
12801
+ el.textContent = STYLES21;
12562
12802
  document.head.appendChild(el);
12563
12803
  }
12564
12804
  var TILE = { width: 111, height: 104, flexShrink: 0, borderRadius: "var(--rounding-lg)", boxSizing: "border-box" };
@@ -12576,7 +12816,7 @@ var MobileFileUpload = /* @__PURE__ */ React99.forwardRef(function MobileFileUpl
12576
12816
  style,
12577
12817
  ...rest
12578
12818
  }, ref) {
12579
- ensureStyles26();
12819
+ ensureStyles27();
12580
12820
  const adds = addTiles ?? (images.length === 0 ? 3 : 0);
12581
12821
  return /* @__PURE__ */ jsxs70(
12582
12822
  "div",
@@ -13211,8 +13451,8 @@ function rootTheme() {
13211
13451
 
13212
13452
  // src/FloatingToolbar/FloatingToolbar.tsx
13213
13453
  import { Fragment as Fragment28, jsx as jsx97, jsxs as jsxs72 } from "react/jsx-runtime";
13214
- var STYLE_ID30 = "leta-floating-toolbar-styles";
13215
- var STYLES21 = `
13454
+ var STYLE_ID31 = "leta-floating-toolbar-styles";
13455
+ var STYLES22 = `
13216
13456
  @keyframes leta-floating-toolbar-in { from { opacity: 0; translate: 0 8px; } to { opacity: 1; translate: 0 0; } }
13217
13457
  @keyframes leta-floating-toolbar-out { from { opacity: 1; translate: 0 0; } to { opacity: 0; translate: 0 8px; } }
13218
13458
  .leta-floating-toolbar[data-presence="enter"] { animation: leta-floating-toolbar-in 200ms cubic-bezier(0.16, 1, 0.3, 1); }
@@ -13221,11 +13461,11 @@ var STYLES21 = `
13221
13461
  .leta-floating-toolbar[data-presence] { animation: none; }
13222
13462
  }
13223
13463
  `;
13224
- function ensureStyles27() {
13225
- if (typeof document === "undefined" || document.getElementById(STYLE_ID30)) return;
13464
+ function ensureStyles28() {
13465
+ if (typeof document === "undefined" || document.getElementById(STYLE_ID31)) return;
13226
13466
  const el = document.createElement("style");
13227
- el.id = STYLE_ID30;
13228
- el.textContent = STYLES21;
13467
+ el.id = STYLE_ID31;
13468
+ el.textContent = STYLES22;
13229
13469
  document.head.appendChild(el);
13230
13470
  }
13231
13471
  var EXIT_MS2 = 160;
@@ -13271,7 +13511,7 @@ var DefaultActions = () => /* @__PURE__ */ jsxs72(Fragment28, { children: [
13271
13511
  ] });
13272
13512
  var FloatingToolbar = /* @__PURE__ */ React103.forwardRef(
13273
13513
  function FloatingToolbar2(props, ref) {
13274
- ensureStyles27();
13514
+ ensureStyles28();
13275
13515
  const anchorRef = React103.useRef(null);
13276
13516
  const setRefs = (el) => {
13277
13517
  anchorRef.current = el;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leta-io/components",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "LETA React component library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,8 +28,8 @@
28
28
  "country-flag-icons": "^1.6.17",
29
29
  "leaflet": "^1.9.4",
30
30
  "lottie-web": "^5.12.2",
31
- "@leta-io/design-tokens": "0.5.1",
32
- "@leta-io/icons": "0.5.1"
31
+ "@leta-io/icons": "0.6.0",
32
+ "@leta-io/design-tokens": "0.6.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": "^18.0.0 || ^19.0.0",