From 5353e77de9968f5f172e9ec01d86c168e982a36f Mon Sep 17 00:00:00 2001 From: jossmac <2730833+jossmac@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:55:36 +1000 Subject: [PATCH 01/12] first pass --- design-system/docs/.storybook/preview.js | 2 +- design-system/docs/package.json | 4 +- design-system/pkg/package.json | 158 +- .../pkg/src/action-bar/ActionBar.tsx | 1 - .../pkg/src/calendar/CalendarCell.tsx | 4 +- .../src/calendar/test/RangeCalendar.test.tsx | 16 +- design-system/pkg/src/combobox/Combobox.tsx | 4 +- .../pkg/src/combobox/MobileCombobox.tsx | 4 +- design-system/pkg/src/date-time/utils.ts | 2 +- .../InsertionIndicatorPrimitive.tsx | 53 + .../pkg/src/editor/EditorListbox.tsx | 22 +- .../pkg/src/list-view/InsertionIndicator.tsx | 52 +- design-system/pkg/src/list-view/ListView.tsx | 125 +- .../pkg/src/list-view/ListViewItem.tsx | 3 +- .../pkg/src/list-view/ListViewLayout.tsx | 71 + design-system/pkg/src/listbox/ListBox.tsx | 2 +- design-system/pkg/src/listbox/ListBoxBase.tsx | 60 +- .../pkg/src/listbox/ListBoxLayout.tsx | 100 + .../pkg/src/listbox/ListBoxOption.tsx | 2 +- .../pkg/src/listbox/ListBoxSection.tsx | 6 +- design-system/pkg/src/listbox/context.ts | 10 +- design-system/pkg/src/listbox/types.ts | 7 +- .../src/menu/stories/ActionMenu.stories.tsx | 4 +- design-system/pkg/src/overlays/Modal.tsx | 1 - design-system/pkg/src/overlays/Popover.tsx | 1 - design-system/pkg/src/overlays/Tray.tsx | 1 - .../pkg/src/overlays/test/Overlay.test.tsx | 1 - design-system/pkg/src/overlays/types.ts | 2 +- design-system/pkg/src/text-field/TextArea.tsx | 2 +- .../pkg/src/tooltip/TooltipTrigger.tsx | 1 - packages/keystatic/package.json | 26 +- .../document/DocumentEditor/insert-menu.tsx | 2 +- .../primitives/BlockPopover.tsx | 1 - .../editor/autocomplete/EditorListbox.tsx | 20 +- pnpm-lock.yaml | 3073 ++++++++++------- 35 files changed, 2383 insertions(+), 1460 deletions(-) create mode 100644 design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx create mode 100644 design-system/pkg/src/list-view/ListViewLayout.tsx create mode 100644 design-system/pkg/src/listbox/ListBoxLayout.tsx diff --git a/design-system/docs/.storybook/preview.js b/design-system/docs/.storybook/preview.js index a39fbcdae..ca820db06 100644 --- a/design-system/docs/.storybook/preview.js +++ b/design-system/docs/.storybook/preview.js @@ -18,7 +18,7 @@ export const decorators = [
( let domRef = useObjectRef(forwardedRef); return ( - /* @ts-expect-error FIXME: resolve ref inconsistencies */ diff --git a/design-system/pkg/src/calendar/CalendarCell.tsx b/design-system/pkg/src/calendar/CalendarCell.tsx index 28b33d1c4..684e1c08a 100644 --- a/design-system/pkg/src/calendar/CalendarCell.tsx +++ b/design-system/pkg/src/calendar/CalendarCell.tsx @@ -158,8 +158,8 @@ type CellStyleProps = { isRangeSelection: boolean; isRangeStart: boolean; isSelected: boolean; - isSelectionEnd: boolean; - isSelectionStart: boolean; + isSelectionEnd: boolean | null; + isSelectionStart: boolean | null; isToday: boolean; isUnavailable: boolean; }; diff --git a/design-system/pkg/src/calendar/test/RangeCalendar.test.tsx b/design-system/pkg/src/calendar/test/RangeCalendar.test.tsx index 0f4b6973b..e1fb2e364 100644 --- a/design-system/pkg/src/calendar/test/RangeCalendar.test.tsx +++ b/design-system/pkg/src/calendar/test/RangeCalendar.test.tsx @@ -217,7 +217,7 @@ describe('calendar/RangeCalendar', () => { // TODO: selects a range with the keyboard it('selects a range by clicking with the mouse', () => { - let onChange = jest.fn<(value: RangeValue) => void>(); + let onChange = jest.fn<(value: RangeValue | null) => void>(); let { getAllByLabelText, getByText } = renderWithProvider( { expect(selectedDates[selectedDates.length - 1].textContent).toBe('17'); expect(onChange).toHaveBeenCalledTimes(1); - let { start, end } = onChange.mock.calls[0][0]; + let result = onChange.mock.calls[0][0]; + if (!result) { + throw new Error('Expected a result'); + } + let { start, end } = result; expect(start).toEqual(new CalendarDate(2019, 6, 7)); expect(end).toEqual(new CalendarDate(2019, 6, 17)); }); it('selects a range by dragging with the mouse', () => { - let onChange = jest.fn<(value: RangeValue) => void>(); + let onChange = jest.fn<(value: RangeValue | null) => void>(); let { getAllByLabelText, getByText } = renderWithProvider( { expect(selectedDates[selectedDates.length - 1].textContent).toBe('23'); expect(onChange).toHaveBeenCalledTimes(1); - let { start, end } = onChange.mock.calls[0][0]; + let result = onChange.mock.calls[0][0]; + if (!result) { + throw new Error('Expected a result'); + } + let { start, end } = result; expect(start).toEqual(new CalendarDate(2019, 6, 17)); expect(end).toEqual(new CalendarDate(2019, 6, 23)); }); diff --git a/design-system/pkg/src/combobox/Combobox.tsx b/design-system/pkg/src/combobox/Combobox.tsx index 265d26efe..f74fad0ed 100644 --- a/design-system/pkg/src/combobox/Combobox.tsx +++ b/design-system/pkg/src/combobox/Combobox.tsx @@ -92,7 +92,7 @@ const ComboboxBase = React.forwardRef(function ComboboxBase( defaultFilter: contains, allowsEmptyCollection: isAsync, }); - let layout = useListBoxLayout(state); + let layout = useListBoxLayout(); let { buttonProps, @@ -104,7 +104,7 @@ const ComboboxBase = React.forwardRef(function ComboboxBase( } = useComboBox( { ...props, - keyboardDelegate: layout, + layoutDelegate: layout, buttonRef, popoverRef: popoverRefLikeValue, listBoxRef, diff --git a/design-system/pkg/src/combobox/MobileCombobox.tsx b/design-system/pkg/src/combobox/MobileCombobox.tsx index 53dc6dd91..60cd053ed 100644 --- a/design-system/pkg/src/combobox/MobileCombobox.tsx +++ b/design-system/pkg/src/combobox/MobileCombobox.tsx @@ -300,13 +300,13 @@ function ComboboxTray(props: ComboboxTrayProps) { let buttonRef = useRef(null); let popoverRef = useRef(null); let listBoxRef = useRef(null); - let layout = useListBoxLayout(state); + let layout = useListBoxLayout(); let stringFormatter = useLocalizedStringFormatter(localizedMessages); let { inputProps, listBoxProps, labelProps } = useComboBox( { ...props, - keyboardDelegate: layout, + layoutDelegate: layout, buttonRef, popoverRef, listBoxRef, diff --git a/design-system/pkg/src/date-time/utils.ts b/design-system/pkg/src/date-time/utils.ts index b15045fd8..2eb010653 100644 --- a/design-system/pkg/src/date-time/utils.ts +++ b/design-system/pkg/src/date-time/utils.ts @@ -6,7 +6,7 @@ import { SpectrumDatePickerBase } from '@react-types/datepicker'; import { Ref, useImperativeHandle, useMemo, useState } from 'react'; export function useFormatHelpText( - props: Pick + props: Pick, 'description' | 'showFormatHelpText'> ) { let formatter = useDateFormatter({ dateStyle: 'short' }); let displayNames = useDisplayNames(); diff --git a/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx b/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx new file mode 100644 index 000000000..f95332ee5 --- /dev/null +++ b/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx @@ -0,0 +1,53 @@ +import { classNames, css, tokenSchema } from '@keystar/ui/style'; +import React, { HTMLAttributes } from 'react'; + +export function InsertionIndicatorPrimitive( + props: { isDropTarget: boolean } & HTMLAttributes +) { + let { children, isDropTarget, ...otherProps } = props; + let maskColor = tokenSchema.color.background.canvas; + let borderColor = tokenSchema.color.background.accentEmphasis; + let borderSize = tokenSchema.size.border.medium; + let circleSize = tokenSchema.size.space.regular; + + return ( +
+ {children} +
+ ); +} diff --git a/design-system/pkg/src/editor/EditorListbox.tsx b/design-system/pkg/src/editor/EditorListbox.tsx index 775b04c6b..dcf8a14d4 100644 --- a/design-system/pkg/src/editor/EditorListbox.tsx +++ b/design-system/pkg/src/editor/EditorListbox.tsx @@ -1,4 +1,7 @@ -import { useSelectableCollection } from '@react-aria/selection'; +import { + ListKeyboardDelegate, + useSelectableCollection, +} from '@react-aria/selection'; import { chain } from '@react-aria/utils'; import { useListState } from '@react-stately/list'; import { @@ -6,7 +9,7 @@ import { CollectionBase, MultipleSelection, } from '@react-types/shared'; -import { Key, RefObject, useEffect, useRef } from 'react'; +import { Key, RefObject, useEffect, useMemo, useRef } from 'react'; import { ListBoxBase, listStyles, useListBoxLayout } from '@keystar/ui/listbox'; import { BaseStyleProps } from '@keystar/ui/style'; @@ -34,12 +37,21 @@ export type EditorListboxProps = { export function EditorListbox(props: EditorListboxProps) { let { listenerRef, onEscape, scrollRef, ...otherProps } = props; let state = useListState(props); - let layout = useListBoxLayout(state); + let layout = useListBoxLayout(); + let listboxRef = useRef(null); + let delegate = useMemo( + () => + new ListKeyboardDelegate({ + collection: state.collection, + ref: listboxRef, + layoutDelegate: layout, + }), + [layout, state.collection] + ); // keyboard and selection management - let listboxRef = useRef(null); let { collectionProps } = useSelectableCollection({ - keyboardDelegate: layout, + keyboardDelegate: delegate, ref: listenerRef, scrollRef: scrollRef ?? listboxRef, selectionManager: state.selectionManager, diff --git a/design-system/pkg/src/list-view/InsertionIndicator.tsx b/design-system/pkg/src/list-view/InsertionIndicator.tsx index 48e6bc72b..ca1ccf7df 100644 --- a/design-system/pkg/src/list-view/InsertionIndicator.tsx +++ b/design-system/pkg/src/list-view/InsertionIndicator.tsx @@ -3,12 +3,7 @@ import { ItemDropTarget } from '@react-types/shared'; import { assert } from 'emery'; import { useRef } from 'react'; -import { - classNames, - css, - toDataAttributes, - tokenSchema, -} from '@keystar/ui/style'; +import { InsertionIndicatorPrimitive } from '@keystar/ui/drag-and-drop'; import { useListViewContext } from './context'; @@ -17,7 +12,7 @@ interface InsertionIndicatorProps { isPresentationOnly?: boolean; } -export default function InsertionIndicator(props: InsertionIndicatorProps) { +export function InsertionIndicator(props: InsertionIndicatorProps) { let { dropState, dragAndDropHooks } = useListViewContext(); const { target, isPresentationOnly } = props; @@ -41,49 +36,12 @@ export default function InsertionIndicator(props: InsertionIndicatorProps) { return null; } - let maskColor = tokenSchema.color.background.canvas; - let borderColor = tokenSchema.color.background.accentEmphasis; - let borderSize = tokenSchema.size.border.medium; - let circleSize = tokenSchema.size.space.regular; - return (
-
{!isPresentationOnly && (
)} -
+
); } diff --git a/design-system/pkg/src/list-view/ListView.tsx b/design-system/pkg/src/list-view/ListView.tsx index f27964fe1..6e226d09f 100644 --- a/design-system/pkg/src/list-view/ListView.tsx +++ b/design-system/pkg/src/list-view/ListView.tsx @@ -1,14 +1,17 @@ import { useGridList } from '@react-aria/gridlist'; import type { DroppableCollectionResult } from '@react-aria/dnd'; import { FocusScope } from '@react-aria/focus'; -import { useCollator, useLocalizedStringFormatter } from '@react-aria/i18n'; +import { useLocalizedStringFormatter } from '@react-aria/i18n'; import { Virtualizer } from '@react-aria/virtualizer'; import { filterDOMProps, mergeProps, useObjectRef } from '@react-aria/utils'; -import type { DroppableCollectionState } from '@react-stately/dnd'; -import { ListLayout } from '@react-stately/layout'; +import type { + DraggableCollectionState, + DroppableCollectionState, +} from '@react-stately/dnd'; import { ListState, useListState } from '@react-stately/list'; import { assert } from 'emery'; import React, { + Key, PropsWithChildren, ReactElement, RefObject, @@ -32,10 +35,12 @@ import { listViewClassList } from './class-list'; import { ListViewProvider, useListViewContext } from './context'; import localizedMessages from './l10n.json'; import { DragPreview as DragPreviewElement } from './DragPreview'; -import InsertionIndicator from './InsertionIndicator'; +import { InsertionIndicator } from './InsertionIndicator'; import { ListViewItem } from './ListViewItem'; +import { ListViewLayout } from './ListViewLayout'; import RootDropIndicator from './RootDropIndicator'; import { ListViewProps } from './types'; +import { ListKeyboardDelegate } from '@react-aria/selection'; const ROW_HEIGHTS = { compact: { @@ -52,35 +57,21 @@ const ROW_HEIGHTS = { }, } as const; -function createLayout( - collator: Intl.Collator, - scale: 'medium' | 'large', - density: keyof typeof ROW_HEIGHTS, - isEmpty: boolean, - _overflowMode: string | undefined -) { - return new ListLayout({ - estimatedRowHeight: ROW_HEIGHTS[density][scale], - padding: 0, - collator, - loaderHeight: isEmpty ? undefined : ROW_HEIGHTS[density][scale], - }); -} - function useListLayout( state: ListState, density: NonNullable['density']>, overflowMode: ListViewProps['overflowMode'] ) { let { scale } = useProvider(); - let collator = useCollator({ usage: 'search', sensitivity: 'base' }); - let isEmpty = state.collection.size === 0; - let layout = useMemo(() => { - return createLayout(collator, scale, density, isEmpty, overflowMode); - }, [collator, scale, density, isEmpty, overflowMode]); + let layout = useMemo( + () => + new ListViewLayout({ + estimatedRowHeight: ROW_HEIGHTS[density][scale], + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [scale, density, overflowMode] + ); - layout.collection = state.collection; - layout.disabledKeys = state.disabledKeys; return layout; } @@ -96,6 +87,7 @@ function ListView( overflowMode = 'truncate', onAction, dragAndDropHooks, + renderEmptyState, ...otherProps } = props; @@ -132,36 +124,29 @@ function ListView( let preview = useRef(null); // DraggableCollectionState; - let dragState = (() => { - if ( - dragAndDropHooks != null && - dragAndDropHooks.useDraggableCollectionState && - dragAndDropHooks.useDraggableCollection - ) { - let state = dragAndDropHooks.useDraggableCollectionState({ - collection, - selectionManager, - preview, - }); - dragAndDropHooks.useDraggableCollection({}, state, domRef); - return state; - } - })(); - + let dragState!: DraggableCollectionState; + if ( + isListDraggable && + dragAndDropHooks?.useDraggableCollectionState && + dragAndDropHooks?.useDraggableCollection + ) { + dragState = dragAndDropHooks.useDraggableCollectionState({ + collection, + selectionManager, + preview, + }); + dragAndDropHooks.useDraggableCollection({}, dragState, domRef); + } let layout = useListLayout(state, props.density || 'regular', overflowMode); - // !!0 is false, so we can cast size or undefined and they'll be falsy - layout.allowDisabledKeyFocus = - state.selectionManager.disabledBehavior === 'selection' || - !!dragState?.draggingKeys.size; let DragPreview = dragAndDropHooks?.DragPreview; - let dropState: DroppableCollectionState; + let dropState!: DroppableCollectionState; let droppableCollection: DroppableCollectionResult; let isRootDropTarget: boolean; if ( - dragAndDropHooks && - dragAndDropHooks.useDroppableCollectionState && - dragAndDropHooks.useDroppableCollection + isListDroppable && + dragAndDropHooks?.useDroppableCollectionState && + dragAndDropHooks?.useDroppableCollection ) { dropState = dragAndDropHooks.useDroppableCollectionState({ collection, @@ -169,7 +154,14 @@ function ListView( }); droppableCollection = dragAndDropHooks.useDroppableCollection( { - keyboardDelegate: layout, + keyboardDelegate: new ListKeyboardDelegate({ + collection, + disabledKeys: dragState?.draggingKeys.size + ? undefined + : selectionManager.disabledKeys, + ref: domRef, + layoutDelegate: layout, + }), dropTargetDelegate: layout, }, dropState, @@ -183,22 +175,28 @@ function ListView( { ...props, isVirtualized: true, - keyboardDelegate: layout, + layoutDelegate: layout, onAction, }, state, domRef ); - // Sync loading state into the layout. - layout.isLoading = isLoading; - let focusedKey = selectionManager.focusedKey; - // @ts-expect-error + let dropTargetKey: Key | null = null; if (dropState?.target?.type === 'item') { - focusedKey = dropState.target.key; + dropTargetKey = dropState.target.key; + if (dropState.target.dropPosition === 'after') { + // Normalize to the "before" drop position since we only render those in the DOM. + dropTargetKey = + state.collection.getKeyAfter(dropTargetKey) ?? dropTargetKey; + } } + let persistedKeys = useMemo(() => { + return new Set([focusedKey, dropTargetKey].filter(k => k !== null)); + }, [focusedKey, dropTargetKey]); + let hasAnyChildren = useMemo( () => [...collection].some(item => item.hasChildNodes), [collection] @@ -210,19 +208,17 @@ function ListView( density, // @ts-expect-error dragAndDropHooks, - // @ts-expect-error dragState, - // @ts-expect-error dropState, isListDraggable, isListDroppable, - // @ts-expect-error layout, // @ts-expect-error loadingState, // @ts-expect-error onAction, overflowMode, + renderEmptyState, state, }} > @@ -248,8 +244,11 @@ function ListView( isLoading={isLoading} onLoadMore={onLoadMore} ref={domRef} - focusedKey={focusedKey} + persistedKeys={persistedKeys} scrollDirection="vertical" + layout={layout} + layoutOptions={useMemo(() => ({ isLoading }), [isLoading])} + collection={collection} className={classNames( listViewClassList.element('root'), css({ @@ -275,9 +274,6 @@ function ListView( }), styleProps.className )} - layout={layout} - collection={collection} - transitionDuration={isLoading ? 160 : 220} > {(type, item) => { if (type === 'item') { @@ -353,7 +349,6 @@ function ListView( assert(item != null, 'Dragged item must exist in collection.'); - // @ts-expect-error let itemCount = dragState.draggingKeys.size; // @ts-expect-error let itemHeight = layout.getLayoutInfo(dragState.draggedKey).rect diff --git a/design-system/pkg/src/list-view/ListViewItem.tsx b/design-system/pkg/src/list-view/ListViewItem.tsx index a193b50e4..5546c4878 100644 --- a/design-system/pkg/src/list-view/ListViewItem.tsx +++ b/design-system/pkg/src/list-view/ListViewItem.tsx @@ -205,8 +205,7 @@ export function ListViewItem(props: ListViewItemProps) { let isFlushWithContainerBottom = false; if (isLastRow && loadingState !== 'loadingMore') { if ( - layout.getContentSize()?.height >= - layout.virtualizer?.getVisibleRect().height + layout.getContentSize()?.height >= layout.virtualizer?.visibleRect.height ) { isFlushWithContainerBottom = true; } diff --git a/design-system/pkg/src/list-view/ListViewLayout.tsx b/design-system/pkg/src/list-view/ListViewLayout.tsx new file mode 100644 index 000000000..2a6ebf8a4 --- /dev/null +++ b/design-system/pkg/src/list-view/ListViewLayout.tsx @@ -0,0 +1,71 @@ +import { + InvalidationContext, + LayoutInfo, + Rect, +} from '@react-stately/virtualizer'; +import { LayoutNode, ListLayout } from '@react-stately/layout'; +import { Node } from '@react-types/shared'; + +interface ListViewLayoutProps { + isLoading?: boolean; +} + +export class ListViewLayout extends ListLayout { + private isLoading: boolean = false; + + update(invalidationContext: InvalidationContext): void { + this.isLoading = invalidationContext.layoutOptions?.isLoading || false; + super.update(invalidationContext); + } + + protected buildCollection(): LayoutNode[] { + let nodes = super.buildCollection(); + let y = this.contentSize.height; + + if (this.isLoading) { + let rect = new Rect( + 0, + y, + this.virtualizer.visibleRect.width, + nodes.length === 0 + ? this.virtualizer.visibleRect.height + : this.estimatedRowHeight + ); + let loader = new LayoutInfo('loader', 'loader', rect); + let node = { + layoutInfo: loader, + validRect: loader.rect, + }; + nodes.push(node); + this.layoutNodes.set(loader.key, node); + y = loader.rect.maxY; + } + + if (nodes.length === 0) { + let rect = new Rect( + 0, + y, + this.virtualizer.visibleRect.width, + this.virtualizer.visibleRect.height + ); + let placeholder = new LayoutInfo('placeholder', 'placeholder', rect); + let node = { + layoutInfo: placeholder, + validRect: placeholder.rect, + }; + nodes.push(node); + this.layoutNodes.set(placeholder.key, node); + y = placeholder.rect.maxY; + } + + this.contentSize.height = y; + return nodes; + } + + protected buildItem(node: Node, x: number, y: number): LayoutNode { + let res = super.buildItem(node, x, y); + // allow overflow so the focus ring/selection ring can extend outside to overlap with the adjacent items borders + res.layoutInfo.allowOverflow = true; + return res; + } +} diff --git a/design-system/pkg/src/listbox/ListBox.tsx b/design-system/pkg/src/listbox/ListBox.tsx index 0a9b54191..04f15e56b 100644 --- a/design-system/pkg/src/listbox/ListBox.tsx +++ b/design-system/pkg/src/listbox/ListBox.tsx @@ -12,7 +12,7 @@ function ListBox( ) { let domRef = useObjectRef(forwardedRef); let state = useListState(props); - let layout = useListBoxLayout(state); + let layout = useListBoxLayout(); return ; } diff --git a/design-system/pkg/src/listbox/ListBoxBase.tsx b/design-system/pkg/src/listbox/ListBoxBase.tsx index b63452ea9..bfbcdbb59 100644 --- a/design-system/pkg/src/listbox/ListBoxBase.tsx +++ b/design-system/pkg/src/listbox/ListBoxBase.tsx @@ -1,10 +1,8 @@ import { FocusScope } from '@react-aria/focus'; import { useListBox } from '@react-aria/listbox'; -import { useCollator, useLocalizedStringFormatter } from '@react-aria/i18n'; +import { useLocalizedStringFormatter } from '@react-aria/i18n'; import { mergeProps } from '@react-aria/utils'; import { Virtualizer, VirtualizerItem } from '@react-aria/virtualizer'; -import { ListLayout } from '@react-stately/layout'; -import { ListState } from '@react-stately/list'; import { ReusableView } from '@react-stately/virtualizer'; import { Node } from '@react-types/shared'; import { RefObject, forwardRef, ReactElement, ReactNode, useMemo } from 'react'; @@ -15,29 +13,25 @@ import { useStyleProps } from '@keystar/ui/style'; import localizedMessages from './l10n.json'; import { ListBoxContext } from './context'; +import { ListBoxLayout } from './ListBoxLayout'; import { ListBoxOption } from './ListBoxOption'; import { ListBoxSection } from './ListBoxSection'; import { ListBoxBaseProps } from './types'; /** @private */ -export function useListBoxLayout(state: ListState) { +export function useListBoxLayout(): ListBoxLayout { let { scale } = useProvider(); - let collator = useCollator({ usage: 'search', sensitivity: 'base' }); let layout = useMemo( () => - new ListLayout({ + new ListBoxLayout({ estimatedRowHeight: scale === 'large' ? 48 : 32, estimatedHeadingHeight: scale === 'large' ? 33 : 26, - padding: scale === 'large' ? 5 : 4, - loaderHeight: 40, + padding: scale === 'large' ? 5 : 4, // TODO: get from DNA placeholderHeight: scale === 'large' ? 48 : 32, - collator, }), - [collator, scale] + [scale] ); - layout.collection = state.collection; - layout.disabledKeys = state.disabledKeys; return layout; } @@ -49,17 +43,18 @@ function ListBoxBase( let { layout, state, - shouldSelectOnPressUp, - focusOnPointerEnter, - shouldUseVirtualFocus, + shouldFocusOnHover = false, + shouldUseVirtualFocus = false, domProps = {}, - transitionDuration = 0, + isLoading, + showLoadingSpinner = isLoading, onScroll, + renderEmptyState, } = props; let { listBoxProps } = useListBox( { ...props, - keyboardDelegate: layout, + layoutDelegate: layout, isVirtualized: true, }, state, @@ -68,9 +63,6 @@ function ListBoxBase( let styleProps = useStyleProps(props); let stringFormatter = useLocalizedStringFormatter(localizedMessages); - // Sync loading state into the layout. - layout.isLoading = !!props.isLoading; - // This overrides collection view's renderWrapper to support heirarchy of items in sections. // The header is extracted from the children so it can receive ARIA labeling properties. type View = ReusableView, ReactNode>; @@ -108,24 +100,40 @@ function ListBoxBase( ); }; + let focusedKey = state.selectionManager.focusedKey; + let persistedKeys = useMemo( + () => (focusedKey != null ? new Set([focusedKey]) : null), + [focusedKey] + ); + return ( - + ({ + isLoading: showLoadingSpinner, + }), + [showLoadingSpinner] + )} collection={state.collection} renderWrapper={renderWrapper} - transitionDuration={transitionDuration} isLoading={props.isLoading} onLoadMore={props.onLoadMore} - shouldUseVirtualFocus={shouldUseVirtualFocus} onScroll={onScroll} > {(type, item: Node) => { @@ -133,8 +141,6 @@ function ListBoxBase( return ( ); diff --git a/design-system/pkg/src/listbox/ListBoxLayout.tsx b/design-system/pkg/src/listbox/ListBoxLayout.tsx new file mode 100644 index 000000000..47f41ab47 --- /dev/null +++ b/design-system/pkg/src/listbox/ListBoxLayout.tsx @@ -0,0 +1,100 @@ +import { + InvalidationContext, + LayoutInfo, + Rect, +} from '@react-stately/virtualizer'; +import { + LayoutNode, + ListLayout, + ListLayoutOptions, +} from '@react-stately/layout'; +import { Node } from '@react-types/shared'; + +interface ListBoxLayoutProps { + isLoading?: boolean; +} + +interface ListBoxLayoutOptions extends ListLayoutOptions { + placeholderHeight: number; + padding: number; +} + +export class ListBoxLayout extends ListLayout { + private isLoading: boolean = false; + private placeholderHeight: number; + private padding: number; + + constructor(opts: ListBoxLayoutOptions) { + super(opts); + this.placeholderHeight = opts.placeholderHeight; + this.padding = opts.padding; + } + + update(invalidationContext: InvalidationContext): void { + this.isLoading = invalidationContext.layoutOptions?.isLoading || false; + super.update(invalidationContext); + } + + protected buildCollection(): LayoutNode[] { + let nodes = super.buildCollection(this.padding); + let y = this.contentSize.height; + + if (this.isLoading) { + let rect = new Rect(0, y, this.virtualizer.visibleRect.width, 40); + let loader = new LayoutInfo('loader', 'loader', rect); + let node = { + layoutInfo: loader, + validRect: loader.rect, + }; + nodes.push(node); + this.layoutNodes.set(loader.key, node); + y = loader.rect.maxY; + } + + if (nodes.length === 0) { + let rect = new Rect( + 0, + y, + this.virtualizer.visibleRect.width, + this.placeholderHeight ?? this.virtualizer.visibleRect.height + ); + let placeholder = new LayoutInfo('placeholder', 'placeholder', rect); + let node = { + layoutInfo: placeholder, + validRect: placeholder.rect, + }; + nodes.push(node); + this.layoutNodes.set(placeholder.key, node); + y = placeholder.rect.maxY; + } + + this.contentSize.height = y + this.padding; + return nodes; + } + + protected buildSection(node: Node, x: number, y: number): LayoutNode { + // Synthesize a collection node for the header. + let headerNode = { + type: 'header', + key: node.key + ':header', + parentKey: node.key, + value: null, + level: node.level, + hasChildNodes: false, + childNodes: [], + rendered: node.rendered, + textValue: node.textValue, + }; + + // Build layout node for it and adjust y offset of section children. + let header = this.buildSectionHeader(headerNode, x, y); + header.node = headerNode; + header.layoutInfo.parentKey = node.key; + this.layoutNodes.set(headerNode.key, header); + y += header.layoutInfo.rect.height; + + let section = super.buildSection(node, x, y); + section.children?.unshift(header); + return section; + } +} diff --git a/design-system/pkg/src/listbox/ListBoxOption.tsx b/design-system/pkg/src/listbox/ListBoxOption.tsx index 6af8a08d8..98bf1baf7 100644 --- a/design-system/pkg/src/listbox/ListBoxOption.tsx +++ b/design-system/pkg/src/listbox/ListBoxOption.tsx @@ -32,7 +32,7 @@ export function ListBoxOption(props: OptionProps) { let { rendered, key } = item; - let state = useListBoxContext(); + let { state } = useListBoxContext(); let ref = useRef(null); let { diff --git a/design-system/pkg/src/listbox/ListBoxSection.tsx b/design-system/pkg/src/listbox/ListBoxSection.tsx index 059ee3f1d..a1db47824 100644 --- a/design-system/pkg/src/listbox/ListBoxSection.tsx +++ b/design-system/pkg/src/listbox/ListBoxSection.tsx @@ -9,11 +9,11 @@ import { LayoutInfo } from '@react-stately/virtualizer'; import { Node } from '@react-types/shared'; import { Fragment, ReactNode, useRef } from 'react'; +import { Divider } from '@keystar/ui/layout'; import { classNames, css, tokenSchema } from '@keystar/ui/style'; +import { Text } from '@keystar/ui/typography'; import { useListBoxContext } from './context'; -import { Text } from '@keystar/ui/typography'; -import { Divider } from '@keystar/ui/layout'; interface ListBoxSectionProps extends Omit { headerLayoutInfo: LayoutInfo; @@ -37,7 +37,7 @@ export function ListBoxSection(props: ListBoxSectionProps) { }); let { direction } = useLocale(); - let state = useListBoxContext(); + let { state } = useListBoxContext(); return ( diff --git a/design-system/pkg/src/listbox/context.ts b/design-system/pkg/src/listbox/context.ts index 80f7b9261..03e40f8a3 100644 --- a/design-system/pkg/src/listbox/context.ts +++ b/design-system/pkg/src/listbox/context.ts @@ -1,8 +1,14 @@ import { ListState } from '@react-stately/list'; import { assert } from 'emery'; -import { createContext, useContext } from 'react'; +import { type ReactNode, createContext, useContext } from 'react'; -export const ListBoxContext = createContext | null>(null); +interface ListBoxContextValue { + state: ListState; + renderEmptyState?: () => ReactNode; + shouldFocusOnHover: boolean; + shouldUseVirtualFocus: boolean; +} +export const ListBoxContext = createContext(null); export function useListBoxContext() { let context = useContext(ListBoxContext); diff --git a/design-system/pkg/src/listbox/types.ts b/design-system/pkg/src/listbox/types.ts index a2309fbb8..8733a5747 100644 --- a/design-system/pkg/src/listbox/types.ts +++ b/design-system/pkg/src/listbox/types.ts @@ -1,5 +1,4 @@ import { AriaListBoxOptions } from '@react-aria/listbox'; -import { ListLayout } from '@react-stately/layout'; import { ListState } from '@react-stately/list'; import { AriaLabelingProps, @@ -14,6 +13,8 @@ import { HTMLAttributes, ReactNode } from 'react'; import { BaseStyleProps } from '@keystar/ui/style'; +import { ListBoxLayout } from './ListBoxLayout'; + /** @private */ export type ListBoxBaseProps = { autoFocus?: boolean | FocusStrategy; @@ -21,15 +22,15 @@ export type ListBoxBaseProps = { domProps?: HTMLAttributes; focusOnPointerEnter?: boolean; isLoading?: boolean; - layout: ListLayout; + layout: ListBoxLayout; onLoadMore?: () => void; onScroll?: () => void; renderEmptyState?: () => ReactNode; shouldFocusWrap?: boolean; shouldSelectOnPressUp?: boolean; shouldUseVirtualFocus?: boolean; + showLoadingSpinner?: boolean; state: ListState; - transitionDuration?: number; } & AriaListBoxOptions & AriaLabelingProps & BaseStyleProps & diff --git a/design-system/pkg/src/menu/stories/ActionMenu.stories.tsx b/design-system/pkg/src/menu/stories/ActionMenu.stories.tsx index b13527409..3c01eda81 100644 --- a/design-system/pkg/src/menu/stories/ActionMenu.stories.tsx +++ b/design-system/pkg/src/menu/stories/ActionMenu.stories.tsx @@ -137,9 +137,9 @@ export const DOMId = { args: { id: 'my-action-menu' }, }; -export const Quiet = { +export const LowProminence = { render: Template, - args: { isQuiet: true }, + args: { prominence: 'low' }, }; export const Disabled = { diff --git a/design-system/pkg/src/overlays/Modal.tsx b/design-system/pkg/src/overlays/Modal.tsx index 3b2554ad1..7290c9714 100644 --- a/design-system/pkg/src/overlays/Modal.tsx +++ b/design-system/pkg/src/overlays/Modal.tsx @@ -43,7 +43,6 @@ export const Modal: ForwardRefExoticComponent< let wrapperRef = useRef(null); return ( - /* @ts-expect-error FIXME: resolve ref inconsistencies */ {children} diff --git a/design-system/pkg/src/overlays/Popover.tsx b/design-system/pkg/src/overlays/Popover.tsx index 04fb9d052..a37f601f6 100644 --- a/design-system/pkg/src/overlays/Popover.tsx +++ b/design-system/pkg/src/overlays/Popover.tsx @@ -42,7 +42,6 @@ export const Popover: ForwardRefExoticComponent< let wrapperRef = useRef(null); return ( - /* @ts-expect-error FIXME: resolve ref inconsistencies */ {children} diff --git a/design-system/pkg/src/overlays/Tray.tsx b/design-system/pkg/src/overlays/Tray.tsx index 555b2064f..9bead4783 100644 --- a/design-system/pkg/src/overlays/Tray.tsx +++ b/design-system/pkg/src/overlays/Tray.tsx @@ -42,7 +42,6 @@ export const Tray: ForwardRefExoticComponent< let wrapperRef = useRef(null); return ( - /* @ts-expect-error FIXME: resolve ref inconsistencies */ {children} diff --git a/design-system/pkg/src/overlays/test/Overlay.test.tsx b/design-system/pkg/src/overlays/test/Overlay.test.tsx index d2a52455a..572db4222 100644 --- a/design-system/pkg/src/overlays/test/Overlay.test.tsx +++ b/design-system/pkg/src/overlays/test/Overlay.test.tsx @@ -35,7 +35,6 @@ const ExampleOverlay = forwardRef(function ExampleOverlay( ) { let nodeRef = useRef(null); return ( - /* @ts-expect-error FIXME: resolve ref inconsistencies */ Overlay content diff --git a/design-system/pkg/src/overlays/types.ts b/design-system/pkg/src/overlays/types.ts index 5a302a883..b83510a80 100644 --- a/design-system/pkg/src/overlays/types.ts +++ b/design-system/pkg/src/overlays/types.ts @@ -39,7 +39,7 @@ export type TrayProps = { export type TransitionProps = { children: ReactNode; isOpen?: boolean; - nodeRef: MutableRefObject; + nodeRef: MutableRefObject; onEnter?: () => void; onEntered?: () => void; onEntering?: () => void; diff --git a/design-system/pkg/src/text-field/TextArea.tsx b/design-system/pkg/src/text-field/TextArea.tsx index f77a91343..8b971c464 100644 --- a/design-system/pkg/src/text-field/TextArea.tsx +++ b/design-system/pkg/src/text-field/TextArea.tsx @@ -14,7 +14,7 @@ export const TextArea = forwardRef( let domRef = useObjectRef(forwardedRef); let [inputValue, setInputValue] = useControlledState( props.value, - props.defaultValue, + props.defaultValue ?? '', () => {} ); diff --git a/design-system/pkg/src/tooltip/TooltipTrigger.tsx b/design-system/pkg/src/tooltip/TooltipTrigger.tsx index 21eb2c910..3fd1a170b 100644 --- a/design-system/pkg/src/tooltip/TooltipTrigger.tsx +++ b/design-system/pkg/src/tooltip/TooltipTrigger.tsx @@ -42,7 +42,6 @@ function TooltipTrigger(props: TooltipTriggerProps) { ...tooltipProps, }} > - {/* @ts-expect-error FIXME: resolve ref inconsistencies */} {tooltipElement} diff --git a/packages/keystatic/package.json b/packages/keystatic/package.json index 53c770d82..256948712 100644 --- a/packages/keystatic/package.json +++ b/packages/keystatic/package.json @@ -119,19 +119,19 @@ "@internationalized/string": "^3.1.1", "@keystar/ui": "workspace:^", "@markdoc/markdoc": "^0.4.0", - "@react-aria/focus": "^3.14.3", - "@react-aria/i18n": "^3.8.0", - "@react-aria/interactions": "^3.21.1", - "@react-aria/label": "^3.7.2", - "@react-aria/overlays": "^3.18.1", - "@react-aria/selection": "^3.17.1", - "@react-aria/utils": "^3.23.2", - "@react-aria/visually-hidden": "^3.8.6", - "@react-stately/collections": "^3.10.2", - "@react-stately/list": "^3.10.0", - "@react-stately/overlays": "^3.6.3", - "@react-stately/utils": "^3.8.0", - "@react-types/shared": "^3.21.0", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.11", + "@react-aria/overlays": "^3.23.2", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.15", + "@react-stately/collections": "^3.10.9", + "@react-stately/list": "^3.10.8", + "@react-stately/overlays": "^3.6.10", + "@react-stately/utils": "^3.10.3", + "@react-types/shared": "^3.24.1", "@sindresorhus/slugify": "^1.1.2", "@toeverything/y-indexeddb": "^0.10.0-canary.9", "@ts-gql/tag": "^0.7.3", diff --git a/packages/keystatic/src/form/fields/document/DocumentEditor/insert-menu.tsx b/packages/keystatic/src/form/fields/document/DocumentEditor/insert-menu.tsx index 2d40b5a3e..688751fad 100644 --- a/packages/keystatic/src/form/fields/document/DocumentEditor/insert-menu.tsx +++ b/packages/keystatic/src/form/fields/document/DocumentEditor/insert-menu.tsx @@ -266,7 +266,7 @@ export function InsertMenu({ } }, [state.selectionManager.focusedKey]); const listboxRef = useRef(null); - let layout = useListBoxLayout(state); + let layout = useListBoxLayout(); return ( (null); return ( - /* @ts-expect-error FIXME: resolve ref inconsistencies */ diff --git a/packages/keystatic/src/form/fields/markdoc/editor/autocomplete/EditorListbox.tsx b/packages/keystatic/src/form/fields/markdoc/editor/autocomplete/EditorListbox.tsx index 266015a95..347be6aa5 100644 --- a/packages/keystatic/src/form/fields/markdoc/editor/autocomplete/EditorListbox.tsx +++ b/packages/keystatic/src/form/fields/markdoc/editor/autocomplete/EditorListbox.tsx @@ -1,4 +1,7 @@ -import { useSelectableCollection } from '@react-aria/selection'; +import { + ListKeyboardDelegate, + useSelectableCollection, +} from '@react-aria/selection'; import { chain } from '@react-aria/utils'; import { useListState } from '@react-stately/list'; import { @@ -6,7 +9,7 @@ import { CollectionBase, MultipleSelection, } from '@react-types/shared'; -import { Key, RefObject, useEffect, useRef } from 'react'; +import { Key, RefObject, useEffect, useMemo, useRef } from 'react'; import { HStack } from '@keystar/ui/layout'; import { ListBoxBase, listStyles, useListBoxLayout } from '@keystar/ui/listbox'; @@ -40,12 +43,21 @@ export function useEditorListbox( ) { let { listenerRef, onEscape, scrollRef, ...otherProps } = props; let state = useListState(props); - let layout = useListBoxLayout(state); + let layout = useListBoxLayout(); + let delegate = useMemo( + () => + new ListKeyboardDelegate({ + collection: state.collection, + ref: listboxRef, + layoutDelegate: layout, + }), + [layout, state.collection] + ); // keyboard and selection management let listboxRef = useRef(null); let { collectionProps } = useSelectableCollection({ - keyboardDelegate: layout, + keyboardDelegate: delegate, ref: listenerRef, scrollRef: scrollRef ?? listboxRef, selectionManager: state.selectionManager, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7e7cfddf..22d270b36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -121,10 +121,10 @@ importers: version: 7.22.15 '@cloudflare/next-on-pages': specifier: ^1.11.0 - version: 1.11.0(vercel@33.6.3)(wrangler@3.34.2) + version: 1.11.0(vercel@33.6.3)(wrangler@3.72.2) '@internationalized/date': - specifier: ^3.5.0 - version: 3.5.0 + specifier: ^3.5.5 + version: 3.5.5 '@keystar/ui': specifier: workspace:^ version: link:../pkg @@ -138,8 +138,8 @@ importers: specifier: ^0.4.0 version: 0.4.0(@types/react@18.2.21)(react@18.2.0) '@react-aria/i18n': - specifier: ^3.8.0 - version: 3.8.1(react@18.2.0) + specifier: ^3.12.1 + version: 3.12.2(react@18.2.0) clipboard-copy: specifier: ^4.0.1 version: 4.0.1 @@ -252,239 +252,239 @@ importers: specifier: ^0.24.0 version: 0.24.8(react-dom@18.2.0)(react@18.2.0) '@internationalized/date': - specifier: ^3.5.0 - version: 3.5.0 + specifier: ^3.5.5 + version: 3.5.5 '@react-aria/actiongroup': - specifier: ^3.6.4 - version: 3.6.4(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.7.8 + version: 3.7.8(react-dom@18.2.0)(react@18.2.0) '@react-aria/breadcrumbs': - specifier: ^3.5.11 - version: 3.5.11(react@18.2.0) + specifier: ^3.5.16 + version: 3.5.16(react@18.2.0) '@react-aria/button': - specifier: ^3.8.4 - version: 3.8.4(react@18.2.0) + specifier: ^3.9.8 + version: 3.9.8(react@18.2.0) '@react-aria/calendar': - specifier: ^3.5.2 - version: 3.5.2(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.5.11 + version: 3.5.11(react-dom@18.2.0)(react@18.2.0) '@react-aria/checkbox': - specifier: ^3.11.2 - version: 3.11.2(react@18.2.0) + specifier: ^3.14.6 + version: 3.14.6(react@18.2.0) '@react-aria/combobox': - specifier: ^3.7.1 - version: 3.7.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.10.3 + version: 3.10.3(react-dom@18.2.0)(react@18.2.0) '@react-aria/datepicker': - specifier: ^3.8.1 - version: 3.8.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.11.2 + version: 3.11.2(react-dom@18.2.0)(react@18.2.0) '@react-aria/dialog': - specifier: ^3.5.7 - version: 3.5.7(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.5.17 + version: 3.5.17(react-dom@18.2.0)(react@18.2.0) '@react-aria/dnd': - specifier: ^3.4.3 - version: 3.4.3(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.7.2 + version: 3.7.2(react-dom@18.2.0)(react@18.2.0) '@react-aria/focus': - specifier: ^3.14.3 - version: 3.14.3(react@18.2.0) + specifier: ^3.18.1 + version: 3.18.2(react@18.2.0) '@react-aria/gridlist': - specifier: ^3.7.1 - version: 3.7.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.9.3 + version: 3.9.3(react-dom@18.2.0)(react@18.2.0) '@react-aria/i18n': - specifier: ^3.8.0 - version: 3.10.2(react@18.2.0) + specifier: ^3.12.1 + version: 3.12.2(react@18.2.0) '@react-aria/interactions': - specifier: ^3.21.1 - version: 3.21.1(react@18.2.0) + specifier: ^3.22.1 + version: 3.22.2(react@18.2.0) '@react-aria/label': - specifier: ^3.7.2 - version: 3.7.2(react@18.2.0) + specifier: ^3.7.11 + version: 3.7.11(react@18.2.0) '@react-aria/link': - specifier: ^3.6.5 - version: 3.6.5(react@18.2.0) + specifier: ^3.7.4 + version: 3.7.4(react@18.2.0) '@react-aria/listbox': - specifier: ^3.11.1 - version: 3.11.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.13.3 + version: 3.13.3(react-dom@18.2.0)(react@18.2.0) '@react-aria/live-announcer': - specifier: ^3.3.2 - version: 3.3.2 + specifier: ^3.3.4 + version: 3.3.4 '@react-aria/menu': - specifier: ^3.11.1 - version: 3.11.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.15.3 + version: 3.15.3(react-dom@18.2.0)(react@18.2.0) '@react-aria/meter': - specifier: ^3.4.7 - version: 3.4.7(react@18.2.0) + specifier: ^3.4.16 + version: 3.4.16(react@18.2.0) '@react-aria/numberfield': - specifier: ^3.9.1 - version: 3.9.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.11.6 + version: 3.11.6(react-dom@18.2.0)(react@18.2.0) '@react-aria/overlays': - specifier: ^3.18.1 - version: 3.18.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.23.2 + version: 3.23.2(react-dom@18.2.0)(react@18.2.0) '@react-aria/progress': - specifier: ^3.4.7 - version: 3.4.7(react@18.2.0) + specifier: ^3.4.16 + version: 3.4.16(react@18.2.0) '@react-aria/radio': - specifier: ^3.8.2 - version: 3.8.2(react@18.2.0) + specifier: ^3.10.7 + version: 3.10.7(react@18.2.0) '@react-aria/searchfield': - specifier: ^3.5.7 - version: 3.5.7(react@18.2.0) + specifier: ^3.7.8 + version: 3.7.8(react@18.2.0) '@react-aria/select': - specifier: ^3.13.1 - version: 3.13.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.14.9 + version: 3.14.9(react-dom@18.2.0)(react@18.2.0) '@react-aria/selection': - specifier: ^3.17.1 - version: 3.17.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.19.3 + version: 3.19.3(react-dom@18.2.0)(react@18.2.0) '@react-aria/separator': - specifier: ^3.3.7 - version: 3.3.7(react@18.2.0) + specifier: ^3.4.2 + version: 3.4.2(react@18.2.0) '@react-aria/ssr': - specifier: ^3.8.0 - version: 3.8.0(react@18.2.0) + specifier: ^3.9.5 + version: 3.9.5(react@18.2.0) '@react-aria/switch': - specifier: ^3.5.6 - version: 3.5.6(react@18.2.0) + specifier: ^3.6.7 + version: 3.6.7(react@18.2.0) '@react-aria/table': - specifier: ^3.13.1 - version: 3.13.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.15.1 + version: 3.15.3(react-dom@18.2.0)(react@18.2.0) '@react-aria/tabs': - specifier: ^3.8.1 - version: 3.8.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.9.5 + version: 3.9.5(react-dom@18.2.0)(react@18.2.0) '@react-aria/textfield': - specifier: ^3.12.2 - version: 3.12.2(react@18.2.0) + specifier: ^3.14.8 + version: 3.14.8(react@18.2.0) '@react-aria/toast': - specifier: 3.0.0-beta.2 - version: 3.0.0-beta.2(react@18.2.0) + specifier: 3.0.0-beta.15 + version: 3.0.0-beta.15(react@18.2.0) '@react-aria/tooltip': - specifier: ^3.6.4 - version: 3.6.4(react@18.2.0) + specifier: ^3.7.7 + version: 3.7.7(react@18.2.0) '@react-aria/utils': - specifier: ^3.23.2 - version: 3.23.2(react@18.2.0) + specifier: ^3.25.1 + version: 3.25.2(react@18.2.0) '@react-aria/virtualizer': - specifier: ^3.9.5 - version: 3.9.5(react-dom@18.2.0)(react@18.2.0) + specifier: ^4.0.2 + version: 4.0.2(react-dom@18.2.0)(react@18.2.0) '@react-aria/visually-hidden': - specifier: ^3.8.6 - version: 3.8.6(react@18.2.0) + specifier: ^3.8.15 + version: 3.8.15(react@18.2.0) '@react-stately/calendar': - specifier: ^3.4.1 - version: 3.4.1(react@18.2.0) + specifier: ^3.5.4 + version: 3.5.4(react@18.2.0) '@react-stately/checkbox': - specifier: ^3.5.1 - version: 3.5.1(react@18.2.0) + specifier: ^3.6.8 + version: 3.6.8(react@18.2.0) '@react-stately/collections': - specifier: ^3.10.2 - version: 3.10.2(react@18.2.0) + specifier: ^3.10.9 + version: 3.10.9(react@18.2.0) '@react-stately/combobox': - specifier: ^3.7.1 - version: 3.7.1(react@18.2.0) + specifier: ^3.9.2 + version: 3.9.2(react@18.2.0) '@react-stately/data': - specifier: ^3.10.3 - version: 3.10.3(react@18.2.0) + specifier: ^3.11.6 + version: 3.11.6(react@18.2.0) '@react-stately/datepicker': - specifier: ^3.8.0 - version: 3.8.0(react@18.2.0) + specifier: ^3.10.2 + version: 3.10.2(react@18.2.0) '@react-stately/dnd': - specifier: ^3.2.5 - version: 3.2.5(react@18.2.0) + specifier: ^3.4.2 + version: 3.4.2(react@18.2.0) '@react-stately/layout': - specifier: ^3.13.3 - version: 3.13.3(react@18.2.0) + specifier: ^4.0.2 + version: 4.0.2(react@18.2.0) '@react-stately/list': - specifier: ^3.10.0 - version: 3.10.0(react@18.2.0) + specifier: ^3.10.8 + version: 3.10.8(react@18.2.0) '@react-stately/menu': - specifier: ^3.5.6 - version: 3.5.6(react@18.2.0) + specifier: ^3.8.2 + version: 3.8.2(react@18.2.0) '@react-stately/numberfield': - specifier: ^3.6.2 - version: 3.6.2(react@18.2.0) + specifier: ^3.9.6 + version: 3.9.6(react@18.2.0) '@react-stately/overlays': - specifier: ^3.6.3 - version: 3.6.3(react@18.2.0) + specifier: ^3.6.10 + version: 3.6.10(react@18.2.0) '@react-stately/radio': - specifier: ^3.9.1 - version: 3.9.1(react@18.2.0) + specifier: ^3.10.7 + version: 3.10.7(react@18.2.0) '@react-stately/searchfield': - specifier: ^3.4.6 - version: 3.4.6(react@18.2.0) + specifier: ^3.5.6 + version: 3.5.6(react@18.2.0) '@react-stately/select': - specifier: ^3.5.5 - version: 3.5.5(react@18.2.0) + specifier: ^3.6.7 + version: 3.6.7(react@18.2.0) '@react-stately/table': - specifier: ^3.11.2 - version: 3.11.2(react@18.2.0) + specifier: ^3.12.1 + version: 3.12.2(react@18.2.0) '@react-stately/tabs': - specifier: ^3.6.1 - version: 3.6.1(react@18.2.0) + specifier: ^3.6.9 + version: 3.6.9(react@18.2.0) '@react-stately/toast': - specifier: 3.0.0-beta.1 - version: 3.0.0-beta.1(react@18.2.0) + specifier: 3.0.0-beta.5 + version: 3.0.0-beta.5(react@18.2.0) '@react-stately/toggle': - specifier: ^3.6.3 - version: 3.6.3(react@18.2.0) + specifier: ^3.7.7 + version: 3.7.7(react@18.2.0) '@react-stately/tooltip': - specifier: ^3.4.5 - version: 3.4.5(react@18.2.0) + specifier: ^3.4.12 + version: 3.4.12(react@18.2.0) '@react-stately/tree': - specifier: ^3.7.3 - version: 3.7.3(react@18.2.0) + specifier: ^3.8.4 + version: 3.8.4(react@18.2.0) '@react-stately/utils': - specifier: ^3.8.0 - version: 3.8.0(react@18.2.0) + specifier: ^3.10.3 + version: 3.10.3(react@18.2.0) '@react-stately/virtualizer': - specifier: ^3.6.5 - version: 3.6.5(react@18.2.0) + specifier: ^4.0.2 + version: 4.0.2(react@18.2.0) '@react-types/actionbar': - specifier: ^3.1.5 - version: 3.1.5(react@18.2.0) + specifier: ^3.1.9 + version: 3.1.9(react@18.2.0) '@react-types/actiongroup': - specifier: ^3.4.5 - version: 3.4.5(react@18.2.0) + specifier: ^3.4.11 + version: 3.4.11(react@18.2.0) '@react-types/breadcrumbs': - specifier: ^3.7.3 - version: 3.7.3(react@18.2.0) + specifier: ^3.7.7 + version: 3.7.7(react@18.2.0) '@react-types/button': - specifier: ^3.9.0 - version: 3.9.0(react@18.2.0) + specifier: ^3.9.6 + version: 3.9.6(react@18.2.0) '@react-types/calendar': - specifier: ^3.4.1 - version: 3.4.1(react@18.2.0) + specifier: ^3.4.9 + version: 3.4.9(react@18.2.0) '@react-types/combobox': - specifier: ^3.8.1 - version: 3.8.1(react@18.2.0) + specifier: ^3.12.1 + version: 3.12.1(react@18.2.0) '@react-types/datepicker': - specifier: ^3.6.1 - version: 3.6.1(react@18.2.0) + specifier: ^3.8.2 + version: 3.8.2(react@18.2.0) '@react-types/grid': - specifier: ^3.2.2 - version: 3.2.2(react@18.2.0) + specifier: ^3.2.8 + version: 3.2.8(react@18.2.0) '@react-types/menu': - specifier: ^3.9.5 - version: 3.9.5(react@18.2.0) + specifier: ^3.9.11 + version: 3.9.11(react@18.2.0) '@react-types/numberfield': - specifier: ^3.6.1 - version: 3.6.1(react@18.2.0) + specifier: ^3.8.5 + version: 3.8.5(react@18.2.0) '@react-types/overlays': + specifier: ^3.8.9 + version: 3.8.9(react@18.2.0) + '@react-types/radio': specifier: ^3.8.3 version: 3.8.3(react@18.2.0) - '@react-types/radio': - specifier: ^3.5.2 - version: 3.5.2(react@18.2.0) '@react-types/select': - specifier: ^3.8.4 - version: 3.8.4(react@18.2.0) + specifier: ^3.9.6 + version: 3.9.6(react@18.2.0) '@react-types/shared': - specifier: ^3.21.0 - version: 3.21.0(react@18.2.0) + specifier: ^3.24.1 + version: 3.24.1(react@18.2.0) '@react-types/switch': - specifier: ^3.4.2 - version: 3.4.2(react@18.2.0) + specifier: ^3.5.5 + version: 3.5.5(react@18.2.0) '@react-types/table': - specifier: ^3.9.0 - version: 3.9.0(react@18.2.0) + specifier: ^3.10.1 + version: 3.10.1(react@18.2.0) '@react-types/tabs': - specifier: ^3.3.3 - version: 3.3.3(react@18.2.0) + specifier: ^3.3.9 + version: 3.3.9(react@18.2.0) '@types/react': specifier: ^18.2.8 version: 18.2.21 @@ -505,8 +505,8 @@ importers: specifier: workspace:^ version: link:../docs/storybook '@react-aria/landmark': - specifier: 3.0.0-beta.2 - version: 3.0.0-beta.2(react@18.2.0) + specifier: 3.0.0-beta.15 + version: 3.0.0-beta.15(react@18.2.0) '@svgr/core': specifier: ^6.5.1 version: 6.5.1 @@ -539,7 +539,7 @@ importers: version: 0.314.0 next: specifier: ^14.1.3 - version: 14.1.3(@babel/core@7.24.5)(react-dom@18.2.0)(react@18.2.0) + version: 14.1.3(@babel/core@7.25.2)(react-dom@18.2.0)(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -606,7 +606,7 @@ importers: version: 7.0.0(astro@4.0.3) '@astrojs/react': specifier: ^3.0.7 - version: 3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.2.12) + version: 3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.4.2) '@braintree/sanitize-url': specifier: ^6.0.2 version: 6.0.4 @@ -681,7 +681,7 @@ importers: version: 7.0.0(astro@4.0.3) '@astrojs/react': specifier: ^3.0.7 - version: 3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.2.12) + version: 3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.4.2) '@astrojs/sitemap': specifier: ^3.0.3 version: 3.0.3 @@ -762,7 +762,7 @@ importers: version: 7.22.15 '@cloudflare/next-on-pages': specifier: ^1.11.0 - version: 1.11.0(vercel@33.6.3)(wrangler@3.34.2) + version: 1.11.0(vercel@33.6.3)(wrangler@3.72.2) '@keystar/ui': specifier: workspace:^ version: link:../../design-system/pkg @@ -952,7 +952,7 @@ importers: dependencies: '@cloudflare/next-on-pages': specifier: ^1.11.0 - version: 1.11.0(vercel@33.6.3)(wrangler@3.34.2) + version: 1.11.0(vercel@33.6.3)(wrangler@3.72.2) '@fontsource/inter': specifier: ^5.0.5 version: 5.0.8 @@ -1127,44 +1127,44 @@ importers: specifier: ^0.4.0 version: 0.4.0(@types/react@18.2.21)(react@18.2.0) '@react-aria/focus': - specifier: ^3.14.3 - version: 3.14.3(react@18.2.0) + specifier: ^3.18.1 + version: 3.18.2(react@18.2.0) '@react-aria/i18n': - specifier: ^3.8.0 - version: 3.8.1(react@18.2.0) + specifier: ^3.12.1 + version: 3.12.2(react@18.2.0) '@react-aria/interactions': - specifier: ^3.21.1 - version: 3.21.1(react@18.2.0) + specifier: ^3.22.1 + version: 3.22.2(react@18.2.0) '@react-aria/label': - specifier: ^3.7.2 - version: 3.7.2(react@18.2.0) + specifier: ^3.7.11 + version: 3.7.11(react@18.2.0) '@react-aria/overlays': - specifier: ^3.18.1 - version: 3.18.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.23.2 + version: 3.23.2(react-dom@18.2.0)(react@18.2.0) '@react-aria/selection': - specifier: ^3.17.1 - version: 3.17.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^3.19.3 + version: 3.19.3(react-dom@18.2.0)(react@18.2.0) '@react-aria/utils': - specifier: ^3.23.2 - version: 3.23.2(react@18.2.0) + specifier: ^3.25.1 + version: 3.25.2(react@18.2.0) '@react-aria/visually-hidden': - specifier: ^3.8.6 - version: 3.8.6(react@18.2.0) + specifier: ^3.8.15 + version: 3.8.15(react@18.2.0) '@react-stately/collections': - specifier: ^3.10.2 - version: 3.10.2(react@18.2.0) + specifier: ^3.10.9 + version: 3.10.9(react@18.2.0) '@react-stately/list': - specifier: ^3.10.0 - version: 3.10.0(react@18.2.0) + specifier: ^3.10.8 + version: 3.10.8(react@18.2.0) '@react-stately/overlays': - specifier: ^3.6.3 - version: 3.6.3(react@18.2.0) + specifier: ^3.6.10 + version: 3.6.10(react@18.2.0) '@react-stately/utils': - specifier: ^3.8.0 - version: 3.8.0(react@18.2.0) + specifier: ^3.10.3 + version: 3.10.3(react@18.2.0) '@react-types/shared': - specifier: ^3.21.0 - version: 3.21.0(react@18.2.0) + specifier: ^3.24.1 + version: 3.24.1(react@18.2.0) '@sindresorhus/slugify': specifier: ^1.1.2 version: 1.1.2 @@ -1461,7 +1461,7 @@ importers: version: 0.8.0(@types/react@18.2.21)(astro@4.0.3)(react@18.2.0) '@astrojs/react': specifier: ^3.0.7 - version: 3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.2.12) + version: 3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.4.2) '@keystatic/astro': specifier: workspace:^ version: link:../../packages/astro @@ -1599,6 +1599,14 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.19 + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + /@astrojs/compiler@2.3.2: resolution: {integrity: sha512-jkY7bCVxl27KeZsSxIZ+pqACe+g8VQUdTiSJRj/sXYdIaZlW3ZMq4qF2M17P/oDt3LBq0zLNwQr4Cb7fSpRGxQ==} @@ -1668,7 +1676,7 @@ packages: dependencies: prismjs: 1.29.0 - /@astrojs/react@3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.2.12): + /@astrojs/react@3.0.7(@types/react-dom@18.3.0)(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0)(vite@5.4.2): resolution: {integrity: sha512-MpjuFw7YGta44OaQExKVCWyXjujUtUsp5Nst/wIjRHbkmBBlypdj+MF9/xqjsYM+vjcrByOGupmluRrFQO67YQ==} engines: {node: '>=18.14.1'} peerDependencies: @@ -1679,7 +1687,7 @@ packages: dependencies: '@types/react': 18.2.21 '@types/react-dom': 18.3.0 - '@vitejs/plugin-react': 4.2.1(vite@5.2.12) + '@vitejs/plugin-react': 4.2.1(vite@5.4.2) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ultrahtml: 1.4.0 @@ -1748,7 +1756,7 @@ packages: slash: 2.0.0 optionalDependencies: '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 - chokidar: 3.5.3 + chokidar: 3.6.0 dev: true /@babel/code-frame@7.22.13: @@ -1792,6 +1800,11 @@ packages: resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} engines: {node: '>=6.9.0'} + /@babel/compat-data@7.25.4: + resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/core@7.23.0: resolution: {integrity: sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==} engines: {node: '>=6.9.0'} @@ -1858,6 +1871,29 @@ packages: transitivePeerDependencies: - supports-color + /@babel/core@7.25.2: + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.5 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.4 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + convert-source-map: 2.0.0 + debug: 4.3.6 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/eslint-parser@7.23.3(@babel/core@7.24.5)(eslint@8.48.0): resolution: {integrity: sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} @@ -1927,6 +1963,16 @@ packages: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 + /@babel/generator@7.25.5: + resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.25.4 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + dev: true + /@babel/helper-annotate-as-pure@7.22.5: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} @@ -1965,6 +2011,17 @@ packages: lru-cache: 5.1.1 semver: 6.3.1 + /@babel/helper-compilation-targets@7.25.2: + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.25.4 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.23.3 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.0): resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==} engines: {node: '>=6.9.0'} @@ -2171,6 +2228,16 @@ packages: dependencies: '@babel/types': 7.24.7 + /@babel/helper-module-imports@7.24.7: + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.0): resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} engines: {node: '>=6.9.0'} @@ -2237,6 +2304,21 @@ packages: '@babel/helper-split-export-declaration': 7.24.5 '@babel/helper-validator-identifier': 7.24.5 + /@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2): + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-optimise-call-expression@7.22.5: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} @@ -2353,6 +2435,16 @@ packages: dependencies: '@babel/types': 7.24.5 + /@babel/helper-simple-access@7.24.7: + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} engines: {node: '>=6.9.0'} @@ -2402,6 +2494,11 @@ packages: resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} engines: {node: '>=6.9.0'} + /@babel/helper-string-parser@7.24.8: + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} @@ -2422,6 +2519,11 @@ packages: resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.24.8: + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-wrap-function@7.22.10: resolution: {integrity: sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==} engines: {node: '>=6.9.0'} @@ -2460,6 +2562,14 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helpers@7.25.0: + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.25.0 + '@babel/types': 7.25.4 + dev: true + /@babel/highlight@7.22.13: resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} engines: {node: '>=6.9.0'} @@ -2529,6 +2639,14 @@ packages: dependencies: '@babel/types': 7.24.7 + /@babel/parser@7.25.4: + resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.25.4 + dev: true + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.23.0): resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==} engines: {node: '>=6.9.0'} @@ -4696,6 +4814,15 @@ packages: '@babel/parser': 7.24.7 '@babel/types': 7.24.7 + /@babel/template@7.25.0: + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.25.4 + '@babel/types': 7.25.4 + dev: true + /@babel/traverse@7.23.0: resolution: {integrity: sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==} engines: {node: '>=6.9.0'} @@ -4781,6 +4908,21 @@ packages: transitivePeerDependencies: - supports-color + /@babel/traverse@7.25.4: + resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.5 + '@babel/parser': 7.25.4 + '@babel/template': 7.25.0 + '@babel/types': 7.25.4 + debug: 4.3.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/types@7.23.0: resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} engines: {node: '>=6.9.0'} @@ -4821,6 +4963,15 @@ packages: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + /@babel/types@7.25.4: + resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + dev: true + /@base2/pretty-print-object@1.0.1: resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} dev: true @@ -5071,13 +5222,14 @@ packages: bundledDependencies: - is-unicode-supported - /@cloudflare/kv-asset-handler@0.3.1: - resolution: {integrity: sha512-lKN2XCfKCmpKb86a1tl4GIwsJYDy9TGuwjhDELLmpKygQhw8X2xR4dusgpC5Tg7q1pB96Eb0rBo81kxSILQMwA==} + /@cloudflare/kv-asset-handler@0.3.4: + resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} + engines: {node: '>=16.13'} dependencies: mime: 3.0.0 dev: false - /@cloudflare/next-on-pages@1.11.0(vercel@33.6.3)(wrangler@3.34.2): + /@cloudflare/next-on-pages@1.11.0(vercel@33.6.3)(wrangler@3.72.2): resolution: {integrity: sha512-/wKpDMrp2THkco+O5IKb7/JA07pppop4cRF3LEgL1FhJYxlOn3jo9WsZSuW58PovQJR2tZisLB/EJjJpmt1KOA==} hasBin: true peerDependencies: @@ -5101,7 +5253,7 @@ packages: pcre-to-regexp: 1.1.0 semver: 7.5.4 vercel: 33.6.3(@swc/core@1.3.82) - wrangler: 3.34.2 + wrangler: 3.72.2 transitivePeerDependencies: - bufferutil - supports-color @@ -5117,6 +5269,15 @@ packages: dev: false optional: true + /@cloudflare/workerd-darwin-64@1.20240821.1: + resolution: {integrity: sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@cloudflare/workerd-darwin-arm64@1.20240304.0: resolution: {integrity: sha512-IXGOxHsPdRYfAzcY6IroI1PDvx3hhXf18qFCloHp8Iw5bzLgq/PTjcp10Z/2xedZ2hVlfpHy1eEptsTmi9YeNw==} engines: {node: '>=16'} @@ -5126,6 +5287,15 @@ packages: dev: false optional: true + /@cloudflare/workerd-darwin-arm64@1.20240821.1: + resolution: {integrity: sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@cloudflare/workerd-linux-64@1.20240304.0: resolution: {integrity: sha512-G1BEzbw9TFIeMvc425F145IetC7fuH4KOkGhseLq9y/mt5PfDWkghwmXSK+q0BiMwm0XAobtzVlHcEr2u4WlRQ==} engines: {node: '>=16'} @@ -5135,6 +5305,15 @@ packages: dev: false optional: true + /@cloudflare/workerd-linux-64@1.20240821.1: + resolution: {integrity: sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@cloudflare/workerd-linux-arm64@1.20240304.0: resolution: {integrity: sha512-LLk/d/y77TRu6QOG3CJUI2cD3Ff2lSg0ts6G83bsm9ZK+WKObWFFSPBy9l81m3EnlKFh7RZCzxN4J10kuDaO8w==} engines: {node: '>=16'} @@ -5144,6 +5323,15 @@ packages: dev: false optional: true + /@cloudflare/workerd-linux-arm64@1.20240821.1: + resolution: {integrity: sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@cloudflare/workerd-windows-64@1.20240304.0: resolution: {integrity: sha512-I/j6nVpM+WDPg+bYUAiKLkwQsjrXFjpOGHvwYmcM44hnDjgODzk7AbVssEIXnhEO3oupBeuKvffr0lvX0Ngmpw==} engines: {node: '>=16'} @@ -5153,6 +5341,20 @@ packages: dev: false optional: true + /@cloudflare/workerd-windows-64@1.20240821.1: + resolution: {integrity: sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@cloudflare/workers-shared@0.3.0: + resolution: {integrity: sha512-cqtLW1QiBC/ABaZIhAdyGCsnHHY6pAb6hsVUZg82Co2gQtf/faxRYV1FgpCwUYroTdk6A66xUMSTmFqreKCJow==} + engines: {node: '>=16.7.0'} + dev: false + /@colors/colors@1.5.0: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -5302,6 +5504,15 @@ packages: requiresBuild: true optional: true + /@esbuild/aix-ppc64@0.21.5: + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: false + optional: true + /@esbuild/android-arm64@0.17.19: resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -5345,6 +5556,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm64@0.21.5: + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + /@esbuild/android-arm@0.15.18: resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} engines: {node: '>=12'} @@ -5397,6 +5617,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm@0.21.5: + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + /@esbuild/android-x64@0.17.19: resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} engines: {node: '>=12'} @@ -5440,6 +5669,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-x64@0.21.5: + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + /@esbuild/darwin-arm64@0.17.19: resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} engines: {node: '>=12'} @@ -5483,6 +5721,15 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-arm64@0.21.5: + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@esbuild/darwin-x64@0.17.19: resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} engines: {node: '>=12'} @@ -5526,6 +5773,15 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-x64@0.21.5: + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@esbuild/freebsd-arm64@0.17.19: resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} engines: {node: '>=12'} @@ -5569,6 +5825,15 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-arm64@0.21.5: + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + /@esbuild/freebsd-x64@0.17.19: resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} engines: {node: '>=12'} @@ -5612,6 +5877,15 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-x64@0.21.5: + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-arm64@0.17.19: resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} engines: {node: '>=12'} @@ -5655,6 +5929,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm64@0.21.5: + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-arm@0.17.19: resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} engines: {node: '>=12'} @@ -5698,6 +5981,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm@0.21.5: + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-ia32@0.17.19: resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} engines: {node: '>=12'} @@ -5741,6 +6033,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ia32@0.21.5: + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-loong64@0.14.54: resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} engines: {node: '>=12'} @@ -5801,6 +6102,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-loong64@0.21.5: + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-mips64el@0.17.19: resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} engines: {node: '>=12'} @@ -5844,6 +6154,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-mips64el@0.21.5: + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-ppc64@0.17.19: resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} engines: {node: '>=12'} @@ -5887,6 +6206,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ppc64@0.21.5: + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-riscv64@0.17.19: resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} engines: {node: '>=12'} @@ -5930,6 +6258,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-riscv64@0.21.5: + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-s390x@0.17.19: resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} engines: {node: '>=12'} @@ -5973,6 +6310,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-s390x@0.21.5: + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-x64@0.17.19: resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} engines: {node: '>=12'} @@ -6016,6 +6362,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-x64@0.21.5: + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/netbsd-x64@0.17.19: resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} engines: {node: '>=12'} @@ -6059,6 +6414,15 @@ packages: requiresBuild: true optional: true + /@esbuild/netbsd-x64@0.21.5: + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + /@esbuild/openbsd-x64@0.17.19: resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} engines: {node: '>=12'} @@ -6102,6 +6466,15 @@ packages: requiresBuild: true optional: true + /@esbuild/openbsd-x64@0.21.5: + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + /@esbuild/sunos-x64@0.17.19: resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} engines: {node: '>=12'} @@ -6145,6 +6518,15 @@ packages: requiresBuild: true optional: true + /@esbuild/sunos-x64@0.21.5: + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + /@esbuild/win32-arm64@0.17.19: resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} engines: {node: '>=12'} @@ -6188,6 +6570,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-arm64@0.21.5: + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@esbuild/win32-ia32@0.17.19: resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} engines: {node: '>=12'} @@ -6231,6 +6622,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-ia32@0.21.5: + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@esbuild/win32-x64@0.17.19: resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} engines: {node: '>=12'} @@ -6274,6 +6674,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-x64@0.21.5: + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6361,13 +6770,13 @@ packages: resolution: {integrity: sha512-6ueQTeJZtwKjmh23bdkq/DMqH4l4bmfvtQH98blOSbiXv/OUiyijSW6jU22IT8BNM1ujCaEvJfTtyCYVH38EMQ==} dependencies: '@formatjs/intl-localematcher': 0.4.0 - tslib: 2.6.2 + tslib: 2.7.0 dev: false /@formatjs/fast-memoize@2.2.0: resolution: {integrity: sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 dev: false /@formatjs/icu-messageformat-parser@2.6.0: @@ -6375,20 +6784,20 @@ packages: dependencies: '@formatjs/ecma402-abstract': 1.17.0 '@formatjs/icu-skeleton-parser': 1.6.0 - tslib: 2.6.2 + tslib: 2.7.0 dev: false /@formatjs/icu-skeleton-parser@1.6.0: resolution: {integrity: sha512-eMmxNpoX/J1IPUjPGSZwo0Wh+7CEvdEMddP2Jxg1gQJXfGfht/FdW2D5XDFj3VMbOTUQlDIdZJY7uC6O6gjPoA==} dependencies: '@formatjs/ecma402-abstract': 1.17.0 - tslib: 2.6.2 + tslib: 2.7.0 dev: false /@formatjs/intl-localematcher@0.4.0: resolution: {integrity: sha512-bRTd+rKomvfdS4QDlVJ6TA/Jx1F2h/TBVO5LjvhQ7QPPHp19oPNMIum7W2CMEReq/zPxpmCeB31F9+5gl/qtvw==} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 dev: false /@graphql-typed-document-node/core@3.2.0(graphql@16.8.0): @@ -6436,48 +6845,23 @@ packages: /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - /@internationalized/date@3.5.0: - resolution: {integrity: sha512-nw0Q+oRkizBWMioseI8+2TeUPEyopJVz5YxoYVzR0W1v+2YytiYah7s/ot35F149q/xAg4F1gT/6eTd+tsUpFQ==} - dependencies: - '@swc/helpers': 0.5.2 - dev: false - - /@internationalized/date@3.5.2: - resolution: {integrity: sha512-vo1yOMUt2hzp63IutEaTUxROdvQg1qlMRsbCvbay2AK2Gai7wIgCyK5weEX3nHkiLgo4qCXHijFNC/ILhlRpOQ==} - dependencies: - '@swc/helpers': 0.5.2 - dev: false - - /@internationalized/message@3.1.1: - resolution: {integrity: sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw==} + /@internationalized/date@3.5.5: + resolution: {integrity: sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==} dependencies: - '@swc/helpers': 0.5.2 - intl-messageformat: 10.5.0 + '@swc/helpers': 0.5.12 dev: false - /@internationalized/message@3.1.2: - resolution: {integrity: sha512-MHAWsZWz8jf6jFPZqpTudcCM361YMtPIRu9CXkYmKjJ/0R3pQRScV5C0zS+Qi50O5UAm8ecKhkXx6mWDDcF6/g==} + /@internationalized/message@3.1.4: + resolution: {integrity: sha512-Dygi9hH1s7V9nha07pggCkvmRfDd3q2lWnMGvrJyrOwYMe1yj4D2T9BoH9I6MGR7xz0biQrtLPsqUkqXzIrBOw==} dependencies: - '@swc/helpers': 0.5.2 + '@swc/helpers': 0.5.12 intl-messageformat: 10.5.0 dev: false - /@internationalized/number@3.2.1: - resolution: {integrity: sha512-hK30sfBlmB1aIe3/OwAPg9Ey0DjjXvHEiGVhNaOiBJl31G0B6wMaX8BN3ibzdlpyRNE9p7X+3EBONmxtJO9Yfg==} + /@internationalized/number@3.5.3: + resolution: {integrity: sha512-rd1wA3ebzlp0Mehj5YTuTI50AQEx80gWFyHcQu+u91/5NgdwBecO8BH6ipPfE+lmQ9d63vpB3H9SHoIUiupllw==} dependencies: - '@swc/helpers': 0.5.2 - dev: false - - /@internationalized/number@3.3.0: - resolution: {integrity: sha512-PuxgnKE5NJMOGKUcX1QROo8jq7sW7UWLrL5B6Rfe8BdWgU/be04cVvLyCeALD46vvbAv3d1mUvyHav/Q9a237g==} - dependencies: - '@swc/helpers': 0.5.2 - dev: false - - /@internationalized/number@3.5.1: - resolution: {integrity: sha512-N0fPU/nz15SwR9IbfJ5xaS9Ss/O5h1sVXMZf43vc9mxEG48ovglvvzBjF53aHlq20uoR6c+88CrIXipU/LSzwg==} - dependencies: - '@swc/helpers': 0.5.2 + '@swc/helpers': 0.5.12 dev: false /@internationalized/string@3.1.1: @@ -6486,10 +6870,10 @@ packages: '@swc/helpers': 0.5.1 dev: false - /@internationalized/string@3.2.1: - resolution: {integrity: sha512-vWQOvRIauvFMzOO+h7QrdsJmtN1AXAFVcaLWP9AseRN2o7iHceZ6bIXhBD4teZl8i91A3gxKnWBlGgjCwU6MFQ==} + /@internationalized/string@3.2.3: + resolution: {integrity: sha512-9kpfLoA8HegiWTeCbR2livhdVeKobCnVv8tlJ6M2jF+4tcMqDo94ezwlnrUANBWPgd8U7OXIHCk2Ov2qhk4KXw==} dependencies: - '@swc/helpers': 0.5.2 + '@swc/helpers': 0.5.12 dev: false /@isaacs/cliui@8.0.2: @@ -7927,1358 +8311,1266 @@ packages: '@babel/runtime': 7.22.15 dev: true - /@react-aria/actiongroup@3.6.4(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-k1LP4rb2uv3Izsj2PIpCtwHajb7juTGZmDsd6muADc7XtHctL7oEa7Wj+bkslPROBTwaXvgdud8ivA0/vmu6kA==} + /@react-aria/actiongroup@3.7.8(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-0Hz6Ec6HugO3WOTzs1wODPb1Bf//a9ad6w6uriTE8QRKveFueypsjDbex5dBOhCtdzgrpflhpy812s9FoCUZ/Q==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/list': 3.10.0(react@18.2.0) - '@react-types/actiongroup': 3.4.5(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-types/actiongroup': 3.4.11(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/breadcrumbs@3.5.11(react@18.2.0): - resolution: {integrity: sha512-bQz4g2tKvcWxeqPGj9O0RQf++Ka8f2o/pJMJB+QQ27DVQWhxpQpND//oFku2aFYkxHB/fyD9qVoiqpQR25bidw==} + /@react-aria/breadcrumbs@3.5.16(react@18.2.0): + resolution: {integrity: sha512-OXLKKu4SmjnSaSHkk4kow5/aH/SzlHWPJt+Uq3xec9TwDOr/Ob8aeFVGFoY0HxfGozuQlUz+4e+d29vfA0jNWg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/link': 3.6.5(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/breadcrumbs': 3.7.3(react@18.2.0) - '@react-types/shared': 3.22.1(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/link': 3.7.4(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/breadcrumbs': 3.7.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/button@3.8.4(react@18.2.0): - resolution: {integrity: sha512-rTGZk5zu+lQNjfij2fwnw2PAgBgzNLi3zbMw1FL5/XwVx+lEH2toeqKLoqULtd7nSxskYuQz56VhmjUok6Qkmg==} + /@react-aria/button@3.9.8(react@18.2.0): + resolution: {integrity: sha512-MdbMQ3t5KSCkvKtwYd/Z6sgw0v+r1VQFRYOZ4L53xOkn+u140z8vBpNeWKZh/45gxGv7SJn9s2KstLPdCWmIxw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/toggle': 3.6.3(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/calendar@3.5.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-HiyUiY0C2aoHa2252Es/Rj1fh5/tewLf6/3gUr42zKl7lq4IqG9cyW7LVRwA47ow1VGLPZSSqTcVakB7jgr7Zw==} + /@react-aria/calendar@3.5.11(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-VLhBovLVu3uJXBkHbgEippmo/K58QLcc/tSJQ0aJUNyHsrvPgHEcj484cb+Uj/yOirXEIzaoW6WEvhcdKrb49Q==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/date': 3.5.0 - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/live-announcer': 3.3.2 - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/calendar': 3.4.1(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/calendar': 3.4.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@internationalized/date': 3.5.5 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/calendar': 3.5.4(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/checkbox@3.11.2(react@18.2.0): - resolution: {integrity: sha512-8cgXxpc7IMJ9buw+Rbhr1xc66zNp2ePuFpjw3uWyH7S3IJEd2f5kXUDNWLXQRADJso95UlajRlJQiG4QIObEnA==} + /@react-aria/checkbox@3.14.6(react@18.2.0): + resolution: {integrity: sha512-LICY1PR3WsW/VbuLMjZbxo75+poeo3XCXGcUnk6hxMlWfp/Iy/XHVsHlGu9stRPKRF8BSuOGteaHWVn6IXfwtA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/label': 3.7.2(react@18.2.0) - '@react-aria/toggle': 3.8.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/checkbox': 3.5.1(react@18.2.0) - '@react-stately/toggle': 3.6.3(react@18.2.0) - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/toggle': 3.10.7(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/checkbox': 3.6.8(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/combobox@3.7.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-37no1b3sRI9mDh3MpMPWNt0Q8QdoRipnx12Vx5Uvtb0PA23hwOWDquICzs157SoJpXP49/+eH6LiA0uTsqwVuQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/listbox': 3.11.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/live-announcer': 3.3.2 - '@react-aria/menu': 3.11.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/overlays': 3.18.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/textfield': 3.12.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/combobox': 3.7.1(react@18.2.0) - '@react-stately/layout': 3.13.3(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/combobox': 3.8.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + /@react-aria/combobox@3.10.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-EdDwr2Rp1xy7yWjOYHt2qF1IpAtUrkaNKZJzlIw1XSwcqizQY6E8orNPdZr6ZwD6/tgujxF1N71JTKyffrR0Xw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/listbox': 3.13.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/menu': 3.15.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/textfield': 3.14.8(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/combobox': 3.9.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/combobox': 3.12.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/datepicker@3.8.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-q2Z5DYDkic3RWzvg3oysrA2VEebuxtEfqj8PSlNFndZh/pNrA+Tvkaatdk/BoxlsZsfeLof+/tBq6yWeqTDguQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@internationalized/date': 3.5.0 - '@internationalized/number': 3.3.0 - '@internationalized/string': 3.1.1 - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/label': 3.7.2(react@18.2.0) - '@react-aria/spinbutton': 3.5.4(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/datepicker': 3.8.0(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/calendar': 3.4.1(react@18.2.0) - '@react-types/datepicker': 3.6.1(react@18.2.0) - '@react-types/dialog': 3.5.6(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + /@react-aria/datepicker@3.11.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-6sbLln3VXSBcBRDgSACBzIzF/5KV5NlNOhZvXPFE6KqFw6GbevjZQTv5BNDXiwA3CQoawIRF7zgRvTANw8HkNA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@internationalized/number': 3.5.3 + '@internationalized/string': 3.2.3 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/spinbutton': 3.6.8(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/datepicker': 3.10.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/datepicker': 3.8.2(react@18.2.0) + '@react-types/dialog': 3.5.12(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/dialog@3.5.7(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-IKeBaIQBl+WYkhytyE0eISW4ApOEvCJZuw9Xq7gjlKFBlF4X6ffo8souv12KpaznK6/fp1vtEXMmy1AfejiT8Q==} + /@react-aria/dialog@3.5.17(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-lvfEgaqg922J1hurscqCS600OZQVitGtdpo81kAefJaUzMnCxzrYviyT96aaW0simHOlimbYF5js8lxBLZJRaw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/overlays': 3.18.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/overlays': 3.6.3(react@18.2.0) - '@react-types/dialog': 3.5.6(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/dialog': 3.5.12(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/dnd@3.4.3(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-9yiYTQvfT5EUmSsGY3vZlK1xs+xHOFDw5I+c+HyvwqiSu0AIZ4yXqpJVwbarKeZlTOQGCWtb/SOHEdMXfaXKgA==} + /@react-aria/dnd@3.7.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-NuE3EGqoBbe9aXAO9mDfbu4kMO7S4MCgkjkCqYi16TWfRUf38ajQbIlqodCx91b3LVN3SYvNbE3D4Tj5ebkljw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/string': 3.1.1 - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/live-announcer': 3.3.2 - '@react-aria/overlays': 3.18.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-aria/visually-hidden': 3.8.6(react@18.2.0) - '@react-stately/dnd': 3.2.5(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@internationalized/string': 3.2.3 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/dnd': 3.4.2(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/focus@3.14.3(react@18.2.0): - resolution: {integrity: sha512-gvO/frZ7SxyfyHJYC+kRsUXnXct8hGHKlG1TwbkzCCXim9XIPKDgRzfNGuFfj0i8ZpR9xmsjOBUkHZny0uekFA==} + /@react-aria/focus@3.18.2(react@18.2.0): + resolution: {integrity: sha512-Jc/IY+StjA3uqN73o6txKQ527RFU7gnG5crEl5Xy3V+gbYp2O5L3ezAo/E0Ipi2cyMbG6T5Iit1IDs7hcGu8aw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) '@swc/helpers': 0.5.2 - clsx: 1.2.1 + clsx: 2.0.0 react: 18.2.0 + dev: false - /@react-aria/focus@3.16.2(react@18.2.0): - resolution: {integrity: sha512-Rqo9ummmgotESfypzFjI3uh58yMpL+E+lJBbQuXkBM0u0cU2YYzu0uOrFrq3zcHk997udZvq1pGK/R+2xk9B7g==} + /@react-aria/form@3.0.8(react@18.2.0): + resolution: {integrity: sha512-8S2QiyUdAgK43M3flohI0R+2rTyzH088EmgeRArA8euvJTL16cj/oSOKMEgWVihjotJ9n6awPb43ZhKboyNsMg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.22.1(react@18.2.0) - '@swc/helpers': 0.5.2 - clsx: 2.0.0 + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/grid@3.8.4(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-UxEz98Z6yxVAOq7QSZ9OmSsvMwxJDVl7dVRwUHeqWxNprk9o5GGCLjhMv948XBUEnOvLV2qgtI7UoGzSdliUJA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/live-announcer': 3.3.2 - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/grid': 3.8.2(react@18.2.0) - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-stately/virtualizer': 3.6.5(react@18.2.0) - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/grid': 3.2.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + /@react-aria/grid@3.10.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-l0r9mz05Gwjq3t6JOTNQOf+oAoWN0bXELPJtIr8m0XyXMPFCQe1xsTaX8igVQdrDmXyBc75RAWS0BJo2JF2fIA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/grid': 3.9.2(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/gridlist@3.7.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-XnU8mTc/KrwHsGayQm0u5aoaDzdZ8DftKSSfyBEqLiCaibKFqMADb987SOY5+IVGEtYkxDRn1Reo52U0Fs4mxg==} + /@react-aria/gridlist@3.9.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bb9GnKKeuL6NljoVUcHxr9F0cy/2WDOXRYeMikTnviRw6cuX95oojrhFfCUvz2d6ID22Btrvh7LkE+oIPVuc+g==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/grid': 3.8.4(react-dom@18.2.0)(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/list': 3.10.0(react@18.2.0) - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/grid': 3.10.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-stately/tree': 3.8.4(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/i18n@3.10.2(react@18.2.0): - resolution: {integrity: sha512-Z1ormoIvMOI4mEdcFLYsoJy9w/EzBdBmgfLP+S/Ah+1xwQOXpgwZxiKOhYHpWa0lf6hkKJL34N9MHJvCJ5Crvw==} + /@react-aria/i18n@3.12.2(react@18.2.0): + resolution: {integrity: sha512-PvEyC6JWylTpe8dQEWqQwV6GiA+pbTxHQd//BxtMSapRW3JT9obObAnb/nFhj3HthkUvqHyj0oO1bfeN+mtD8A==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/date': 3.5.2 - '@internationalized/message': 3.1.2 - '@internationalized/number': 3.5.1 - '@internationalized/string': 3.2.1 - '@react-aria/ssr': 3.9.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.22.1(react@18.2.0) + '@internationalized/date': 3.5.5 + '@internationalized/message': 3.1.4 + '@internationalized/number': 3.5.3 + '@internationalized/string': 3.2.3 + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) '@swc/helpers': 0.5.2 react: 18.2.0 dev: false - /@react-aria/i18n@3.8.1(react@18.2.0): - resolution: {integrity: sha512-ftH3saJlhWaHoHEDb/YjYqP8I4/9t4Ksf0D0kvPDRfRcL98DKUSHZD77+EmbjsmzJInzm76qDeEV0FYl4oj7gg==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@internationalized/date': 3.5.0 - '@internationalized/message': 3.1.1 - '@internationalized/number': 3.2.1 - '@internationalized/string': 3.1.1 - '@react-aria/ssr': 3.7.1(react@18.2.0) - '@react-aria/utils': 3.19.0(react@18.2.0) - '@react-types/shared': 3.19.0(react@18.2.0) - '@swc/helpers': 0.5.1 - react: 18.2.0 - dev: false - - /@react-aria/interactions@3.21.1(react@18.2.0): - resolution: {integrity: sha512-AlHf5SOzsShkHfV8GLLk3v9lEmYqYHURKcXWue0JdYbmquMRkUsf/+Tjl1+zHVAQ8lKqRnPYbTmc4AcZbqxltw==} + /@react-aria/interactions@3.22.2(react@18.2.0): + resolution: {integrity: sha512-xE/77fRVSlqHp2sfkrMeNLrqf2amF/RyuAS6T5oDJemRSgYM3UoxTbWjucPhfnoW7r32pFPHHgz4lbdX8xqD/g==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/ssr': 3.9.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.22.1(react@18.2.0) + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) '@swc/helpers': 0.5.2 react: 18.2.0 + dev: false - /@react-aria/label@3.7.2(react@18.2.0): - resolution: {integrity: sha512-rS0xQy+4RH1+JLESzLZd9H285McjNNf2kKwBhzU0CW3akjlu7gqaMKEJhX9MlpPDIVOUc2oEObGdU3UMmqa8ew==} + /@react-aria/label@3.7.11(react@18.2.0): + resolution: {integrity: sha512-REgejE5Qr8cXG/b8H2GhzQmjQlII/0xQW/4eDzydskaTLvA7lF5HoJUE6biYTquH5va38d8XlH465RPk+bvHzA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/label': 3.8.1(react@18.2.0) - '@react-types/shared': 3.22.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/landmark@3.0.0-beta.2(react@18.2.0): - resolution: {integrity: sha512-PzRx/KwzxUUVk9bGbTNWHCtkzzGfnUL8yozd/sJjnCofa7BPrt71EnvB4W53W0MDD3hod8JDwk3TlzNyXPi/ww==} + /@react-aria/landmark@3.0.0-beta.15(react@18.2.0): + resolution: {integrity: sha512-EEABy0IFzqoS7r11HoD2YwiGR5LFw4kWDFTFUFwJkRP5tHEzsrEgkKPSPJXScQr5m7tenV6j0/Zzl1+w1ki3lA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.2.0) - /@react-aria/link@3.6.5(react@18.2.0): - resolution: {integrity: sha512-kg8CxKqkciQFzODvLAfxEs8gbqNXFZCW/ISOE2LHYKbh9pA144LVo71qO3SPeYVVzIjmZeW4vEMdZwqkNozecw==} + /@react-aria/link@3.7.4(react@18.2.0): + resolution: {integrity: sha512-E8SLDuS9ssm/d42+3sDFNthfMcNXMUrT2Tq1DIZt22EsMcuEzmJ9B0P7bDP5RgvIw05xVGqZ20nOpU4mKTxQtA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.16.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/link': 3.5.3(react@18.2.0) - '@react-types/shared': 3.22.1(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/link': 3.5.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/listbox@3.11.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-AkguQaIkqpP5oe++EZqYHowD7FfeQs+yY0QZVSsVPpNExcBug8/GcXvhSclcOxdh6ekZg4Wwcq7K0zhuTSOPzg==} + /@react-aria/listbox@3.13.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-htluPyDfFtn66OEYaJdIaFCYH9wGCNk30vOgZrQkPul9F9Cjce52tTyPVR0ERsf14oCUsjjS5qgeq3dGidRqEw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/label': 3.7.2(react@18.2.0) - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/list': 3.10.0(react@18.2.0) - '@react-types/listbox': 3.4.5(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-types/listbox': 3.5.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/live-announcer@3.3.2: - resolution: {integrity: sha512-aOyPcsfyY9tLCBhuUaYCruwcd1IrYLc47Ou+J7wMzjeN9v4lsaEfiN12WFl8pDqOwfy6/7It2wmlm5hOuZY8wQ==} + /@react-aria/live-announcer@3.3.4: + resolution: {integrity: sha512-w8lxs35QrRrn6pBNzVfyGOeqWdxeVKf9U6bXIVwhq7rrTqRULL8jqy8RJIMfIs1s8G5FpwWYjyBOjl2g5Cu1iA==} dependencies: - '@swc/helpers': 0.5.2 + '@swc/helpers': 0.5.12 dev: false - /@react-aria/menu@3.11.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-1eVVDrGnSExaL7e8IiaM9ndWTjT23rsnQGUK3p66R1Ojs8Q5rPBuJpP74rsmIpYiKOCr8WyZunjm5Fjv5KfA5Q==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/overlays': 3.18.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/menu': 3.5.6(react@18.2.0) - '@react-stately/tree': 3.7.3(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/menu': 3.9.5(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + /@react-aria/menu@3.15.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-vvUmVjJwIg3h2r+7isQXTwlmoDlPAFBckHkg94p3afrT1kNOTHveTsaVl17mStx/ymIioaAi3PrIXk/PZXp1jw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/menu': 3.8.2(react@18.2.0) + '@react-stately/tree': 3.8.4(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/menu': 3.9.11(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/meter@3.4.7(react@18.2.0): - resolution: {integrity: sha512-Cp4d6Pd5K6iphXMS/VZ81YxlboUi0I4WPQ+EYb4fxFBJMXVwMK6N5dnn8kwG0vpIx9m0pkFVxSZhlbrwnvW9KA==} + /@react-aria/meter@3.4.16(react@18.2.0): + resolution: {integrity: sha512-hJqKnEE6mmK2Psx5kcI7NZ44OfTg0Bp7DatQSQ4zZE4yhnykRRwxqSKjze37tPR63cCqgRXtQ5LISfBfG54c0Q==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/progress': 3.4.7(react@18.2.0) - '@react-types/meter': 3.3.5(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/progress': 3.4.16(react@18.2.0) + '@react-types/meter': 3.4.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/numberfield@3.9.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-s9LM5YUzZpbOn5KldUS2JmkDNOA9obVmm8TofICH+z6RnReznp72NLPn0IwblRnocmMOIvGINT55Tz50BmbfNA==} + /@react-aria/numberfield@3.11.6(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-nvEWiQcWRwj6O2JXmkXEeWoBX/GVZT9zumFJcew3XknGTWJUr3h2AOymIQFt9g4mpag8IgOFEpSIlwhtZHdp1A==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/live-announcer': 3.3.2 - '@react-aria/spinbutton': 3.5.4(react-dom@18.2.0)(react@18.2.0) - '@react-aria/textfield': 3.12.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/numberfield': 3.6.2(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/numberfield': 3.6.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/textfield': 3.8.1(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/spinbutton': 3.6.8(react-dom@18.2.0)(react@18.2.0) + '@react-aria/textfield': 3.14.8(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/numberfield': 3.9.6(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/numberfield': 3.8.5(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/overlays@3.18.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-C74eZbTp3OA/gXy9/+4iPrZiz7g27Zy6Q1+plbg5QTLpsFLBt2Ypy9jTTANNRZfW7a5NW/Bnw9WIRjCdtTBRXw==} + /@react-aria/overlays@3.23.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-vjlplr953YAuJfHiP4O+CyrTlr6OaFgXAGrzWq4MVMjnpV/PT5VRJWYFHR0sUGlHTPqeKS4NZbi/xCSgl/3pGQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/ssr': 3.8.0(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-aria/visually-hidden': 3.8.6(react@18.2.0) - '@react-stately/overlays': 3.6.3(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/overlays': 3.8.3(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-aria/visually-hidden': 3.8.15(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/progress@3.4.7(react@18.2.0): - resolution: {integrity: sha512-wQ+xnzt5bBdbyQ2Qx80HxaFrPZRFKge57tmJWg4qelo7tzmgb3a22tf0Ug4C3gEz/uAv0JQWOtqLKTxjsiVP7g==} + /@react-aria/progress@3.4.16(react@18.2.0): + resolution: {integrity: sha512-RbDIFQg4+/LG+KYZeLAijt2zH7K2Gp0CY9RKWdho3nU5l3/w57Fa7NrfDGWtpImrt7bR2nRmXMA6ESfr7THfrg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/label': 3.7.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/progress': 3.5.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/progress': 3.5.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/radio@3.8.2(react@18.2.0): - resolution: {integrity: sha512-j8yyGjboTgoBEQWlnJbQVvegKiUeQEUvU/kZ7ZAdj+eAL3BqfO6FO7yt6WzK7ZIBzjGS9YbesaUa3hwIjDi3LA==} + /@react-aria/radio@3.10.7(react@18.2.0): + resolution: {integrity: sha512-o2tqIe7xd1y4HeCBQfz/sXIwLJuI6LQbVoCQ1hgk/5dGhQ0LiuXohRYitGRl9zvxW8jYdgLULmOEDt24IflE8A==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/label': 3.7.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/radio': 3.9.1(react@18.2.0) - '@react-types/radio': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/radio': 3.10.7(react@18.2.0) + '@react-types/radio': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/searchfield@3.5.7(react@18.2.0): - resolution: {integrity: sha512-HYjB/QH3AR2E39N6eu+P/DmJMjGweg6LrO1QUbBbKJS+LDorHTN9YNKA4N89gnDDz2IPyycjxtr71hEv0I092A==} + /@react-aria/searchfield@3.7.8(react@18.2.0): + resolution: {integrity: sha512-SsF5xwH8Us548QgzivvbM7nhFbw7pu23xnRRIuhlP3MwOR3jRUFh17NKxf3Z0jvrDv/u0xfm3JKHIgaUN0KJ2A==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/textfield': 3.12.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/searchfield': 3.4.6(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/searchfield': 3.5.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/textfield': 3.14.8(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/searchfield': 3.5.6(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/searchfield': 3.5.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/select@3.13.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-tWWOnMnrV1nlZzdO04Ntvf5GCJ6MPkg8Gwv6y0klDDjt12Qyc7J8INluW5A4eMUdtxCkWdaiEsXjyYBHT14ILQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/label': 3.7.2(react@18.2.0) - '@react-aria/listbox': 3.11.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/menu': 3.11.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-aria/visually-hidden': 3.8.6(react@18.2.0) - '@react-stately/select': 3.5.5(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/select': 3.8.4(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + /@react-aria/select@3.14.9(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-tiNgMyA2G9nKnFn3pB/lMSgidNToxSFU7r6l4OcG+Vyr63J7B/3dF2lTXq8IYhlfOR3K3uQkjroSx52CmC3NDw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/listbox': 3.13.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/menu': 3.15.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-aria/visually-hidden': 3.8.15(react@18.2.0) + '@react-stately/select': 3.6.7(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/select': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/selection@3.17.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-g5gkSc/M+zJiVgWbUpKN095ea0D4fxdluH9ZcXxN4AAvcrVfEJyAnMmWOIKRebN8xR0KPfNRnKB7E6jld2tbuQ==} + /@react-aria/selection@3.19.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GYoObXCXlmGK08hp7Qfl6Bk0U+bKP5YDWSsX+MzNjJsqzQSLm4S06tRB9ACM7gIo9dDCvL4IRxdSYTJAlJc6bw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/separator@3.3.7(react@18.2.0): - resolution: {integrity: sha512-5XjDhvGVmGHxxOrXLFCQhOs75v579nPTaSlrKhG/5BjTN3JrByAtuNAw8XZf3HbtiCRZnnL2bKdVbHBjmbuvDw==} + /@react-aria/separator@3.4.2(react@18.2.0): + resolution: {integrity: sha512-Xql9Kg3VlGesEUC7QheE+L5b3KgBv0yxiUU+/4JP8V2vfU/XSz4xmprHEeq7KVQVOetn38iiXU8gA5g26SEsUA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/spinbutton@3.5.4(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-W5dhUOjyBIgd8d4z526fW/HXQ+BdFceeGyvNAXoYBi/1gt3KqN/6CZgskG7OQEufxCOWc9e4A2eWNwvkQVJvWg==} + /@react-aria/spinbutton@3.6.8(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OJMAYRIZ0WrWE+5tZsywrSg4t+aOwl6vl/e1+J64YcGMM+p+AKd61KGG5T0OgNSORXjoVIZOmj6wZ6Od4xfPMw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/live-announcer': 3.3.2 - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/ssr@3.7.1(react@18.2.0): - resolution: {integrity: sha512-ovVPSD1WlRpZHt7GI9DqJrWG3OIYS+NXQ9y5HIewMJpSe+jPQmMQfyRmgX4EnvmxSlp0u04Wg/7oItcoSIb/RA==} - engines: {node: '>= 12'} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@swc/helpers': 0.5.2 - react: 18.2.0 - dev: false - - /@react-aria/ssr@3.8.0(react@18.2.0): - resolution: {integrity: sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A==} - engines: {node: '>= 12'} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@swc/helpers': 0.5.2 - react: 18.2.0 - dev: false - - /@react-aria/ssr@3.9.2(react@18.2.0): - resolution: {integrity: sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw==} + /@react-aria/ssr@3.9.5(react@18.2.0): + resolution: {integrity: sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==} engines: {node: '>= 12'} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@swc/helpers': 0.5.2 + '@swc/helpers': 0.5.12 react: 18.2.0 - /@react-aria/switch@3.5.6(react@18.2.0): - resolution: {integrity: sha512-W6H/0TFa72MJY02AatUERt5HKgaDTF8lOaTjNNmS6U6U20+//uvrVCqcBof8OMe4M60mQpkp7Bd6756CJAMX1w==} + /@react-aria/switch@3.6.7(react@18.2.0): + resolution: {integrity: sha512-yBNvKylhc3ZRQ0+7mD0mIenRRe+1yb8YaqMMZr8r3Bf87LaiFtQyhRFziq6ZitcwTJz5LEWjBihxbSVvUrf49w==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/toggle': 3.8.2(react@18.2.0) - '@react-stately/toggle': 3.6.3(react@18.2.0) - '@react-types/switch': 3.4.2(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/toggle': 3.10.7(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/switch': 3.5.5(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/table@3.13.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-TBtCmJsKl3rJW/dCzA0ZxPGb8mN7ndbryLh3u+iV/+GVAVsytvAenOGrq9sLHHWXwQo5RJoO1bkUudvrZrJ5/g==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/grid': 3.8.4(react-dom@18.2.0)(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/live-announcer': 3.3.2 - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-aria/visually-hidden': 3.8.6(react@18.2.0) - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/flags': 3.0.0 - '@react-stately/table': 3.11.2(react@18.2.0) - '@react-stately/virtualizer': 3.6.5(react@18.2.0) - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/grid': 3.2.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/table': 3.9.0(react@18.2.0) + /@react-aria/table@3.15.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-nQCLjlEvyJHyuijHw8ESqnA9fxNJfQHx0WPcl08VDEb8VxcE/MVzSAIedSWaqjG5k9Oflz6o/F/zHtzw4AFAow==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/grid': 3.10.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-aria/visually-hidden': 3.8.15(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/flags': 3.0.3 + '@react-stately/table': 3.12.2(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/table': 3.10.1(react@18.2.0) '@swc/helpers': 0.5.2 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/tabs@3.8.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-3kRd5rYKclmW9lllcANq0oun2d1pZq7Onma95laYfrWtPBZ3YDVKOkujGSqdfSQAFVshWBjl2Q03yyvcRiwzbQ==} + /@react-aria/tabs@3.9.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aQZGAoOIg1B16qlvXIy6+rHbNBNVcWkGjOjeyvqTTPMjXt/FmElkICnqckI7MRJ1lTqzyppCOBitYOHSXRo8Uw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/selection': 3.17.1(react-dom@18.2.0)(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/list': 3.10.0(react@18.2.0) - '@react-stately/tabs': 3.6.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/tabs': 3.3.3(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/tabs': 3.6.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tabs': 3.3.9(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/textfield@3.12.2(react@18.2.0): - resolution: {integrity: sha512-wRg8LJjZV6o4S/LRFqxs5waGDTiuIa/CRN+/X37Fu7GeZFeK0IBvWjKPlXLe7gMswaFqRmTKnQCU42mzUdDK1g==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/label': 3.7.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/textfield': 3.8.1(react@18.2.0) - '@swc/helpers': 0.5.1 - react: 18.2.0 - dev: false - - /@react-aria/toast@3.0.0-beta.2(react@18.2.0): - resolution: {integrity: sha512-PW+3ueOfMqzHlAb8ixocxBprRiLdz+xH7YEIn1E+iRregkdfcjfqchzU2PN3UQm7Othk1b3Bt9LemCOM66YRcA==} + /@react-aria/textfield@3.14.8(react@18.2.0): + resolution: {integrity: sha512-FHEvsHdE1cMR2B7rlf+HIneITrC40r201oLYbHAp3q26jH/HUujzFBB9I20qhXjyBohMWfQLqJhSwhs1VW1RJQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/landmark': 3.0.0-beta.2(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/toast': 3.0.0-beta.1(react@18.2.0) - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/textfield': 3.9.6(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/toggle@3.8.2(react@18.2.0): - resolution: {integrity: sha512-0+RmlOQtyRmU+Dd9qM9od4DPpITC7jqA+n3aZn732XtCsosz5gPGbhFuLbSdWRZ42FQgqo7pZQWaDRZpJPkipA==} + /@react-aria/toast@3.0.0-beta.15(react@18.2.0): + resolution: {integrity: sha512-bg6ZXq4B5JYVt3GXVlf075tQOakcfumbDLnUMaijez4BhacuxF01+IvBPzAVEsARVNXfELoXa7Frb2K54Wgvtw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/toggle': 3.6.3(react@18.2.0) - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/switch': 3.4.2(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/landmark': 3.0.0-beta.15(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/toast': 3.0.0-beta.5(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/tooltip@3.6.4(react@18.2.0): - resolution: {integrity: sha512-5WCOiRSugzbfEOH+Bjpuf6EsNyynqq5S1uDh/P6J8qiYDjc0xLRJ5dyLdytX7c8MK9Y0pIHi6xb0xR9jDqJXTw==} + /@react-aria/toggle@3.10.7(react@18.2.0): + resolution: {integrity: sha512-/RJQU8QlPZXRElZ3Tt10F5K5STgUBUGPpfuFUGuwF3Kw3GpPxYsA1YAVjxXz2MMGwS0+y6+U/J1xIs1AF0Jwzg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/focus': 3.14.3(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/tooltip': 3.4.5(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/tooltip': 3.4.5(react@18.2.0) - '@swc/helpers': 0.5.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/utils@3.19.0(react@18.2.0): - resolution: {integrity: sha512-5GXqTCrUQtr78aiLVHZoeeGPuAxO4lCM+udWbKpSCh5xLfCZ7zFlZV9Q9FS0ea+IQypUcY8ngXCLsf22nSu/yg==} + /@react-aria/tooltip@3.7.7(react@18.2.0): + resolution: {integrity: sha512-UOTTDbbUz7OaE48VjNSWl+XQbYCUs5Gss4I3Tv1pfRLXzVtGYXv3ur/vRayvZR0xd12ANY26fZPNkSmCFpmiXw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/ssr': 3.7.1(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 - clsx: 1.2.1 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/tooltip': 3.4.12(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tooltip': 3.4.11(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-aria/utils@3.23.2(react@18.2.0): - resolution: {integrity: sha512-yznR9jJ0GG+YJvTMZxijQwVp+ahP66DY0apZf7X+dllyN+ByEDW+yaL1ewYPIpugxVzH5P8jhnBXsIyHKN411g==} + /@react-aria/utils@3.25.2(react@18.2.0): + resolution: {integrity: sha512-GdIvG8GBJJZygB4L2QJP1Gabyn2mjFsha73I2wSe+o4DYeGWoJiMZRM06PyTIxLH4S7Sn7eVDtsSBfkc2VY/NA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/ssr': 3.9.2(react@18.2.0) - '@react-stately/utils': 3.9.1(react@18.2.0) - '@react-types/shared': 3.22.1(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 clsx: 2.0.0 react: 18.2.0 - /@react-aria/virtualizer@3.9.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+lmPMlRlqk/vWHtL5BGYVGlvkwzrFZCp3n9J2dqOEqITrIFiBFKj7tDbEeV455E7i0ypwIKPdeYLDvIsxCqxgg==} + /@react-aria/virtualizer@4.0.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-HNhpZl53UM2Z8g0DNvjAW7aZRwOReYgKRxdTF/IlYHNMLpdqWZinKwLbxZCsbgX3SCjdIGns90YhkMSKVpfrpw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/i18n': 3.10.2(react@18.2.0) - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-stately/virtualizer': 3.6.5(react@18.2.0) - '@react-types/shared': 3.22.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/virtualizer': 4.0.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@react-aria/visually-hidden@3.8.6(react@18.2.0): - resolution: {integrity: sha512-6DmS/JLbK9KgU/ClK1WjwOyvpn8HtwYn+uisMLdP7HlCm692peYOkXDR1jqYbHL4GlyLCD0JLI+/xGdVh5aR/w==} + /@react-aria/visually-hidden@3.8.15(react@18.2.0): + resolution: {integrity: sha512-l+sJ7xTdD5Sd6+rDNDaeJCSPnHOsI+BaJyApvb/YcVgHa7rB47lp6TXCWUCDItcPY4JqRGyeByRJVrtzBFTWCw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/interactions': 3.21.1(react@18.2.0) - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 - clsx: 1.2.1 + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/calendar@3.4.1(react@18.2.0): - resolution: {integrity: sha512-XKCdrXNA7/ukZ842EeDZfLqYUQDv/x5RoAVkzTbp++3U/MLM1XZXsqj+5xVlQfJiWpQzM9L6ySjxzzgepJDeuw==} + /@react-stately/calendar@3.5.4(react@18.2.0): + resolution: {integrity: sha512-R2011mtFSXIjzMXaA+CZ1sflPm9XkTBMqVk77Bnxso2ZsG7FUX8nqFmaDavxwTuHFC6OUexAGSMs8bP9KycTNg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/date': 3.5.0 - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/calendar': 3.4.1(react@18.2.0) - '@react-types/datepicker': 3.6.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@internationalized/date': 3.5.5 + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/checkbox@3.5.1(react@18.2.0): - resolution: {integrity: sha512-j+EbHpZgS8J2LbysbVDK3vQAJc7YZHOjHRX20auEzVmulAFKwkRpevo/R5gEL4EpOz4bRyu+BH/jbssHXG+Ezw==} + /@react-stately/checkbox@3.6.8(react@18.2.0): + resolution: {integrity: sha512-c8TWjU67XHHBCpqj6+FXXhQUWGr2Pil1IKggX81pkedhWiJl3/7+WHJuZI0ivGnRjp3aISNOG8UNVlBEjS9E8A==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/toggle': 3.6.3(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/collections@3.10.2(react@18.2.0): - resolution: {integrity: sha512-h+LzCa1gWhVRWVH8uR+ZxsKmFSx7kW3RIlcjWjhfyc59BzXCuojsOJKTTAyPVFP/3kOdJeltw8g/reV1Cw/x6Q==} + /@react-stately/collections@3.10.9(react@18.2.0): + resolution: {integrity: sha512-plyrng6hOQMG8LrjArMA6ts/DgWyXln3g90/hFNbqe/hdVYF53sDVsj8Jb+5LtoYTpiAlV6eOvy1XR0vPZUf8w==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/combobox@3.7.1(react@18.2.0): - resolution: {integrity: sha512-JMKsbhCgP8HpwRjHLBmJILzyU9WzWykjXyP4QF/ifmkzGRjC/s46+Ieq+WonjVaLNGCoi6XqhYn2x2RyACSbsQ==} + /@react-stately/combobox@3.9.2(react@18.2.0): + resolution: {integrity: sha512-ZsbAcD58IvxZqwYxg9d2gOf8R/k5RUB2TPUiGKD6wgWfEKH6SDzY3bgRByHGOyMCyJB62cHjih/ZShizNTguqA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/list': 3.10.0(react@18.2.0) - '@react-stately/menu': 3.5.6(react@18.2.0) - '@react-stately/select': 3.5.5(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/combobox': 3.8.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-stately/select': 3.6.7(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/combobox': 3.12.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/data@3.10.3(react@18.2.0): - resolution: {integrity: sha512-cC9mxCZU4N9GbdOB4g2/J8+W+860GvBd874to0ObSc/XOR4VbuIsxAFIabW5UwmJV+XaqqK4TUBG0C6YScXeWQ==} + /@react-stately/data@3.11.6(react@18.2.0): + resolution: {integrity: sha512-S8q1Ejuhijl8SnyVOdDNFrMrWWnLk/Oh1ZT3KHSbTdpfMRtvhi5HukoiP06jlzz75phnpSPQL40npDtUB/kk3Q==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/datepicker@3.8.0(react@18.2.0): - resolution: {integrity: sha512-6YDSmkrRafYCWhRHks8Z2tZavM1rqSOy8GY8VYjYMCVTFpRuhPK9TQaFv2BdzZL/vJ6OGThxqoglcEwywZVq2g==} + /@react-stately/datepicker@3.10.2(react@18.2.0): + resolution: {integrity: sha512-pa5IZUw+49AyOnddwu4XwU2kI5eo/1thbiIVNHP8uDpbbBrBkquSk3zVFDAGX1cu/I1U2VUkt64U/dxgkwaMQw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/date': 3.5.0 - '@internationalized/string': 3.1.1 - '@react-stately/overlays': 3.6.3(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/datepicker': 3.6.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@internationalized/date': 3.5.5 + '@internationalized/string': 3.2.3 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/datepicker': 3.8.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/dnd@3.2.5(react@18.2.0): - resolution: {integrity: sha512-f9S+ycjAMEaz9HqGxkx4jsqo/ZS8kh0o97rxSKpGFKPZ02UMFWCr9lJI1p3hVGukiMahrmsNtoQXAvMcFAZyQQ==} + /@react-stately/dnd@3.4.2(react@18.2.0): + resolution: {integrity: sha512-VrHmNoNdVGrx5JHdz/zewmN+N8rlZe+vL/iAOLmvQ74RRLEz8KDFnHdlhgKg1AZqaSg3JJ18BlHEkS7oL1n+tA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/flags@3.0.0: - resolution: {integrity: sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w==} + /@react-stately/flags@3.0.3: + resolution: {integrity: sha512-/ha7XFA0RZTQsbzSPwu3KkbNMgbvuM0GuMTYLTBWpgBrovBNTM+QqI/PfZTdHg8PwCYF4H5Y8gjdSpdulCvJFw==} dependencies: - '@swc/helpers': 0.4.36 + '@swc/helpers': 0.5.12 dev: false - /@react-stately/grid@3.8.2(react@18.2.0): - resolution: {integrity: sha512-CB5QpYjXFatuXZodj3r0vIiqTysUe6DURZdJu6RKG2Elx19n2k49fKyx7P7CTKD2sPBOMSSX4edWuTzpL8Tl+A==} + /@react-stately/form@3.0.5(react@18.2.0): + resolution: {integrity: sha512-J3plwJ63HQz109OdmaTqTA8Qhvl3gcYYK7DtgKyNP6mc/Me2Q4tl2avkWoA+22NRuv5m+J8TpBk4AVHUEOwqeQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-types/grid': 3.2.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/layout@3.13.3(react@18.2.0): - resolution: {integrity: sha512-AZ2Sm7iSRcRsNATXg7bjbPpZIjV3z7bHAJtICWA1wHieVVSV1FFoyDyiXdDTIOxyuGeytNPaxtGfPpFZia9Wsg==} + /@react-stately/grid@3.9.2(react@18.2.0): + resolution: {integrity: sha512-2gK//sqAqg2Xaq6UITTFQwFUJnBRgcW+cKBVbFt+F8d152xB6UwwTS/K79E5PUkOotwqZgTEpkrSFs/aVxCLpw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/table': 3.11.2(react@18.2.0) - '@react-stately/virtualizer': 3.6.5(react@18.2.0) - '@react-types/grid': 3.2.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/table': 3.9.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/list@3.10.0(react@18.2.0): - resolution: {integrity: sha512-Yspumiln2fvzoO8AND8jNAIfBu1XPaYioeeDmsB5Vrya2EvOkzEGsauQSNBJ6Vhee1fQqpnmzH1HB0jfIKUfzg==} + /@react-stately/layout@4.0.2(react@18.2.0): + resolution: {integrity: sha512-g3IOrYQcaWxWKW44fYCOLoLMYKEmoOAcT9vQIbgK8MLTQV9Zgt9sGREwn4WJPm85N58Ij6yP72aQ7og/PSymvg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/table': 3.12.2(react@18.2.0) + '@react-stately/virtualizer': 4.0.2(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/table': 3.10.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/menu@3.5.6(react@18.2.0): - resolution: {integrity: sha512-Cm82SVda1qP71Fcz8ohIn3JYKmKCuSUIFr1WsEo/YwDPkX0x9+ev6rmphHTsxDdkCLcYHSTQL6e2KL0wAg50zA==} + /@react-stately/list@3.10.8(react@18.2.0): + resolution: {integrity: sha512-rHCiPLXd+Ry3ztR9DkLA5FPQeH4Zd4/oJAEDWJ77W3oBBOdiMp3ZdHDLP7KBRh17XGNLO/QruYoHWAQTPiMF4g==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/overlays': 3.6.3(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/menu': 3.9.5(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/numberfield@3.6.2(react@18.2.0): - resolution: {integrity: sha512-li/SO3BU3RGySRNlXhPRKr161GJyNbQe6kjnj+0BFTS/ST9nxCgxFK4llHf+S+I/shNI6+0U2nAjE85QOv4emQ==} + /@react-stately/menu@3.8.2(react@18.2.0): + resolution: {integrity: sha512-lt6hIHmSixMzkKx1rKJf3lbAf01EmEvvIlENL20GLiU9cRbpPnPJ1aJMZ5Ad5ygglA7wAemAx+daPhlTQfF2rg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/number': 3.3.0 - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/numberfield': 3.6.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/menu': 3.9.11(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/overlays@3.6.3(react@18.2.0): - resolution: {integrity: sha512-K3eIiYAdAGTepYqNf2pVb+lPqLoVudXwmxPhyOSZXzjgpynD6tR3E9QfWQtkMazBuU73PnNX7zkH4l87r2AmTg==} + /@react-stately/numberfield@3.9.6(react@18.2.0): + resolution: {integrity: sha512-p2R9admGLI439qZzB39dyANhkruprJJtZwuoGVtxW/VD0ficw6BrPVqAaKG25iwKPkmveleh9p8o+yRqjGedcQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/overlays': 3.8.3(react@18.2.0) - '@swc/helpers': 0.5.2 + '@internationalized/number': 3.5.3 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/numberfield': 3.8.5(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/radio@3.9.1(react@18.2.0): - resolution: {integrity: sha512-DrQPHiP9pz1uQbBP/NDFdO8uOZigPbvuAWPUNK7Gq6kye5lW+RsS97IUnYJePNTSMvhiAVz/aleBt05Gr/PZmg==} + /@react-stately/overlays@3.6.10(react@18.2.0): + resolution: {integrity: sha512-XxZ2qScT5JPwGk9qiVJE4dtVh3AXTcYwGRA5RsHzC26oyVVsegPqY2PmNJGblAh6Q57VyodoVUyebE0Eo5CzRw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/radio': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/searchfield@3.4.6(react@18.2.0): - resolution: {integrity: sha512-DeVacER0MD35gzQjrYpX/e3k8rjKF82W0OooTkRjeQ2U48femZkQpmp3O+j10foQx2LLaxqt9PSW7QS0Ww1bCA==} + /@react-stately/radio@3.10.7(react@18.2.0): + resolution: {integrity: sha512-ZwGzFR+sGd42DxRlDTp3G2vLZyhMVtgHkwv2BxazPHxPMvLO9yYl7+3PPNxAmhMB4tg2u9CrzffpGX2rmEJEXA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/searchfield': 3.5.1(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/radio': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/select@3.5.5(react@18.2.0): - resolution: {integrity: sha512-nDkvFeAZbN7dK/Ty+mk1h4LZYYaoPpkwrG49wa67DTHkCc8Zk2+UEjhKPwOK20th4vfJKHzKjVa0Dtq4DIj0rw==} + /@react-stately/searchfield@3.5.6(react@18.2.0): + resolution: {integrity: sha512-gVzU0FeWiLYD8VOYRgWlk79Qn7b2eirqOnWhtI5VNuGN8WyNaCIuBp6SkXTW2dY8hs2Hzn8HlMbgy1MIc7130Q==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/list': 3.10.0(react@18.2.0) - '@react-stately/menu': 3.5.6(react@18.2.0) - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/select': 3.8.4(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/searchfield': 3.5.8(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/selection@3.14.0(react@18.2.0): - resolution: {integrity: sha512-E5rNH+gVGDJQDSnPO30ynu6jZ0Z0++VPUbM5Bu3P/bZ3+TgoTtDDvlONba3fspgSBDfdnHpsuG9eqYnDtEAyYA==} + /@react-stately/select@3.6.7(react@18.2.0): + resolution: {integrity: sha512-hCUIddw0mPxVy1OH6jhyaDwgNea9wESjf+MYdnnTG/abRB+OZv/dWScd87OjzVsHTHWcw7CN4ZzlJoXm0FJbKQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/select': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/table@3.11.2(react@18.2.0): - resolution: {integrity: sha512-EVgksPAsnEoqeT+5ej4aGJdu9kAu3LCDqQfnmif2P/R1BP5eDU1Kv0N/mV/90Xp546g7kuZ1wS2if/hWDXEA5g==} + /@react-stately/selection@3.16.2(react@18.2.0): + resolution: {integrity: sha512-C4eSKw7BIZHJLPzwqGqCnsyFHiUIEyryVQZTJDt6d0wYBOHU6k1pW+Q4VhrZuzSv+IMiI2RkiXeJKc55f0ZXrg==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/flags': 3.0.0 - '@react-stately/grid': 3.8.2(react@18.2.0) - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/grid': 3.2.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/table': 3.9.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/tabs@3.6.1(react@18.2.0): - resolution: {integrity: sha512-akGmejEaXg2RMZuWbRZ0W1MLr515e0uV0iVZefKBlcHtD/mK9K9Bo2XxBScf0TIhaPJ6Qa2w2k2+V7RmT7r8Ag==} + /@react-stately/table@3.12.2(react@18.2.0): + resolution: {integrity: sha512-dUcsrdALylhWz6exqIoqtR/dnrzjIAptMyAUPT378Y/mCYs4PxKkHSvtPEQrZhdQS1ALIIgfeg9KUVIempoXPw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/list': 3.10.0(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/tabs': 3.3.3(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/flags': 3.0.3 + '@react-stately/grid': 3.9.2(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/table': 3.10.1(react@18.2.0) '@swc/helpers': 0.5.2 react: 18.2.0 dev: false - /@react-stately/toast@3.0.0-beta.1(react@18.2.0): - resolution: {integrity: sha512-NeWdLXpHfXu8UXjmn+6iZv39Xvan/D0uNWzIyCxkDOeNNOHt1N4kSwdvQ56ScQ3f7KBVPqKz32t7K466Zpa8Jg==} + /@react-stately/tabs@3.6.9(react@18.2.0): + resolution: {integrity: sha512-YZDqZng3HrRX+uXmg6u78x73Oi24G5ICpiXVqDKKDkO333XCA5H8MWItiuPZkYB2h3SbaCaLqSobLkvCoWYpNQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@swc/helpers': 0.5.1 + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tabs': 3.3.9(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) dev: false - /@react-stately/toggle@3.6.3(react@18.2.0): - resolution: {integrity: sha512-4kIMTjRjtaapFk4NVmBoFDUYfkmyqDaYAmHpRyEIHTDpBYn0xpxZL/MHv9WuLYa4MjJLRp0MeicuWiZ4ai7f6Q==} + /@react-stately/toast@3.0.0-beta.5(react@18.2.0): + resolution: {integrity: sha512-MEdQwcKsexlcJ4YQZ9cN5QSIqTlGGdgC5auzSKXXoq15DHuo4mtHfLzXPgcMDYOhOdmyphMto8Vt+21UL2FOrw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 - react: 18.2.0 - dev: false - - /@react-stately/tooltip@3.4.5(react@18.2.0): - resolution: {integrity: sha512-VrwQcjnrNddSulh+Zql8P8cORRnWqSPkHPqQwD/Ly91Rva3gUIy+VwnYeThbGDxRzlUv1wfN+UQraEcrgwSZ/Q==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-stately/overlays': 3.6.3(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/tooltip': 3.4.5(react@18.2.0) - '@swc/helpers': 0.5.2 + '@swc/helpers': 0.5.12 react: 18.2.0 + use-sync-external-store: 1.2.2(react@18.2.0) dev: false - /@react-stately/tree@3.7.3(react@18.2.0): - resolution: {integrity: sha512-wB/68qetgCYTe7OMqbTFmtWRrEqVdIH2VlACPCsMlECr3lW9TrrbrOwlHIJfLhkxWvY3kSCoKcOJ5KTiJC9LGA==} + /@react-stately/toggle@3.7.7(react@18.2.0): + resolution: {integrity: sha512-AS+xB4+hHWa3wzYkbS6pwBkovPfIE02B9SnuYTe0stKcuejpWKo5L3QMptW0ftFYsW3ZPCXuneImfObEw2T01A==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-stately/collections': 3.10.2(react@18.2.0) - '@react-stately/selection': 3.14.0(react@18.2.0) - '@react-stately/utils': 3.8.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/utils@3.8.0(react@18.2.0): - resolution: {integrity: sha512-wCIoFDbt/uwNkWIBF+xV+21k8Z8Sj5qGO3uptTcVmjYcZngOaGGyB4NkiuZhmhG70Pkv+yVrRwoC1+4oav9cCg==} + /@react-stately/tooltip@3.4.12(react@18.2.0): + resolution: {integrity: sha512-QKYT/cze7n9qaBsk7o5ais3jRfhYCzcVRfps+iys/W+/9FFbbhjfQG995Lwi6b+vGOHWfXxXpwmyIO2tzM1Iog==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@swc/helpers': 0.5.2 + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/tooltip': 3.4.11(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-stately/utils@3.9.1(react@18.2.0): - resolution: {integrity: sha512-yzw75GE0iUWiyps02BOAPTrybcsMIxEJlzXqtvllAb01O9uX5n0i3X+u2eCpj2UoDF4zS08Ps0jPgWxg8xEYtA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@swc/helpers': 0.5.2 - react: 18.2.0 - - /@react-stately/virtualizer@3.6.5(react@18.2.0): - resolution: {integrity: sha512-v0cZeNCGPMeo3LP4UrGuDo3Xpq7ufNaZyGObgSvdrIW49qK5F02kczcKy6NKg+QfOgC/+Nc9Tof/2S8dcxDrCA==} + /@react-stately/tree@3.8.4(react@18.2.0): + resolution: {integrity: sha512-HFNclIXJ/3QdGQWxXbj+tdlmIX/XwCfzAMB5m26xpJ6HtJhia6dtx3GLfcdyHNjmuRbAsTBsAAnnVKBmNRUdIQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-aria/utils': 3.23.2(react@18.2.0) - '@react-types/shared': 3.22.0(react@18.2.0) - '@swc/helpers': 0.5.2 + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-types/actionbar@3.1.5(react@18.2.0): - resolution: {integrity: sha512-Z3hfIoaOaW8wJxQm1NyWVvSftpNDYv9iWqpEWBEdhxuqsUkOVszZ7KcNaF4qsm4bJIcJWn3FNKhaTKGwISZcdQ==} + /@react-stately/utils@3.10.3(react@18.2.0): + resolution: {integrity: sha512-moClv7MlVSHpbYtQIkm0Cx+on8Pgt1XqtPx6fy9rQFb2DNc9u1G3AUVnqA17buOkH1vLxAtX4MedlxMWyRCYYA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.22.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 - dev: false - /@react-types/actiongroup@3.4.5(react@18.2.0): - resolution: {integrity: sha512-WUyMT47rACA/4MZ5WK4pRcRsdyA9FqQXpsK2+ubpWuCznx+o4ndF+8rUVJXnc1jiZ33xYPsmplBrrBYZdbdifA==} + /@react-stately/virtualizer@4.0.2(react@18.2.0): + resolution: {integrity: sha512-LiSr6E6OoL/cKVFO088zEzkNGj41g02nlOAgLluYONncNEjoYiHmb8Yw0otPgViVLKiFjO6Kk4W+dbt8EZ51Ag==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/button': 3.9.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.12 react: 18.2.0 dev: false - /@react-types/breadcrumbs@3.7.3(react@18.2.0): - resolution: {integrity: sha512-eFto/+6J+JR58vThNcALZRA1OlqlG3GzQ/bq3q8IrrkOZcrfbEJJCWit/+53Ia98siJKuF4OJHnotxIVIz5I3w==} + /@react-types/actionbar@3.1.9(react@18.2.0): + resolution: {integrity: sha512-omCribEByWYcDr27W63LpmFq+muACc949UzCcMzlc6fvkKc6Gq+HjRRoTQjX6k8hXXFqEbQoYJFVyRXnig6u5g==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/link': 3.5.3(react@18.2.0) - '@react-types/shared': 3.22.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/button@3.9.0(react@18.2.0): - resolution: {integrity: sha512-YhbchUDB7yL88ZFA0Zqod6qOMdzCLD5yVRmhWymk0yNLvB7EB1XX4c5sRANalfZSFP0RpCTlkjB05Hzp4+xOYg==} + /@react-types/actiongroup@3.4.11(react@18.2.0): + resolution: {integrity: sha512-gO/A+nbPoDwovqWlEyILNlfBY1loXFR0+P7OzH+vqppCHFz+Y2dF6Ry2LqUAmE0XPaYLzwg4Y/Nkuc20jIVujQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/calendar@3.4.1(react@18.2.0): - resolution: {integrity: sha512-tiCkHi6IQtYcVoAESG79eUBWDXoo8NImo+Mj8WAWpo1lOA3SV1W2PpeXkoRNqtloilQ0aYcmsaJJUhciQG4ndg==} + /@react-types/breadcrumbs@3.7.7(react@18.2.0): + resolution: {integrity: sha512-ZmhXwD2LLzfEA2OvOCp/QvXu8A/Edsrn5q0qUDGsmOZj9SCVeT82bIv8P+mQnATM13mi2gyoik6102Jc1OscJA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/date': 3.5.0 - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/link': 3.5.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/checkbox@3.5.2(react@18.2.0): - resolution: {integrity: sha512-iRQrbY8vRRya3bt3i7sHAifhP/ozfkly1/TItkRK5MNPRNPRDKns55D8ZFkRMj4NSyKQpjVt1zzlBXrnSOxWdQ==} + /@react-types/button@3.9.6(react@18.2.0): + resolution: {integrity: sha512-8lA+D5JLbNyQikf8M/cPP2cji91aVTcqjrGpDqI7sQnaLFikM8eFR6l1ZWGtZS5MCcbfooko77ha35SYplSQvw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/combobox@3.8.1(react@18.2.0): - resolution: {integrity: sha512-F910tk8K5qE0TksJ9LRGcJIpaPzpsCnFxT6E9oJH3ssK4N8qZL8QfT9tIKo2XWhK9Uxb/tIZOGQwA8Cn7TyZrA==} + /@react-types/calendar@3.4.9(react@18.2.0): + resolution: {integrity: sha512-O/PS9c21HgO9qzxOyZ7/dTccxabFZdF6tj3UED4DrBw7AN3KZ7JMzwzYbwHinOcO7nUcklGgNoAIHk45UAKR9g==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@internationalized/date': 3.5.5 + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/datepicker@3.6.1(react@18.2.0): - resolution: {integrity: sha512-/M+0e9hL9w98f5k4EoxeH2UfPsUPoS6fvmFsmwUZJcDiw7wP510XngnDLy9GOHj9xgqagZ20S79cxcEuTq7U6g==} + /@react-types/checkbox@3.8.3(react@18.2.0): + resolution: {integrity: sha512-f4c1mnLEt0iS1NMkyZXgT3q3AgcxzDk7w6MSONOKydcnh0xG5L2oefY14DhVDLkAuQS7jThlUFwiAs+MxiO3MA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@internationalized/date': 3.5.0 - '@react-types/calendar': 3.4.1(react@18.2.0) - '@react-types/overlays': 3.8.3(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/dialog@3.5.6(react@18.2.0): - resolution: {integrity: sha512-lwwaAgoi4xe4eEJxBns+cBIRstIPTKWWddMkp51r7Teeh2uKs1Wki7N+Acb9CfT6JQTQDqtVJm6K76rcqNBVwg==} + /@react-types/combobox@3.12.1(react@18.2.0): + resolution: {integrity: sha512-bd5YwHZWtgnJx4jGbplWbYzXj7IbO5w3IY5suNR7r891rx6IktquZ8GQwyYH0pQ/x+X5LdK2xI59i6+QC2PmlA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/overlays': 3.8.3(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/grid@3.2.2(react@18.2.0): - resolution: {integrity: sha512-R4USOpn1xfsWVGwZsakRlIdsBA10XNCnAUcRXQTn2JmzLjDCtcln6uYo9IFob080lQuvjkSw3j4zkw7Yo4Qepg==} + /@react-types/datepicker@3.8.2(react@18.2.0): + resolution: {integrity: sha512-Ih4F0bNVGrEuwCD8XmmBAspuuOBsj/Svn/pDFtC2RyAZjXfWh+sI+n4XLz/sYKjvARh5TUI8GNy9smYS4vYXug==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@internationalized/date': 3.5.5 + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/label@3.8.1(react@18.2.0): - resolution: {integrity: sha512-fA6zMTF2TmfU7H8JBJi0pNd8t5Ak4gO+ZA3cZBysf8r3EmdAsgr3LLqFaGTnZzPH1Fux6c7ARI3qjVpyNiejZQ==} + /@react-types/dialog@3.5.12(react@18.2.0): + resolution: {integrity: sha512-JmpQbSpXltqEyYfEwoqDolABIiojeExkqolHNdQlayIsfFuSxZxNwXZPOpz58Ri/iwv21JP7K3QF0Gb2Ohxl9w==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/link@3.5.3(react@18.2.0): - resolution: {integrity: sha512-yVafjW3IejyVnK3oMBNjFABCGG6J27EUG8rvkaGaI1uB6srGUEhpJ97XLv11aj1QkXHBy3VGXqxEV3S7wn4HTw==} + /@react-types/grid@3.2.8(react@18.2.0): + resolution: {integrity: sha512-6PJrpukwMqlv3IhJSDkJuVbhHM8Oe6hd2supWqd9adMXrlSP7QHt9a8SgFcFblCCTx8JzUaA0PvY5sTudcEtOQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.22.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/listbox@3.4.5(react@18.2.0): - resolution: {integrity: sha512-nuRY3l8h/rBYQWTXWdZz5YJdl6QDDmXpHrnPuX7PxTwbXcwjhoMK+ZkJ0arA8Uv3MPs1OUcT6K6CInsPnG2ARQ==} + /@react-types/link@3.5.7(react@18.2.0): + resolution: {integrity: sha512-2WyaVmm1qr9UrSG3Dq6iz+2ziuVp+DH8CsYZ9CA6aNNb6U18Hxju3LTPb4a5gM0eC7W0mQGNBmrgGlAdDZEJOw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/menu@3.9.5(react@18.2.0): - resolution: {integrity: sha512-KB5lJM0p9PxwpVlHV9sRdpjh+sqINeHrJgGizy/cQI9bj26nupiEgamSD14dULNI6BFT9DkgKCsobBtE04DDKQ==} + /@react-types/listbox@3.5.1(react@18.2.0): + resolution: {integrity: sha512-n5bOgD9lgfK1qaLtag9WPnu151SwXBCNn/OgGY/Br9mWRl+nPUEYtFcPX+2VCld7uThf54kwrTmzlFnaraIlcw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/overlays': 3.8.3(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/meter@3.3.5(react@18.2.0): - resolution: {integrity: sha512-7kSP/bqkt6ANHUJLJ4OsHOPNwg9ETvWHAKXDYoCqkLYzdhFh0H/8EAW9z4Bh/io0GvR7ePds9s+32iislfSwDg==} + /@react-types/menu@3.9.11(react@18.2.0): + resolution: {integrity: sha512-IguQVF70d7aHXgWB1Rd2a/PiIuLZ2Nt7lyayJshLcy/NLOYmgpTmTyn2WCtlA5lTfQwmQrNFf4EvnWkeljJXdA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/progress': 3.5.0(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/numberfield@3.6.1(react@18.2.0): - resolution: {integrity: sha512-jdMCN0mQ7eZkPrCKYkkG+jSjcG2VQ5P7mR9tTaCQeQK1wo+tF/8LWD+6n6dU7hH/qlU9sxVEg3U3kJ9sgNK+Hw==} + /@react-types/meter@3.4.3(react@18.2.0): + resolution: {integrity: sha512-Y2fX5CTAPGRKxVSeepbeyN6/K+wlF9pMRcNxTSU2qDwdoFqNCtTWMcWuCsU/Y2L/zU0jFWu4x0Vo7WkrcsgcMA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/progress': 3.5.6(react@18.2.0) react: 18.2.0 dev: false - /@react-types/overlays@3.8.3(react@18.2.0): - resolution: {integrity: sha512-TrCG2I2+V+TD0PGi3CqfnyU5jEzcelSGgYJQvVxsl5Vv3ri7naBLIsOjF9x66tPxhINLCPUtOze/WYRAexp8aw==} + /@react-types/numberfield@3.8.5(react@18.2.0): + resolution: {integrity: sha512-LVWggkxwd1nyVZomXBPfQA1E4I4/i4PBifjcDs2AfcV7q5RE9D+DVIDXsYucVOBxPlDOxiAq/T9ypobspWSwHw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/progress@3.5.0(react@18.2.0): - resolution: {integrity: sha512-c1KLQCfYjdUdkTcPy0ZW31dc2+D86ZiZRHPNOaSYFGJjk9ItbWWi8BQTwlrw6D2l/+0d/YDdUFGaZhHMrY9mBQ==} + /@react-types/overlays@3.8.9(react@18.2.0): + resolution: {integrity: sha512-9ni9upQgXPnR+K9cWmbYWvm3ll9gH8P/XsEZprqIV5zNLMF334jADK48h4jafb1X9RFnj0WbHo6BqcSObzjTig==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/radio@3.5.2(react@18.2.0): - resolution: {integrity: sha512-crYQ+97abd5v0Iw9X+Tt+E7KWdm5ckr4g0+Iy8byV1g6MyiBOsNtq9QT99TOzyWJPqqD8T9qZfAOk49wK7KEDg==} + /@react-types/progress@3.5.6(react@18.2.0): + resolution: {integrity: sha512-Nh43sjQ5adyN1bTHBPRaIPhXUdBqP0miYeJpeMY3V/KUl4qmouJLwDnccwFG4xLm6gBfYe22lgbbV7nAfNnuTQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/searchfield@3.5.1(react@18.2.0): - resolution: {integrity: sha512-+v9fo50JrZOfFzbdgJsW39hyTFv1gVH458nx82aidYJzQocFJniiAEl0ZhhRzbE8RijyjLleKIAY+klPeFmEaQ==} + /@react-types/radio@3.8.3(react@18.2.0): + resolution: {integrity: sha512-fUVJt4Bb6jOReFqnhHVNxWXH7t6c60uSFfoPKuXt/xI9LL1i2jhpur0ggpTfIn3qLIAmNBU6bKBCWAdr4KjeVQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) - '@react-types/textfield': 3.8.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/select@3.8.4(react@18.2.0): - resolution: {integrity: sha512-jHBaLiAHTcYPz52kuJpypBbR0WAA+YCZHy2HH+W8711HuTqePZCEp6QAWHK9Fw0qwSZQ052jYaWvOsgEZZ6ojQ==} + /@react-types/searchfield@3.5.8(react@18.2.0): + resolution: {integrity: sha512-EcdqalHNIC6BJoRfmqUhAvXRd3aHkWlV1cFCz57JJKgUEFYyXPNrXd1b73TKLzTXEk+X/D6LKV15ILYpEaxu8w==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/textfield': 3.9.6(react@18.2.0) react: 18.2.0 dev: false - /@react-types/shared@3.19.0(react@18.2.0): - resolution: {integrity: sha512-h852l8bWhqUxbXIG8vH3ab7gE19nnP3U1kuWf6SNSMvgmqjiRN9jXKPIFxF/PbfdvnXXm0yZSgSMWfUCARF0Cg==} + /@react-types/select@3.9.6(react@18.2.0): + resolution: {integrity: sha512-cVSFR0eJLup/ht1Uto+y8uyLmHO89J6wNh65SIHb3jeVz9oLBAedP3YNI2qB+F9qFMUcA8PBSLXIIuT6gXzLgQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/shared@3.21.0(react@18.2.0): - resolution: {integrity: sha512-wJA2cUF8dP4LkuNUt9Vh2kkfiQb2NLnV2pPXxVnKJZ7d4x2/7VPccN+LYPnH8m0X3+rt50cxWuPKQmjxSsCFOg==} + /@react-types/shared@3.24.1(react@18.2.0): + resolution: {integrity: sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: react: 18.2.0 - /@react-types/shared@3.22.0(react@18.2.0): - resolution: {integrity: sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA==} + /@react-types/switch@3.5.5(react@18.2.0): + resolution: {integrity: sha512-SZx1Bd+COhAOs/RTifbZG+uq/llwba7VAKx7XBeX4LeIz1dtguy5bigOBgFTMQi4qsIVCpybSWEEl+daj4XFPw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/shared@3.22.1(react@18.2.0): - resolution: {integrity: sha512-PCpa+Vo6BKnRMuOEzy5zAZ3/H5tnQg1e80khMhK2xys0j6ZqzkgQC+fHMNZ7VDFNLqqNMj/o0eVeSBDh2POjkw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - react: 18.2.0 - - /@react-types/switch@3.4.2(react@18.2.0): - resolution: {integrity: sha512-OQWpawikWhF+ET1/kE0/JeJVr6gHjkR72p/idTsT7RUJySBcehhAscbIA8iWzVWJvdFCVF2hG7uzBAJTeDMr9A==} + /@react-types/table@3.10.1(react@18.2.0): + resolution: {integrity: sha512-xsNh0Gm4GtNeSknZqkMsfGvc94fycmfhspGO+FzQKim2hB5k4yILwd+lHYQ2UKW6New9GVH/zN2Pd3v67IeZ2g==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/checkbox': 3.5.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/table@3.9.0(react@18.2.0): - resolution: {integrity: sha512-WOLxZ3tzLA4gxRxvnsZhnnQDbh4Qe/johpHNk4coSOFOP5W8PbunPacXnbvdPkSx6rqrOIzCnYcZCtgk4gDQmg==} + /@react-types/tabs@3.3.9(react@18.2.0): + resolution: {integrity: sha512-3Q9kRVvg/qDyeJR/W1+C2z2OyvDWQrSLvOCvAezX5UKzww4rBEAA8OqBlyDwn7q3fiwrh/m64l6p+dbln+RdxQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/grid': 3.2.2(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/tabs@3.3.3(react@18.2.0): - resolution: {integrity: sha512-Zc4g5TIwJpKS5fiT9m4dypbCr1xqtauL4wqM76fGERCAZy0FwXTH/yjzHJDYKyWFJrQNWtJ0KAhJR/ZqKDVnIw==} + /@react-types/textfield@3.9.6(react@18.2.0): + resolution: {integrity: sha512-0uPqjJh4lYp1aL1HL9IlV8Cgp8eT0PcsNfdoCktfkLytvvBPmox2Pfm57W/d0xTtzZu2CjxhYNTob+JtGAOeXA==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false - /@react-types/textfield@3.8.1(react@18.2.0): - resolution: {integrity: sha512-p8Xmew9kzJd+tCM7h9LyebZHpv7SH1IE1Nu13hLCOV5cZ/tVVVCwjNGLMv4MtUpSn++H42YLJgAW9Uif+a+RHg==} + /@react-types/tooltip@3.4.11(react@18.2.0): + resolution: {integrity: sha512-WPikHQxeT5Lb09yJEaW6Ja3ecE0g1YM6ukWYS2v/iZLUPn5YlYrGytspuCYQNSh/u7suCz4zRLEHYCl7OCigjw==} peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 dependencies: - '@react-types/shared': 3.21.0(react@18.2.0) - react: 18.2.0 - dev: false - - /@react-types/tooltip@3.4.5(react@18.2.0): - resolution: {integrity: sha512-pv87Vlu+Pn1Titw199y5aiSuXF/GHX+fBCihi9BeePqtwYm505e/Si01BNh5ejCeXXOS4JIMuXwmGGzGVdGk6Q==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - dependencies: - '@react-types/overlays': 3.8.3(react@18.2.0) - '@react-types/shared': 3.21.0(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) react: 18.2.0 dev: false @@ -9627,6 +9919,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-android-arm-eabi@4.21.1: + resolution: {integrity: sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-android-arm-eabi@4.6.1: resolution: {integrity: sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==} cpu: [arm] @@ -9641,6 +9941,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-android-arm64@4.21.1: + resolution: {integrity: sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-android-arm64@4.6.1: resolution: {integrity: sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA==} cpu: [arm64] @@ -9655,6 +9963,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-darwin-arm64@4.21.1: + resolution: {integrity: sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-darwin-arm64@4.6.1: resolution: {integrity: sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw==} cpu: [arm64] @@ -9669,6 +9985,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-darwin-x64@4.21.1: + resolution: {integrity: sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-darwin-x64@4.6.1: resolution: {integrity: sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg==} cpu: [x64] @@ -9683,6 +10007,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-arm-gnueabihf@4.21.1: + resolution: {integrity: sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-arm-gnueabihf@4.6.1: resolution: {integrity: sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ==} cpu: [arm] @@ -9697,6 +10029,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-arm-musleabihf@4.21.1: + resolution: {integrity: sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-arm64-gnu@4.18.0: resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} cpu: [arm64] @@ -9704,6 +10044,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-arm64-gnu@4.21.1: + resolution: {integrity: sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-arm64-gnu@4.6.1: resolution: {integrity: sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw==} cpu: [arm64] @@ -9718,6 +10066,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-arm64-musl@4.21.1: + resolution: {integrity: sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-arm64-musl@4.6.1: resolution: {integrity: sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw==} cpu: [arm64] @@ -9732,6 +10088,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-powerpc64le-gnu@4.21.1: + resolution: {integrity: sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-riscv64-gnu@4.18.0: resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} cpu: [riscv64] @@ -9739,6 +10103,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-riscv64-gnu@4.21.1: + resolution: {integrity: sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-s390x-gnu@4.18.0: resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} cpu: [s390x] @@ -9746,6 +10118,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-s390x-gnu@4.21.1: + resolution: {integrity: sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-x64-gnu@4.18.0: resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} cpu: [x64] @@ -9753,6 +10133,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-x64-gnu@4.21.1: + resolution: {integrity: sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-x64-gnu@4.6.1: resolution: {integrity: sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA==} cpu: [x64] @@ -9767,6 +10155,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-linux-x64-musl@4.21.1: + resolution: {integrity: sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-linux-x64-musl@4.6.1: resolution: {integrity: sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ==} cpu: [x64] @@ -9781,6 +10177,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-win32-arm64-msvc@4.21.1: + resolution: {integrity: sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-win32-arm64-msvc@4.6.1: resolution: {integrity: sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ==} cpu: [arm64] @@ -9795,6 +10199,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-win32-ia32-msvc@4.21.1: + resolution: {integrity: sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-win32-ia32-msvc@4.6.1: resolution: {integrity: sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw==} cpu: [ia32] @@ -9809,6 +10221,14 @@ packages: requiresBuild: true optional: true + /@rollup/rollup-win32-x64-msvc@4.21.1: + resolution: {integrity: sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@rollup/rollup-win32-x64-msvc@4.6.1: resolution: {integrity: sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A==} cpu: [x64] @@ -11108,23 +11528,16 @@ packages: '@swc/core-win32-ia32-msvc': 1.3.82 '@swc/core-win32-x64-msvc': 1.3.82 - /@swc/helpers@0.4.14: - resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==} - dependencies: - tslib: 2.6.2 - dev: false - - /@swc/helpers@0.4.36: - resolution: {integrity: sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==} + /@swc/helpers@0.5.1: + resolution: {integrity: sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==} dependencies: - legacy-swc-helpers: /@swc/helpers@0.4.14 tslib: 2.6.2 dev: false - /@swc/helpers@0.5.1: - resolution: {integrity: sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==} + /@swc/helpers@0.5.12: + resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 /@swc/helpers@0.5.2: resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} @@ -11699,6 +12112,12 @@ packages: form-data: 3.0.1 dev: true + /@types/node-forge@1.3.11: + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + dependencies: + '@types/node': 16.11.13 + dev: false + /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false @@ -12378,7 +12797,7 @@ packages: ts-morph: 12.0.0 dev: false - /@vitejs/plugin-react@4.2.1(vite@5.2.12): + /@vitejs/plugin-react@4.2.1(vite@5.4.2): resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -12389,7 +12808,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.5) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.2.12(@types/node@16.11.13) + vite: 5.4.2(@types/node@16.11.13) transitivePeerDependencies: - supports-color dev: false @@ -12522,7 +12941,7 @@ packages: esbuild: '>=0.10.0' dependencies: esbuild: 0.18.20 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /@yarnpkg/fslib@2.10.3: @@ -12615,6 +13034,13 @@ packages: engines: {node: '>=0.4.0'} dev: false + /acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + dependencies: + acorn: 8.12.1 + dev: false + /acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} @@ -12631,6 +13057,12 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + /address@1.2.2: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} engines: {node: '>= 10.0.0'} @@ -12973,14 +13405,14 @@ packages: resolution: {integrity: sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==} engines: {node: '>=4'} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 dev: true /ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 dev: true /astring@1.8.6: @@ -13055,7 +13487,7 @@ packages: yargs-parser: 21.1.1 zod: 3.22.4 optionalDependencies: - sharp: 0.32.5 + sharp: 0.32.6 transitivePeerDependencies: - '@types/node' - less @@ -13638,6 +14070,17 @@ packages: node-releases: 2.0.14 update-browserslist-db: 1.0.16(browserslist@4.23.0) + /browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001653 + electron-to-chromium: 1.5.13 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + dev: true + /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} dependencies: @@ -13783,7 +14226,7 @@ packages: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} dependencies: pascal-case: 3.1.2 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /camelcase-css@2.0.1: @@ -13817,11 +14260,15 @@ packages: /caniuse-lite@1.0.30001597: resolution: {integrity: sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==} + /caniuse-lite@1.0.30001653: + resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==} + dev: true + /capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 upper-case-first: 2.0.2 dev: true @@ -13829,7 +14276,7 @@ packages: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} dependencies: debug: 4.3.4 - tslib: 2.6.2 + tslib: 2.7.0 transitivePeerDependencies: - supports-color dev: false @@ -13934,6 +14381,20 @@ packages: optionalDependencies: fsevents: 2.3.3 + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -14047,10 +14508,6 @@ packages: engines: {node: '>=0.8'} dev: true - /clsx@1.2.1: - resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} - engines: {node: '>=6'} - /clsx@2.0.0: resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} engines: {node: '>=6'} @@ -14236,6 +14693,11 @@ packages: engines: {node: '>=0.8'} dev: true + /consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + dev: false + /console-browserify@1.2.0: resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} dev: true @@ -14248,7 +14710,7 @@ packages: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 upper-case: 2.0.2 dev: true @@ -14538,6 +15000,10 @@ packages: resolution: {integrity: sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==} dev: false + /date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + dev: false + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -14581,6 +15047,18 @@ packages: dependencies: ms: 2.1.2 + /debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -14722,6 +15200,10 @@ packages: resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} dev: true + /defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + dev: false + /del@6.1.1: resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} engines: {node: '>=10'} @@ -14978,7 +15460,7 @@ packages: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /dotenv-expand@10.0.0: @@ -15045,6 +15527,10 @@ packages: /electron-to-chromium@1.4.779: resolution: {integrity: sha512-oaTiIcszNfySXVJzKcjxd2YjPxziAd+GmXyb2HbidCeFo6Z88ygOT7EimlrEQhM2U08VhSrbKhLOXP0kKUCZ6g==} + /electron-to-chromium@1.5.13: + resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} + dev: true + /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} dependencies: @@ -16043,6 +16529,37 @@ packages: '@esbuild/win32-ia32': 0.20.2 '@esbuild/win32-x64': 0.20.2 + /esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + dev: false + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -17695,7 +18212,7 @@ packages: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.17.4 + uglify-js: 3.19.2 dev: true /hard-rejection@2.1.0: @@ -17879,7 +18396,7 @@ packages: resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} dependencies: capital-case: 1.0.4 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /hermes-estree@0.20.1: @@ -18285,7 +18802,7 @@ packages: '@formatjs/ecma402-abstract': 1.17.0 '@formatjs/fast-memoize': 2.2.0 '@formatjs/icu-messageformat-parser': 2.6.0 - tslib: 2.6.2 + tslib: 2.7.0 dev: false /invariant@2.2.4: @@ -19709,7 +20226,7 @@ packages: /lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 dev: true /lowercase-keys@3.0.0: @@ -20902,6 +21419,29 @@ packages: - utf-8-validate dev: false + /miniflare@3.20240821.0: + resolution: {integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==} + engines: {node: '>=16.13'} + hasBin: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.12.1 + acorn-walk: 8.3.3 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.28.4 + workerd: 1.20240821.1 + ws: 8.18.0 + youch: 3.3.3 + zod: 3.23.8 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} dev: true @@ -21217,7 +21757,7 @@ packages: - babel-plugin-macros dev: true - /next@14.1.3(@babel/core@7.24.5)(react-dom@18.2.0)(react@18.2.0): + /next@14.1.3(@babel/core@7.25.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-oexgMV2MapI0UIWiXKkixF8J8ORxpy64OuJ/J9oVUmIthXOUCcuVEZX+dtpgq7wIfIqtBwQsKEDXejcjTsan9g==} engines: {node: '>=18.17.0'} hasBin: true @@ -21240,7 +21780,7 @@ packages: postcss: 8.4.31 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.1(@babel/core@7.24.5)(react@18.2.0) + styled-jsx: 5.1.1(@babel/core@7.25.2)(react@18.2.0) optionalDependencies: '@next/swc-darwin-arm64': 14.1.3 '@next/swc-darwin-x64': 14.1.3 @@ -21265,7 +21805,7 @@ packages: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: lower-case: 2.0.2 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /node-abi@3.47.0: @@ -21295,6 +21835,10 @@ packages: /node-fetch-native@1.4.0: resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==} + /node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + dev: false + /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -21382,6 +21926,10 @@ packages: /node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + /node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + dev: true + /nopt@5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} @@ -21860,7 +22408,7 @@ packages: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} dependencies: dot-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /parent-module@1.0.1: @@ -21959,7 +22507,7 @@ packages: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /path-browserify@1.0.1: @@ -21969,7 +22517,7 @@ packages: resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} dependencies: dot-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /path-exists@3.0.0: @@ -22037,6 +22585,10 @@ packages: /path-to-regexp@6.2.1: resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + /path-to-regexp@6.2.2: + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + dev: false + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -22045,6 +22597,10 @@ packages: resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} dev: true + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: false + /pbkdf2@3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} @@ -22482,6 +23038,15 @@ packages: picocolors: 1.0.1 source-map-js: 1.2.0 + /postcss@8.4.41: + resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + dev: false + /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} @@ -23146,7 +23711,7 @@ packages: '@types/react': 18.2.21 react: 18.2.0 react-style-singleton: 2.2.1(@types/react@18.2.21)(react@18.2.0) - tslib: 2.6.2 + tslib: 2.7.0 dev: true /react-remove-scroll@2.5.5(@types/react@18.2.21)(react@18.2.0): @@ -23214,7 +23779,7 @@ packages: get-nonce: 1.0.1 invariant: 2.2.4 react: 18.2.0 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /react-universal-interface@0.6.2(react@18.2.0)(tslib@2.6.2): @@ -23340,7 +23905,7 @@ packages: ast-types: 0.15.2 esprima: 4.0.1 source-map: 0.6.1 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /recast@0.23.4: @@ -23351,7 +23916,7 @@ packages: ast-types: 0.16.1 esprima: 4.0.1 source-map: 0.6.1 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /redent@3.0.0: @@ -23832,6 +24397,32 @@ packages: '@rollup/rollup-win32-x64-msvc': 4.18.0 fsevents: 2.3.3 + /rollup@4.21.1: + resolution: {integrity: sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.21.1 + '@rollup/rollup-android-arm64': 4.21.1 + '@rollup/rollup-darwin-arm64': 4.21.1 + '@rollup/rollup-darwin-x64': 4.21.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.1 + '@rollup/rollup-linux-arm-musleabihf': 4.21.1 + '@rollup/rollup-linux-arm64-gnu': 4.21.1 + '@rollup/rollup-linux-arm64-musl': 4.21.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.1 + '@rollup/rollup-linux-riscv64-gnu': 4.21.1 + '@rollup/rollup-linux-s390x-gnu': 4.21.1 + '@rollup/rollup-linux-x64-gnu': 4.21.1 + '@rollup/rollup-linux-x64-musl': 4.21.1 + '@rollup/rollup-win32-arm64-msvc': 4.21.1 + '@rollup/rollup-win32-ia32-msvc': 4.21.1 + '@rollup/rollup-win32-x64-msvc': 4.21.1 + fsevents: 2.3.3 + dev: false + /rollup@4.6.1: resolution: {integrity: sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -24016,6 +24607,15 @@ packages: engines: {node: '>=10'} dependencies: node-forge: 1.3.1 + dev: true + + /selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + dependencies: + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 + dev: false /sembear@0.5.2: resolution: {integrity: sha512-Ij1vCAdFgWABd7zTg50Xw1/p0JgESNxuLlneEAsmBrKishA06ulTTL/SHGmNy2Zud7+rKrHTKNI6moJsn1ppAQ==} @@ -24071,7 +24671,7 @@ packages: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 upper-case-first: 2.0.2 dev: true @@ -24167,8 +24767,8 @@ packages: kind-of: 6.0.3 dev: true - /sharp@0.32.5: - resolution: {integrity: sha512-0dap3iysgDkNaPOaOL4X/0akdu0ma62GcdC2NBQ+93eqpePdDdr2/LM0sFdDSMmN7yS+odyZtPsb7tx/cYBKnQ==} + /sharp@0.32.6: + resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} engines: {node: '>=14.15.0'} requiresBuild: true dependencies: @@ -24351,7 +24951,7 @@ packages: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} dependencies: dot-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.7.0 dev: true /sockjs@0.3.24: @@ -24877,7 +25477,7 @@ packages: react: 18.2.0 dev: true - /styled-jsx@5.1.1(@babel/core@7.24.5)(react@18.2.0): + /styled-jsx@5.1.1(@babel/core@7.25.2)(react@18.2.0): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -24890,7 +25490,7 @@ packages: babel-plugin-macros: optional: true dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.25.2 client-only: 0.0.1 react: 18.2.0 dev: true @@ -25441,6 +26041,9 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + /tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + /tsutils@3.21.0(typescript@5.5.3): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -25583,8 +26186,12 @@ packages: resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==} dev: true - /uglify-js@3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + /ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + dev: false + + /uglify-js@3.19.2: + resolution: {integrity: sha512-S8KA6DDI47nQXJSi2ctQ629YzwOVs+bQML6DAtvy0wgNdpi+0ySpQK0g2pxBq2xfF2z3YCscu7NNA8nXT9PlIQ==} engines: {node: '>=0.8.0'} hasBin: true requiresBuild: true @@ -25621,10 +26228,28 @@ packages: '@fastify/busboy': 2.1.1 dev: false + /undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + dependencies: + '@fastify/busboy': 2.1.1 + dev: false + /undici@6.18.1: resolution: {integrity: sha512-/0BWqR8rJNRysS5lqVmfc7eeOErcOP4tZpATVjJOojjHZ71gSYVAtFhEmadcIjwMIUehh5NFyKGsXCnXIajtbA==} engines: {node: '>=18.17'} + /unenv-nightly@1.10.0-1717606461.a117952: + resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} + dependencies: + consola: 3.2.3 + defu: 6.1.4 + mime: 3.0.0 + node-fetch-native: 1.6.4 + pathe: 1.1.2 + ufo: 1.5.4 + dev: false + /unherit@3.0.1: resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==} @@ -25830,16 +26455,27 @@ packages: escalade: 3.1.2 picocolors: 1.0.1 + /update-browserslist-db@1.1.0(browserslist@4.23.3): + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 + dev: true + /upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 dev: true /upper-case@2.0.2: resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} dependencies: - tslib: 2.6.2 + tslib: 2.7.0 dev: true /uri-js@4.4.1: @@ -25921,8 +26557,8 @@ packages: react: 18.2.0 tslib: 2.6.2 - /use-sync-external-store@1.2.0(react@18.2.0): - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + /use-sync-external-store@1.2.2(react@18.2.0): + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: @@ -26201,6 +26837,45 @@ packages: optionalDependencies: fsevents: 2.3.3 + /vite@5.4.2(@types/node@16.11.13): + resolution: {integrity: sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 16.11.13 + esbuild: 0.21.5 + postcss: 8.4.41 + rollup: 4.21.1 + optionalDependencies: + fsevents: 2.3.3 + dev: false + /vitefu@0.2.5(vite@5.0.6): resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} peerDependencies: @@ -26600,29 +27275,46 @@ packages: '@cloudflare/workerd-windows-64': 1.20240304.0 dev: false - /wrangler@3.34.2: - resolution: {integrity: sha512-j580WXlOe0GtYdcREym7FLcaaZq9+RZEBuzOtKXx74KKUlEC8cglgf5WWa2C2OpEtJCcrAieEHsNXe7mhy9knA==} + /workerd@1.20240821.1: + resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} + engines: {node: '>=16'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20240821.1 + '@cloudflare/workerd-darwin-arm64': 1.20240821.1 + '@cloudflare/workerd-linux-64': 1.20240821.1 + '@cloudflare/workerd-linux-arm64': 1.20240821.1 + '@cloudflare/workerd-windows-64': 1.20240821.1 + dev: false + + /wrangler@3.72.2: + resolution: {integrity: sha512-7nxkJ4md+KtESNJ/0DwTM7bHZP+uNRpJT5gMDT9WllP9UVzYdtXCTF+p4CHtxIReUpe6pOi7tb05hK9/Q6WaiA==} engines: {node: '>=16.17.0'} hasBin: true peerDependencies: - '@cloudflare/workers-types': ^4.20230914.0 + '@cloudflare/workers-types': ^4.20240821.1 peerDependenciesMeta: '@cloudflare/workers-types': optional: true dependencies: - '@cloudflare/kv-asset-handler': 0.3.1 + '@cloudflare/kv-asset-handler': 0.3.4 + '@cloudflare/workers-shared': 0.3.0 '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) blake3-wasm: 2.1.5 - chokidar: 3.5.3 + chokidar: 3.6.0 + date-fns: 3.6.0 esbuild: 0.17.19 - miniflare: 3.20240304.2 + miniflare: 3.20240821.0 nanoid: 3.3.7 - path-to-regexp: 6.2.1 + path-to-regexp: 6.2.2 resolve: 1.22.8 resolve.exports: 2.0.2 - selfsigned: 2.1.1 + selfsigned: 2.4.1 source-map: 0.6.1 + unenv: /unenv-nightly@1.10.0-1717606461.a117952 + workerd: 1.20240821.1 xxhash-wasm: 1.0.2 optionalDependencies: fsevents: 2.3.3 @@ -26713,6 +27405,19 @@ packages: utf-8-validate: optional: true + /ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /xdg-app-paths@5.1.0: resolution: {integrity: sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==} engines: {node: '>=6'} @@ -26914,5 +27619,9 @@ packages: /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + /zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + dev: false + /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} From 9e45a3f38983fd07ccfc05f644bf6b4a0f333493 Mon Sep 17 00:00:00 2001 From: jossmac <2730833+jossmac@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:56:46 +1000 Subject: [PATCH 02/12] fix `useLink` instances; pass through all props --- design-system/pkg/src/button/ActionButton.tsx | 23 ++-------------- design-system/pkg/src/button/Button.tsx | 23 ++-------------- .../pkg/src/button/stories/Button.stories.tsx | 3 ++- .../pkg/src/button/useButtonStyles.tsx | 8 +++--- .../pkg/src/link/TextLink/TextLinkAnchor.tsx | 26 +++---------------- .../pkg/src/link/TextLink/useTextLink.ts | 5 ---- 6 files changed, 13 insertions(+), 75 deletions(-) diff --git a/design-system/pkg/src/button/ActionButton.tsx b/design-system/pkg/src/button/ActionButton.tsx index 3660fca18..7150286e5 100644 --- a/design-system/pkg/src/button/ActionButton.tsx +++ b/design-system/pkg/src/button/ActionButton.tsx @@ -60,26 +60,14 @@ const LinkButton = forwardRef(function LinkActionButton( props: ActionLinkElementProps, forwardedRef: ForwardedRef ) { - const { - children, - isDisabled, - // link specific - download, - href, - hrefLang, - ping, - referrerPolicy, - rel, - target, - ...otherProps - } = props; + const { children, isDisabled, ...otherProps } = props; const domRef = useObjectRef(forwardedRef); const { buttonProps, isPressed } = useButton( { elementType: 'a', ...props }, domRef ); - const { linkProps } = useLink(otherProps, domRef); + const { linkProps } = useLink(props, domRef); const { hoverProps, isHovered } = useHover({ isDisabled }); const styleProps = useActionButtonStyles(props, { isHovered, isPressed }); @@ -88,13 +76,6 @@ const LinkButton = forwardRef(function LinkActionButton( {...filterDOMProps(otherProps)} {...mergeProps(buttonProps, linkProps, hoverProps, styleProps)} ref={domRef} - download={download} - href={href} - hrefLang={hrefLang} - ping={ping} - referrerPolicy={referrerPolicy} - rel={rel} - target={target} > {children} diff --git a/design-system/pkg/src/button/Button.tsx b/design-system/pkg/src/button/Button.tsx index 42adbcb62..6b9ce35cd 100644 --- a/design-system/pkg/src/button/Button.tsx +++ b/design-system/pkg/src/button/Button.tsx @@ -61,26 +61,14 @@ const LinkButton = forwardRef(function Button( props: LinkElementProps, forwardedRef: ForwardedRef ) { - const { - children, - isDisabled, - // link specific - download, - href, - hrefLang, - ping, - referrerPolicy, - rel, - target, - ...otherProps - } = props; + const { children, isDisabled, ...otherProps } = props; const domRef = useObjectRef(forwardedRef); const { buttonProps, isPressed } = useButton( { elementType: 'a', ...props }, domRef ); - const { linkProps } = useLink(otherProps, domRef); + const { linkProps } = useLink(props, domRef); const { hoverProps, isHovered } = useHover({ isDisabled }); const styleProps = useButtonStyles(props, { isHovered, isPressed }); @@ -89,13 +77,6 @@ const LinkButton = forwardRef(function Button( {...filterDOMProps(otherProps)} {...mergeProps(buttonProps, linkProps, hoverProps, styleProps)} ref={domRef} - download={download} - href={href} - hrefLang={hrefLang} - ping={ping} - referrerPolicy={referrerPolicy} - rel={rel} - target={target} > {children} diff --git a/design-system/pkg/src/button/stories/Button.stories.tsx b/design-system/pkg/src/button/stories/Button.stories.tsx index a4db48168..e73970eec 100644 --- a/design-system/pkg/src/button/stories/Button.stories.tsx +++ b/design-system/pkg/src/button/stories/Button.stories.tsx @@ -77,8 +77,8 @@ export const StaticLight = () => ( {render('High', { prominence: 'high', static: 'light' })} {render('Default', { prominence: 'default', static: 'light' })} @@ -102,6 +102,7 @@ export const StaticDark = () => ( gap="regular" backgroundColor="accent" padding="large" + UNSAFE_style={{ backgroundColor: '#eee' }} > {render('High', { prominence: 'high', static: 'dark' })} {render('Default', { prominence: 'default', static: 'dark' })} diff --git a/design-system/pkg/src/button/useButtonStyles.tsx b/design-system/pkg/src/button/useButtonStyles.tsx index f58854702..0a13aab07 100644 --- a/design-system/pkg/src/button/useButtonStyles.tsx +++ b/design-system/pkg/src/button/useButtonStyles.tsx @@ -33,7 +33,7 @@ export function useButtonStyles(props: ButtonProps, state: ButtonState) { pending: isPending || undefined, pressed: isPressed || undefined, prominence: prominence === 'default' ? undefined : prominence, - tone: tone === 'neutral' ? undefined : tone, + tone: tone, static: props.static, }), style: styleProps.style, @@ -131,7 +131,7 @@ export function useButtonStyles(props: ButtonProps, state: ButtonState) { }, // states - '&:disabled, &[data-pending=true]': { + '&:disabled, &[aria-disabled=true]': { backgroundColor: tokenSchema.color.alias.backgroundDisabled, color: tokenSchema.color.alias.foregroundDisabled, }, @@ -206,7 +206,7 @@ export function useButtonStyles(props: ButtonProps, state: ButtonState) { }, // tone selector to increase specificity - '&[data-tone]:disabled, &[data-tone][data-pending=true]': { + '&[data-tone]:disabled, &[data-tone][aria-disabled=true]': { backgroundColor: tokenSchema.color.alias.backgroundDisabled, color: tokenSchema.color.alias.foregroundDisabled, }, @@ -277,7 +277,7 @@ export function useButtonStyles(props: ButtonProps, state: ButtonState) { }, }, - '&:disabled, &[data-pending=true]': { + '&:disabled, &[aria-disabled=true]': { backgroundColor: tokenSchema.color.alias.backgroundDisabled, color: tokenSchema.color.alias.foregroundDisabled, }, diff --git a/design-system/pkg/src/link/TextLink/TextLinkAnchor.tsx b/design-system/pkg/src/link/TextLink/TextLinkAnchor.tsx index 9b74f2ecc..215009f14 100644 --- a/design-system/pkg/src/link/TextLink/TextLinkAnchor.tsx +++ b/design-system/pkg/src/link/TextLink/TextLinkAnchor.tsx @@ -10,35 +10,15 @@ export const TextLinkAnchor = forwardRef< HTMLAnchorElement, TextLinkAnchorProps >(function TextLink(props, forwardedRef) { - const { - children, - download, - href, - hrefLang, - ping, - referrerPolicy, - rel, - target, - ...otherProps - } = props; + const { children } = props; const domRef = useObjectRef(forwardedRef); const { Wrapper, ...styleProps } = useTextLink(props); - const { linkProps } = useLink(otherProps, domRef); + const { linkProps } = useLink(props, domRef); return ( - + {children} diff --git a/design-system/pkg/src/link/TextLink/useTextLink.ts b/design-system/pkg/src/link/TextLink/useTextLink.ts index b6246b364..fbf4fcf68 100644 --- a/design-system/pkg/src/link/TextLink/useTextLink.ts +++ b/design-system/pkg/src/link/TextLink/useTextLink.ts @@ -27,10 +27,6 @@ export function useTextLink({ const { focusProps, isFocusVisible } = useFocusRing({ autoFocus }); const { hoverProps, isHovered } = useHover({}); - const fontWeight = headingContext - ? undefined - : tokenSchema.typography.fontWeight.medium; - const dataOptions = { prominence, hover: isHovered ? 'true' : undefined, @@ -45,7 +41,6 @@ export function useTextLink({ css({ color: tokenSchema.color.foreground.neutral, cursor: 'pointer', - fontWeight, outline: 0, textDecoration: 'underline', textDecorationColor: tokenSchema.color.border.emphasis, From 9d7595c02bbcb89d5eea6758d4bb8d2f2d4a67dc Mon Sep 17 00:00:00 2001 From: jossmac <2730833+jossmac@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:27:02 +1000 Subject: [PATCH 03/12] increase checkbox hitarea --- design-system/pkg/src/checkbox/Checkbox.tsx | 7 ++++++- design-system/pkg/src/checkbox/CheckboxGroup.tsx | 8 +------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/design-system/pkg/src/checkbox/Checkbox.tsx b/design-system/pkg/src/checkbox/Checkbox.tsx index a5ba65495..ed0a44ffa 100644 --- a/design-system/pkg/src/checkbox/Checkbox.tsx +++ b/design-system/pkg/src/checkbox/Checkbox.tsx @@ -91,6 +91,8 @@ function CheckboxInner( alignItems: 'flex-start', display: 'inline-flex', gap: tokenSchema.size.space.regular, + paddingInlineEnd: tokenSchema.size.space.large, + paddingBlock: tokenSchema.size.space.regular, position: 'relative', userSelect: 'none', }); @@ -118,6 +120,7 @@ function CheckboxInner( position: 'absolute', zIndex: 1, inset: 0, + insetInlineStart: `calc(${tokenSchema.size.space.regular} * -1)`, opacity: 0.0001, }) )} @@ -159,6 +162,7 @@ const Indicator = (props: IndicatorProps) => { position: 'relative', height: sizeToken, width: sizeToken, + // marginBlock: `calc((${tokenSchema.size.element.regular} - ${tokenSchema.typography.text.regular.size}) / 2)`, // prominence '--selected-idle-bg': tokenSchema.color.scale.indigo9, @@ -265,8 +269,9 @@ const Content = (props: HTMLAttributes) => { css({ color: tokenSchema.color.alias.foregroundIdle, display: 'grid', - paddingTop: `calc((${sizeToken} - ${tokenSchema.typography.text.regular.capheight}) / 2)`, gap: tokenSchema.size.space.large, + // paddingTop: `calc((${tokenSchema.size.element.regular} - ${tokenSchema.typography.text.regular.capheight}) / 2)`, + paddingTop: `calc((${sizeToken} - ${tokenSchema.typography.text.regular.capheight}) / 2)`, 'input[type="checkbox"]:hover ~ &': { color: tokenSchema.color.alias.foregroundHovered, diff --git a/design-system/pkg/src/checkbox/CheckboxGroup.tsx b/design-system/pkg/src/checkbox/CheckboxGroup.tsx index bb92d879a..3538ef85b 100644 --- a/design-system/pkg/src/checkbox/CheckboxGroup.tsx +++ b/design-system/pkg/src/checkbox/CheckboxGroup.tsx @@ -8,12 +8,7 @@ import React, { import { useProviderProps } from '@keystar/ui/core'; import { FieldPrimitive, validateFieldProps } from '@keystar/ui/field'; -import { - classNames, - css, - toDataAttributes, - tokenSchema, -} from '@keystar/ui/style'; +import { classNames, css, toDataAttributes } from '@keystar/ui/style'; import { CheckboxGroupContext } from './context'; import { CheckboxGroupProps } from './types'; @@ -50,7 +45,6 @@ export const CheckboxGroup: ForwardRefExoticComponent = className={classNames( css({ display: 'flex', - gap: tokenSchema.size.space.large, '&[data-orientation="vertical"]': { flexDirection: 'column', From 4aaa8d7c77c856cd69467507323b86dd4d2bfb78 Mon Sep 17 00:00:00 2001 From: jossmac <2730833+jossmac@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:28:07 +1000 Subject: [PATCH 04/12] update dnd types --- .../InsertionIndicatorPrimitive.tsx | 3 +- design-system/pkg/src/drag-and-drop/index.ts | 2 ++ design-system/pkg/src/drag-and-drop/types.ts | 15 ++++++--- .../pkg/src/drag-and-drop/useDragAndDrop.ts | 31 ++++++++++++------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx b/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx index f95332ee5..87d8ba36f 100644 --- a/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx +++ b/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx @@ -44,7 +44,8 @@ export function InsertionIndicatorPrimitive( zIndex: 5, }, }, - }) + }), + otherProps.className )} > {children} diff --git a/design-system/pkg/src/drag-and-drop/index.ts b/design-system/pkg/src/drag-and-drop/index.ts index 5135af667..cfc1d5166 100644 --- a/design-system/pkg/src/drag-and-drop/index.ts +++ b/design-system/pkg/src/drag-and-drop/index.ts @@ -4,6 +4,8 @@ export type { DropZoneProps } from './DropZone'; export { FileTrigger } from './FileTrigger'; export type { FileTriggerProps } from './FileTrigger'; +export { InsertionIndicatorPrimitive } from './InsertionIndicatorPrimitive'; + export { useDragAndDrop } from './useDragAndDrop'; export type { DragAndDropOptions, DragAndDropHooks } from './types'; diff --git a/design-system/pkg/src/drag-and-drop/types.ts b/design-system/pkg/src/drag-and-drop/types.ts index 1660a1262..0efddb4cf 100644 --- a/design-system/pkg/src/drag-and-drop/types.ts +++ b/design-system/pkg/src/drag-and-drop/types.ts @@ -33,7 +33,7 @@ export interface DragHooks { useDraggableCollection?: ( props: DraggableCollectionOptions, state: DraggableCollectionState, - ref: RefObject + ref: RefObject ) => void; useDraggableItem?: ( props: DraggableItemProps, @@ -49,24 +49,27 @@ export interface DropHooks { useDroppableCollection?: ( props: DroppableCollectionOptions, state: DroppableCollectionState, - ref: RefObject + ref: RefObject ) => DroppableCollectionResult; useDroppableItem?: ( options: DroppableItemOptions, state: DroppableCollectionState, - ref: RefObject + ref: RefObject ) => DroppableItemResult; useDropIndicator?: ( props: DropIndicatorProps, state: DroppableCollectionState, - ref: RefObject + ref: RefObject ) => DropIndicatorAria; } export interface DragAndDropHooks { /** Drag and drop hooks for the collection element. */ dragAndDropHooks: DragHooks & - DropHooks & { isVirtualDragging?: () => boolean }; + DropHooks & { + isVirtualDragging?: () => boolean; + renderPreview?: (keys: Set, draggedKey: Key | null) => JSX.Element; + }; } export interface DragAndDropOptions @@ -77,4 +80,6 @@ export interface DragAndDropOptions * @default () => [] */ getItems?: (keys: Set) => DragItem[]; + /** Provide a custom drag preview. `draggedKey` represents the key of the item the user actually dragged. */ + renderPreview?: (keys: Set, draggedKey: Key | null) => JSX.Element; } diff --git a/design-system/pkg/src/drag-and-drop/useDragAndDrop.ts b/design-system/pkg/src/drag-and-drop/useDragAndDrop.ts index 43b76de2d..18ee4a637 100644 --- a/design-system/pkg/src/drag-and-drop/useDragAndDrop.ts +++ b/design-system/pkg/src/drag-and-drop/useDragAndDrop.ts @@ -16,6 +16,7 @@ import { useDraggableCollectionState, useDroppableCollectionState, } from '@react-stately/dnd'; +import type { Key } from '@react-types/shared'; import { RefObject, useMemo } from 'react'; import { @@ -26,14 +27,19 @@ import { } from './types'; /** - * Provides the hooks required to enable drag and drop behavior for a drag and - * drop compatible component. + * Provides the hooks required to enable drag and drop behavior for a drag and drop compatible React Spectrum component. */ -// NOTE: if more components become drag-n-droppable move elsewhere. export function useDragAndDrop(options: DragAndDropOptions): DragAndDropHooks { let dragAndDropHooks = useMemo(() => { - let { onDrop, onInsert, onItemDrop, onReorder, onRootDrop, getItems } = - options; + let { + onDrop, + onInsert, + onItemDrop, + onReorder, + onRootDrop, + getItems, + renderPreview, + } = options; let isDraggable = !!getItems; let isDroppable = !!( @@ -45,7 +51,10 @@ export function useDragAndDrop(options: DragAndDropOptions): DragAndDropHooks { ); let hooks = {} as DragHooks & - DropHooks & { isVirtualDragging?: () => boolean }; + DropHooks & { + isVirtualDragging?: () => boolean; + renderPreview?: (keys: Set, draggedKey: Key) => JSX.Element; + }; if (isDraggable) { // @ts-expect-error hooks.useDraggableCollectionState = @@ -57,21 +66,21 @@ export function useDragAndDrop(options: DragAndDropOptions): DragAndDropHooks { hooks.useDraggableCollection = useDraggableCollection; hooks.useDraggableItem = useDraggableItem; hooks.DragPreview = DragPreview; + hooks.renderPreview = renderPreview; } if (isDroppable) { - // eslint-disable-next-line no-unused-expressions - (hooks.useDroppableCollectionState = + hooks.useDroppableCollectionState = function useDroppableCollectionStateOverride( props: DroppableCollectionStateOptions ) { return useDroppableCollectionState({ ...props, ...options }); - }), - (hooks.useDroppableItem = useDroppableItem); + }; + hooks.useDroppableItem = useDroppableItem; hooks.useDroppableCollection = function useDroppableCollectionOverride( props: DroppableCollectionOptions, state: DroppableCollectionState, - ref: RefObject + ref: RefObject ) { return useDroppableCollection({ ...props, ...options }, state, ref); }; From ebf4881d527a2823ae063af770242f9791e8ebdc Mon Sep 17 00:00:00 2001 From: jossmac <2730833+jossmac@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:28:38 +1000 Subject: [PATCH 05/12] first pass at table updates; - drag-and-drop - resizable columns --- design-system/pkg/src/table/DragPreview.tsx | 53 + .../pkg/src/table/InsertionIndicator.tsx | 68 + design-system/pkg/src/table/Resizer.tsx | 166 ++ design-system/pkg/src/table/TableView.tsx | 1734 ++++++++++++----- .../pkg/src/table/TableViewLayout.tsx | 104 + design-system/pkg/src/table/context.tsx | 82 + design-system/pkg/src/table/l10n.json | 318 ++- .../pkg/src/table/stories/ReorderExample.tsx | 204 ++ .../pkg/src/table/stories/Table.stories.tsx | 126 +- design-system/pkg/src/table/styles.tsx | 594 +++--- design-system/pkg/src/table/types.ts | 47 +- 11 files changed, 2678 insertions(+), 818 deletions(-) create mode 100644 design-system/pkg/src/table/DragPreview.tsx create mode 100644 design-system/pkg/src/table/InsertionIndicator.tsx create mode 100644 design-system/pkg/src/table/Resizer.tsx create mode 100644 design-system/pkg/src/table/TableViewLayout.tsx create mode 100644 design-system/pkg/src/table/context.tsx create mode 100644 design-system/pkg/src/table/stories/ReorderExample.tsx diff --git a/design-system/pkg/src/table/DragPreview.tsx b/design-system/pkg/src/table/DragPreview.tsx new file mode 100644 index 000000000..8a4265a3a --- /dev/null +++ b/design-system/pkg/src/table/DragPreview.tsx @@ -0,0 +1,53 @@ +import { classNames } from '@keystar/ui/style'; +import { Text } from '@keystar/ui/typography'; +import { Flex } from '@keystar/ui/layout'; +import React from 'react'; + +import { + cellClassname, + cellContentsClassname, + rowClassname, + rowDragPreviewClassname, +} from './styles'; + +type DragPreviewProps = { + itemText?: string; // can't guarantee this will be available + itemCount: number; + height: number; + maxWidth?: number; +}; + +export function DragPreview(props: DragPreviewProps) { + let { itemText, itemCount, height, maxWidth } = props; + let isDraggingMultiple = itemCount > 1; + return ( + +
+ {itemText} +
+ + {/* export as `DragPreviewCount` from "@keystar/ui/drag-and-drop" for use here and in the list view */} + {isDraggingMultiple && ( + + + {itemCount} + + + )} +
+ ); +} diff --git a/design-system/pkg/src/table/InsertionIndicator.tsx b/design-system/pkg/src/table/InsertionIndicator.tsx new file mode 100644 index 000000000..51fa3ce38 --- /dev/null +++ b/design-system/pkg/src/table/InsertionIndicator.tsx @@ -0,0 +1,68 @@ +import { useVisuallyHidden } from '@react-aria/visually-hidden'; +import { FocusableElement, ItemDropTarget } from '@react-types/shared'; +import { assert } from 'emery'; +import React, { DOMAttributes, HTMLAttributes, useRef } from 'react'; + +import { InsertionIndicatorPrimitive } from '@keystar/ui/drag-and-drop'; + +import { useTableContext } from './context'; +import { Rect } from '@react-stately/virtualizer'; + +interface InsertionIndicatorProps { + rowProps: HTMLAttributes & DOMAttributes; + target: ItemDropTarget; + visibleRect: Rect; +} + +export function InsertionIndicator(props: InsertionIndicatorProps) { + let { dropState, dragAndDropHooks } = useTableContext(); + const { rowProps, target, visibleRect } = props; + + assert( + !!dragAndDropHooks?.useDropIndicator, + 'dragAndDropHooks.useDropIndicator is not defined.' + ); + + let ref = useRef(null); + let { dropIndicatorProps } = dragAndDropHooks.useDropIndicator( + props, + dropState, + ref + ); + let { visuallyHiddenProps } = useVisuallyHidden(); + + let isDropTarget = dropState.isDropTarget(target); + + if (!isDropTarget && dropIndicatorProps['aria-hidden']) { + return null; + } + + console.log('rowProps', rowProps); + + return ( +
+ +
+ +
+ ); +} diff --git a/design-system/pkg/src/table/Resizer.tsx b/design-system/pkg/src/table/Resizer.tsx new file mode 100644 index 000000000..d06f99d21 --- /dev/null +++ b/design-system/pkg/src/table/Resizer.tsx @@ -0,0 +1,166 @@ +import { FocusRing } from '@react-aria/focus'; +import { useLocale, useLocalizedStringFormatter } from '@react-aria/i18n'; +import { useUNSTABLE_PortalContext } from '@react-aria/overlays'; +import { useTableColumnResize } from '@react-aria/table'; +import { mergeProps, useObjectRef } from '@react-aria/utils'; +import { TableColumnResizeState } from '@react-stately/table'; +import { GridNode } from '@react-types/grid'; +import { Key, RefObject } from '@react-types/shared'; +import { ColumnSize } from '@react-types/table'; +import React, { + createContext, + ForwardedRef, + PropsWithChildren, + useContext, + useEffect, + useState, +} from 'react'; +import ReactDOM from 'react-dom'; + +import { useTableContext, useVirtualizerContext } from './context'; +import localizedMessages from './l10n.json'; +import { + columnResizerClassname, + columnResizerPlaceholderClassname, +} from './styles'; + +interface ResizerProps { + column: GridNode; + showResizer: boolean; + triggerRef: RefObject; + onResizeStart: (widths: Map) => void; + onResize: (widths: Map) => void; + onResizeEnd: (widths: Map) => void; +} + +const CURSORS = { + ew: 'col-resize', + w: 'w-resize', + e: 'e-resize', +}; + +export const ResizeStateContext = + createContext | null>(null); +export function useResizeStateContext() { + const context = useContext(ResizeStateContext); + if (context === null) { + throw new Error('ResizeStateContext not found'); + } + return context; +} + +function Resizer( + props: ResizerProps, + forwardedRef: ForwardedRef +) { + let { column, showResizer } = props; + let { isEmpty, onFocusedResizer } = useTableContext(); + let layout = useContext(ResizeStateContext)!; + // Virtualizer re-renders, but these components are all cached + // in order to get around that and cause a rerender here, we use context + // but we don't actually need any value, they are available on the layout object + useVirtualizerContext(); + let stringFormatter = useLocalizedStringFormatter( + localizedMessages, + '@react-spectrum/table' + ); + let { direction } = useLocale(); + + let [isPointerDown, setIsPointerDown] = useState(false); + useEffect(() => { + let setDown = (e: PointerEvent) => { + if (e.pointerType === 'mouse') { + setIsPointerDown(true); + } + }; + let setUp = (e: PointerEvent) => { + if (e.pointerType === 'mouse') { + setIsPointerDown(false); + } + }; + document.addEventListener('pointerdown', setDown, { capture: true }); + document.addEventListener('pointerup', setUp, { capture: true }); + return () => { + document.removeEventListener('pointerdown', setDown, { capture: true }); + document.removeEventListener('pointerup', setUp, { capture: true }); + }; + }, []); + + let domRef = useObjectRef(forwardedRef); + let { inputProps, resizerProps } = useTableColumnResize( + mergeProps(props, { + 'aria-label': stringFormatter.format('columnResizer'), + isDisabled: isEmpty, + }), + layout, + domRef + ); + + let isEResizable = + layout.getColumnMinWidth(column.key) >= layout.getColumnWidth(column.key); + let isWResizable = + layout.getColumnMaxWidth(column.key) <= layout.getColumnWidth(column.key); + let isResizing = layout.resizingColumn === column.key; + let cursor = ''; + if (isEResizable) { + cursor = direction === 'rtl' ? CURSORS.w : CURSORS.e; + } else if (isWResizable) { + cursor = direction === 'rtl' ? CURSORS.e : CURSORS.w; + } else { + cursor = CURSORS.ew; + } + + let style = { + ...resizerProps.style, + height: '100%', + display: showResizer ? undefined : 'none', + cursor, + }; + + return ( + <> + +
+ +
+
+ {/* Placeholder so that the title doesn't intersect with space reserved by the resizer when it appears. */} +
+ +
+ + + ); +} + +function CursorOverlay(props: PropsWithChildren<{ show: boolean }>) { + let { show, children } = props; + let { getContainer } = useUNSTABLE_PortalContext(); + return show + ? ReactDOM.createPortal(children, getContainer?.() ?? document.body) + : null; +} + +const _Resizer = React.forwardRef(Resizer); +export { _Resizer as Resizer }; diff --git a/design-system/pkg/src/table/TableView.tsx b/design-system/pkg/src/table/TableView.tsx index 8f6e238fa..9c2410e0d 100644 --- a/design-system/pkg/src/table/TableView.tsx +++ b/design-system/pkg/src/table/TableView.tsx @@ -1,22 +1,37 @@ import { - CSSProperties, - ForwardedRef, - HTMLAttributes, - Key, - ReactElement, - ReactNode, - createContext, - forwardRef, + type CSSProperties, + type ForwardedRef, + type HTMLAttributes, + type Key, + type PropsWithChildren, + type ReactElement, + type ReactNode, + type RefObject, + Children, + cloneElement, useCallback, - useContext, + useEffect, useMemo, useRef, useState, } from 'react'; +import { useButton } from '@react-aria/button'; +import { + DraggableItemResult, + DropIndicatorAria, + DroppableCollectionResult, + DroppableItemResult, + DropTarget, +} from '@react-aria/dnd'; import { FocusScope, useFocusRing } from '@react-aria/focus'; import { useLocale, useLocalizedStringFormatter } from '@react-aria/i18n'; -import { useHover, usePress } from '@react-aria/interactions'; +import { + getInteractionModality, + useHover, + usePress, +} from '@react-aria/interactions'; +import { ListKeyboardDelegate } from '@react-aria/selection'; import { useTable, useTableCell, @@ -27,166 +42,313 @@ import { useTableSelectAllCheckbox, useTableSelectionCheckbox, } from '@react-aria/table'; -import { filterDOMProps, mergeProps } from '@react-aria/utils'; +import { + mergeProps, + scrollIntoView, + scrollIntoViewport, + useLoadMore, + useObjectRef, +} from '@react-aria/utils'; import { layoutInfoToStyle, ScrollView, setScrollLeft, - useVirtualizer, VirtualizerItem, + VirtualizerItemOptions, } from '@react-aria/virtualizer'; -import { VisuallyHidden } from '@react-aria/visually-hidden'; -import { TableLayout } from '@react-stately/layout'; +import { useVisuallyHidden, VisuallyHidden } from '@react-aria/visually-hidden'; +import { + DraggableCollectionState, + DroppableCollectionState, +} from '@react-stately/dnd'; import { - TableColumnLayout, TableState, + useTableColumnResizeState, useTableState, } from '@react-stately/table'; -import { ReusableView, useVirtualizerState } from '@react-stately/virtualizer'; +import { + LayoutInfo, + Rect, + ReusableView, + useVirtualizerState, +} from '@react-stately/virtualizer'; import { GridNode } from '@react-types/grid'; -import { ColumnSize } from '@react-types/table'; +import { ColumnSize, TableCollection } from '@react-types/table'; import { Checkbox } from '@keystar/ui/checkbox'; +import { Icon } from '@keystar/ui/icon'; +import { gripVerticalIcon } from '@keystar/ui/icon/icons/gripVerticalIcon'; import { ProgressCircle } from '@keystar/ui/progress'; -import { SlotProvider } from '@keystar/ui/slots'; -import { classNames, css, tokenSchema } from '@keystar/ui/style'; +import { + classNames, + css, + FocusRing, + toDataAttributes, + tokenSchema, + useStyleProps, +} from '@keystar/ui/style'; import { TooltipTrigger, Tooltip } from '@keystar/ui/tooltip'; import { Text } from '@keystar/ui/typography'; import { isReactText } from '@keystar/ui/utils'; +import { + TableContext, + TableRowContext, + useTableContext, + useTableRowContext, + VirtualizerContext, +} from './context'; +import { DragPreview as KeystarDragPreview } from './DragPreview'; +import { InsertionIndicator } from './InsertionIndicator'; import localizedMessages from './l10n.json'; +import { Resizer, ResizeStateContext, useResizeStateContext } from './Resizer'; import { SortIndicator, - tableViewClassList, - useBodyStyleProps, - useCellStyleProps, - useHeadStyleProps, - useHeaderWrapperStyleProps, - useRowHeaderStyleProps, - useRowStyleProps, - useSelectionCellStyleProps, - useTableStyleProps, + bodyClassname, + bodyResizeIndicatorClassname, + cellClassname, + cellContentsClassname, + cellWrapperClassname, + centeredWrapperClassname, + checkboxCellClassname, + columnResizeIndicatorClassname, + dragCellClassname, + headerCellClassname, + headerClassname, + headerWrapperClassname, + rowClassname, + tableClassname, } from './styles'; -import { ColumnProps, TableProps } from './types'; +import { TableViewLayout } from './TableViewLayout'; +import { ColumnProps, TableCosmeticConfig, TableProps } from './types'; +import { SlotProvider } from '../slots'; // Constants -const DEFAULT_HEADER_HEIGHT = 34; -const DEFAULT_HIDE_HEADER_CELL_WIDTH = 34; -const SELECTION_CELL_DEFAULT_WIDTH = 34; +const DEFAULT_HEADER_HEIGHT = 36; +const DEFAULT_HIDE_HEADER_CELL_WIDTH = 36; +const SELECTION_CELL_DEFAULT_WIDTH = 36; +const DRAG_BUTTON_CELL_DEFAULT_WIDTH = 20; const ROW_HEIGHTS = { - compact: 26, - regular: 34, - spacious: 42, + compact: 28, + regular: 36, + spacious: 44, } as const; -// Context - -export interface TableContextValue { - state: TableState; - layout: TableLayout & { state: TableState }; - isEmpty: boolean; -} - -// @ts-ignore FIXME: generics in context? -export const TableContext = createContext>(null); -export function useTableContext() { - return useContext(TableContext); -} +// Main -export const VirtualizerContext = createContext(null); -export function useVirtualizerContext() { - return useContext(VirtualizerContext); -} +export function TableView( + props: TableProps, + forwardedRef: ForwardedRef +) { + let { + density = 'regular', + prominence = 'default', + dragAndDropHooks, + onAction, + onResizeEnd: propsOnResizeEnd, + onResizeStart: propsOnResizeStart, + overflowMode = 'truncate', + } = props; -// Main + let isTableDraggable = !!dragAndDropHooks?.useDraggableCollectionState; + let isTableDroppable = !!dragAndDropHooks?.useDroppableCollectionState; + let dragHooksProvided = useRef(isTableDraggable); + let dropHooksProvided = useRef(isTableDroppable); + let state = useTableState({ + ...props, + showSelectionCheckboxes: true, + showDragButtons: isTableDraggable, + selectionBehavior: 'toggle', + }); -export function TableView(props: TableProps) { + useEffect(() => { + if (dragHooksProvided.current !== isTableDraggable) { + console.warn( + 'Drag hooks were provided during one render, but not another. This should be avoided as it may produce unexpected behavior.' + ); + } + if (dropHooksProvided.current !== isTableDroppable) { + console.warn( + 'Drop hooks were provided during one render, but not another. This should be avoided as it may produce unexpected behavior.' + ); + } + if ('expandedKeys' in state && (isTableDraggable || isTableDroppable)) { + console.warn( + 'Drag and drop is not yet fully supported with expandable rows and may produce unexpected results.' + ); + } + }, [isTableDraggable, isTableDroppable, state]); + + // Starts when the user selects resize from the menu, ends when resizing ends + // used to control the visibility of the resizer Nubbin + let [isInResizeMode, setIsInResizeMode] = useState(false); + // Starts when the resizer is actually moved + // entering resizing/exiting resizing doesn't trigger a render + // with table layout, so we need to track it here + let [, setIsResizing] = useState(false); + + // TODO: support consumer provided ref + // let domRef = useObjectRef(forwardedRef); let domRef = useRef(null); let headerRef = useRef(null); let bodyRef = useRef(null); - let { direction } = useLocale(); - let stringFormatter = useLocalizedStringFormatter(localizedMessages); + let styleProps = useStyleProps(props); + + let layout = useMemo( + () => + new TableViewLayout({ + // If props.overflowMode is wrap, then use estimated heights based on scale, otherwise use fixed heights. + rowHeight: + props.overflowMode === 'wrap' ? undefined : ROW_HEIGHTS[density], + estimatedRowHeight: + props.overflowMode === 'wrap' ? ROW_HEIGHTS[density] : undefined, + headingHeight: + props.overflowMode === 'wrap' ? undefined : DEFAULT_HEADER_HEIGHT, + estimatedHeadingHeight: + props.overflowMode === 'wrap' ? DEFAULT_HEADER_HEIGHT : undefined, + }), + // don't recompute when state.collection changes, only used for initial value + // eslint-disable-next-line react-hooks/exhaustive-deps + [props.overflowMode, density] + ); + + let dragState: DraggableCollectionState | undefined = undefined; + let preview = useRef(null); + if ( + dragAndDropHooks?.useDraggableCollection && + dragAndDropHooks?.useDraggableCollectionState + ) { + dragState = dragAndDropHooks.useDraggableCollectionState({ + collection: state.collection, + selectionManager: state.selectionManager, + preview, + }); + dragAndDropHooks.useDraggableCollection({}, dragState, domRef); + } + + let DragPreview = dragAndDropHooks?.DragPreview; + let dropState: DroppableCollectionState | undefined = undefined; + let droppableCollection: DroppableCollectionResult | undefined = undefined; + let isRootDropTarget = false; + if ( + dragAndDropHooks?.useDroppableCollection && + dragAndDropHooks?.useDroppableCollectionState + ) { + dropState = dragAndDropHooks.useDroppableCollectionState({ + collection: state.collection, + selectionManager: state.selectionManager, + }); + droppableCollection = dragAndDropHooks.useDroppableCollection( + { + keyboardDelegate: new ListKeyboardDelegate({ + collection: state.collection, + disabledKeys: state.selectionManager.disabledKeys, + ref: domRef, + layoutDelegate: layout, + }), + dropTargetDelegate: layout, + }, + dropState, + domRef + ); - let { density = 'regular', overflowMode } = props; + isRootDropTarget = dropState.isDropTarget({ type: 'root' }); + } - // Renderers + let { gridProps } = useTable( + { + ...props, + isVirtualized: true, + layoutDelegate: layout, + onRowAction: onAction ?? props.onRowAction, + scrollRef: bodyRef, + }, + state, + domRef + ); + let [headerMenuOpen, setHeaderMenuOpen] = useState(false); + let [headerRowHovered, setHeaderRowHovered] = useState(false); // This overrides collection view's renderWrapper to support DOM hierarchy. - type View = ReusableView, ReactNode>; - let renderWrapper = ( - parent: View, - reusableView: View, - children: View[], - renderChildren: (views: View[]) => ReactElement[] - ) => { - let style = layoutInfoToStyle( - reusableView.layoutInfo!, - direction, - parent && parent.layoutInfo - ); - if (style.overflow === 'hidden') { - style.overflow = 'visible'; // needed to support position: sticky - } + let renderWrapper = useCallback( + ( + parent: View, + reusableView: View, + children: View[], + renderChildren: (views: View[]) => ReactElement[] + ) => { + if (reusableView.viewType === 'rowgroup') { + return ( + + {renderChildren(children)} + + ); + } - if (reusableView.viewType === 'rowgroup') { - return ( - - {renderChildren(children)} - - ); - } + if (reusableView.viewType === 'header') { + return ( + + {renderChildren(children)} + + ); + } - if (reusableView.viewType === 'header') { - return ( - - {renderChildren(children)} - - ); - } + if (reusableView.viewType === 'row') { + return ( + + {renderChildren(children)} + + ); + } - if (reusableView.viewType === 'row') { - return ( - - {renderChildren(children)} - - ); - } + if (reusableView.viewType === 'headerrow') { + return ( + + {renderChildren(children)} + + ); + } - if (reusableView.viewType === 'headerrow') { return ( - - {renderChildren(children)} - + {reusableView.rendered} + ); - } - - return ( - - {reusableView.rendered} - - ); - }; + }, + [] + ); - let renderView = (type: string, item: GridNode) => { + let renderView = useCallback((type: string, item: GridNode) => { switch (type) { case 'header': case 'rowgroup': @@ -199,14 +361,20 @@ export function TableView(props: TableProps) { return ; } - return ; + if (item.props.isDragButtonCell) { + return ; + } + + return ; } case 'placeholder': return (
1 ? item.colspan : undefined} + aria-colindex={item.index && item.index + 1} + aria-colspan={ + item.colspan && item.colspan > 1 ? item.colspan : undefined + } /> ); case 'column': @@ -214,6 +382,11 @@ export function TableView(props: TableProps) { return ; } + if (item.props.isDragButtonCell) { + return ; + } + + // TODO: consider this case, what if we have hidden headers and a empty table if (item.props.hideHeader) { return ( @@ -223,460 +396,1077 @@ export function TableView(props: TableProps) { ); } + // NOTE: don't allow resizing on the last column, it creates a weird UX + // where the combined column width can be less than the table + if (item.props.allowsResizing && !!item.nextKey) { + return ; + } + return ; case 'loader': - return ( - - 0 - ? stringFormatter.format('loadingMore') - : stringFormatter.format('loading') - } - /> - - ); + return ; case 'empty': { - let emptyState = props.renderEmptyState - ? props.renderEmptyState() - : null; - if (emptyState == null) { - return null; - } - - return {emptyState}; + return ; } } - }; + }, []); + + let [isVerticalScrollbarVisible, setVerticalScollbarVisible] = + useState(false); + let [isHorizontalScrollbarVisible, setHorizontalScollbarVisible] = + useState(false); + let viewport = useRef({ x: 0, y: 0, width: 0, height: 0 }); + let onVisibleRectChange = useCallback((rect: Rect) => { + if ( + viewport.current.width === rect.width && + viewport.current.height === rect.height + ) { + return; + } + viewport.current = rect; + if (bodyRef.current) { + setVerticalScollbarVisible( + bodyRef.current.clientWidth + 2 < bodyRef.current.offsetWidth + ); + setHorizontalScollbarVisible( + bodyRef.current.clientHeight + 2 < bodyRef.current.offsetHeight + ); + } + }, []); + let { isFocusVisible, focusProps } = useFocusRing(); + let isEmpty = state.collection.size === 0; - let state = useTableState({ - ...props, - showSelectionCheckboxes: props.selectionMode === 'multiple', - }); + let onFocusedResizer = () => { + if (bodyRef.current && headerRef.current) { + bodyRef.current.scrollLeft = headerRef.current.scrollLeft; + } + }; - const getDefaultWidth = useCallback( - ({ - props: { hideHeader, isSelectionCell }, - }: GridNode): ColumnSize | null | undefined => { - if (hideHeader) { - return DEFAULT_HIDE_HEADER_CELL_WIDTH; - } else if (isSelectionCell) { - return SELECTION_CELL_DEFAULT_WIDTH; - } + let onResizeStart = useCallback( + (widths: Map) => { + setIsResizing(true); + propsOnResizeStart?.(widths); }, - [] + [setIsResizing, propsOnResizeStart] ); - const getDefaultMinWidth = useCallback( - ({ - props: { hideHeader, isSelectionCell }, - }: GridNode): ColumnSize | null | undefined => { - if (hideHeader) { - return DEFAULT_HIDE_HEADER_CELL_WIDTH; - } else if (isSelectionCell) { - return SELECTION_CELL_DEFAULT_WIDTH; - } - - return 75; + let onResizeEnd = useCallback( + (widths: Map) => { + setIsInResizeMode(false); + setIsResizing(false); + propsOnResizeEnd?.(widths); }, - [] - ); - let columnLayout = useMemo( - () => - new TableColumnLayout({ - getDefaultWidth, - getDefaultMinWidth, - }), - [getDefaultWidth, getDefaultMinWidth] + [propsOnResizeEnd, setIsInResizeMode, setIsResizing] ); - const [initialCollection] = useState(state.collection); - - let tableLayout = useMemo( - () => - new TableLayout({ - // If props.rowHeight is auto, then use estimated heights, otherwise use fixed heights. - rowHeight: overflowMode === 'wrap' ? undefined : ROW_HEIGHTS[density], - estimatedRowHeight: - overflowMode === 'wrap' ? ROW_HEIGHTS[density] : undefined, - headingHeight: - overflowMode === 'wrap' ? undefined : DEFAULT_HEADER_HEIGHT, - estimatedHeadingHeight: - overflowMode === 'wrap' ? DEFAULT_HEADER_HEIGHT : undefined, - columnLayout, - initialCollection, - }), - [overflowMode, density, columnLayout, initialCollection] - ); + let focusedKey = state.selectionManager.focusedKey; + let dropTargetKey: Key | null = null; + if (dropState?.target?.type === 'item') { + dropTargetKey = dropState.target.key; + if ( + dropState.target.dropPosition === 'before' && + dropTargetKey !== state.collection.getFirstKey() + ) { + // Normalize to the "after" drop position since we only render those in the DOM. + // The exception to this is for the first row in the table, where we also render the "before" position. + dropTargetKey = state.collection.getKeyBefore(dropTargetKey); + } + } - // Use a proxy so that a new object is created for each render so that alternate instances aren't affected by mutation. - // This can be thought of as equivalent to `{…tableLayout, tableState: state}`, but works with classes as well. - let layout = useMemo(() => { - let proxy = new Proxy(tableLayout, { - get(target, prop, receiver) { - return prop === 'tableState' - ? state - : Reflect.get(target, prop, receiver); - }, - }); - return proxy as TableLayout & { state: TableState }; - }, [state, tableLayout]); + let persistedKeys = useMemo(() => { + return new Set([focusedKey, dropTargetKey].filter(k => k !== null)); + }, [focusedKey, dropTargetKey]); - let { gridProps } = useTable( - { ...props, isVirtualized: true, layout }, - state, - domRef + let mergedProps = mergeProps( + isTableDroppable ? droppableCollection?.collectionProps : {}, + gridProps, + focusProps ); - - const isEmpty = state.collection.size === 0; + if (dragAndDropHooks?.isVirtualDragging?.()) { + delete mergedProps.tabIndex; + } + let cosmeticConfig = { + density, + overflowMode, + prominence, + }; return ( - + + {DragPreview && isTableDraggable && ( + + {() => { + if (dragAndDropHooks?.renderPreview && dragState?.draggingKeys) { + return dragAndDropHooks.renderPreview( + dragState.draggingKeys, + dragState.draggedKey + ); + } + let itemCount = dragState?.draggingKeys.size ?? 0; + let maxWidth = bodyRef?.current?.getBoundingClientRect().width; + let height = ROW_HEIGHTS[density]; + let itemText = state.collection.getTextValue?.( + dragState?.draggedKey! + ); + return ( + + ); + }} + + )} ); } -type View = ReusableView, ReactNode>; -type TableVirtualizerProps = TableProps & { - collection: TableState['collection']; - layout: TableLayout & { state: TableState }; - domRef: React.RefObject; - headerRef: React.RefObject; - bodyRef: React.RefObject; - renderView: ( - type: string, - item: GridNode - ) => ReactElement | null | undefined; - renderWrapper: ( - parent: View, - reusableView: View, - children: View[], - renderChildren: (views: View[]) => ReactElement[] +type View = ReusableView, ReactNode>; +interface TableVirtualizerProps extends HTMLAttributes { + cosmeticConfig: TableCosmeticConfig; + tableState: TableState; + layout: TableViewLayout; + collection: TableCollection; + persistedKeys: Set | null; + renderView: (type: string, content: GridNode) => ReactElement; + renderWrapper?: ( + parent: View | null, + reusableView: View, + children: View[], + renderChildren: (views: View[]) => ReactElement[] ) => ReactElement; -}; + domRef: RefObject; + bodyRef: RefObject; + headerRef: RefObject; + onVisibleRectChange: (rect: Rect) => void; + isFocusVisible: boolean; + isVirtualDragging: boolean; + isRootDropTarget: boolean; +} -function TableVirtualizer(props: TableVirtualizerProps) { +function TableVirtualizer(props: TableVirtualizerProps) { let { + cosmeticConfig, + tableState, layout, collection, - // focusedKey, + persistedKeys, renderView, renderWrapper, domRef, bodyRef, headerRef, - disallowEmptySelection: UNUSED_disallowEmptySelection, - onRowAction: UNUSED_onRowAction, - onSelectionChange: UNUSED_onSelectionChange, - onSortChange: UNUSED_onSortChange, - overflowMode: UNUSED_overflowMode, - renderEmptyState: UNUSED_renderEmptyState, - selectedKeys: UNUSED_selectedKeys, - sortDescriptor: UNUSED_sortDescriptor, - selectionMode, + onVisibleRectChange: onVisibleRectChangeProp, + isFocusVisible, + isVirtualDragging, + isRootDropTarget, ...otherProps } = props; - let { direction } = useLocale(); let loadingState = collection.body.props.loadingState; let isLoading = loadingState === 'loading' || loadingState === 'loadingMore'; let onLoadMore = collection.body.props.onLoadMore; + let [tableWidth, setTableWidth] = useState(0); + + const slots = useMemo(() => { + return { text: { truncate: cosmeticConfig.overflowMode === 'truncate' } }; + }, [cosmeticConfig.overflowMode]); + + const getDefaultWidth = useCallback( + ({ + props: { hideHeader, isSelectionCell, showDivider, isDragButtonCell }, + }: GridNode): ColumnSize | null | undefined => { + if (hideHeader) { + let width = DEFAULT_HIDE_HEADER_CELL_WIDTH; + return showDivider ? width + 1 : width; + } else if (isSelectionCell) { + return SELECTION_CELL_DEFAULT_WIDTH; + } else if (isDragButtonCell) { + return DRAG_BUTTON_CELL_DEFAULT_WIDTH; + } + }, + [] + ); + + const getDefaultMinWidth = useCallback( + ({ + props: { hideHeader, isSelectionCell, showDivider, isDragButtonCell }, + }: GridNode): ColumnSize | null | undefined => { + if (hideHeader) { + let width = DEFAULT_HIDE_HEADER_CELL_WIDTH; + return showDivider ? width + 1 : width; + } else if (isSelectionCell) { + return SELECTION_CELL_DEFAULT_WIDTH; + } else if (isDragButtonCell) { + return DRAG_BUTTON_CELL_DEFAULT_WIDTH; + } + return 75; + }, + [] + ); + + let columnResizeState = useTableColumnResizeState( + { + tableWidth, + getDefaultWidth, + getDefaultMinWidth, + }, + tableState + ); - let virtualizerState = useVirtualizerState({ + let state = useVirtualizerState, ReactNode>({ layout, collection, renderView, - renderWrapper, onVisibleRectChange(rect) { - let bodyEl = bodyRef.current; - if (bodyEl) { - bodyEl.scrollTop = rect.y; - setScrollLeft(bodyEl, direction, rect.x); + if (bodyRef.current) { + bodyRef.current.scrollTop = rect.y; + setScrollLeft(bodyRef.current, direction, rect.x); } }, + persistedKeys, + layoutOptions: useMemo( + () => ({ + columnWidths: columnResizeState.columnWidths, + }), + [columnResizeState.columnWidths] + ), }); - let styleProps = useTableStyleProps(props); + + useLoadMore({ isLoading, onLoadMore, scrollOffset: 1 }, bodyRef); + let onVisibleRectChange = useCallback( + (rect: Rect) => { + state.setVisibleRect(rect); + }, + [state] + ); + + let onVisibleRectChangeMemo = useCallback( + (rect: Rect) => { + setTableWidth(rect.width); + onVisibleRectChange(rect); + onVisibleRectChangeProp(rect); + }, + [onVisibleRectChange, onVisibleRectChangeProp] + ); + + // this effect runs whenever the contentSize changes, it doesn't matter what the content size is + // only that it changes in a resize, and when that happens, we want to sync the body to the + // header scroll position + useEffect(() => { + if ( + getInteractionModality() === 'keyboard' && + bodyRef.current && + domRef.current && + headerRef.current && + headerRef.current.contains(document.activeElement) && + document.activeElement instanceof HTMLElement + ) { + scrollIntoView(headerRef.current, document.activeElement); + scrollIntoViewport(document.activeElement, { + containingElement: domRef.current, + }); + bodyRef.current.scrollLeft = headerRef.current.scrollLeft; + } + }, [state.contentSize, headerRef, bodyRef, domRef]); + + let headerHeight = layout.getLayoutInfo('header')?.rect.height || 0; // Sync the scroll position from the table body to the header container. - let syncScroll = useCallback(() => { - let bodyEl = bodyRef.current; - let headerEl = headerRef.current; - if (bodyEl && headerEl) { - headerEl.scrollLeft = bodyEl.scrollLeft; + let onScroll = useCallback(() => { + if (bodyRef.current && headerRef.current) { + headerRef.current.scrollLeft = bodyRef.current.scrollLeft; } }, [bodyRef, headerRef]); - let scrollToItem = useCallback( - (key: Key) => { - let item = collection.getItem(key); - let column = collection.columns[0]; - let virtualizer = virtualizerState.virtualizer; - - virtualizer.scrollToItem(key, { - duration: 0, - // Prevent scrolling to the top when clicking on column headers. - shouldScrollY: item?.type !== 'column', - // Offset scroll position by width of selection cell - // (which is sticky and will overlap the cell we're scrolling to). - offsetX: - column.props.isSelectionCell || column.props.isDragButtonCell - ? layout.getColumnWidth(column.key) - : 0, - }); - - // Sync the scroll positions of the column headers and the body so scrollIntoViewport can - // properly decide if the column is outside the viewport or not - syncScroll(); - }, - [collection, layout, syncScroll, virtualizerState.virtualizer] - ); - let memoedVirtualizerProps = useMemo( + let resizerPosition = + columnResizeState.resizingColumn != null + ? layout.getLayoutInfo(columnResizeState.resizingColumn).rect.maxX - 2 + : 0; + + // minimize re-render caused on Resizers by memoing this + let resizingColumnWidth = + columnResizeState.resizingColumn != null + ? columnResizeState.getColumnWidth(columnResizeState.resizingColumn) + : 0; + let resizingColumn = useMemo( () => ({ - scrollToItem, - isLoading, - onLoadMore, + width: resizingColumnWidth, + key: columnResizeState.resizingColumn, }), - [scrollToItem, isLoading, onLoadMore] - ); - let { virtualizerProps, scrollViewProps } = useVirtualizer( - memoedVirtualizerProps, - virtualizerState, - domRef + [resizingColumnWidth, columnResizeState.resizingColumn] ); - let mergedProps = mergeProps(filterDOMProps(otherProps), virtualizerProps); + if (isVirtualDragging) { + delete otherProps.tabIndex; + } - const [headerView, bodyView] = virtualizerState.visibleViews; - let headerHeight = layout.getLayoutInfo('header')?.rect.height || 0; + let firstColumn = collection.columns[0]; + let scrollPadding = 0; + if (firstColumn.props.isSelectionCell || firstColumn.props.isDragButtonCell) { + scrollPadding = columnResizeState.getColumnWidth(firstColumn.key); + } - let bodyStyleProps = useBodyStyleProps({ style: { flex: 1 } }); + // @ts-expect-error `renderWrapper` will be defined + let visibleViews = renderChildren(null, state.visibleViews, renderWrapper); return ( - -
- - {headerView} - - - {bodyView} - -
-
+ + +
+
+ + {visibleViews[0]} + +
+ + + {visibleViews[1]} +
+ + +
+ + ); } // Styled components // ------------------------------ -function TableHead({ children, style }: HTMLAttributes) { +type PropsWithLayoutInfos = { + layoutInfo: LayoutInfo; + parent: LayoutInfo | null; +} & HTMLAttributes; + +function renderChildren( + parent: View | null, + views: View[], + renderWrapper: NonNullable['renderWrapper']> +): ReactElement[] { + return views.map(view => { + return renderWrapper( + parent, + view, + view.children ? Array.from(view.children) : [], + childViews => renderChildren(view, childViews, renderWrapper) + ); + }); +} + +function useStyle(layoutInfo: LayoutInfo, parent: LayoutInfo | null) { + let { direction } = useLocale(); + let style = layoutInfoToStyle(layoutInfo, direction, parent); + if (style.overflow === 'hidden') { + style.overflow = 'visible'; // needed to support position: sticky + } + return style; +} + +function TableHead({ + children, + layoutInfo, + parent, + ...otherProps +}: PropsWithLayoutInfos) { let { rowGroupProps } = useTableRowGroup(); - let styleProps = useHeadStyleProps({ style }); + let style = useStyle(layoutInfo, parent); return ( -
+
{children}
); } -function TableBody(props: HTMLAttributes) { - let { rowGroupProps } = useTableRowGroup(); - return
; +function TableDragHeaderCell(props: { column: GridNode }) { + let { column } = props; + let ref = useRef(null); + let { state } = useTableContext(); + let { columnHeaderProps } = useTableColumnHeader( + { + node: column, + isVirtualized: true, + }, + state, + ref + ); + let stringFormatter = useLocalizedStringFormatter(localizedMessages); + + return ( + +
+ {stringFormatter.format('drag')} +
+
+ ); } -const TableHeaderWrapper = forwardRef(function TableHeaderWrapper( - props: { - children: ReactNode; - style: CSSProperties; - }, - ref: ForwardedRef -) { - let styleProps = useHeaderWrapperStyleProps(props); +function TableBody({ + children, + layoutInfo, + parent, + ...otherProps +}: PropsWithLayoutInfos) { + let { rowGroupProps } = useTableRowGroup(); + let style = useStyle(layoutInfo, parent); return ( -
- {props.children} +
+ {children}
); -}); +} function TableHeaderRow(props: { children: ReactNode; + onHoverChange: (hovered: boolean) => void; item: any; style: CSSProperties; }) { let ref = useRef(null); let { state } = useTableContext(); + let { hoverProps } = useHover(props); let { rowProps } = useTableHeaderRow( { node: props.item, isVirtualized: true }, state, ref ); - let styleProps = useRowHeaderStyleProps(props); + // let styleProps = useRowHeaderStyleProps(props); return ( -
+
{props.children}
); } -function TableColumnHeader({ column }: { column: any }) { +function TableColumnHeader(props: { column: GridNode }) { + let { column } = props; + let columnProps = column.props as ColumnProps; + let ref = useRef(null); - let { state } = useTableContext(); + let { cosmeticConfig, isEmpty, state } = useTableContext(); let { columnHeaderProps } = useTableColumnHeader( { node: column, isVirtualized: true }, state, ref ); - let { isFocusVisible, focusProps } = useFocusRing(); - let columnProps = column.props as ColumnProps; - let cellStyleProps = useCellStyleProps(columnProps, { isFocusVisible }); + let { hoverProps, isHovered } = useHover({ + ...props, + isDisabled: isEmpty || !columnProps.allowsSorting, + }); + let slots = useMemo(() => { + return { + text: { color: 'inherit', weight: 'medium', truncate: true }, + } as const; + }, []); return ( -
- {columnProps.allowsSorting && columnProps.align === 'end' && ( - - )} + +
+ + {columnProps.hideHeader ? ( + {column.rendered} + ) : isReactText(column.rendered) ? ( + {column.rendered} + ) : ( + column.rendered + )} + + + {columnProps.allowsSorting && } +
+
+ ); +} - {columnProps.hideHeader ? ( - {column.rendered} - ) : isReactText(column.rendered) ? ( - - {column.rendered} - - ) : ( - column.rendered - )} +function ResizableTableColumnHeader(props: { column: GridNode }) { + let { column } = props; + let ref = useRef(null); + let triggerRef = useRef(null); + let resizingRef = useRef(null); + let { + state, + onResizeStart, + onResize, + onResizeEnd, + headerRowHovered, + isEmpty, + } = useTableContext(); + let columnResizeState = useResizeStateContext(); + let { pressProps, isPressed } = usePress({ isDisabled: isEmpty }); + let { columnHeaderProps } = useTableColumnHeader( + { + node: column, + isVirtualized: true, + }, + state, + ref + ); + let { hoverProps, isHovered } = useHover({ ...props, isDisabled: isEmpty }); + let slots = useMemo(() => { + return { + text: { color: 'inherit', weight: 'medium', truncate: true }, + } as const; + }, []); + + let resizingColumn = columnResizeState.resizingColumn; + let showResizer = + !isEmpty && + ((headerRowHovered && getInteractionModality() !== 'keyboard') || + resizingColumn != null); + let alignment = 'start'; + if ( + column.props.align === 'center' || + (column.colspan && column.colspan > 1) + ) { + alignment = 'center'; + } else if (column.props.align === 'end') { + alignment = 'end'; + } - {columnProps.allowsSorting && columnProps.align !== 'end' && ( - - )} -
+ return ( + +
+ + {column.props.hideHeader ? ( + {column.rendered} + ) : isReactText(column.rendered) ? ( + {column.rendered} + ) : ( + column.rendered + )} + + + {/* TODO: consider grid layout/areas on the parent to position the sort indicator */} + {column.props.allowsSorting && } + +
+
+ ); } -function TableRow({ - children, - hasAction, - item, - style, -}: { - children: ReactNode; - hasAction: boolean; - item: any; - style: CSSProperties; -}) { - let ref = useRef(null); - let { state } = useTableContext(); - let allowsInteraction = - state.selectionManager.selectionMode !== 'none' || hasAction; - let isDisabled = !allowsInteraction || state.disabledKeys.has(item.key); - - let { rowProps } = useTableRow( - { node: item, isVirtualized: true }, +function TableRow(props: PropsWithLayoutInfos & { item: GridNode }) { + let { item, children, layoutInfo, parent, ...otherProps } = props; + let ref = useRef(null); + let { + state, + layout, + dragAndDropHooks, + isTableDraggable, + isTableDroppable, + dragState, + dropState, + } = useTableContext(); + let { rowProps, hasAction, allowsSelection } = useTableRow( + { + node: item, + isVirtualized: true, + shouldSelectOnPressUp: isTableDraggable, + }, state, ref ); + + let isSelected = state.selectionManager.isSelected(item.key); + let isDisabled = state.selectionManager.isDisabled(item.key); + let isInteractive = + !isDisabled && (hasAction || allowsSelection || isTableDraggable); + let isDroppable = isTableDroppable && !isDisabled; + let { pressProps, isPressed } = usePress({ isDisabled: !isInteractive }); + // The row should show the focus background style when any cell inside it is focused. // If the row itself is focused, then it should have a blue focus indicator on the left. - let { isFocusVisible: isFocusWithin, focusProps: focusWithinProps } = + let { isFocusVisible: isFocusVisibleWithin, focusProps: focusWithinProps } = useFocusRing({ within: true }); let { isFocusVisible, focusProps } = useFocusRing(); - let { hoverProps, isHovered } = useHover({ isDisabled }); - let { pressProps, isPressed } = usePress({ isDisabled }); - let styleProps = useRowStyleProps( - { style }, - { - isFocusVisible, - isFocusWithin, - isHovered, - isPressed, + let { hoverProps, isHovered } = useHover({ isDisabled: !isInteractive }); + let isFirstRow = + state.collection.rows.find(row => row.level === 1)?.key === item.key; + let isLastRow = item.nextKey == null; + // Figure out if the TableView content is equal or greater in height to the container. If so, we'll need to round the bottom + // border corners of the last row when selected. + let isFlushWithContainerBottom = false; + if (isLastRow) { + if ( + layout.getContentSize()?.height >= layout.virtualizer?.visibleRect.height + ) { + isFlushWithContainerBottom = true; } + } + + let draggableItem: DraggableItemResult | null = null; + if (isTableDraggable && dragAndDropHooks?.useDraggableItem) { + // eslint-disable-next-line react-hooks/rules-of-hooks + draggableItem = dragAndDropHooks.useDraggableItem( + { key: item.key, hasDragButton: true }, + dragState + ); + if (isDisabled) { + draggableItem = null; + } + } + let droppableItem: DroppableItemResult | null = null; + let isDropTarget: boolean = false; + let dropIndicator: DropIndicatorAria | null = null; + let dropIndicatorRef = useRef(null); + if ( + isTableDroppable && + dragAndDropHooks?.useDropIndicator && + dragAndDropHooks?.useDroppableItem + ) { + let target = { + type: 'item', + key: item.key, + dropPosition: 'on', + } as DropTarget; + isDropTarget = dropState.isDropTarget(target); + droppableItem = dragAndDropHooks.useDroppableItem( + { target }, + dropState, + dropIndicatorRef + ); + dropIndicator = dragAndDropHooks.useDropIndicator( + { target }, + dropState, + dropIndicatorRef + ); + } + + let dragButtonRef = useRef(null); + let { buttonProps: dragButtonProps } = useButton( + { + ...draggableItem?.dragButtonProps, + elementType: 'div', + }, + dragButtonRef + ); + + let style = useStyle(layoutInfo, parent); + + let mergedRowProps = mergeProps( + rowProps, + otherProps, + { style }, + focusWithinProps, + focusProps, + hoverProps, + pressProps, + draggableItem?.dragProps ); + // Remove tab index from list row if performing a screenreader drag. This + // prevents TalkBack from focusing the row, allowing for single swipe + // navigation between row drop indicator + if (dragAndDropHooks?.isVirtualDragging?.()) { + delete mergedRowProps.tabIndex; + } + + let dropProps = isDroppable + ? droppableItem?.dropProps + : { 'aria-hidden': droppableItem?.dropProps['aria-hidden'] }; + let { visuallyHiddenProps } = useVisuallyHidden(); return ( -
- {children} -
+ {isTableDroppable && isFirstRow && ( + + )} + {isTableDroppable && !dropIndicator?.isHidden && ( +
+
+
+
+
+ )} +
+ {children} +
+ {isTableDroppable && ( + + )} + ); } -function TableCell({ - cell, - overflowMode, -}: { - cell: any; - overflowMode: TableProps['overflowMode']; -}) { +function TableDragCell(props: { cell: GridNode }) { + let { cell } = props; let ref = useRef(null); - let { state } = useTableContext(); + let { cosmeticConfig, state, isTableDraggable } = useTableContext(); + let isDisabled = + cell.parentKey && state.selectionManager.isDisabled(cell.parentKey); let { gridCellProps } = useTableCell( - { node: cell, isVirtualized: true }, + { + node: cell, + isVirtualized: true, + }, state, ref ); - let { isFocusVisible, focusProps } = useFocusRing(); - let styleProps = useCellStyleProps(cell.column.props, { isFocusVisible }); return ( -
- - {isReactText(cell.rendered) ? ( - {cell.rendered} - ) : ( - cell.rendered + +
-
+ ref={ref} + className={classNames(cellClassname, dragCellClassname)} + > + {isTableDraggable && !isDisabled && } +
+ + ); +} + +function DragButton() { + let { dragButtonProps, dragButtonRef, isFocusVisibleWithin, isHovered } = + useTableRowContext(); + let { visuallyHiddenProps } = useVisuallyHidden(); + return ( + +
)} + className={css({ + borderRadius: tokenSchema.size.radius.xsmall, + display: 'flex', + justifyContent: 'center', + outline: 0, + padding: 0, + height: tokenSchema.size.icon.regular, + width: 10, // magic number specific to this icon. minimizing space taken by drag handle + + '&[data-focus=visible]': { + outline: `${tokenSchema.size.alias.focusRing} solid ${tokenSchema.color.alias.focusRing}`, + }, + })} + style={ + !isFocusVisibleWithin && !isHovered ? visuallyHiddenProps.style : {} + } + ref={dragButtonRef} + draggable="true" + > + +
+
+ ); +} + +function TableCell({ cell }: { cell: GridNode }) { + let { cosmeticConfig, state } = useTableContext(); + let ref = useRef(null); + let { gridCellProps } = useTableCell( + { + node: cell, + isVirtualized: true, + }, + state, + ref + ); + let { id, ...otherGridCellProps } = gridCellProps; + + return ( + +
+ + {isReactText(cell.rendered) ? ( + {cell.rendered} + ) : ( + cell.rendered + )} + +
+
+ ); +} +function CellContents(props: HTMLAttributes) { + const { children, ...attributes } = props; + const slots = useMemo(() => ({ text: { color: 'inherit' } }) as const, []); + const element = Children.only(children) as ReactElement; + return ( + + {cloneElement(element, mergeProps(element.props, attributes))} + + ); +} + +export function getWrappedElement( + children: string | ReactElement | ReactNode +): ReactElement { + let element: ReactElement; + if (isReactText(children)) { + element = {children}; + } else { + element = React.Children.only(children) as ReactElement; + } + return element; +} + +function TableCellWrapper( + props: VirtualizerItemOptions & { + parent: GridNode; + } & HTMLAttributes +) { + let { layoutInfo, virtualizer, parent, children } = props; + let { isTableDroppable, dropState } = useTableContext(); + let isDropTarget = false; + let isRootDroptarget = false; + if (isTableDroppable) { + // @ts-expect-error + let key = parent.content.key; + if (key) { + isDropTarget = dropState.isDropTarget({ + type: 'item', + dropPosition: 'on', + key: key, + }); + } + isRootDroptarget = dropState.isDropTarget({ type: 'root' }); + } + + return ( + + {children} + ); } function TableCheckboxCell({ cell }: { cell: any }) { let ref = useRef(null); - let { state } = useTableContext(); + let { cosmeticConfig, state } = useTableContext(); + // The TableCheckbox should always render its disabled status if the row is disabled, regardless of disabledBehavior, + // but the cell itself should not render its disabled styles if disabledBehavior="selection" because the row might have actions on it. + let isSelectionDisabled = state.disabledKeys.has(cell.parentKey); + let isDisabled = state.selectionManager.isDisabled(cell.parentKey); let { gridCellProps } = useTableCell( { node: cell, isVirtualized: true }, state, @@ -686,11 +1476,18 @@ function TableCheckboxCell({ cell }: { cell: any }) { { key: cell.parentKey }, state ); - let styleProps = useSelectionCellStyleProps(); return ( -
- +
+
); } @@ -704,12 +1501,21 @@ function TableSelectAllCell({ column }: { column: any }) { ref ); let { checkboxProps } = useTableSelectAllCheckbox(state); - let styleProps = useSelectionCellStyleProps(); + // FIXME + // let styleProps = useSelectionCellStyleProps(); return ( -
+
{state.selectionManager.selectionMode === 'single' ? ( - {checkboxProps['aria-label']} + {checkboxProps['aria-label']} ) : ( )} @@ -717,22 +1523,42 @@ function TableSelectAllCell({ column }: { column: any }) { ); } -function CenteredWrapper({ children }: { children: ReactNode }) { +function LoadingState() { let { state } = useTableContext(); + let stringFormatter = useLocalizedStringFormatter(localizedMessages); return ( -
+ + 0 + ? stringFormatter.format('loadingMore') + : stringFormatter.format('loading') + } + /> + + ); +} + +function EmptyState() { + let { renderEmptyState } = useTableContext(); + let emptyState = renderEmptyState ? renderEmptyState() : null; + if (emptyState == null) { + return null; + } + + return {emptyState}; +} + +function CenteredWrapper({ children }: PropsWithChildren) { + let { state } = useTableContext(); + let rowProps = { + 'aria-rowindex': + state.collection.headerRows.length + state.collection.size + 1, + }; + + return ( +
{children}
diff --git a/design-system/pkg/src/table/TableViewLayout.tsx b/design-system/pkg/src/table/TableViewLayout.tsx new file mode 100644 index 000000000..e56ae4c3c --- /dev/null +++ b/design-system/pkg/src/table/TableViewLayout.tsx @@ -0,0 +1,104 @@ +import { DropTarget } from '@react-types/shared'; +import { GridNode } from '@react-types/grid'; +import { LayoutInfo, Rect } from '@react-stately/virtualizer'; +import { LayoutNode, TableLayout } from '@react-stately/layout'; + +export class TableViewLayout extends TableLayout { + private isLoading: boolean = false; + + protected buildCollection(): LayoutNode[] { + let loadingState = this.collection.body.props.loadingState; + this.isLoading = + loadingState === 'loading' || loadingState === 'loadingMore'; + return super.buildCollection(); + } + + protected buildColumn(node: GridNode, x: number, y: number): LayoutNode { + let res = super.buildColumn(node, x, y); + res.layoutInfo.allowOverflow = true; // for resizer nubbin + return res; + } + + protected buildBody(): LayoutNode { + let node = super.buildBody(0); + let { children, layoutInfo } = node; + let width = node.layoutInfo.rect.width; + + if (this.isLoading) { + // Add some margin around the loader to ensure that scrollbars don't flicker in and out. + let rect = new Rect( + 40, + children?.length === 0 ? 40 : layoutInfo.rect.maxY, + (width || this.virtualizer.visibleRect.width) - 80, + children?.length === 0 ? this.virtualizer.visibleRect.height - 80 : 60 + ); + let loader = new LayoutInfo('loader', 'loader', rect); + loader.parentKey = layoutInfo.key; + loader.isSticky = children?.length === 0; + let node = { + layoutInfo: loader, + validRect: loader.rect, + }; + children?.push(node); + this.layoutNodes.set(loader.key, node); + layoutInfo.rect.height = loader.rect.maxY; + width = Math.max(width, rect.width); + } else if (children?.length === 0) { + let rect = new Rect( + 40, + 40, + this.virtualizer.visibleRect.width - 80, + this.virtualizer.visibleRect.height - 80 + ); + let empty = new LayoutInfo('empty', 'empty', rect); + empty.parentKey = layoutInfo.key; + empty.isSticky = true; + let node = { + layoutInfo: empty, + validRect: empty.rect, + }; + children.push(node); + layoutInfo.rect.height = empty.rect.maxY; + width = Math.max(width, rect.width); + } + + return node; + } + + protected buildRow(node: GridNode, x: number, y: number): LayoutNode { + let res = super.buildRow(node, x, y); + res.layoutInfo.rect.height += 1; // for bottom border + return res; + } + + protected buildCell(node: GridNode, x: number, y: number): LayoutNode { + let res = super.buildCell(node, x, y); + if (node.column?.props.hideHeader) { + res.layoutInfo.allowOverflow = true; + } + return res; + } + + protected getEstimatedRowHeight(): number { + return super.getEstimatedRowHeight() + 1; // for bottom border + } + + protected isStickyColumn(node: GridNode) { + return node.props?.isDragButtonCell || node.props?.isSelectionCell; + } + + getDropTargetFromPoint( + x: number, + y: number, + isValidDropTarget: (target: DropTarget) => boolean + ): DropTarget { + // Offset for height of header row + let headerRowHeight = this.virtualizer.layout + .getVisibleLayoutInfos(new Rect(x, y, 1, 1)) + .find(info => info.type === 'headerrow')?.rect.height; + if (headerRowHeight) { + y -= headerRowHeight; + } + return super.getDropTargetFromPoint(x, y, isValidDropTarget); + } +} diff --git a/design-system/pkg/src/table/context.tsx b/design-system/pkg/src/table/context.tsx new file mode 100644 index 000000000..ee29298a9 --- /dev/null +++ b/design-system/pkg/src/table/context.tsx @@ -0,0 +1,82 @@ +import type { DragAndDropHooks } from '@keystar/ui/drag-and-drop'; + +import type { + DraggableCollectionState, + DroppableCollectionState, +} from '@react-stately/dnd'; +import { TableState } from '@react-stately/table'; +import type { ColumnSize } from '@react-types/table'; +import type { Key } from '@react-types/shared'; +import { + type HTMLAttributes, + type ReactElement, + type RefObject, + createContext, + useContext, +} from 'react'; + +import { TableViewLayout } from './TableViewLayout'; +import { TableCosmeticConfig } from './types'; + +export type TableContextValue = { + cosmeticConfig: TableCosmeticConfig; + dragAndDropHooks?: DragAndDropHooks['dragAndDropHooks']; + dragState?: DraggableCollectionState; + dropState?: DroppableCollectionState; + headerMenuOpen: boolean; + headerRowHovered: boolean; + isEmpty: boolean; + isInResizeMode: boolean; + isTableDraggable: boolean; + isTableDroppable: boolean; + layout: TableViewLayout; + onFocusedResizer: () => void; + onResize: (widths: Map) => void; + onResizeEnd: (widths: Map) => void; + onResizeStart: (widths: Map) => void; + renderEmptyState?: () => ReactElement; + setHeaderMenuOpen: (val: boolean) => void; + setIsInResizeMode: (val: boolean) => void; + state: TableState; +}; + +export const TableContext = createContext | null>( + null +); +export function useTableContext() { + const context = useContext(TableContext); + if (context === null) { + throw new Error('TableContext not found'); + } + return context; +} + +type VirtualizerContextValue = { + key: Key | null; + width: number; +}; +export const VirtualizerContext = createContext( + null +); +export function useVirtualizerContext() { + const context = useContext(VirtualizerContext); + if (context === null) { + throw new Error('VirtualizerContext not found'); + } + return context; +} + +type TableRowContextValue = { + dragButtonProps: HTMLAttributes; + dragButtonRef: RefObject; + isFocusVisibleWithin: boolean; + isHovered: boolean; +}; +export const TableRowContext = createContext(null); +export function useTableRowContext() { + const context = useContext(TableRowContext); + if (context === null) { + throw new Error('TableRowContext not found'); + } + return context; +} diff --git a/design-system/pkg/src/table/l10n.json b/design-system/pkg/src/table/l10n.json index cdd4c8f2a..f4bedd876 100644 --- a/design-system/pkg/src/table/l10n.json +++ b/design-system/pkg/src/table/l10n.json @@ -1,138 +1,376 @@ { "ar-AE": { + "collapse": "طي", + "columnResizer": "أداة تغيير حجم العمود", + "drag": "سحب", + "expand": "مد", "loading": "جارٍ التحميل...", - "loadingMore": "جارٍ تحميل المزيد..." + "loadingMore": "جارٍ تحميل المزيد...", + "resizeColumn": "تغيير حجم العمود", + "sortAscending": "فرز بترتيب تصاعدي", + "sortDescending": "فرز بترتيب تنازلي" }, "bg-BG": { + "collapse": "Свиване", + "columnResizer": "Преоразмеряване на колони", + "drag": "Плъзнете", + "expand": "Разширяване", "loading": "Зареждане...", - "loadingMore": "Зареждане на още..." + "loadingMore": "Зареждане на още...", + "resizeColumn": "Преоразмеряване на колона", + "sortAscending": "Възходящо сортиране", + "sortDescending": "Низходящо сортиране " }, "cs-CZ": { + "collapse": "Zmenšit", + "columnResizer": "Změna velikosti sloupce", + "drag": "Přetáhnout", + "expand": "Roztáhnout", "loading": "Načítání...", - "loadingMore": "Načítání dalších..." + "loadingMore": "Načítání dalších...", + "resizeColumn": "Změnit velikost sloupce", + "sortAscending": "Seřadit vzestupně", + "sortDescending": "Seřadit sestupně" }, "da-DK": { - "loading": "Indlæser...", - "loadingMore": "Indlæser flere..." + "collapse": "Skjul", + "columnResizer": "Kolonneændring", + "drag": "Træk", + "expand": "Udvid", + "loading": "Indlæser ...", + "loadingMore": "Indlæser flere ...", + "resizeColumn": "Tilpas størrelse på kolonne", + "sortAscending": "Sorter stigende", + "sortDescending": "Sorter faldende" }, "de-DE": { + "collapse": "Reduzieren", + "columnResizer": "Spaltenanpassung", + "drag": "Ziehen", + "expand": "Erweitern", "loading": "Laden...", - "loadingMore": "Mehr laden ..." + "loadingMore": "Mehr laden ...", + "resizeColumn": "Spaltengröße ändern", + "sortAscending": "Aufsteigend sortieren", + "sortDescending": "Absteigend sortieren" }, "el-GR": { + "collapse": "Σύμπτυξη", + "columnResizer": "Αλλαγή μεγέθους στήλης", + "drag": "Μεταφορά", + "expand": "Ανάπτυξη", "loading": "Φόρτωση...", - "loadingMore": "Φόρτωση περισσότερων..." + "loadingMore": "Φόρτωση περισσότερων...", + "resizeColumn": "Αλλαγή μεγέθους στήλης", + "sortAscending": "Ταξινόμηση κατά αύξουσα σειρά", + "sortDescending": "Ταξινόμηση κατά φθίνουσα σειρά" }, "en-US": { "loading": "Loading…", - "loadingMore": "Loading more…" + "loadingMore": "Loading more…", + "sortAscending": "Sort Ascending", + "sortDescending": "Sort Descending", + "resizeColumn": "Resize column", + "columnResizer": "Column resizer", + "drag": "Drag", + "expand": "Expand", + "collapse": "Collapse" }, "es-ES": { + "collapse": "Contraer", + "columnResizer": "Redimensionador de columnas", + "drag": "Arrastrar", + "expand": "Ampliar", "loading": "Cargando…", - "loadingMore": "Cargando más…" + "loadingMore": "Cargando más…", + "resizeColumn": "Cambiar el tamaño de la columna", + "sortAscending": "Orden de subida", + "sortDescending": "Orden de bajada" }, "et-EE": { + "collapse": "Ahenda", + "columnResizer": "Veeru suuruse muutja", + "drag": "Lohista", + "expand": "Laienda", "loading": "Laadimine...", - "loadingMore": "Laadi rohkem..." + "loadingMore": "Laadi rohkem...", + "resizeColumn": "Muuda veeru suurust", + "sortAscending": "Sordi kasvavalt", + "sortDescending": "Sordi kahanevalt" }, "fi-FI": { + "collapse": "Pienennä", + "columnResizer": "Sarakekoon muuttaja", + "drag": "Vedä", + "expand": "Laajenna", "loading": "Ladataan…", - "loadingMore": "Ladataan lisää…" + "loadingMore": "Ladataan lisää…", + "resizeColumn": "Muuta sarakkeen kokoa", + "sortAscending": "Lajittelujärjestys: nouseva", + "sortDescending": "Lajittelujärjestys: laskeva" }, "fr-FR": { + "collapse": "Réduire", + "columnResizer": "Redimensionnement de colonne", + "drag": "Faire glisser", + "expand": "Développer", "loading": "Chargement...", - "loadingMore": "Chargement supplémentaire..." + "loadingMore": "Chargement supplémentaire...", + "resizeColumn": "Redimensionner la colonne", + "sortAscending": "Trier par ordre croissant", + "sortDescending": "Trier par ordre décroissant" }, "he-IL": { + "collapse": "כווץ", + "columnResizer": "שינוי גודל עמודה", + "drag": "גרור", + "expand": "הרחב", "loading": "טוען...", - "loadingMore": "טוען עוד..." + "loadingMore": "טוען עוד...", + "resizeColumn": "שנה את גודל העמודה", + "sortAscending": "מיין בסדר עולה", + "sortDescending": "מיין בסדר יורד" }, "hr-HR": { + "collapse": "Sažmi", + "columnResizer": "Alat za promjenu veličine stupca", + "drag": "Povucite", + "expand": "Proširi", "loading": "Učitavam...", - "loadingMore": "Učitavam još..." + "loadingMore": "Učitavam još...", + "resizeColumn": "Promijeni veličinu stupca", + "sortAscending": "Sortiraj uzlazno", + "sortDescending": "Sortiraj silazno" }, "hu-HU": { + "collapse": "Összecsukás", + "columnResizer": "Oszlopátméretező", + "drag": "Húzás", + "expand": "Kibontás", "loading": "Betöltés folyamatban…", - "loadingMore": "Továbbiak betöltése folyamatban…" + "loadingMore": "Továbbiak betöltése folyamatban…", + "resizeColumn": "Oszlop átméretezése", + "sortAscending": "Növekvő rendezés", + "sortDescending": "Csökkenő rendezés" }, "it-IT": { + "collapse": "Comprimi", + "columnResizer": "Ridimensionamento colonne", + "drag": "Trascina", + "expand": "Espandi", "loading": "Caricamento...", - "loadingMore": "Caricamento altri..." + "loadingMore": "Caricamento altri...", + "resizeColumn": "Ridimensiona colonna", + "sortAscending": "Ordinamento crescente", + "sortDescending": "Ordinamento decrescente" }, "ja-JP": { + "collapse": "折りたたむ", + "columnResizer": "列リサイザー", + "drag": "ドラッグ", + "expand": "展開", "loading": "読み込み中...", - "loadingMore": "さらに読み込み中..." + "loadingMore": "さらに読み込み中...", + "resizeColumn": "列幅を変更", + "sortAscending": "昇順に並べ替え", + "sortDescending": "降順に並べ替え" }, "ko-KR": { - "loading": "로드 중…", - "loadingMore": "추가 로드 중…" + "collapse": "접기", + "columnResizer": "열 크기 조정기", + "drag": "드래그", + "expand": "펼치기", + "loading": "로드 중", + "loadingMore": "추가 로드 중", + "resizeColumn": "열 크기 조정", + "sortAscending": "오름차순 정렬", + "sortDescending": "내림차순 정렬" }, "lt-LT": { + "collapse": "Sutraukti", + "columnResizer": "Stulpelio dydžio keitiklis", + "drag": "Vilkti", + "expand": "Išskleisti", "loading": "Įkeliama...", - "loadingMore": "Įkeliama daugiau..." + "loadingMore": "Įkeliama daugiau...", + "resizeColumn": "Keisti stulpelio dydį", + "sortAscending": "Rikiuoti didėjimo tvarka", + "sortDescending": "Rikiuoti mažėjimo tvarka" }, "lv-LV": { + "collapse": "Sakļaut", + "columnResizer": "Kolonnas izmēru mainītājs", + "drag": "Vilkšana", + "expand": "Izvērst", "loading": "Notiek ielāde...", - "loadingMore": "Tiek ielādēts vēl..." + "loadingMore": "Tiek ielādēts vēl...", + "resizeColumn": "Mainīt kolonnas lielumu", + "sortAscending": "Kārtot augošā secībā", + "sortDescending": "Kārtot dilstošā secībā" }, "nb-NO": { + "collapse": "Skjul", + "columnResizer": "Størrelsesendring av kolonne", + "drag": "Dra", + "expand": "Utvid", "loading": "Laster inn ...", - "loadingMore": "Laster inn flere ..." + "loadingMore": "Laster inn flere ...", + "resizeColumn": "Endre størrelse på kolonne", + "sortAscending": "Sorter stigende", + "sortDescending": "Sorter synkende" }, "nl-NL": { + "collapse": "Samenvouwen", + "columnResizer": "Groottewijziging van kolom", + "drag": "Slepen", + "expand": "Uitvouwen", "loading": "Laden...", - "loadingMore": "Meer laden..." + "loadingMore": "Meer laden...", + "resizeColumn": "Kolomgrootte wijzigen", + "sortAscending": "Oplopend sorteren", + "sortDescending": "Aflopend sorteren" }, "pl-PL": { + "collapse": "Zwiń", + "columnResizer": "Narzędzie zmiany rozmiaru kolumny", + "drag": "Przeciągnij", + "expand": "Rozwiń", "loading": "Ładowanie...", - "loadingMore": "Wczytywanie większej liczby..." + "loadingMore": "Wczytywanie większej liczby...", + "resizeColumn": "Zmień rozmiar kolumny", + "sortAscending": "Sortuj rosnąco", + "sortDescending": "Sortuj malejąco" }, "pt-BR": { + "collapse": "Recolher", + "columnResizer": "Redimensionamento de colunas", + "drag": "Arraste", + "expand": "Expandir", "loading": "Carregando...", - "loadingMore": "Carregando mais..." + "loadingMore": "Carregando mais...", + "resizeColumn": "Redimensionar coluna", + "sortAscending": "Ordenar por ordem crescente", + "sortDescending": "Ordenar por ordem decrescente" }, "pt-PT": { + "collapse": "Colapsar", + "columnResizer": "Redimensionador de coluna", + "drag": "Arrastar", + "expand": "Expandir", "loading": "A carregar...", - "loadingMore": "A carregar mais..." + "loadingMore": "A carregar mais...", + "resizeColumn": "Redimensionar coluna", + "sortAscending": "Ordenar por ordem ascendente", + "sortDescending": "Ordenar por ordem decrescente" }, "ro-RO": { + "collapse": "Restrângeți", + "columnResizer": "Instrument redimensionare coloane", + "drag": "Trageți", + "expand": "Extindeți", "loading": "Se încarcă...", - "loadingMore": "Se încarcă mai multe..." + "loadingMore": "Se încarcă mai multe...", + "resizeColumn": "Redimensionați coloana", + "sortAscending": "Sortați crescător", + "sortDescending": "Sortați descrescător" }, "ru-RU": { + "collapse": "Свернуть", + "columnResizer": "Средство изменения размера столбцов", + "drag": "Перетаскивание", + "expand": "Развернуть", "loading": "Загрузка...", - "loadingMore": "Дополнительная загрузка..." + "loadingMore": "Дополнительная загрузка...", + "resizeColumn": "Изменить размер столбца", + "sortAscending": "Сортировать по возрастанию", + "sortDescending": "Сортировать по убыванию" }, "sk-SK": { + "collapse": "Zbaliť", + "columnResizer": "Nástroj na zmenu veľkosti stĺpcov", + "drag": "Presunúť", + "expand": "Rozbaliť", "loading": "Načítava sa...", - "loadingMore": "Načítava sa viac..." + "loadingMore": "Načítava sa viac...", + "resizeColumn": "Zmeniť veľkosť stĺpca", + "sortAscending": "Zoradiť vzostupne", + "sortDescending": "Zoradiť zostupne" }, "sl-SI": { - "loading": "Nalaganje ...", - "loadingMore": "Nalaganje več vsebine ..." + "collapse": "Strni", + "columnResizer": "Prilagojevalnik velikosti stolpcev", + "drag": "Povleci", + "expand": "Razširi", + "loading": "Nalaganje...", + "loadingMore": "Nalaganje več vsebine...", + "resizeColumn": "Spremeni velikost stolpca", + "sortAscending": "Razvrsti naraščajoče", + "sortDescending": "Razvrsti padajoče" }, "sr-SP": { + "collapse": "Sažmi", + "columnResizer": "Alat za promenu veličine kolone", + "drag": "Prevuci", + "expand": "Proširi", "loading": "Učitavam...", - "loadingMore": "Učitavam još..." + "loadingMore": "Učitavam još...", + "resizeColumn": "Promeni veličinu kolone", + "sortAscending": "Sortiraj po rastućem redosledu", + "sortDescending": "Sortiraj po opadajućem redosledu" }, "sv-SE": { + "collapse": "Dölj", + "columnResizer": "Ändra storlek på kolumn", + "drag": "Dra", + "expand": "Expandera", "loading": "Läser in...", - "loadingMore": "Läser in mer..." + "loadingMore": "Läser in mer...", + "resizeColumn": "Ändra storlek på kolumn", + "sortAscending": "Sortera i stigande ordning", + "sortDescending": "Sortera i fallande ordning" }, "tr-TR": { + "collapse": "Daralt", + "columnResizer": "Yeniden sütun boyutlandırıcı", + "drag": "Sürükle", + "expand": "Genişlet", "loading": "Yükleniyor...", - "loadingMore": "Daha fazla yükleniyor..." + "loadingMore": "Daha fazla yükleniyor...", + "resizeColumn": "Sütunu yeniden boyutlandır", + "sortAscending": "Artan Sıralama", + "sortDescending": "Azalan Sıralama" }, "uk-UA": { + "collapse": "Згорнути", + "columnResizer": "Засіб змінення розміру стовпця", + "drag": "Перетягнути", + "expand": "Розгорнути", "loading": "Завантаження…", - "loadingMore": "Завантаження інших об’єктів..." + "loadingMore": "Завантаження інших об’єктів...", + "resizeColumn": "Змінити розмір стовпця", + "sortAscending": "Сортувати за зростанням", + "sortDescending": "Сортувати за спаданням" }, "zh-CN": { + "collapse": "折叠", + "columnResizer": "列尺寸调整器", + "drag": "拖动", + "expand": "扩展", "loading": "正在加载...", - "loadingMore": "正在加载更多..." - }, - "zh-T": { - "loading": "載入中…", - "loadingMore": "正在載入更多…" + "loadingMore": "正在加载更多...", + "resizeColumn": "调整列大小", + "sortAscending": "升序排序", + "sortDescending": "降序排序" + }, + "zh-TW": { + "collapse": "收合", + "columnResizer": "欄大小調整器", + "drag": "拖曳", + "expand": "展開", + "loading": "正在載入", + "loadingMore": "正在載入更多…", + "resizeColumn": "調整欄大小", + "sortAscending": "升序排序", + "sortDescending": "降序排序" } } diff --git a/design-system/pkg/src/table/stories/ReorderExample.tsx b/design-system/pkg/src/table/stories/ReorderExample.tsx new file mode 100644 index 000000000..62371e7f1 --- /dev/null +++ b/design-system/pkg/src/table/stories/ReorderExample.tsx @@ -0,0 +1,204 @@ +import { action } from '@keystar/ui-storybook'; +import { useListData } from '@react-stately/data'; +import { ItemDropTarget, Key } from '@react-types/shared'; +import React from 'react'; + +import { useDragAndDrop } from '@keystar/ui/drag-and-drop'; + +import { Cell, Column, Row, TableBody, TableHeader, TableView } from '../index'; + +let columns = [ + { name: 'First name', key: 'first_name', isRowHeader: true }, + { name: 'Last name', key: 'last_name', isRowHeader: true }, + { name: 'Email', key: 'email' }, + { name: 'Department', key: 'department' }, + { name: 'Job Title', key: 'job_title' }, + { name: 'IP Address', key: 'ip_address' }, +]; + +export let items = [ + { + id: 'a', + first_name: 'Vin', + last_name: 'Charlet', + email: 'vcharlet0@123-reg.co.uk', + ip_address: '18.45.175.130', + department: 'Services', + job_title: 'Analog Circuit Design manager', + }, + { + id: 'b', + first_name: 'Lexy', + last_name: 'Maddison', + email: 'lmaddison1@xinhuanet.com', + ip_address: '238.210.151.48', + department: 'Research and Development', + job_title: 'Analog Circuit Design manager', + }, + { + id: 'c', + first_name: 'Robbi', + last_name: 'Persence', + email: 'rpersence2@hud.gov', + ip_address: '130.2.120.99', + department: 'Business Development', + job_title: 'Analog Circuit Design manager', + }, + { + id: 'd', + first_name: 'Dodie', + last_name: 'Hurworth', + email: 'dhurworth3@webs.com', + ip_address: '235.183.154.184', + department: 'Training', + job_title: 'Account Coordinator', + }, + { + id: 'e', + first_name: 'Audrye', + last_name: 'Hember', + email: 'ahember4@blogtalkradio.com', + ip_address: '136.25.192.37', + department: 'Legal', + job_title: 'Operator', + }, + { + id: 'f', + first_name: 'Beau', + last_name: 'Oller', + email: 'boller5@nytimes.com', + ip_address: '93.111.22.12', + department: 'Business Development', + job_title: 'Speech Pathologist', + }, + { + id: 'g', + first_name: 'Roarke', + last_name: 'Gration', + email: 'rgration6@purevolume.com', + ip_address: '234.221.23.241', + department: 'Product Management', + job_title: 'Electrical Engineer', + }, + { + id: 'h', + first_name: 'Cathy', + last_name: 'Lishman', + email: 'clishman7@constantcontact.com', + ip_address: '181.158.213.202', + department: 'Research and Development', + job_title: 'Assistant Professor', + }, + { + id: 'i', + first_name: 'Enrika', + last_name: 'Soitoux', + email: 'esoitoux8@google.com.hk', + ip_address: '51.244.20.173', + department: 'Support', + job_title: 'Teacher', + }, + { + id: 'j', + first_name: 'Aloise', + last_name: 'Tuxsell', + email: 'atuxsell9@jigsy.com', + ip_address: '253.46.84.168', + department: 'Training', + job_title: 'Financial Advisor', + }, +]; + +let getAllowedDropOperationsAction = action('getAllowedDropOperationsAction'); + +export function ReorderExample(props) { + let { onDrop, onDragStart, onDragEnd, tableViewProps, ...otherProps } = props; + let list = useListData({ + initialItems: (props.items as typeof items) || items, + getKey: item => item.id, + }); + + // Use a random drag type so the items can only be reordered within this table and not dragged elsewhere. + let dragType = React.useMemo( + () => `keys-${Math.random().toString(36).slice(2)}`, + [] + ); + + let onMove = (keys: Key[], target: ItemDropTarget) => { + console.log('onMove', keys, target); + if (target.dropPosition === 'before') { + list.moveBefore(target.key, keys); + } else { + list.moveAfter(target.key, keys); + } + }; + + let { dragAndDropHooks } = useDragAndDrop({ + getItems(keys) { + return [...keys].map(key => { + key = JSON.stringify(key); + return { + [dragType]: key, + 'text/plain': key, + }; + }); + }, + getAllowedDropOperations() { + getAllowedDropOperationsAction(); + return ['move', 'cancel']; + }, + onDragStart: onDragStart, + onDragEnd: onDragEnd, + async onDrop(e) { + onDrop(e); + if (e.target.type !== 'root' && e.target.dropPosition !== 'on') { + let keys = []; + for (let item of e.items) { + if (item.kind === 'text') { + let key; + if (item.types.has(dragType)) { + key = JSON.parse(await item.getText(dragType)); + keys.push(key); + } else if (item.types.has('text/plain')) { + // Fallback for Chrome Android case: https://bugs.chromium.org/p/chromium/issues/detail?id=1293803 + // Multiple drag items are contained in a single string so we need to split them out + key = await item.getText('text/plain'); + keys = key.split('\n').map(val => val.replaceAll('"', '')); + } + } + } + onMove(keys, e.target); + } + }, + getDropOperation(target) { + if (target.type === 'root' || target.dropPosition === 'on') { + return 'cancel'; + } + + return 'move'; + }, + }); + + return ( + + + {column => ( + + {column.name} + + )} + + + {item => {key => {item[key]}}} + + + ); +} diff --git a/design-system/pkg/src/table/stories/Table.stories.tsx b/design-system/pkg/src/table/stories/Table.stories.tsx index 0faede366..86469a964 100644 --- a/design-system/pkg/src/table/stories/Table.stories.tsx +++ b/design-system/pkg/src/table/stories/Table.stories.tsx @@ -1,9 +1,12 @@ import { action, ArgTypes } from '@keystar/ui-storybook'; -import { Flex, VStack } from '@keystar/ui/layout'; +import { Badge } from '@keystar/ui/badge'; +import { Box, Flex, VStack } from '@keystar/ui/layout'; import { TextLink } from '@keystar/ui/link'; import { tokenSchema } from '@keystar/ui/style'; +import { ActionButton } from '@keystar/ui/button'; import { Switch } from '@keystar/ui/switch'; import { Heading, Text } from '@keystar/ui/typography'; +import { useAsyncList } from '@react-stately/data'; import { Key, useMemo, useState } from 'react'; import { @@ -16,7 +19,7 @@ import { TableHeader, } from '..'; import { pokemonItems } from './data'; -import { useAsyncList } from '@react-stately/data'; +import { ReorderExample } from './ReorderExample'; function onSelectionChange(keys: 'all' | Set) { const selection = typeof keys === 'string' ? keys : [...keys]; @@ -35,7 +38,7 @@ export default { density: 'regular', height: undefined, width: 'scale.6000', - onRowAction: action('onRowAction'), + onAction: action('onAction'), onSelectionChange: action('onSelectionChange'), onSortChange: action('onSortChange'), }, @@ -44,7 +47,7 @@ export default { // there is no argType for function // use the controls reset button to undo it // https://storybook.js.org/docs/react/essentials/controls#annotation - onRowAction: { + onAction: { control: 'select', options: [undefined], }, @@ -58,6 +61,11 @@ export default { disable: true, }, }, + disabledBehavior: { + table: { + disable: true, + }, + }, disabledKeys: { table: { disable: true, @@ -168,11 +176,17 @@ export const Dynamic = (args: ArgTypes) => ( ); -export const DisabledKeys = (args: ArgTypes) => ; +export const DisabledKeys = (args: ArgTypes) => ( + +); DisabledKeys.args = { disabledKeys: new Set(['Foo 1', 'Foo 3']), + selectionMode: 'none', }; -DisabledKeys.storyName = 'disabled keys'; export const HiddenHeader = (args: ArgTypes) => ( ( {...args} > - Foo - Bar - + + Foo + + + Bar + + Actions @@ -193,14 +211,14 @@ export const HiddenHeader = (args: ArgTypes) => ( One Two - + Three Four Five - + Six @@ -224,14 +242,16 @@ export const FocusableContent = (args: ArgTypes) => ( - Yahoo + Thinkmill - Three + + Company + @@ -239,14 +259,16 @@ export const FocusableContent = (args: ArgTypes) => ( - Google + Keystatic - Three + + Project + @@ -254,14 +276,16 @@ export const FocusableContent = (args: ArgTypes) => ( - Yahoo + Keystone - Three + + Project + @@ -275,7 +299,6 @@ export const Selection = (args: ArgTypes) => ( aria-label="TableView with selection" // width="scale.3400" // height="scale.2400" - onRowAction={args.none ? action('onRowAction') : undefined} onSelectionChange={onSelectionChange} {...args} > @@ -302,6 +325,51 @@ Selection.args = { selectionMode: 'multiple', }; +export const Resizing = (args: ArgTypes) => ( + + + + + Foo + + + Bar + + + Baz + + + + + One + Two + Three + + + Four + Five + Six + + + + +); + +export const Reorderable = (args: ArgTypes) => ( + +); + export const TableProps = (args: ArgTypes) => ( { width="scale.6000" height="scale.2400" selectionMode="multiple" - // onRowAction={(...args) => { - // console.log('onRowAction', ...args); - // action('onRowAction')(...args); + // onAction={(...args) => { + // console.log('onAction', ...args); + // action('onAction')(...args); // }} onSelectionChange={onSelectionChange} onSortChange={descriptor => { @@ -382,8 +450,8 @@ export const StickyCheckboxes = () => { { // ); // } - return ( - - {value} - - ); + return {value}; }} )} diff --git a/design-system/pkg/src/table/styles.tsx b/design-system/pkg/src/table/styles.tsx index 54ad1a280..8dab2204f 100644 --- a/design-system/pkg/src/table/styles.tsx +++ b/design-system/pkg/src/table/styles.tsx @@ -4,35 +4,19 @@ import { ClassList, classNames, css, - toDataAttributes, tokenSchema, transition, - useStyleProps, } from '@keystar/ui/style'; -import { CSSProperties, HTMLAttributes } from 'react'; - -import { TableProps } from './types'; +import { HTMLAttributes } from 'react'; export const tableViewClassList = new ClassList('TableView', [ 'cell', 'cell-wrapper', 'row', + 'body', + 'header', ]); -// ============================================================================ -// UTILS -// ============================================================================ - -// function getStyleFromColumn(props: CellProps) { -// const { maxWidth, minWidth, width } = props; - -// if (width) { -// return { flex: '0 0 auto', width, maxWidth, minWidth }; -// } - -// return { maxWidth, minWidth }; -// } - // ============================================================================ // COMPONENTS // ============================================================================ @@ -65,6 +49,7 @@ export const SortIndicator = () => { alignItems: 'center', display: 'flex', flexShrink: 0, + gridArea: 'sort-indicator', height: labelHeight, justifyContent: 'center', marginInline: tokenSchema.size.space.small, @@ -93,94 +78,222 @@ export const SortIndicator = () => { }; // ============================================================================ -// HOOKS +// CLASSES // ============================================================================ -// Table root +// TODO: review styles +export const tableClassname = css({ + display: 'flex', + flexDirection: 'column', + isolation: 'isolate', + minHeight: 0, + minWidth: 0, + outline: 'none', + position: 'relative', + userSelect: 'none', +}); + +// Row group (head/body/foot) // ---------------------------------------------------------------------------- -export function useTableStyleProps(props: TableProps) { - let { density, overflowMode, prominence } = props; - let styleProps = useStyleProps(props); +export const headerWrapperClassname = css({ + boxSizing: 'content-box', + // keep aligned with the border of the body + borderLeft: `${tokenSchema.size.border.regular} solid transparent`, + borderRight: `${tokenSchema.size.border.regular} solid transparent`, +}); +export const headerClassname = classNames( + tableViewClassList.element('header'), + css({ + boxSizing: 'border-box', + }) +); + +export const bodyClassname = classNames( + tableViewClassList.element('body'), + css({ + backgroundColor: tokenSchema.color.background.canvas, + border: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.neutral}`, + borderRadius: tokenSchema.size.radius.medium, + /* Fix scrollbars on iOS with sticky row headers */ + transform: 'translate3d(0, 0, 0)', + }) +); + +// resizing +export const columnResizerClassname = css({ + blockSize: '100%', + boxSizing: 'border-box', + display: 'flex', + flexShrink: 0, + inlineSize: 21, + insetInlineEnd: -10, + justifyContent: 'center', + outline: 0, + position: 'absolute', + userSelect: 'none', - return { - ...toDataAttributes({ density, overflowMode, prominence }), - className: classNames( - tableViewClassList.element('root'), - styleProps.className, - css({ - display: 'flex', - flexDirection: 'column', - isolation: 'isolate', - minHeight: 0, - minWidth: 0, - outline: 'none', - position: 'relative', - userSelect: 'none', - }) - ), - style: styleProps.style, - }; -} + '&::after': { + backgroundColor: tokenSchema.color.border.neutral, + blockSize: '100%', + boxSizing: 'border-box', + content: '""', + display: 'block', + inlineSize: 1, + }, +}); +export const columnResizerPlaceholderClassname = css({ + blockSize: '100%', + boxSizing: 'border-box', + flex: '0 0 auto', + flexShrink: 0, + inlineSize: 10, + userSelect: 'none', +}); +export const columnResizeIndicatorClassname = css({ + backgroundColor: tokenSchema.color.background.accentEmphasis, + display: 'none', + flexShrink: 0, + height: '100%', + insetInlineEnd: 0, + pointerEvents: 'none', + position: 'absolute', + top: 1, + width: 2, + zIndex: 3, + + '&[data-resizing=true]': { + display: 'block', + }, +}); +export const bodyResizeIndicatorClassname = css({ + backgroundColor: tokenSchema.color.background.accentEmphasis, + display: 'none', + height: '100%', + position: 'absolute', + top: 0, + width: 2, +}); -// Row group (head/body/foot) +// utilities +export const centeredWrapperClassname = css({ + alignItems: 'center', + display: 'flex', + height: '100%', + justifyContent: 'center', + width: '100%', +}); + +// Row // ---------------------------------------------------------------------------- -export function useHeaderWrapperStyleProps({ - style, -}: { - style?: CSSProperties; -} = {}) { - return { - className: css({ - overflow: 'hidden', - position: 'relative', - boxSizing: 'content-box', - flex: 'none', - // keep aligned with the border of the body - [`${tableViewClassList.selector('root')}:not([data-prominence="low"]) &`]: - { - borderLeft: `${tokenSchema.size.border.regular} solid transparent`, - borderRight: `${tokenSchema.size.border.regular} solid transparent`, - }, - }), - style, - }; -} -export function useHeadStyleProps({ style }: { style?: CSSProperties } = {}) { - return { - className: css({ - boxSizing: 'border-box', - display: 'flex', - flexDirection: 'column', - }), - style, - }; -} -export function useBodyStyleProps({ style }: { style?: CSSProperties } = {}) { - return { - className: css({ - [`${tableViewClassList.selector('root')}[data-prominence="low"] &`]: { - borderBlock: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.muted}`, - }, - [`${tableViewClassList.selector('root')}:not([data-prominence="low"]) &`]: - { - backgroundColor: tokenSchema.color.background.canvas, - border: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.muted}`, - borderRadius: tokenSchema.size.radius.medium, - /* Fix scrollbars on iOS with sticky row headers */ - transform: 'translate3d(0, 0, 0)', - }, - }), - style, - }; -} +export const rowClassname = css({ + boxSizing: 'border-box', + display: 'flex', + position: 'relative', + outline: 0, -// Cell common + // separators + [`${tableViewClassList.selector('body')} &::after`]: { + content: '""', + boxShadow: `inset 0 -1px 0 0 ${tokenSchema.color.border.muted}`, + position: 'absolute', + inset: 0, + pointerEvents: 'none', + zIndex: 2, + }, + '&[data-flush-with-container-bottom]::after': { + display: 'none', + }, + // selection + '&[aria-selected="true"]::after': { + boxShadow: `inset 0 -1px 0 0 ${tokenSchema.color.alias.backgroundSelectedHovered}`, + }, + '&[data-next-selected="true"]::after': { + boxShadow: `inset 0 -1px 0 0 ${tokenSchema.color.alias.backgroundSelectedHovered}`, + }, + + // prominence + [`${tableViewClassList.selector('root')}:not([data-prominence="low"]) &`]: { + '&:first-child': { + borderStartStartRadius: `calc(${tokenSchema.size.radius.medium} - ${tokenSchema.size.border.regular})`, + borderStartEndRadius: `calc(${tokenSchema.size.radius.medium} - ${tokenSchema.size.border.regular})`, + }, + '&:last-child': { + borderEndStartRadius: `calc(${tokenSchema.size.radius.medium} - ${tokenSchema.size.border.regular})`, + borderEndEndRadius: `calc(${tokenSchema.size.radius.medium} - ${tokenSchema.size.border.regular})`, + }, + }, + + // focus indicator + '&[data-focus-visible]': { + '&::before': { + backgroundColor: tokenSchema.color.background.accentEmphasis, + borderRadius: tokenSchema.size.space.small, + content: '""', + insetInlineStart: tokenSchema.size.space.xsmall, + marginBlock: tokenSchema.size.space.xsmall, + marginInlineEnd: `calc(${tokenSchema.size.space.small} * -1)`, + position: 'sticky', + width: tokenSchema.size.space.small, + zIndex: 4, + }, + }, + + // interactions + [`&[data-hovered=true] ${tableViewClassList.selector('cell')}`]: { + backgroundColor: tokenSchema.color.scale.slate2, + }, + [`&[data-pressed=true] ${tableViewClassList.selector('cell')}`]: { + backgroundColor: tokenSchema.color.scale.slate3, + // backgroundColor: tokenSchema.color.alias.backgroundPressed, + }, + [`&[data-disabled] ${tableViewClassList.selector('cell')}`]: { + color: tokenSchema.color.alias.foregroundDisabled, + }, + + // selected + [`&[aria-selected="true"] ${tableViewClassList.selector('cell')}`]: { + backgroundColor: tokenSchema.color.alias.backgroundSelected, + }, + [`&[aria-selected="true"][data-hovered=true] ${tableViewClassList.selector( + 'cell' + )}`]: { + backgroundColor: tokenSchema.color.alias.backgroundSelectedHovered, + }, +}); + +export const rowDragPreviewClassname = css({ + backgroundColor: tokenSchema.color.background.canvas, + border: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.alias.borderSelected}`, + borderRadius: tokenSchema.size.radius.small, + paddingInline: tokenSchema.size.space.medium, + position: 'relative', + outline: 0, + width: tokenSchema.size.alias.singleLineWidth, + + // indicate that multiple items are being dragged by implying a stack + '&[data-multi=true]::after': { + backgroundColor: 'inherit', + border: 'inherit', + borderRadius: 'inherit', + content: '" "', + display: 'block', + height: '100%', + insetInlineStart: 4, + position: 'absolute', + top: 4, + width: '100%', + // zIndex: -1, + }, +}); + +// Cell // ---------------------------------------------------------------------------- -const commonCellStyles = { - // borderBottom: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.neutral}`, +// FIXME: review these styles. many may not be necessary. def get rid of the +// root selectors, and pass data-attributes onto elements directly +const commonCellStyles = css({ boxSizing: 'border-box', cursor: 'default', display: 'flex', @@ -190,208 +303,115 @@ const commonCellStyles = { outline: 0, paddingInline: tokenSchema.size.space.medium, position: 'relative', + textAlign: 'start', + + // focus ring + '&[data-focus=visible]': { + borderRadius: tokenSchema.size.radius.small, + inset: 0, + outline: `${tokenSchema.size.alias.focusRing} solid ${tokenSchema.color.alias.focusRing}`, + outlineOffset: `calc(${tokenSchema.size.alias.focusRingGap} * -1)`, + position: 'absolute', + }, - // Density - paddingBlock: tokenSchema.size.space.medium, - [`${tableViewClassList.selector( - 'root' - )}[data-density="compact"] &:not([role="columnheader"])`]: { - paddingBlock: tokenSchema.size.space.regular, + // density + paddingBlock: tokenSchema.size.space.regular, + '&[data-density="compact"]': { + paddingBlock: tokenSchema.size.space.small, }, - [`${tableViewClassList.selector( - 'root' - )}[data-density="spacious"] &:not([role="columnheader"])`]: { - paddingBlock: tokenSchema.size.space.large, + '&[data-density="spacious"]': { + paddingBlock: tokenSchema.size.space.medium, }, - // wrapping text shouldn't be centered - alignItems: 'center', - [`${tableViewClassList.selector( - 'root' - )}[data-overflow-mode="wrap"] &:not([role="columnheader"])`]: { - alignItems: 'start', + // alignment + '&[data-align="end"]': { + justifyContent: 'flex-end', + textAlign: 'end', + }, + '&[data-align="center"]': { + justifyContent: 'center', + textAlign: 'center', }, -} as const; - -type CellProps = { - align?: 'start' | 'end' | 'center'; - maxWidth?: number | string; - minWidth?: number | string; - width?: number | string; -}; - -export function useCellStyleProps( - props: CellProps, - state?: { isFocusVisible: boolean } -) { - const className = classNames( - tableViewClassList.element('cell'), - css([ - commonCellStyles, - { - // Alignment - '&[data-align="end"]': { - justifyContent: 'flex-end', - textAlign: 'end', - }, - '&[data-align="center"]': { - justifyContent: 'center', - textAlign: 'center', - }, - - // focus ring - '&[data-focus="visible"]::after': { - borderRadius: tokenSchema.size.radius.small, - boxShadow: `inset 0 0 0 ${tokenSchema.size.alias.focusRing} ${tokenSchema.color.alias.focusRing}`, - content: '""', - inset: 0, - position: 'absolute', - transition: transition(['box-shadow', 'margin'], { - easing: 'easeOut', - }), - }, - - // HEADERS - '&[role="columnheader"]': { - color: tokenSchema.color.foreground.neutralSecondary, - - ['&[aria-sort]']: { - cursor: 'default', - - '&:hover, &[data-focus="visible"]': { - color: tokenSchema.color.foreground.neutralEmphasis, - }, - }, - }, - }, - ]) - ); - - return { - ...toDataAttributes({ - focus: state?.isFocusVisible ? 'visible' : undefined, - align: props?.align, - }), - className, - // style: getStyleFromColumn(props), - }; -} - -export function useSelectionCellStyleProps() { - return { - className: classNames( - tableViewClassList.element('cell'), - css(commonCellStyles, { - alignItems: 'center', - flex: '0 0 auto', - paddingInlineStart: tokenSchema.size.space.medium, - width: 'auto', - }) - ), - }; -} - -// Row body -// ---------------------------------------------------------------------------- -export function useRowStyleProps( - props: { - style?: CSSProperties; + // overflow mode + '&[data-overflow-mode="truncate"]': { + alignItems: 'center', }, - state: { - isFocusVisible: boolean; - isFocusWithin: boolean; - isPressed: boolean; - isHovered: boolean; - } -) { - let { style } = props; - let calculatedRadius = `calc(${tokenSchema.size.radius.medium} - ${tokenSchema.size.border.regular})`; - - const className = css({ - boxSizing: 'border-box', - display: 'flex', - position: 'relative', - outline: 0, - - // separators - '&:not(:last-child)': { - backgroundColor: tokenSchema.color.border.muted, - paddingBottom: 1, - }, +}); - // prominence - [`${tableViewClassList.selector('root')}:not([data-prominence="low"]) &`]: { - '&:first-child': { - borderStartStartRadius: calculatedRadius, - borderStartEndRadius: calculatedRadius, - }, - '&:last-child': { - borderEndStartRadius: calculatedRadius, - borderEndEndRadius: calculatedRadius, +export const cellWrapperClassname = css({ + [`${tableViewClassList.selector('body')} &`]: { + backgroundColor: tokenSchema.color.background.canvas, + }, +}); + +// data-attributes +// - align +// - hide-header +// - show-divider +export const cellClassname = classNames( + tableViewClassList.element('cell'), + commonCellStyles, + css({ + color: tokenSchema.color.foreground.neutral, + }) +); +// TODO: assess styles +export const cellContentsClassname = css({ + // color: tokenSchema.color.foreground.neutral, + // fontFamily: tokenSchema.typography.fontFamily.base, + // fontSize: tokenSchema.typography.text.regular.size, + minWidth: 0, + flex: 1, +}); + +export const headerCellClassname = classNames( + commonCellStyles, + css({ + alignItems: 'center', + backgroundColor: tokenSchema.color.background.surface, + color: tokenSchema.color.foreground.neutralSecondary, + minWidth: 0, + flex: 1, + + // SORTABLE + ['&[aria-sort]']: { + display: 'grid', + gridTemplateAreas: '". sort-indicator"', + + '&[data-align="end"]': { + gridTemplateAreas: '"sort-indicator ."', }, - }, - - // focus indicator - '&[data-focus="visible"]': { - '&::before': { - backgroundColor: tokenSchema.color.background.accentEmphasis, - borderRadius: tokenSchema.size.space.small, - content: '""', - insetInlineStart: tokenSchema.size.space.xsmall, - marginBlock: tokenSchema.size.space.xsmall, - marginInlineEnd: `calc(${tokenSchema.size.space.small} * -1)`, - position: 'sticky', - width: tokenSchema.size.space.small, - zIndex: 4, + '&[data-hovered=true]': { + color: tokenSchema.color.foreground.neutralEmphasis, }, }, + }) +); + +export const dragCellClassname = css({ + paddingInlineStart: tokenSchema.size.space.regular, + paddingInlineEnd: 0, +}); +export const checkboxCellClassname = css({ + paddingBlock: 0, + paddingInlineEnd: tokenSchema.size.space.regular, + + label: { + paddingInlineEnd: tokenSchema.size.space.regular, + paddingBlock: tokenSchema.size.space.regular, + }, - // interactions - [`&[data-interaction="hover"] ${tableViewClassList.selector('cell')}`]: { - backgroundColor: tokenSchema.color.scale.slate2, - }, - [`&[data-interaction="press"] ${tableViewClassList.selector('cell')}`]: { - backgroundColor: tokenSchema.color.scale.slate3, - // backgroundColor: tokenSchema.color.alias.backgroundPressed, - }, - - // selected - [`&[aria-selected="true"] ${tableViewClassList.selector('cell')}`]: { - backgroundColor: tokenSchema.color.alias.backgroundSelected, + '&[data-density="compact"]': { + paddingBlock: 0, + label: { + paddingBlock: tokenSchema.size.space.small, }, - [`&[aria-selected="true"][data-interaction="hover"] ${tableViewClassList.selector( - 'cell' - )}`]: { - backgroundColor: tokenSchema.color.alias.backgroundSelectedHovered, + }, + '&[data-density="spacious"]': { + paddingBlock: 0, + label: { + paddingBlock: tokenSchema.size.space.medium, }, - }); - - return { - ...toDataAttributes({ - focus: state.isFocusVisible - ? 'visible' - : state.isFocusWithin - ? 'within' - : undefined, - interaction: state.isPressed - ? 'press' - : state.isHovered - ? 'hover' - : undefined, - }), - className: classNames(tableViewClassList.element('row'), className), - style, - }; -} - -// Row header -// ---------------------------------------------------------------------------- - -export function useRowHeaderStyleProps({ style }: { style?: CSSProperties }) { - const className = css({ - display: 'flex', - }); - - return { className, style }; -} + }, +}); diff --git a/design-system/pkg/src/table/types.ts b/design-system/pkg/src/table/types.ts index 5e8f936e6..12cbb5fcc 100644 --- a/design-system/pkg/src/table/types.ts +++ b/design-system/pkg/src/table/types.ts @@ -1,20 +1,26 @@ -import { CollectionChildren, DOMProps } from '@react-types/shared'; -import { TableProps as _TableProps } from '@react-types/table'; +import { + AriaLabelingProps, + CollectionChildren, + DOMProps, +} from '@react-types/shared'; +import { + ColumnSize, + TableProps as ReactAriaTableProps, +} from '@react-types/table'; import { Key, ReactElement, ReactNode } from 'react'; +import { DragAndDropHooks } from '@keystar/ui/drag-and-drop'; import { BaseStyleProps } from '@keystar/ui/style'; type ColumnElement = ReactElement>; type ColumnRenderer = (item: T) => ColumnElement; -export type TableProps = { +export type TableCosmeticConfig = { /** * Sets the amount of vertical padding within each cell. * @default 'regular' */ density?: 'compact' | 'regular' | 'spacious'; - /** Handler that is called when a user performs an action on a row. */ - onRowAction?: (key: Key) => void; /** * Sets the overflow behavior for the cell contents. * @default 'truncate' @@ -25,9 +31,38 @@ export type TableProps = { * @default 'default' */ prominence?: 'default' | 'low'; +}; +export type TableProps = { + /** Handler that is called when a user performs an action on a row. */ + onAction?: (key: Key) => void; + /** @deprecated Use `onAction` instead. */ + onRowAction?: (key: Key) => void; /** What should render when there is no content to display. */ renderEmptyState?: () => JSX.Element; -} & _TableProps & + /** + * Handler that is called when a user starts a column resize. + */ + onResizeStart?: (widths: Map) => void; + /** + * Handler that is called when a user performs a column resize. + * Can be used with the width property on columns to put the column widths into + * a controlled state. + */ + onResize?: (widths: Map) => void; + /** + * Handler that is called after a user performs a column resize. + * Can be used to store the widths of columns for another future session. + */ + onResizeEnd?: (widths: Map) => void; + /** + * The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the TableView. + * @version beta + */ + dragAndDropHooks?: DragAndDropHooks['dragAndDropHooks']; +} & AriaLabelingProps & + DOMProps & + TableCosmeticConfig & + ReactAriaTableProps & BaseStyleProps & DOMProps; From e6d2aa3e4ad3321535645f08f2f7b8403a4b7eaf Mon Sep 17 00:00:00 2001 From: jossmac <2730833+jossmac@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:21:53 +1000 Subject: [PATCH 06/12] improve table types, still a bit sketchy --- .../InsertionIndicatorPrimitive.tsx | 2 +- design-system/pkg/src/table/DragPreview.tsx | 21 ++++------ .../pkg/src/table/InsertionIndicator.tsx | 20 +++++----- design-system/pkg/src/table/TableView.tsx | 39 +++++++++---------- .../pkg/src/table/stories/ReorderExample.tsx | 24 +++++++----- design-system/pkg/src/table/styles.tsx | 6 +-- 6 files changed, 54 insertions(+), 58 deletions(-) diff --git a/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx b/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx index 87d8ba36f..0bd6071c3 100644 --- a/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx +++ b/design-system/pkg/src/drag-and-drop/InsertionIndicatorPrimitive.tsx @@ -2,7 +2,7 @@ import { classNames, css, tokenSchema } from '@keystar/ui/style'; import React, { HTMLAttributes } from 'react'; export function InsertionIndicatorPrimitive( - props: { isDropTarget: boolean } & HTMLAttributes + props: { isDropTarget?: boolean } & HTMLAttributes ) { let { children, isDropTarget, ...otherProps } = props; let maskColor = tokenSchema.color.background.canvas; diff --git a/design-system/pkg/src/table/DragPreview.tsx b/design-system/pkg/src/table/DragPreview.tsx index 8a4265a3a..dce1e1198 100644 --- a/design-system/pkg/src/table/DragPreview.tsx +++ b/design-system/pkg/src/table/DragPreview.tsx @@ -1,14 +1,8 @@ -import { classNames } from '@keystar/ui/style'; import { Text } from '@keystar/ui/typography'; import { Flex } from '@keystar/ui/layout'; import React from 'react'; -import { - cellClassname, - cellContentsClassname, - rowClassname, - rowDragPreviewClassname, -} from './styles'; +import { rowDragPreviewClassname } from './styles'; type DragPreviewProps = { itemText?: string; // can't guarantee this will be available @@ -21,25 +15,24 @@ export function DragPreview(props: DragPreviewProps) { let { itemText, itemCount, height, maxWidth } = props; let isDraggingMultiple = itemCount > 1; return ( + /* TODO: export as `DragPreview` from "@keystar/ui/drag-and-drop" for use here and in the list view */ -
- {itemText} -
+ {itemText} - {/* export as `DragPreviewCount` from "@keystar/ui/drag-and-drop" for use here and in the list view */} + {/* TODO: export as `DragPreviewCount` from "@keystar/ui/drag-and-drop" for use here and in the list view */} {isDraggingMultiple && ( diff --git a/design-system/pkg/src/table/InsertionIndicator.tsx b/design-system/pkg/src/table/InsertionIndicator.tsx index 51fa3ce38..8c6244506 100644 --- a/design-system/pkg/src/table/InsertionIndicator.tsx +++ b/design-system/pkg/src/table/InsertionIndicator.tsx @@ -15,15 +15,16 @@ interface InsertionIndicatorProps { } export function InsertionIndicator(props: InsertionIndicatorProps) { + let { rowProps, target, visibleRect } = props; let { dropState, dragAndDropHooks } = useTableContext(); - const { rowProps, target, visibleRect } = props; + let ref = useRef(null); assert( !!dragAndDropHooks?.useDropIndicator, 'dragAndDropHooks.useDropIndicator is not defined.' ); + assert(!!dropState, 'dropState is not defined.'); - let ref = useRef(null); let { dropIndicatorProps } = dragAndDropHooks.useDropIndicator( props, dropState, @@ -31,26 +32,23 @@ export function InsertionIndicator(props: InsertionIndicatorProps) { ); let { visuallyHiddenProps } = useVisuallyHidden(); - let isDropTarget = dropState.isDropTarget(target); + let isDropTarget = dropState && dropState.isDropTarget(target); if (!isDropTarget && dropIndicatorProps['aria-hidden']) { return null; } - console.log('rowProps', rowProps); + let rowTop = Number(rowProps?.style?.top) ?? 0; + let rowHeight = Number(rowProps?.style?.height) ?? 0; return (
( - props: TableProps, - forwardedRef: ForwardedRef + props: TableProps + // forwardedRef: ForwardedRef ) { let { density = 'regular', @@ -324,6 +323,7 @@ export function TableView( ( isTableDroppable, layout, onFocusedResizer, - onResize: props.onResize, + onResize: props.onResize ?? (() => {}), onResizeEnd, onResizeStart, renderEmptyState: props.renderEmptyState, @@ -1087,8 +1087,8 @@ function ResizableTableColumnHeader(props: { column: GridNode }) { )} - {/* TODO: consider grid layout/areas on the parent to position the sort indicator */} {column.props.allowsSorting && } + }) { } let draggableItem: DraggableItemResult | null = null; - if (isTableDraggable && dragAndDropHooks?.useDraggableItem) { - // eslint-disable-next-line react-hooks/rules-of-hooks + if (isTableDraggable) { + assert(!!dragAndDropHooks?.useDraggableItem); + assert(!!dragState); draggableItem = dragAndDropHooks.useDraggableItem( { key: item.key, hasDragButton: true }, dragState @@ -1173,11 +1174,10 @@ function TableRow(props: PropsWithLayoutInfos & { item: GridNode }) { let isDropTarget: boolean = false; let dropIndicator: DropIndicatorAria | null = null; let dropIndicatorRef = useRef(null); - if ( - isTableDroppable && - dragAndDropHooks?.useDropIndicator && - dragAndDropHooks?.useDroppableItem - ) { + if (isTableDroppable) { + assert(!!dragAndDropHooks?.useDroppableItem); + assert(!!dragAndDropHooks?.useDropIndicator); + assert(!!dropState); let target = { type: 'item', key: item.key, @@ -1335,7 +1335,7 @@ function DragButton() { return (
)} + {...(dragButtonProps as HTMLAttributes)} className={css({ borderRadius: tokenSchema.size.radius.xsmall, display: 'flex', @@ -1418,14 +1418,14 @@ export function getWrappedElement( if (isReactText(children)) { element = {children}; } else { - element = React.Children.only(children) as ReactElement; + element = Children.only(children) as ReactElement; } return element; } function TableCellWrapper( props: VirtualizerItemOptions & { - parent: GridNode; + parent: View; } & HTMLAttributes ) { let { layoutInfo, virtualizer, parent, children } = props; @@ -1433,7 +1433,7 @@ function TableCellWrapper( let isDropTarget = false; let isRootDroptarget = false; if (isTableDroppable) { - // @ts-expect-error + assert(!!dropState); let key = parent.content.key; if (key) { isDropTarget = dropState.isDropTarget({ @@ -1449,7 +1449,6 @@ function TableCellWrapper( {column => ( - + {column.name} )} - {item => {key => {item[key]}}} + {item => ( + {key => {item[key as keyof typeof item]}} + )} ); diff --git a/design-system/pkg/src/table/styles.tsx b/design-system/pkg/src/table/styles.tsx index 8dab2204f..64d750ae7 100644 --- a/design-system/pkg/src/table/styles.tsx +++ b/design-system/pkg/src/table/styles.tsx @@ -280,11 +280,11 @@ export const rowDragPreviewClassname = css({ content: '" "', display: 'block', height: '100%', - insetInlineStart: 4, + insetBlockStart: tokenSchema.size.space.small, + insetInlineStart: tokenSchema.size.space.small, position: 'absolute', - top: 4, width: '100%', - // zIndex: -1, + zIndex: -1, }, }); From 1e0c79af5e4a9f635fc8300db605a7bdae491f43 Mon Sep 17 00:00:00 2001 From: jossmac <2730833+jossmac@users.noreply.github.com> Date: Mon, 2 Sep 2024 13:38:36 +1000 Subject: [PATCH 07/12] fix some tests --- .../src/action-bar/test/ActionBar.test.tsx | 70 ++--- design-system/pkg/src/field/types.tsx | 4 + design-system/pkg/src/menu/test/Menu.test.tsx | 5 +- .../pkg/src/menu/test/MenuTrigger.test.tsx | 59 +++-- design-system/pkg/src/picker/Picker.tsx | 5 +- design-system/pkg/src/toast/Toast.tsx | 78 +++--- .../pkg/src/toast/test/Toast.test.tsx | 250 +++++++++--------- .../src/tooltip/test/TooltipTrigger.test.tsx | 95 +++---- 8 files changed, 285 insertions(+), 281 deletions(-) diff --git a/design-system/pkg/src/action-bar/test/ActionBar.test.tsx b/design-system/pkg/src/action-bar/test/ActionBar.test.tsx index 950346891..ebcd6592b 100644 --- a/design-system/pkg/src/action-bar/test/ActionBar.test.tsx +++ b/design-system/pkg/src/action-bar/test/ActionBar.test.tsx @@ -6,22 +6,18 @@ import { it, jest, } from '@jest/globals'; -// import { announce } from '@react-aria/live-announcer'; +import userEvent from '@testing-library/user-event'; import React from 'react'; -import { - act, - fireEvent, - firePress, - renderWithProvider, - within, -} from '#test-utils'; +import { act, renderWithProvider, within } from '#test-utils'; import { ListExample } from '../stories/ListExample'; // jest.mock('@react-aria/live-announcer'); describe('action-bar/ActionBar', () => { + let user: ReturnType; beforeAll(() => { + user = userEvent.setup({ delay: null }); jest .spyOn(window.HTMLElement.prototype, 'clientWidth', 'get') .mockImplementation(() => 1000); @@ -35,17 +31,15 @@ describe('action-bar/ActionBar', () => { act(() => jest.runAllTimers()); }); - it('should open when there are selected items', () => { + it('should open when there are selected items', async () => { let tree = renderWithProvider(); - act(() => { - jest.runAllTimers(); - }); + act(() => jest.runAllTimers()); let grid = tree.getByRole('grid'); let rows = within(grid).getAllByRole('row'); expect(tree.queryByRole('toolbar')).toBeNull(); - firePress(rows[1]); + await user.click(rows[1]); // FIXME: get this mock working // expect(announce).toHaveBeenCalledWith('Actions available.'); @@ -62,88 +56,78 @@ describe('action-bar/ActionBar', () => { expect(clearButton.tagName).toBe('BUTTON'); }); - it('should update the selected count when selecting more items', () => { + it('should update the selected count when selecting more items', async () => { let tree = renderWithProvider(); - act(() => { - jest.runAllTimers(); - }); + act(() => jest.runAllTimers()); let grid = tree.getByRole('grid'); let rows = within(grid).getAllByRole('row'); - firePress(rows[1]); + await user.click(rows[1]); let selectedCount = tree.getByText('1 selected'); - firePress(rows[2]); + await user.click(rows[2]); expect(selectedCount).toHaveTextContent('2 selected'); }); - it('should close and restore focus when pressing the clear button', () => { + it('should close and restore focus when pressing the clear button', async () => { let tree = renderWithProvider(); - act(() => { - jest.runAllTimers(); - }); + act(() => jest.runAllTimers()); let grid = tree.getByRole('grid'); let rows = within(grid).getAllByRole('row'); let checkbox = within(rows[1]).getByRole('checkbox'); - firePress(checkbox); + await user.click(checkbox); act(() => jest.runAllTimers()); expect(document.activeElement).toBe(checkbox); let clearButton = tree.getByLabelText('Clear selection'); - act(() => clearButton.focus()); - firePress(clearButton); + await user.click(clearButton); act(() => jest.runAllTimers()); act(() => jest.runAllTimers()); expect(tree.queryByRole('toolbar')).toBeNull(); - expect(document.activeElement).toBe(checkbox); + expect(document.activeElement).toBe(checkbox.closest('[role="row"]')); }); - it('should close when pressing the escape key', () => { + it('should close when pressing the escape key', async () => { let tree = renderWithProvider(); - act(() => { - jest.runAllTimers(); - }); + act(() => jest.runAllTimers()); - let grid = tree.getByRole('grid'); - let rows = within(grid).getAllByRole('row'); + let table = tree.getByRole('grid'); + let rows = within(table).getAllByRole('row'); let checkbox = within(rows[1]).getByRole('checkbox'); - firePress(checkbox); + await user.click(checkbox); act(() => jest.runAllTimers()); expect(document.activeElement).toBe(checkbox); let toolbar = tree.getByRole('toolbar'); act(() => within(toolbar).getAllByRole('button')[0].focus()); - fireEvent.keyDown(document.activeElement!, { key: 'Escape' }); - fireEvent.keyUp(document.activeElement!, { key: 'Escape' }); + await user.keyboard('{Escape}'); act(() => jest.runAllTimers()); act(() => jest.runAllTimers()); expect(tree.queryByRole('toolbar')).toBeNull(); - expect(document.activeElement).toBe(checkbox); + expect(document.activeElement).toBe(checkbox.closest('[role="row"]')); }); - it('should fire onAction when clicking on an action', () => { + it('should fire onAction when clicking on an action', async () => { let onAction = jest.fn(); let tree = renderWithProvider(); - act(() => { - jest.runAllTimers(); - }); + act(() => jest.runAllTimers()); let grid = tree.getByRole('grid'); let rows = within(grid).getAllByRole('row'); - firePress(rows[1]); + await user.click(rows[1]); let toolbar = tree.getByRole('toolbar'); - firePress(within(toolbar).getAllByRole('button')[0]); + await user.click(within(toolbar).getAllByRole('button')[0]); expect(onAction).toHaveBeenCalledWith('edit'); }); diff --git a/design-system/pkg/src/field/types.tsx b/design-system/pkg/src/field/types.tsx index f2b224233..700bd89a0 100644 --- a/design-system/pkg/src/field/types.tsx +++ b/design-system/pkg/src/field/types.tsx @@ -30,6 +30,7 @@ export type FieldProps = Pick< DOMProps; export type FieldPrimitiveProps = { + /** The field contents. */ children: ReactElement; /** A `ContextualHelp` element to place next to the label. */ contextualHelp?: ReactElement; @@ -38,12 +39,14 @@ export type FieldPrimitiveProps = { * field. */ description?: ReactNode; + /** Props for the description element. */ descriptionProps?: HTMLAttributes; /** * Error messages inform the user when the input does not meet validation * criteria. */ errorMessage?: ReactNode; + /** Props for the message element. */ errorMessageProps?: HTMLAttributes; /** Whether user input is required on the input before form submission. */ isRequired?: boolean; @@ -54,6 +57,7 @@ export type FieldPrimitiveProps = { * @default 'label' */ labelElementType?: HTMLTag; + /** Props for the label element. */ labelProps?: HTMLAttributes; /** * For controls that DO NOT use a semantic element for user input. In these diff --git a/design-system/pkg/src/menu/test/Menu.test.tsx b/design-system/pkg/src/menu/test/Menu.test.tsx index f8989b2bd..d8011d4c7 100644 --- a/design-system/pkg/src/menu/test/Menu.test.tsx +++ b/design-system/pkg/src/menu/test/Menu.test.tsx @@ -121,7 +121,7 @@ describe('menu/Menu', () => { let selectedItem = menuItems[3]; expect(selectedItem).toBe(document.activeElement); expect(selectedItem).toHaveAttribute('aria-checked', 'true'); - expect(selectedItem).toHaveAttribute('tabindex', '0'); + expect(selectedItem).toHaveAttribute('tabindex', '-1'); let itemText = within(selectedItem).getByText('Blah'); expect(itemText).toBeTruthy(); let checkmark: HTMLElement | null = within(selectedItem).getByRole( @@ -147,6 +147,7 @@ describe('menu/Menu', () => { expect(onSelectionChange).toHaveBeenCalledTimes(1); expect(onSelectionChange.mock.calls[0][0].has('Bleh')).toBeTruthy(); }); + it('supports `selectedKeys` (controlled)', () => { let tree = renderComponent({ selectionMode: 'single', @@ -160,7 +161,7 @@ describe('menu/Menu', () => { let selectedItem = menuItems[3]; expect(selectedItem).toBe(document.activeElement); expect(selectedItem).toHaveAttribute('aria-checked', 'true'); - expect(selectedItem).toHaveAttribute('tabindex', '0'); + expect(selectedItem).toHaveAttribute('tabindex', '-1'); let itemText = within(selectedItem).getByText('Blah'); expect(itemText).toBeTruthy(); let checkmark: HTMLElement | null = within(selectedItem).getByRole( diff --git a/design-system/pkg/src/menu/test/MenuTrigger.test.tsx b/design-system/pkg/src/menu/test/MenuTrigger.test.tsx index a1c7f4b2e..5a2f6d0f9 100644 --- a/design-system/pkg/src/menu/test/MenuTrigger.test.tsx +++ b/design-system/pkg/src/menu/test/MenuTrigger.test.tsx @@ -7,6 +7,17 @@ import { beforeAll, afterAll, } from '@jest/globals'; +import { + Item, + Menu, + MenuProps, + MenuTrigger, + MenuTriggerProps, + Section, +} from '..'; +import { Button, ButtonProps } from '@keystar/ui/button'; +import { SelectionMode } from '@react-types/shared'; +import { createRef } from 'react'; import { RenderResult, act, @@ -23,17 +34,6 @@ import { waitFor, } from '#test-utils'; -import { - Item, - Menu, - MenuProps, - MenuTrigger, - MenuTriggerProps, - Section, -} from '..'; -import { Button, ButtonProps } from '@keystar/ui/button'; -import { createRef } from 'react'; - let triggerText = 'Menu Button'; let withSection = [ @@ -213,7 +213,10 @@ describe('menu/MenuTrigger', () => { describe('default focus behavior', function () { it('autofocuses the selected item on menu open', function () { - let tree = renderComponent({}, { selectedKeys: ['Bar'] }); + let tree = renderComponent( + {}, + { selectedKeys: ['Bar'], selectionMode: 'single' } + ); act(() => { jest.runAllTimers(); }); @@ -224,7 +227,7 @@ describe('menu/MenuTrigger', () => { }); let menu = tree.getByRole('menu'); expect(menu).toBeTruthy(); - let menuItems = within(menu).getAllByRole('menuitem'); + let menuItems = within(menu).getAllByRole('menuitemradio'); let selectedItem = menuItems[1]; expect(selectedItem).toBe(document.activeElement); firePress(button); @@ -244,7 +247,7 @@ describe('menu/MenuTrigger', () => { jest.runAllTimers(); }); menu = tree.getByRole('menu'); - menuItems = within(menu).getAllByRole('menuitem'); + menuItems = within(menu).getAllByRole('menuitemradio'); selectedItem = menuItems[1]; expect(selectedItem).toBe(document.activeElement); firePress(button); @@ -256,7 +259,7 @@ describe('menu/MenuTrigger', () => { // Opening menu via up arrow still autofocuses the selected item fireEvent.keyDown(button, KEYS.ArrowUp); menu = tree.getByRole('menu'); - menuItems = within(menu).getAllByRole('menuitem'); + menuItems = within(menu).getAllByRole('menuitemradio'); selectedItem = menuItems[1]; expect(selectedItem).toBe(document.activeElement); }); @@ -895,10 +898,20 @@ describe('menu/MenuTrigger', () => { describe('trigger="longPress" focus behavior', function () { installPointerEvent(); - function expectMenuItemToBeActive(tree: RenderResult, idx: number) { + function expectMenuItemToBeActive( + tree: RenderResult, + idx: number, + selectionMode: SelectionMode + ) { + let menuItemRole = 'menuitem'; + if (selectionMode === 'multiple') { + menuItemRole = 'menuitemcheckbox'; + } else if (selectionMode === 'single') { + menuItemRole = 'menuitemradio'; + } let menu = tree.getByRole('menu'); expect(menu).toBeTruthy(); - let menuItems = within(menu).getAllByRole('menuitem'); + let menuItems = within(menu).getAllByRole(menuItemRole); let selectedItem = menuItems[idx < 0 ? menuItems.length + idx : idx]; expect(selectedItem).toBe(document.activeElement); return menu; @@ -907,14 +920,14 @@ describe('menu/MenuTrigger', () => { it('should focus the selected item on menu open', async function () { let tree = renderComponent( { trigger: 'longPress' }, - { selectedKeys: ['Bar'] } + { selectedKeys: ['Bar'], selectionMode: 'single' } ); let button = tree.getByRole('button'); act(() => { fireLongPress(button); jest.runAllTimers(); }); - let menu = expectMenuItemToBeActive(tree, 1); + let menu = expectMenuItemToBeActive(tree, 1, 'single'); act(() => { fireTouch(button); jest.runAllTimers(); @@ -926,7 +939,7 @@ describe('menu/MenuTrigger', () => { // Opening menu via Alt+ArrowUp still autofocuses the selected item fireEvent.keyDown(button, { key: 'ArrowUp', altKey: true }); - menu = expectMenuItemToBeActive(tree, 1); + menu = expectMenuItemToBeActive(tree, 1, 'single'); act(() => { fireTouch(button); @@ -938,7 +951,7 @@ describe('menu/MenuTrigger', () => { // Opening menu via Alt+ArrowDown still autofocuses the selected item fireEvent.keyDown(button, { key: 'ArrowDown', altKey: true }); - menu = expectMenuItemToBeActive(tree, 1); + menu = expectMenuItemToBeActive(tree, 1, 'single'); act(() => { fireTouch(button); @@ -953,14 +966,14 @@ describe('menu/MenuTrigger', () => { let tree = renderComponent({ trigger: 'longPress' }); let button = tree.getByRole('button'); fireEvent.keyDown(button, { key: 'ArrowUp', altKey: true }); - expectMenuItemToBeActive(tree, -1); + expectMenuItemToBeActive(tree, -1, 'none'); }); it('should focus the first item on Alt+ArrowDown if no selectedKeys specified', function () { let tree = renderComponent({ trigger: 'longPress' }); let button = tree.getByRole('button'); fireEvent.keyDown(button, { key: 'ArrowDown', altKey: true }); - expectMenuItemToBeActive(tree, 0); + expectMenuItemToBeActive(tree, 0, 'none'); }); }); }); diff --git a/design-system/pkg/src/picker/Picker.tsx b/design-system/pkg/src/picker/Picker.tsx index 70c9c8ec9..89380bb7b 100644 --- a/design-system/pkg/src/picker/Picker.tsx +++ b/design-system/pkg/src/picker/Picker.tsx @@ -60,9 +60,8 @@ function Picker( // We create the listbox layout in Picker and pass it to ListBoxBase below // so that the layout information can be cached even while the listbox is not mounted. - // We also use the layout as the keyboard delegate for type to select. + let layout = useListBoxLayout(); let state = useSelectState(props); - let layout = useListBoxLayout(state); let { labelProps, triggerProps, @@ -70,7 +69,7 @@ function Picker( menuProps, descriptionProps, errorMessageProps, - } = useSelect({ ...props, keyboardDelegate: layout }, state, triggerRef); + } = useSelect(props, state, triggerRef); let isMobile = useIsMobileDevice(); let isLoadingInitial = props.isLoading && state.collection.size === 0; diff --git a/design-system/pkg/src/toast/Toast.tsx b/design-system/pkg/src/toast/Toast.tsx index 69435fb42..5893471da 100644 --- a/design-system/pkg/src/toast/Toast.tsx +++ b/design-system/pkg/src/toast/Toast.tsx @@ -8,6 +8,7 @@ import { Icon } from '@keystar/ui/icon'; import { checkCircle2Icon } from '@keystar/ui/icon/icons/checkCircle2Icon'; import { infoIcon } from '@keystar/ui/icon/icons/infoIcon'; import { alertTriangleIcon } from '@keystar/ui/icon/icons/alertTriangleIcon'; +import { SlotProvider } from '@keystar/ui/slots'; import { classNames, css, @@ -20,7 +21,6 @@ import { isReactText } from '@keystar/ui/utils'; import intlMessages from './l10n.json'; import { ToastProps } from './types'; -import { SlotProvider } from '@keystar/ui/slots'; const ICONS = { info: infoIcon, @@ -40,7 +40,7 @@ function Toast(props: ToastProps, ref: ForwardedRef) { ...otherProps } = props; let domRef = useObjectRef(ref); - let { closeButtonProps, titleProps, toastProps } = useToast( + let { closeButtonProps, titleProps, toastProps, contentProps } = useToast( props, state, domRef @@ -124,50 +124,52 @@ function Toast(props: ToastProps, ref: ForwardedRef) { }} > - {icon && ( - - )} -
+ {icon && ( + )} - >
- {isReactText(children) ? {children} : children} -
- {actionLabel && ( - - )} + {isReactText(children) ? {children} : children} +
+ {actionLabel && ( + + )} +
{ + let user: ReturnType; + + beforeAll(() => { + user = userEvent.setup({ delay: null }); + }); beforeEach(() => { jest.useFakeTimers(); clearToastQueue(); @@ -61,35 +68,44 @@ describe('toast/Toast', () => { act(() => jest.runAllTimers()); }); - it('renders a button that triggers a toast', () => { + it('renders a button that triggers a toast', async () => { let { getByRole, queryByRole } = renderComponent(); let button = getByRole('button'); + expect(queryByRole('alertdialog')).toBeNull(); expect(queryByRole('alert')).toBeNull(); - firePress(button); + await user.click(button); + + act(() => jest.advanceTimersByTime(100)); let region = getByRole('region'); - expect(region).toHaveAttribute('aria-label', 'Notifications'); + expect(region).toHaveAttribute('aria-label', '1 notification.'); - let alert = getByRole('alert'); + let toast = getByRole('alertdialog'); + let alert = within(toast).getByRole('alert'); + expect(toast).toBeVisible(); expect(alert).toBeVisible(); - button = within(alert).getByRole('button'); + button = within(toast).getByRole('button'); expect(button).toHaveAttribute('aria-label', 'Close'); - firePress(button); + await user.click(button); fireAnimationEnd(alert); + expect(queryByRole('alertdialog')).toBeNull(); expect(queryByRole('alert')).toBeNull(); }); - it('should label icon by tone', () => { + it('should label icon by tone', async () => { let { getByRole } = renderComponent(); let button = getByRole('button'); - firePress(button); + await user.click(button); - let alert = getByRole('alert'); + let toast = getByRole('alertdialog'); + let alert = within(toast).getByRole('alert'); let icon = within(alert).getByRole('img'); expect(icon).toHaveAttribute('aria-label', 'Success'); + let title = within(alert).getByText('Toast is default').parentElement!; // content is wrapped + expect(toast).toHaveAttribute('aria-labelledby', `${title.id}`); }); it('removes a toast via timeout', () => { @@ -100,7 +116,7 @@ describe('toast/Toast', () => { firePress(button); - let toast = getByRole('alert'); + let toast = getByRole('alertdialog'); expect(toast).toBeVisible(); act(() => jest.advanceTimersByTime(1000)); @@ -110,55 +126,44 @@ describe('toast/Toast', () => { expect(toast).toHaveAttribute('data-animation', 'exiting'); fireAnimationEnd(toast); - expect(queryByRole('alert')).toBeNull(); + expect(queryByRole('alertdialog')).toBeNull(); }); - // TODO: Can't get this working + it sometimes takes down the other tests... - // it('pauses timers when hovering', () => { - // let { getByRole, queryByRole } = renderComponent( - // - // ); - // let button = getByRole('button'); + it('pauses timers when hovering', async () => { + let { getByRole, queryByRole } = renderComponent( + + ); + let button = getByRole('button'); - // firePress(button); + await user.click(button); - // let toast = getByRole('alert'); - // expect(toast).toBeVisible(); + let toast = getByRole('alertdialog'); + expect(toast).toBeVisible(); - // act(() => { - // jest.advanceTimersByTime(1000); - // }); - // act(() => { - // userEvent.hover(toast); - // }); + act(() => jest.advanceTimersByTime(1000)); + await user.hover(toast); - // act(() => { - // jest.advanceTimersByTime(7000); - // }); - // expect(toast).not.toHaveAttribute('data-animation', 'exiting'); + act(() => jest.advanceTimersByTime(7000)); + expect(toast).not.toHaveAttribute('data-animation', 'exiting'); - // act(() => { - // userEvent.unhover(toast); - // }); + await user.unhover(toast); - // act(() => { - // jest.advanceTimersByTime(4000); - // }); - // expect(toast).toHaveAttribute('data-animation', 'exiting'); + act(() => jest.advanceTimersByTime(4000)); + expect(toast).toHaveAttribute('data-animation', 'exiting'); - // fireAnimationEnd(toast); - // expect(queryByRole('alert')).toBeNull(); - // }); + fireAnimationEnd(toast); + expect(queryByRole('alertdialog')).toBeNull(); + }); - it('pauses timers when focusing', () => { + it('pauses timers when focusing', async () => { let { getByRole, queryByRole } = renderComponent( ); let button = getByRole('button'); - firePress(button); + await user.click(button); - let toast = getByRole('alert'); + let toast = getByRole('alertdialog'); expect(toast).toBeVisible(); act(() => jest.advanceTimersByTime(1000)); @@ -173,10 +178,10 @@ describe('toast/Toast', () => { expect(toast).toHaveAttribute('data-animation', 'exiting'); fireAnimationEnd(toast); - expect(queryByRole('alert')).toBeNull(); + expect(queryByRole('alertdialog')).toBeNull(); }); - it('renders a toast with an action', () => { + it('renders a toast with an action', async () => { let onAction = jest.fn(); let onClose = jest.fn(); let { getByRole, queryByRole } = renderComponent( @@ -188,21 +193,24 @@ describe('toast/Toast', () => { ); let button = getByRole('button'); - expect(queryByRole('alert')).toBeNull(); - firePress(button); + expect(queryByRole('alertdialog')).toBeNull(); + await user.click(button); - let alert = getByRole('alert'); + act(() => jest.advanceTimersByTime(100)); + let toast = getByRole('alertdialog'); + let alert = within(toast).getByRole('alert'); + expect(toast).toBeVisible(); expect(alert).toBeVisible(); let buttons = within(alert).getAllByRole('button'); expect(buttons[0]).toHaveTextContent('Action'); - firePress(buttons[0]); + await user.click(buttons[0]); expect(onAction).toHaveBeenCalledTimes(1); expect(onClose).not.toHaveBeenCalled(); }); - it('closes toast on action', () => { + it('closes toast on action', async () => { let onAction = jest.fn(); let onClose = jest.fn(); let { getByRole, queryByRole } = renderComponent( @@ -215,25 +223,28 @@ describe('toast/Toast', () => { ); let button = getByRole('button'); - expect(queryByRole('alert')).toBeNull(); - firePress(button); + expect(queryByRole('alertdialog')).toBeNull(); + await user.click(button); - let alert = getByRole('alert'); + act(() => jest.advanceTimersByTime(100)); + let toast = getByRole('alertdialog'); + let alert = within(toast).getByRole('alert'); + expect(toast).toBeVisible(); expect(alert).toBeVisible(); - let buttons = within(alert).getAllByRole('button'); + let buttons = within(toast).getAllByRole('button'); expect(buttons[0]).toHaveTextContent('Action'); - firePress(buttons[0]); + await user.click(buttons[0]); expect(onAction).toHaveBeenCalledTimes(1); expect(onClose).toHaveBeenCalledTimes(1); - expect(alert).toHaveAttribute('data-animation', 'exiting'); - fireAnimationEnd(alert); - expect(queryByRole('alert')).toBeNull(); + expect(toast).toHaveAttribute('data-animation', 'exiting'); + fireAnimationEnd(toast); + expect(queryByRole('alertdialog')).toBeNull(); }); - it('prioritizes toasts based on tone', () => { + it('prioritizes toasts based on tone', async () => { function ToastPriorites(props = {}) { return (
@@ -252,57 +263,57 @@ describe('toast/Toast', () => { // show info toast first. error toast should supersede it. - expect(queryByRole('alert')).toBeNull(); - firePress(buttons[0]); + expect(queryByRole('alertdialog')).toBeNull(); + await user.click(buttons[0]); - let alert = getByRole('alert'); - expect(alert).toBeVisible(); - expect(alert).toHaveTextContent('Info'); + let toast = getByRole('alertdialog'); + expect(toast).toBeVisible(); + expect(toast).toHaveTextContent('Info'); - firePress(buttons[1]); - fireAnimationEnd(alert); + await user.click(buttons[1]); + fireAnimationEnd(toast); - alert = getByRole('alert'); - expect(alert).toHaveTextContent('Error'); + toast = getByRole('alertdialog'); + expect(toast).toHaveTextContent('Error'); - firePress(within(alert).getByRole('button')); - fireAnimationEnd(alert); + await user.click(within(toast).getByRole('button')); + fireAnimationEnd(toast); - alert = getByRole('alert'); - expect(alert).toHaveTextContent('Info'); + toast = getByRole('alertdialog'); + expect(toast).toHaveTextContent('Info'); - firePress(within(alert).getByRole('button')); - fireAnimationEnd(alert); - expect(queryByRole('alert')).toBeNull(); + await user.click(within(toast).getByRole('button')); + fireAnimationEnd(toast); + expect(queryByRole('alertdialog')).toBeNull(); // again, but with error toast first. - firePress(buttons[1]); - alert = getByRole('alert'); - expect(alert).toHaveTextContent('Error'); + await user.click(buttons[1]); + toast = getByRole('alertdialog'); + expect(toast).toHaveTextContent('Error'); - firePress(buttons[0]); - alert = getByRole('alert'); - expect(alert).toHaveTextContent('Error'); + await user.click(buttons[0]); + toast = getByRole('alertdialog'); + expect(toast).toHaveTextContent('Error'); - firePress(within(alert).getByRole('button')); - fireAnimationEnd(alert); + await user.click(within(toast).getByRole('button')); + fireAnimationEnd(toast); - alert = getByRole('alert'); - expect(alert).toHaveTextContent('Info'); + toast = getByRole('alertdialog'); + expect(toast).toHaveTextContent('Info'); - firePress(within(alert).getByRole('button')); - fireAnimationEnd(alert); - expect(queryByRole('alert')).toBeNull(); + await user.click(within(toast).getByRole('button')); + fireAnimationEnd(toast); + expect(queryByRole('alertdialog')).toBeNull(); }); - it('can focus toast region using F6', () => { + it('can focus toast region using F6', async () => { let { getByRole } = renderComponent(); let button = getByRole('button'); - firePress(button); + await user.click(button); - let toast = getByRole('alert'); + let toast = getByRole('alertdialog'); expect(toast).toBeVisible(); expect(document.activeElement).toBe(button); @@ -313,46 +324,45 @@ describe('toast/Toast', () => { expect(document.activeElement).toBe(region); }); - it('should restore focus when a toast exits', () => { + it('should restore focus when a toast exits', async () => { let { getByRole, queryByRole } = renderComponent(); let button = getByRole('button'); - firePress(button); + await user.click(button); - let toast = getByRole('alert'); + let toast = getByRole('alertdialog'); let closeButton = within(toast).getByRole('button'); - act(() => closeButton.focus()); - firePress(closeButton); + await user.click(closeButton); fireAnimationEnd(toast); - expect(queryByRole('alert')).toBeNull(); - expect(document.activeElement).toBe(button); + expect(queryByRole('alertdialog')).toBeNull(); + expect(button).toHaveFocus(); }); - it('should move focus to container when a toast exits and there are more', () => { + it('should move focus to the next available toast, when closed', async () => { let { getByRole, queryByRole } = renderComponent(); let button = getByRole('button'); - firePress(button); - firePress(button); + await user.click(button); + await user.click(button); - let toast = getByRole('alert'); + let toast = getByRole('alertdialog'); let closeButton = within(toast).getByRole('button'); - firePress(closeButton); + await user.click(closeButton); fireAnimationEnd(toast); - expect(document.activeElement).toBe(getByRole('region')); - - toast = getByRole('alert'); + // next toast + toast = getByRole('alertdialog'); + expect(document.activeElement).toBe(toast); closeButton = within(toast).getByRole('button'); - firePress(closeButton); + await user.click(closeButton); fireAnimationEnd(toast); - expect(queryByRole('alert')).toBeNull(); + expect(queryByRole('alertdialog')).toBeNull(); expect(document.activeElement).toBe(button); }); - it('should support programmatically closing toasts', () => { + it('should support programmatically closing toasts', async () => { function ToastToggle() { let [close, setClose] = useState<(() => void) | null>(null); @@ -373,17 +383,17 @@ describe('toast/Toast', () => { let { getByRole, queryByRole } = renderComponent(); let button = getByRole('button'); - firePress(button); + await user.click(button); let toast = getByRole('alert'); expect(toast).toBeVisible(); - firePress(button); + await user.click(button); fireAnimationEnd(toast); expect(queryByRole('alert')).toBeNull(); }); - it('should only render one Toaster', () => { + it('should only render one Toaster', async () => { let { getByRole, getAllByRole, rerender } = renderWithProvider( <> @@ -393,10 +403,10 @@ describe('toast/Toast', () => { ); let button = getByRole('button'); - firePress(button); + await user.click(button); expect(getAllByRole('region')).toHaveLength(1); - expect(getAllByRole('alert')).toHaveLength(1); + expect(getAllByRole('alertdialog')).toHaveLength(1); rerender( <> @@ -406,7 +416,7 @@ describe('toast/Toast', () => { ); expect(getAllByRole('region')).toHaveLength(1); - expect(getAllByRole('alert')).toHaveLength(1); + expect(getAllByRole('alertdialog')).toHaveLength(1); rerender( <> @@ -416,7 +426,7 @@ describe('toast/Toast', () => { ); expect(getAllByRole('region')).toHaveLength(1); - expect(getAllByRole('alert')).toHaveLength(1); + expect(getAllByRole('alertdialog')).toHaveLength(1); rerender( <> @@ -427,7 +437,7 @@ describe('toast/Toast', () => { ); expect(getAllByRole('region')).toHaveLength(1); - expect(getAllByRole('alert')).toHaveLength(1); + expect(getAllByRole('alertdialog')).toHaveLength(1); }); it('should support custom aria-label', () => { diff --git a/design-system/pkg/src/tooltip/test/TooltipTrigger.test.tsx b/design-system/pkg/src/tooltip/test/TooltipTrigger.test.tsx index 4836321a1..56bc5548a 100644 --- a/design-system/pkg/src/tooltip/test/TooltipTrigger.test.tsx +++ b/design-system/pkg/src/tooltip/test/TooltipTrigger.test.tsx @@ -1,4 +1,5 @@ import '@testing-library/jest-dom/jest-globals'; +import userEvent from '@testing-library/user-event'; import { act, fireEvent, @@ -29,8 +30,10 @@ const LEAVE_TIMEOUT = 320; // NOTE: skipped tests have something to do with mouse events and timers... describe('tooltip/TooltipTrigger', () => { let onOpenChange = jest.fn(); + let user: ReturnType; beforeAll(() => { + user = userEvent.setup({ delay: null }); jest.useFakeTimers(); }); @@ -85,26 +88,21 @@ describe('tooltip/TooltipTrigger', () => { expect(tooltip).not.toBeInTheDocument(); }); - // eslint-disable-next-line jest/no-disabled-tests - it.skip('opens for hover', async () => { + it('opens for hover', async () => { let { getByRole, getByLabelText } = renderWithProvider(