@astryxdesign/core 0.7.4 → 0.7.5-canary.04434e7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlertDialog/AlertDialog.d.ts +2 -2
- package/dist/AlertDialog/index.d.ts +4 -4
- package/dist/AlertDialog/useImperativeAlertDialog.d.ts +1 -1
- package/dist/AppShell/AppShell.d.ts +4 -4
- package/dist/AppShell/index.d.ts +4 -4
- package/dist/AspectRatio/AspectRatio.d.ts +1 -1
- package/dist/AspectRatio/index.d.ts +2 -2
- package/dist/Avatar/Avatar.d.ts +2 -2
- package/dist/Avatar/AvatarStatusDot.d.ts +2 -2
- package/dist/Avatar/index.d.ts +4 -4
- package/dist/AvatarGroup/AvatarGroup.d.ts +2 -2
- package/dist/AvatarGroup/AvatarGroupContext.d.ts +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
- package/dist/AvatarGroup/index.d.ts +6 -6
- package/dist/Badge/Badge.d.ts +2 -2
- package/dist/Badge/index.d.ts +2 -2
- package/dist/Banner/Banner.d.ts +4 -4
- package/dist/Banner/index.d.ts +2 -2
- package/dist/Blockquote/Blockquote.d.ts +1 -1
- package/dist/Blockquote/index.d.ts +2 -2
- package/dist/BottomSheet/BottomSheet.d.ts +10 -6
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +12 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts +3 -3
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts +1 -1
- package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +2 -2
- package/dist/BottomSheet/index.d.ts +4 -4
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +4 -4
- package/dist/Breadcrumbs/Breadcrumbs.d.ts +2 -2
- package/dist/Breadcrumbs/index.d.ts +12 -12
- package/dist/Button/Button.d.ts +4 -4
- package/dist/Button/index.d.ts +2 -2
- package/dist/ButtonGroup/ButtonGroup.d.ts +4 -4
- package/dist/ButtonGroup/index.d.ts +4 -4
- package/dist/Calendar/Calendar.d.ts +3 -3
- package/dist/Calendar/dayCellUtils.d.ts +1 -1
- package/dist/Calendar/getInitialFocusDate.d.ts +2 -2
- package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts +1 -1
- package/dist/Calendar/hooks/index.d.ts +6 -6
- package/dist/Calendar/hooks/useCalendarConstraints.d.ts +2 -2
- package/dist/Calendar/hooks/useCalendarDays.d.ts +2 -2
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts +2 -2
- package/dist/Calendar/index.d.ts +5 -5
- package/dist/Calendar/utils.d.ts +1 -1
- package/dist/Card/Card.d.ts +4 -4
- package/dist/Card/index.d.ts +2 -2
- package/dist/Carousel/Carousel.d.ts +2 -2
- package/dist/Carousel/index.d.ts +2 -2
- package/dist/Center/Center.d.ts +2 -2
- package/dist/Center/index.d.ts +2 -2
- package/dist/Chat/ChatComposer.d.ts +1 -1
- package/dist/Chat/ChatComposerDrawer.d.ts +1 -1
- package/dist/Chat/ChatComposerInput.d.ts +4 -4
- package/dist/Chat/ChatDictationButton.d.ts +2 -2
- package/dist/Chat/ChatLayout.d.ts +1 -1
- package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
- package/dist/Chat/ChatMessage.d.ts +2 -2
- package/dist/Chat/ChatMessageBubble.d.ts +2 -2
- package/dist/Chat/ChatMessageList.d.ts +3 -3
- package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
- package/dist/Chat/ChatSendButton.d.ts +1 -1
- package/dist/Chat/ChatSystemMessage.d.ts +1 -1
- package/dist/Chat/ChatTokenizedText.d.ts +2 -2
- package/dist/Chat/ChatToolCalls.d.ts +1 -1
- package/dist/Chat/index.d.ts +43 -43
- package/dist/Chat/useChatComposerTokens.d.ts +1 -1
- package/dist/Chat/useChatDictation.d.ts +1 -1
- package/dist/Chat/useChatPasteAsToken.d.ts +1 -1
- package/dist/Chat/useTriggerMenu.d.ts +2 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts +4 -4
- package/dist/CheckboxInput/index.d.ts +2 -2
- package/dist/CheckboxList/CheckboxList.d.ts +4 -4
- package/dist/CheckboxList/CheckboxListItem.d.ts +2 -2
- package/dist/CheckboxList/index.d.ts +4 -4
- package/dist/Citation/Citation.d.ts +1 -1
- package/dist/Citation/index.d.ts +2 -2
- package/dist/ClickableCard/ClickableCard.d.ts +3 -3
- package/dist/ClickableCard/index.d.ts +2 -2
- package/dist/Code/Code.d.ts +1 -1
- package/dist/Code/index.d.ts +1 -1
- package/dist/CodeBlock/CodeBlock.d.ts +2 -2
- package/dist/CodeBlock/highlightRanges.d.ts +1 -1
- package/dist/CodeBlock/index.d.ts +8 -8
- package/dist/Collapsible/Collapsible.d.ts +2 -2
- package/dist/Collapsible/CollapsibleGroup.d.ts +2 -2
- package/dist/Collapsible/index.d.ts +7 -7
- package/dist/CommandPalette/CommandPalette.d.ts +2 -2
- package/dist/CommandPalette/CommandPaletteContext.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteFooter.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteGroup.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteItem.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteList.d.ts +1 -1
- package/dist/CommandPalette/index.d.ts +16 -16
- package/dist/ComplexSelector/ComplexSelector.d.ts +5 -5
- package/dist/ComplexSelector/index.d.ts +1 -1
- package/dist/ContextMenu/ContextMenu.d.ts +4 -4
- package/dist/ContextMenu/index.d.ts +9 -9
- package/dist/DateInput/DateInput.d.ts +7 -7
- package/dist/DateInput/MonthScroller.d.ts +1 -1
- package/dist/DateInput/NativeDateField.d.ts +1 -1
- package/dist/DateInput/TouchDateField.d.ts +1 -1
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +1 -1
- package/dist/DateInput/index.d.ts +2 -2
- package/dist/DateInput/monthGeometry.d.ts +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts +6 -6
- package/dist/DateRangeInput/index.d.ts +2 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts +6 -6
- package/dist/DateTimeInput/NativeDateSegment.d.ts +3 -3
- package/dist/DateTimeInput/NativeTimeSegment.d.ts +4 -4
- package/dist/DateTimeInput/TouchDateTimeField.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts +2 -2
- package/dist/Dialog/Dialog.d.ts +3 -3
- package/dist/Dialog/DialogHeader.d.ts +1 -1
- package/dist/Dialog/index.d.ts +6 -6
- package/dist/Dialog/useImperativeDialog.d.ts +1 -1
- package/dist/Divider/Divider.d.ts +2 -2
- package/dist/Divider/index.d.ts +2 -2
- package/dist/Drawer/Drawer.d.ts +3 -3
- package/dist/Drawer/DrawerHeader.d.ts +1 -1
- package/dist/Drawer/index.d.ts +4 -4
- package/dist/DropdownMenu/DropdownMenu.d.ts +5 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +2 -2
- package/dist/DropdownMenu/DropdownMenuDivider.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuGroup.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +12 -7
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +13 -5
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +2 -2
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +1 -1
- package/dist/DropdownMenu/index.d.ts +10 -10
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +2 -2
- package/dist/DropdownMenu/renderDropdownItems.d.ts +1 -1
- package/dist/DropdownMenu/useMenuDrillIn.d.ts +1 -1
- package/dist/EmptyState/EmptyState.d.ts +1 -1
- package/dist/EmptyState/index.d.ts +2 -2
- package/dist/Field/Field.d.ts +5 -5
- package/dist/Field/FieldLabel.d.ts +2 -2
- package/dist/Field/PanelSearchInput.d.ts +1 -1
- package/dist/Field/fieldInputFamily.testing.d.ts +1 -1
- package/dist/Field/fieldParts.d.ts +1 -1
- package/dist/Field/index.d.ts +10 -10
- package/dist/Field/inputDisabledFocus.d.ts +14 -0
- package/dist/Field/inputDisabledFocus.d.ts.map +1 -0
- package/dist/Field/inputDisabledFocus.js +19 -0
- package/dist/FieldStatus/FieldStatus.d.ts +3 -3
- package/dist/FieldStatus/index.d.ts +2 -2
- package/dist/FieldStatus/useFieldStatusAnnouncement.d.ts +1 -1
- package/dist/FileInput/FileInput.d.ts +4 -4
- package/dist/FileInput/index.d.ts +2 -2
- package/dist/FormLayout/FormLayout.d.ts +2 -2
- package/dist/FormLayout/index.d.ts +4 -4
- package/dist/Grid/Grid.d.ts +3 -3
- package/dist/Grid/GridSpan.d.ts +1 -1
- package/dist/Grid/index.d.ts +4 -4
- package/dist/HStack/HStack.d.ts +2 -2
- package/dist/HStack/index.d.ts +1 -1
- package/dist/Heading/Heading.d.ts +4 -4
- package/dist/Heading/index.d.ts +1 -1
- package/dist/HoverCard/HoverCard.d.ts +4 -4
- package/dist/HoverCard/index.d.ts +4 -4
- package/dist/HoverCard/useHoverCard.d.ts +2 -2
- package/dist/Icon/Icon.d.ts +3 -3
- package/dist/Icon/IconDefaultSizeContext.d.ts +1 -1
- package/dist/Icon/defaultIcons.d.ts +1 -1
- package/dist/Icon/globalIconRegistry.d.ts +1 -1
- package/dist/Icon/index.d.ts +5 -5
- package/dist/Icon/useIcon.d.ts +1 -1
- package/dist/IconButton/IconButton.d.ts +1 -1
- package/dist/IconButton/index.d.ts +2 -2
- package/dist/Indicator/CheckIndicator.d.ts +1 -1
- package/dist/Indicator/CheckboxIndicator.d.ts +1 -1
- package/dist/Indicator/RadioIndicator.d.ts +1 -1
- package/dist/Indicator/index.d.ts +8 -8
- package/dist/Indicator/indicatorRegistry.d.ts +2 -2
- package/dist/Indicator/types.d.ts +1 -1
- package/dist/Indicator/useIndicator.d.ts +2 -2
- package/dist/InputGroup/InputGroup.d.ts +2 -2
- package/dist/InputGroup/InputGroupText.d.ts +1 -1
- package/dist/InputGroup/index.d.ts +6 -6
- package/dist/InteractiveRoleContext/InteractiveRoleContext.d.ts +1 -1
- package/dist/InteractiveRoleContext/index.d.ts +1 -1
- package/dist/Item/Item.d.ts +1 -1
- package/dist/Item/ItemSwipeLayer.d.ts +2 -2
- package/dist/Item/index.d.ts +2 -2
- package/dist/Kbd/Kbd.d.ts +1 -1
- package/dist/Kbd/index.d.ts +2 -2
- package/dist/Layer/LayerProvider.d.ts +1 -1
- package/dist/Layer/index.d.ts +18 -18
- package/dist/Layer/layerInset.d.ts +1 -1
- package/dist/Layer/layerSlideRules.d.ts +1 -1
- package/dist/Layer/modalOutlet.d.ts +1 -1
- package/dist/Layer/modalOutlet.js +1 -1
- package/dist/Layer/useLayerDismissal.d.ts +1 -1
- package/dist/Layer/useTouchTrigger.d.ts +14 -1
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
- package/dist/Layer/useTouchTrigger.js +72 -17
- package/dist/Layout/Layout.d.ts +2 -2
- package/dist/Layout/LayoutContent.d.ts +2 -2
- package/dist/Layout/LayoutFooter.d.ts +2 -2
- package/dist/Layout/LayoutHeader.d.ts +2 -2
- package/dist/Layout/LayoutPanel.d.ts +3 -3
- package/dist/Layout/index.d.ts +29 -29
- package/dist/Layout/padding.stylex.d.ts +1 -1
- package/dist/Lightbox/Lightbox.d.ts +1 -1
- package/dist/Lightbox/index.d.ts +4 -4
- package/dist/Lightbox/useLightbox.d.ts +1 -1
- package/dist/Link/Link.d.ts +3 -3
- package/dist/Link/LinkContext.d.ts +1 -1
- package/dist/Link/LinkProvider.d.ts +1 -1
- package/dist/Link/index.d.ts +8 -8
- package/dist/Link/useLinkComponent.d.ts +1 -1
- package/dist/List/List.d.ts +3 -3
- package/dist/List/ListItem.d.ts +2 -2
- package/dist/List/index.d.ts +4 -4
- package/dist/Markdown/Markdown.d.ts +4 -4
- package/dist/Markdown/headingProjection.d.ts +3 -3
- package/dist/Markdown/index.d.ts +7 -7
- package/dist/Markdown/parser/index.d.ts +3 -3
- package/dist/Markdown/parser.d.ts +3 -3
- package/dist/Markdown/plugin-renderer/MarkdownPluginNodeRenderer.d.ts +1 -1
- package/dist/Markdown/plugin-renderer/index.d.ts +2 -2
- package/dist/Markdown/plugins/frontmatter.d.ts +2 -2
- package/dist/Markdown/plugins/headingLinks.d.ts +2 -2
- package/dist/Markdown/plugins/index.d.ts +14 -14
- package/dist/Markdown/plugins/protocol.d.ts +1 -1
- package/dist/Markdown/plugins/semanticFence.d.ts +2 -2
- package/dist/Markdown/plugins/softBreaks.d.ts +1 -1
- package/dist/Markdown/plugins/sourceDecoration.d.ts +2 -2
- package/dist/Markdown/plugins/sourceLines.d.ts +1 -1
- package/dist/Markdown/plugins/textTransform.d.ts +2 -2
- package/dist/Markdown/remark.d.ts +1 -1
- package/dist/Markdown/utils.d.ts +4 -4
- package/dist/MetadataList/MetadataList.d.ts +2 -2
- package/dist/MetadataList/MetadataListItem.d.ts +1 -1
- package/dist/MetadataList/index.d.ts +5 -5
- package/dist/MobileNav/MobileNav.d.ts +1 -1
- package/dist/MobileNav/MobileNavToggle.d.ts +1 -1
- package/dist/MobileNav/index.d.ts +4 -4
- package/dist/MoreMenu/MoreMenu.d.ts +4 -4
- package/dist/MoreMenu/index.d.ts +1 -1
- package/dist/MultiSelector/MultiSelector.d.ts +7 -7
- package/dist/MultiSelector/hooks.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts +3 -3
- package/dist/MultiSelector/types.d.ts +1 -1
- package/dist/NavIcon/NavIcon.d.ts +1 -1
- package/dist/NavIcon/index.d.ts +2 -2
- package/dist/NavMenu/NavHeadingMenu.d.ts +2 -2
- package/dist/NavMenu/NavHeadingMenuItem.d.ts +2 -2
- package/dist/NavMenu/index.d.ts +6 -6
- package/dist/NumberInput/NumberInput.d.ts +8 -8
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +46 -20
- package/dist/NumberInput/index.d.ts +2 -2
- package/dist/NumberInput/numberInputCommit.d.ts +1 -1
- package/dist/NumberInput/numberParser.d.ts +1 -1
- package/dist/Outline/Outline.d.ts +3 -3
- package/dist/Outline/index.d.ts +7 -7
- package/dist/Outline/parseOutlineFromMarkdown.d.ts +2 -2
- package/dist/Outline/useOutlineFromDOM.d.ts +1 -1
- package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -3
- package/dist/Outline/useScrollSpy.d.ts +1 -1
- package/dist/OverflowList/OverflowList.d.ts +2 -2
- package/dist/OverflowList/index.d.ts +2 -2
- package/dist/Overlay/Overlay.d.ts +2 -2
- package/dist/Overlay/index.d.ts +5 -5
- package/dist/Overlay/useOverlay.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts +2 -2
- package/dist/Pagination/index.d.ts +2 -2
- package/dist/Popover/Popover.d.ts +3 -3
- package/dist/Popover/index.d.ts +4 -4
- package/dist/Popover/usePopover.d.ts +2 -2
- package/dist/PowerSearch/PowerSearch.d.ts +5 -5
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts +2 -2
- package/dist/PowerSearch/PowerSearchFilterEditor.d.ts +1 -1
- package/dist/PowerSearch/PowerSearchToken.d.ts +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts +2 -2
- package/dist/PowerSearch/formatFilterValue.d.ts +3 -3
- package/dist/PowerSearch/index.d.ts +8 -8
- package/dist/PowerSearch/resolveDateTimeRangePart.d.ts +1 -1
- package/dist/PowerSearch/resolveOperatorLabel.d.ts +2 -2
- package/dist/PowerSearch/types.d.ts +1 -1
- package/dist/PowerSearch/useInternalConfig.d.ts +1 -1
- package/dist/PowerSearch/usePowerSearchConfig.d.ts +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts +3 -3
- package/dist/PowerSearch/utils.d.ts +3 -3
- package/dist/ProgressBar/ProgressBar.d.ts +2 -2
- package/dist/ProgressBar/index.d.ts +2 -2
- package/dist/RadioList/RadioList.d.ts +3 -3
- package/dist/RadioList/RadioListItem.d.ts +2 -2
- package/dist/RadioList/index.d.ts +4 -4
- package/dist/Resizable/ResizeHandle.d.ts +2 -2
- package/dist/Resizable/index.d.ts +6 -6
- package/dist/Resizable/useResizable.d.ts +2 -2
- package/dist/Resizable/utils.d.ts +3 -3
- package/dist/ScrollableArea/ScrollableArea.d.ts +3 -3
- package/dist/ScrollableArea/index.d.ts +4 -4
- package/dist/Section/Section.d.ts +3 -3
- package/dist/Section/index.d.ts +2 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts +2 -2
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/index.d.ts +5 -5
- package/dist/SelectableCard/SelectableCard.d.ts +3 -3
- package/dist/SelectableCard/index.d.ts +2 -2
- package/dist/Selector/Selector.d.ts +8 -8
- package/dist/Selector/SelectorOption.d.ts +1 -1
- package/dist/Selector/hooks.d.ts +1 -1
- package/dist/Selector/index.d.ts +4 -4
- package/dist/Selector/types.d.ts +1 -1
- package/dist/Selector/useSelectorPresentation.d.ts +2 -2
- package/dist/Selector/utils.d.ts +1 -1
- package/dist/SideNav/SideNav.d.ts +3 -3
- package/dist/SideNav/SideNavCollapseButton.d.ts +3 -3
- package/dist/SideNav/SideNavHeading.d.ts +2 -2
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +34 -0
- package/dist/SideNav/SideNavItem.d.ts +4 -4
- package/dist/SideNav/SideNavSection.d.ts +1 -1
- package/dist/SideNav/index.d.ts +14 -14
- package/dist/SizeContext/index.d.ts +1 -1
- package/dist/Skeleton/Skeleton.d.ts +1 -1
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +12 -3
- package/dist/Skeleton/index.d.ts +2 -2
- package/dist/Slider/Slider.d.ts +3 -3
- package/dist/Slider/index.d.ts +2 -2
- package/dist/Spinner/Spinner.d.ts +1 -1
- package/dist/Spinner/index.d.ts +2 -2
- package/dist/Stack/Stack.d.ts +3 -3
- package/dist/Stack/StackItem.d.ts +2 -2
- package/dist/Stack/index.d.ts +6 -6
- package/dist/Stack/stack.stylex.d.ts +1 -1
- package/dist/StatusDot/StatusDot.d.ts +2 -2
- package/dist/StatusDot/index.d.ts +2 -2
- package/dist/Stepper/Step.d.ts +2 -2
- package/dist/Stepper/Step.d.ts.map +1 -1
- package/dist/Stepper/Step.js +3 -3
- package/dist/Stepper/Stepper.d.ts +2 -2
- package/dist/Stepper/index.d.ts +7 -7
- package/dist/Switch/Switch.d.ts +4 -4
- package/dist/Switch/index.d.ts +2 -2
- package/dist/TabList/Tab.d.ts +2 -2
- package/dist/TabList/TabList.d.ts +3 -3
- package/dist/TabList/TabMenu.d.ts +2 -2
- package/dist/TabList/index.d.ts +8 -8
- package/dist/Table/BaseTable.d.ts +1 -1
- package/dist/Table/Table.d.ts +1 -1
- package/dist/Table/TableBody.d.ts +1 -1
- package/dist/Table/TableCell.d.ts +3 -3
- package/dist/Table/TableContext.d.ts +1 -1
- package/dist/Table/TableFooter.d.ts +1 -1
- package/dist/Table/TableHeader.d.ts +1 -1
- package/dist/Table/TableHeaderCell.d.ts +3 -3
- package/dist/Table/TableRow.d.ts +2 -2
- package/dist/Table/TableSelectionToolbar.d.ts +2 -2
- package/dist/Table/columnUtils.d.ts +1 -1
- package/dist/Table/index.d.ts +54 -54
- package/dist/Table/plugins/columnResize/index.d.ts +2 -2
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts +1 -1
- package/dist/Table/plugins/columnSettings/index.d.ts +4 -4
- package/dist/Table/plugins/columnSettings/useTableColumnSettings.d.ts +2 -2
- package/dist/Table/plugins/columnSettings/useTableColumnSettingsState.d.ts +1 -1
- package/dist/Table/plugins/filtering/index.d.ts +4 -4
- package/dist/Table/plugins/filtering/useTableFilterState.d.ts +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts +2 -2
- package/dist/Table/plugins/groupedRows/index.d.ts +2 -2
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +1 -1
- package/dist/Table/plugins/pagination/index.d.ts +3 -3
- package/dist/Table/plugins/pagination/useTablePagination.d.ts +1 -1
- package/dist/Table/plugins/rowExpansion/index.d.ts +2 -2
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +1 -1
- package/dist/Table/plugins/rowIndex/index.d.ts +2 -2
- package/dist/Table/plugins/rowIndex/useTableRowIndex.d.ts +1 -1
- package/dist/Table/plugins/rowStatus/index.d.ts +2 -2
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +2 -2
- package/dist/Table/plugins/selection/index.d.ts +4 -4
- package/dist/Table/plugins/selection/useTableSelection.d.ts +1 -1
- package/dist/Table/plugins/selection/useTableSelectionState.d.ts +1 -1
- package/dist/Table/plugins/sortable/index.d.ts +4 -4
- package/dist/Table/plugins/sortable/useTableSortable.d.ts +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts +1 -1
- package/dist/Table/plugins/stickyColumns/index.d.ts +2 -2
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +1 -1
- package/dist/Table/plugins/tree/index.d.ts +4 -4
- package/dist/Table/plugins/tree/useTableTreeData.d.ts +1 -1
- package/dist/Table/plugins/tree/useTableTreeState.d.ts +1 -1
- package/dist/Table/tableContextMenu.d.ts +2 -2
- package/dist/Table/types.d.ts +3 -3
- package/dist/Table/useBaseTablePlugins.d.ts +1 -1
- package/dist/Table/useTableCellStyles.d.ts +2 -2
- package/dist/Table/utils.d.ts +2 -2
- package/dist/Text/Text.d.ts +3 -3
- package/dist/Text/index.d.ts +4 -4
- package/dist/TextArea/TextArea.d.ts +10 -8
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +14 -11
- package/dist/TextArea/index.d.ts +2 -2
- package/dist/TextInput/TextInput.d.ts +11 -9
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +27 -17
- package/dist/TextInput/index.d.ts +2 -2
- package/dist/Thumbnail/Thumbnail.d.ts +1 -1
- package/dist/Thumbnail/index.d.ts +2 -2
- package/dist/TimeInput/TimeInput.d.ts +6 -6
- package/dist/TimeInput/TouchTimeField.d.ts +1 -1
- package/dist/TimeInput/index.d.ts +3 -3
- package/dist/Timer/Timer.d.ts +2 -2
- package/dist/Timer/index.d.ts +2 -2
- package/dist/Timestamp/Timestamp.d.ts +3 -3
- package/dist/Timestamp/TimestampHoverCard.d.ts +1 -1
- package/dist/Timestamp/formatInstant.d.ts +2 -2
- package/dist/Timestamp/formatRelativeTime.d.ts +1 -1
- package/dist/Timestamp/index.d.ts +3 -3
- package/dist/Timestamp/tooltipEntries.d.ts +2 -2
- package/dist/Toast/Toast.d.ts +2 -2
- package/dist/Toast/ToastContext.d.ts +1 -1
- package/dist/Toast/ToastViewport.d.ts +2 -2
- package/dist/Toast/index.d.ts +6 -6
- package/dist/Toast/useToast.d.ts +1 -1
- package/dist/ToggleButton/ToggleButton.d.ts +3 -3
- package/dist/ToggleButton/ToggleButtonGroup.d.ts +1 -1
- package/dist/ToggleButton/index.d.ts +4 -4
- package/dist/Token/Token.d.ts +2 -2
- package/dist/Token/TokenLink.d.ts +1 -1
- package/dist/Token/index.d.ts +2 -2
- package/dist/Tokenizer/Tokenizer.d.ts +6 -6
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +44 -40
- package/dist/Tokenizer/index.d.ts +2 -2
- package/dist/Tokenizer/useEndLaneReserve.d.ts +3 -2
- package/dist/Tokenizer/useEndLaneReserve.d.ts.map +1 -1
- package/dist/Tokenizer/useEndLaneReserve.js +3 -2
- package/dist/Toolbar/Toolbar.d.ts +4 -4
- package/dist/Toolbar/index.d.ts +2 -2
- package/dist/Tooltip/Tooltip.d.ts +3 -3
- package/dist/Tooltip/index.d.ts +4 -4
- package/dist/Tooltip/useTooltip.d.ts +2 -2
- package/dist/TopNav/TopNav.d.ts +1 -1
- package/dist/TopNav/TopNavHeading.d.ts +2 -2
- package/dist/TopNav/TopNavItem.d.ts +3 -3
- package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.d.ts +2 -2
- package/dist/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/index.d.ts +16 -16
- package/dist/TreeList/TreeList.d.ts +3 -3
- package/dist/TreeList/TreeListItem.d.ts +1 -1
- package/dist/TreeList/TreeListTypes.d.ts +1 -1
- package/dist/TreeList/index.d.ts +3 -3
- package/dist/Typeahead/BaseTypeahead.d.ts +2 -2
- package/dist/Typeahead/Typeahead.d.ts +6 -6
- package/dist/Typeahead/TypeaheadItem.d.ts +2 -2
- package/dist/Typeahead/createStaticSource.d.ts +1 -1
- package/dist/Typeahead/index.d.ts +9 -9
- package/dist/Typeahead/utils.d.ts +3 -3
- package/dist/VStack/VStack.d.ts +2 -2
- package/dist/VStack/index.d.ts +1 -1
- package/dist/VisuallyHidden/VisuallyHidden.d.ts +24 -6
- package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -1
- package/dist/VisuallyHidden/VisuallyHidden.js +24 -5
- package/dist/VisuallyHidden/index.d.ts +2 -2
- package/dist/astryx.css +8 -16
- package/dist/hooks/index.d.ts +52 -52
- package/dist/hooks/useAutoMediaMode.d.ts +1 -1
- package/dist/hooks/useInputContainer.d.ts +1 -1
- package/dist/hooks/useInputStatusIcon.d.ts +3 -3
- package/dist/hooks/useMenuPress.d.ts +1 -1
- package/dist/hooks/usePressFeedback.d.ts +1 -1
- package/dist/hooks/useScrollableArea.d.ts +1 -1
- package/dist/i18n/InternationalizationContext.d.ts +2 -2
- package/dist/i18n/InternationalizationProvider.d.ts +1 -1
- package/dist/i18n/index.d.ts +12 -12
- package/dist/i18n/resolve.d.ts +1 -1
- package/dist/i18n/useLocale.d.ts +1 -1
- package/dist/index.d.ts +111 -111
- package/dist/theme/Theme.d.ts +2 -2
- package/dist/theme/contrast.d.ts +1 -1
- package/dist/theme/defineTheme.d.ts +12 -12
- package/dist/theme/domainTokens/index.d.ts +6 -6
- package/dist/theme/generateThemeRules.d.ts +1 -1
- package/dist/theme/index.d.ts +31 -31
- package/dist/theme/localTokens.d.ts +1 -1
- package/dist/theme/mergeComponents.d.ts +1 -1
- package/dist/theme/onMediaTokens.d.ts +1 -1
- package/dist/theme/resolveThemeValues.d.ts +7 -7
- package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
- package/dist/theme/syntax/index.d.ts +7 -7
- package/dist/theme/syntax/presets.d.ts +1 -1
- package/dist/theme/themeAdaptations.d.ts +5 -5
- package/dist/theme/themeRegistry.d.ts +1 -1
- package/dist/theme/tokens.d.ts +1 -1
- package/dist/theme/types.d.ts +1 -1
- package/dist/theme/useTheme.d.ts +2 -2
- package/dist/utils/dateParser.d.ts +3 -3
- package/dist/utils/groupItems.d.ts +1 -1
- package/dist/utils/index.d.ts +29 -29
- package/dist/utils/plainDate.d.ts +3 -3
- package/package.json +5 -5
- package/src/Badge/Badge.doc.mjs +2 -1
- package/src/BottomSheet/BottomSheet.tsx +12 -1
- package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +82 -0
- package/src/DateInput/DateInputTouch.test.tsx +9 -0
- package/src/DateInput/Wheel.tsx +4 -1
- package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +158 -0
- package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +5 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +226 -0
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +32 -16
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +158 -0
- package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +539 -0
- package/src/Field/inputDisabledFocus.ts +28 -0
- package/src/HoverCard/HoverCard.test.tsx +93 -3
- package/src/Icon/Icon.spec.md +40 -29
- package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +199 -0
- package/src/Layer/modalOutlet.ts +1 -1
- package/src/Layer/useTouchTrigger.ts +95 -41
- package/src/NumberInput/NumberInput.doc.mjs +6 -6
- package/src/NumberInput/NumberInput.test.tsx +144 -14
- package/src/NumberInput/NumberInput.tsx +68 -21
- package/src/Pagination/Pagination.test.tsx +2 -2
- package/src/SideNav/SideNav.test.tsx +15 -6
- package/src/SideNav/SideNavHeading.tsx +41 -0
- package/src/Skeleton/Skeleton.test.tsx +108 -1
- package/src/Skeleton/Skeleton.tsx +30 -2
- package/src/Stepper/Step.tsx +7 -0
- package/src/Stepper/Stepper.test.tsx +33 -0
- package/src/TextArea/TextArea.doc.mjs +6 -6
- package/src/TextArea/TextArea.test.tsx +65 -6
- package/src/TextArea/TextArea.tsx +26 -14
- package/src/TextInput/TextInput.doc.mjs +8 -8
- package/src/TextInput/TextInput.test.tsx +83 -10
- package/src/TextInput/TextInput.tsx +38 -19
- package/src/Toast/ToastViewport.modalHost.test.tsx +139 -4
- package/src/Tokenizer/Tokenizer.test.tsx +26 -8
- package/src/Tokenizer/Tokenizer.tsx +65 -72
- package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +471 -0
- package/src/Tokenizer/useEndLaneReserve.ts +3 -2
- package/src/Tooltip/Tooltip.test.tsx +148 -3
- package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +2 -2
- package/src/VisuallyHidden/VisuallyHidden.doc.mjs +1 -1
- package/src/VisuallyHidden/VisuallyHidden.test.tsx +39 -0
- package/src/VisuallyHidden/VisuallyHidden.tsx +38 -5
- package/src/theme/tokens.test.ts +60 -0
|
@@ -13,6 +13,8 @@ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
|
13
13
|
import {act, useState} from 'react';
|
|
14
14
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
15
15
|
import userEvent from '@testing-library/user-event';
|
|
16
|
+
import * as stylex from '@stylexjs/stylex';
|
|
17
|
+
import {colorVars} from '../theme/tokens.stylex';
|
|
16
18
|
import {TestIcon} from '../__tests__/TestIcon';
|
|
17
19
|
import {InternationalizationProvider} from '../i18n';
|
|
18
20
|
import {registerIcons, resetIcons} from '../Icon';
|
|
@@ -22,6 +24,21 @@ import {defineTheme} from '../theme/defineTheme';
|
|
|
22
24
|
import {generateThemeCSS} from '../theme/generateThemeRules';
|
|
23
25
|
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
24
26
|
|
|
27
|
+
// jsdom cannot match `:focus-visible`: compare the ring's StyleX class hash.
|
|
28
|
+
const RING = stylex
|
|
29
|
+
.props(
|
|
30
|
+
stylex.create({
|
|
31
|
+
ring: {
|
|
32
|
+
boxShadow: {
|
|
33
|
+
default: null,
|
|
34
|
+
':has(> [aria-disabled="true"]:focus-visible)': `inset 0px 0px 0px 2px ${colorVars['--color-accent-muted']}`,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
}).ring,
|
|
38
|
+
)
|
|
39
|
+
.className!.split(' ')
|
|
40
|
+
.pop()!;
|
|
41
|
+
|
|
25
42
|
// FieldStatus announces status messages through the persistent useAnnounce
|
|
26
43
|
// singletons; remove them between tests so role/aria-live queries in this
|
|
27
44
|
// file never match a leftover region.
|
|
@@ -149,7 +166,7 @@ describe('NumberInput', () => {
|
|
|
149
166
|
expect(screen.getByRole('spinbutton')).not.toHaveAttribute('aria-required');
|
|
150
167
|
});
|
|
151
168
|
|
|
152
|
-
it('
|
|
169
|
+
it('exposes aria-disabled, not native disabled, when isDisabled is true (spec:AST-085)', () => {
|
|
153
170
|
render(
|
|
154
171
|
<NumberInput
|
|
155
172
|
label="Quantity"
|
|
@@ -158,7 +175,76 @@ describe('NumberInput', () => {
|
|
|
158
175
|
onChange={() => {}}
|
|
159
176
|
/>,
|
|
160
177
|
);
|
|
161
|
-
expect(screen.getByRole('spinbutton')).
|
|
178
|
+
expect(screen.getByRole('spinbutton')).toHaveAttribute(
|
|
179
|
+
'aria-disabled',
|
|
180
|
+
'true',
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('keeps a disabled input in the tab order and rings it (spec:AST-085 FR1, FR6)', async () => {
|
|
185
|
+
const user = userEvent.setup();
|
|
186
|
+
render(
|
|
187
|
+
<>
|
|
188
|
+
<NumberInput label="First" value={1} onChange={() => {}} />
|
|
189
|
+
<NumberInput label="Second" value={2} onChange={() => {}} isDisabled />
|
|
190
|
+
</>,
|
|
191
|
+
);
|
|
192
|
+
await user.tab();
|
|
193
|
+
await user.tab();
|
|
194
|
+
const input = screen.getByRole('spinbutton', {name: 'Second'});
|
|
195
|
+
expect(input).toHaveFocus();
|
|
196
|
+
expect(input.parentElement).toHaveClass(RING);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('runs no caller handler, steps nothing and submits no form while disabled (spec:AST-085 FR2)', async () => {
|
|
200
|
+
const user = userEvent.setup();
|
|
201
|
+
const handlers = {
|
|
202
|
+
onChange: vi.fn(),
|
|
203
|
+
onEnter: vi.fn(),
|
|
204
|
+
onKeyDown: vi.fn(),
|
|
205
|
+
onPaste: vi.fn(),
|
|
206
|
+
};
|
|
207
|
+
const onSubmit = vi.fn((e: React.FormEvent) => e.preventDefault());
|
|
208
|
+
render(
|
|
209
|
+
<form onSubmit={onSubmit}>
|
|
210
|
+
<NumberInput
|
|
211
|
+
label="Quantity"
|
|
212
|
+
value={5}
|
|
213
|
+
isDisabled
|
|
214
|
+
hasNumberSteppers
|
|
215
|
+
{...handlers}
|
|
216
|
+
/>
|
|
217
|
+
</form>,
|
|
218
|
+
);
|
|
219
|
+
await user.click(screen.getByRole('spinbutton'));
|
|
220
|
+
await user.keyboard('{ArrowUp}{ArrowDown}{Enter}');
|
|
221
|
+
await user.paste('9');
|
|
222
|
+
await user.click(screen.getByRole('button', {name: 'Increment Quantity'}));
|
|
223
|
+
for (const handler of [...Object.values(handlers), onSubmit]) {
|
|
224
|
+
expect(handler).not.toHaveBeenCalled();
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('commits nothing when a field disabled mid-entry loses focus (spec:AST-085 FR2)', async () => {
|
|
229
|
+
const user = userEvent.setup();
|
|
230
|
+
const onChange = vi.fn();
|
|
231
|
+
const field = (isDisabled: boolean) => (
|
|
232
|
+
<NumberInput
|
|
233
|
+
label="Quantity"
|
|
234
|
+
value={5}
|
|
235
|
+
onChange={onChange}
|
|
236
|
+
isDisabled={isDisabled}
|
|
237
|
+
/>
|
|
238
|
+
);
|
|
239
|
+
const {rerender} = render(field(false));
|
|
240
|
+
const input = screen.getByRole('spinbutton');
|
|
241
|
+
await user.clear(input);
|
|
242
|
+
await user.type(input, '8');
|
|
243
|
+
onChange.mockClear();
|
|
244
|
+
rerender(field(true));
|
|
245
|
+
await user.tab();
|
|
246
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
247
|
+
expect(input).toHaveValue('5');
|
|
162
248
|
});
|
|
163
249
|
|
|
164
250
|
it('does not fire onChange when disabled', async () => {
|
|
@@ -1424,10 +1510,10 @@ describe('NumberInput', () => {
|
|
|
1424
1510
|
const increment = screen.getByRole('button', {
|
|
1425
1511
|
name: 'Increment Quantity',
|
|
1426
1512
|
});
|
|
1427
|
-
expect(increment).
|
|
1513
|
+
expect(increment).toHaveAttribute('aria-disabled', 'true');
|
|
1428
1514
|
expect(
|
|
1429
1515
|
screen.getByRole('button', {name: 'Decrement Quantity'}),
|
|
1430
|
-
).
|
|
1516
|
+
).toHaveAttribute('aria-disabled', 'true');
|
|
1431
1517
|
|
|
1432
1518
|
fireEvent.click(increment);
|
|
1433
1519
|
expect(handleChange).not.toHaveBeenCalled();
|
|
@@ -1446,7 +1532,10 @@ describe('NumberInput', () => {
|
|
|
1446
1532
|
/>
|
|
1447
1533
|
</form>,
|
|
1448
1534
|
);
|
|
1449
|
-
expect(screen.getByRole('spinbutton')).
|
|
1535
|
+
expect(screen.getByRole('spinbutton')).toHaveAttribute(
|
|
1536
|
+
'aria-disabled',
|
|
1537
|
+
'true',
|
|
1538
|
+
);
|
|
1450
1539
|
expect([
|
|
1451
1540
|
...new FormData(container.querySelector('form')!).keys(),
|
|
1452
1541
|
]).toEqual([]);
|
|
@@ -1480,6 +1569,24 @@ describe('NumberInput', () => {
|
|
|
1480
1569
|
).toBeInTheDocument();
|
|
1481
1570
|
});
|
|
1482
1571
|
|
|
1572
|
+
it('focuses the field inside the tap that clears it, without scrolling', () => {
|
|
1573
|
+
// iOS Safari brings up its keyboard only for a focus made while
|
|
1574
|
+
// handling the touch.
|
|
1575
|
+
const onChange = vi.fn();
|
|
1576
|
+
const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus');
|
|
1577
|
+
render(
|
|
1578
|
+
<NumberInput label="Qty" value={5} onChange={onChange} hasClear />,
|
|
1579
|
+
);
|
|
1580
|
+
const input = screen.getByRole('spinbutton');
|
|
1581
|
+
fireEvent.click(screen.getByRole('button', {name: 'Clear Qty'}), {
|
|
1582
|
+
detail: 1,
|
|
1583
|
+
});
|
|
1584
|
+
expect(onChange).toHaveBeenCalledWith(null);
|
|
1585
|
+
expect(document.activeElement).toBe(input);
|
|
1586
|
+
expect(focusSpy).toHaveBeenLastCalledWith({preventScroll: true});
|
|
1587
|
+
focusSpy.mockRestore();
|
|
1588
|
+
});
|
|
1589
|
+
|
|
1483
1590
|
it('does not show clear button when value is null', () => {
|
|
1484
1591
|
render(
|
|
1485
1592
|
<NumberInput label="Qty" value={null} onChange={() => {}} hasClear />,
|
|
@@ -1693,7 +1800,7 @@ describe('NumberInput', () => {
|
|
|
1693
1800
|
expect(onChange).not.toHaveBeenCalled();
|
|
1694
1801
|
});
|
|
1695
1802
|
|
|
1696
|
-
it('
|
|
1803
|
+
it('stays focusable when disabled without a reason', () => {
|
|
1697
1804
|
render(
|
|
1698
1805
|
<NumberInput
|
|
1699
1806
|
label="Quantity"
|
|
@@ -1703,8 +1810,8 @@ describe('NumberInput', () => {
|
|
|
1703
1810
|
/>,
|
|
1704
1811
|
);
|
|
1705
1812
|
const input = screen.getByRole('spinbutton');
|
|
1706
|
-
expect(input).toBeDisabled();
|
|
1707
|
-
expect(input).
|
|
1813
|
+
expect(input).not.toBeDisabled();
|
|
1814
|
+
expect(input).toHaveAttribute('aria-disabled', 'true');
|
|
1708
1815
|
});
|
|
1709
1816
|
});
|
|
1710
1817
|
});
|
|
@@ -2006,14 +2113,14 @@ describe('NumberInput stepping', () => {
|
|
|
2006
2113
|
|
|
2007
2114
|
const input = screen.getByRole('spinbutton');
|
|
2008
2115
|
const increment = screen.getByRole('button', {name: 'Increment Amount'});
|
|
2009
|
-
expect(increment).
|
|
2116
|
+
expect(increment).not.toHaveAttribute('aria-disabled');
|
|
2010
2117
|
|
|
2011
2118
|
fireEvent.click(increment);
|
|
2012
2119
|
|
|
2013
2120
|
expect(input).toHaveValue('99.99');
|
|
2014
2121
|
expect(input).toHaveAttribute('aria-valuenow', '99.99');
|
|
2015
2122
|
expect(input).not.toHaveAttribute('aria-invalid');
|
|
2016
|
-
expect(increment).
|
|
2123
|
+
expect(increment).toHaveAttribute('aria-disabled', 'true');
|
|
2017
2124
|
});
|
|
2018
2125
|
|
|
2019
2126
|
it('allows wheel stepping by default and consumes the focused gesture', () => {
|
|
@@ -2259,10 +2366,33 @@ describe('NumberInput stepping', () => {
|
|
|
2259
2366
|
);
|
|
2260
2367
|
expect(
|
|
2261
2368
|
screen.getByRole('button', {name: 'Increment Quantity'}),
|
|
2262
|
-
).
|
|
2369
|
+
).toHaveAttribute('aria-disabled', 'true');
|
|
2263
2370
|
expect(
|
|
2264
2371
|
screen.getByRole('button', {name: 'Decrement Quantity'}),
|
|
2265
|
-
).not.
|
|
2372
|
+
).not.toHaveAttribute('aria-disabled');
|
|
2373
|
+
});
|
|
2374
|
+
|
|
2375
|
+
it('commits nothing from a click on the stepper at the reached boundary (spec:AST-085 FR2)', async () => {
|
|
2376
|
+
const user = userEvent.setup();
|
|
2377
|
+
const onChange = vi.fn();
|
|
2378
|
+
render(
|
|
2379
|
+
<NumberInput
|
|
2380
|
+
label="Quantity"
|
|
2381
|
+
value={5}
|
|
2382
|
+
onChange={onChange}
|
|
2383
|
+
min={0}
|
|
2384
|
+
max={10}
|
|
2385
|
+
hasNumberSteppers
|
|
2386
|
+
/>,
|
|
2387
|
+
);
|
|
2388
|
+
const input = screen.getByRole('spinbutton');
|
|
2389
|
+
await user.clear(input);
|
|
2390
|
+
await user.type(input, '10');
|
|
2391
|
+
onChange.mockClear();
|
|
2392
|
+
await user.click(
|
|
2393
|
+
screen.getByRole('button', {name: 'Increment Quantity'}),
|
|
2394
|
+
);
|
|
2395
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
2266
2396
|
});
|
|
2267
2397
|
|
|
2268
2398
|
it('disables both steppers with the input', () => {
|
|
@@ -2277,10 +2407,10 @@ describe('NumberInput stepping', () => {
|
|
|
2277
2407
|
);
|
|
2278
2408
|
expect(
|
|
2279
2409
|
screen.getByRole('button', {name: 'Increment Quantity'}),
|
|
2280
|
-
).
|
|
2410
|
+
).toHaveAttribute('aria-disabled', 'true');
|
|
2281
2411
|
expect(
|
|
2282
2412
|
screen.getByRole('button', {name: 'Decrement Quantity'}),
|
|
2283
|
-
).
|
|
2413
|
+
).toHaveAttribute('aria-disabled', 'true');
|
|
2284
2414
|
});
|
|
2285
2415
|
});
|
|
2286
2416
|
});
|
|
@@ -53,6 +53,7 @@ import {useTooltip} from '../Tooltip';
|
|
|
53
53
|
import {getInputARIA} from '../utils';
|
|
54
54
|
import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
|
|
55
55
|
import {usePressFeedback} from '../hooks/usePressFeedback';
|
|
56
|
+
import {inputDisabledFocusStyles} from '../Field/inputDisabledFocus';
|
|
56
57
|
import {useSize} from '../SizeContext/SizeContext';
|
|
57
58
|
import {useInputContainer} from '../hooks/useInputContainer';
|
|
58
59
|
import {useInputStatusIcon} from '../hooks/useInputStatusIcon';
|
|
@@ -261,7 +262,7 @@ interface NumberInputPropsBase extends Omit<
|
|
|
261
262
|
* Whether the input is read-only.
|
|
262
263
|
* The value is shown at full opacity and still submits with the form, but
|
|
263
264
|
* cannot be edited. Unlike `isDisabled`, a read-only input is not dimmed and
|
|
264
|
-
*
|
|
265
|
+
* keeps its form value — use it for a value the user should see and send
|
|
265
266
|
* but not change. Stepping is off in every form while read-only: arrow keys,
|
|
266
267
|
* the wheel, and the number steppers. `isDisabled` takes precedence when both
|
|
267
268
|
* are set.
|
|
@@ -275,8 +276,8 @@ interface NumberInputPropsBase extends Omit<
|
|
|
275
276
|
* keyboard and assistive technology. The field cannot be edited (it becomes
|
|
276
277
|
* read-only) while disabled.
|
|
277
278
|
*
|
|
278
|
-
* Use this instead of wrapping a disabled input in `Tooltip
|
|
279
|
-
*
|
|
279
|
+
* Use this instead of wrapping a disabled input in `Tooltip`, so the reason
|
|
280
|
+
* is attached to the field itself.
|
|
280
281
|
*
|
|
281
282
|
* @example
|
|
282
283
|
* ```
|
|
@@ -600,12 +601,20 @@ export function NumberInput({
|
|
|
600
601
|
const [pendingInput, setPendingInput] = useState<string | null>(null);
|
|
601
602
|
const [isFocused, setIsFocused] = useState(false);
|
|
602
603
|
|
|
603
|
-
// Disabled-reason tooltip.
|
|
604
|
-
// tooltip listeners attach to the input container (which already exists) and
|
|
604
|
+
// Disabled-reason tooltip. The tooltip listeners attach to the input container (which already exists) and
|
|
605
605
|
// the input stays perceivable via aria-disabled instead of the native
|
|
606
606
|
// disabled attribute. The field is made read-only so it can't be typed into,
|
|
607
607
|
// and value mutation is blocked by the isDisabled guard in the handlers.
|
|
608
608
|
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
609
|
+
// A disabled field keeps its tab stop but, like a natively disabled one,
|
|
610
|
+
// runs no caller event handler other than focus and blur (`spec:AST-085` FR2).
|
|
611
|
+
const fieldProps = isDisabled
|
|
612
|
+
? Object.fromEntries(
|
|
613
|
+
Object.entries(rest).filter(
|
|
614
|
+
([key]) => !/^on[A-Z]/.test(key) || /^on(Focus|Blur)/.test(key),
|
|
615
|
+
),
|
|
616
|
+
)
|
|
617
|
+
: rest;
|
|
609
618
|
const disabledMessageTooltip = useTooltip({
|
|
610
619
|
placement: 'above',
|
|
611
620
|
// The container div is not naturally focusable; focusin bubbles up from
|
|
@@ -699,6 +708,12 @@ export function NumberInput({
|
|
|
699
708
|
if (pendingInput === null) {
|
|
700
709
|
return;
|
|
701
710
|
}
|
|
711
|
+
if (isDisabled) {
|
|
712
|
+
// A field disabled mid-entry commits nothing; its draft is dropped, as
|
|
713
|
+
// a natively disabled field's was (spec:AST-085 FR2).
|
|
714
|
+
setPendingInput(null);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
702
717
|
|
|
703
718
|
const decision = resolveNumberInputCommit(pendingInput, {
|
|
704
719
|
min,
|
|
@@ -722,7 +737,17 @@ export function NumberInput({
|
|
|
722
737
|
onChange(decision.value);
|
|
723
738
|
}
|
|
724
739
|
},
|
|
725
|
-
[
|
|
740
|
+
[
|
|
741
|
+
hasClear,
|
|
742
|
+
isDisabled,
|
|
743
|
+
isIntegerOnly,
|
|
744
|
+
locale,
|
|
745
|
+
max,
|
|
746
|
+
min,
|
|
747
|
+
onChange,
|
|
748
|
+
pendingInput,
|
|
749
|
+
value,
|
|
750
|
+
],
|
|
726
751
|
);
|
|
727
752
|
|
|
728
753
|
// Blur ends the edit and displays the resulting committed value.
|
|
@@ -780,6 +805,13 @@ export function NumberInput({
|
|
|
780
805
|
// Handle keyboard events
|
|
781
806
|
const handleKeyDown = useCallback(
|
|
782
807
|
(e: KeyboardEvent<HTMLInputElement>) => {
|
|
808
|
+
if (isDisabled) {
|
|
809
|
+
// A read-only field still submits its form on Enter.
|
|
810
|
+
if (e.key === 'Enter') {
|
|
811
|
+
e.preventDefault();
|
|
812
|
+
}
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
783
815
|
// The field is type="text" for formatted display, so an IME can compose
|
|
784
816
|
// into it: Enter commits the candidate and the arrows walk the candidate
|
|
785
817
|
// window. The composing keydown fires before compositionend, so without
|
|
@@ -804,7 +836,7 @@ export function NumberInput({
|
|
|
804
836
|
}
|
|
805
837
|
onKeyDown?.(e);
|
|
806
838
|
},
|
|
807
|
-
[commitPendingInput, onEnter, onKeyDown, stepValue],
|
|
839
|
+
[commitPendingInput, isDisabled, onEnter, onKeyDown, stepValue],
|
|
808
840
|
);
|
|
809
841
|
|
|
810
842
|
// React's delegated wheel listener can be passive, so use a native,
|
|
@@ -860,11 +892,12 @@ export function NumberInput({
|
|
|
860
892
|
if (!e || e.detail === 0) {
|
|
861
893
|
inputRef.current?.focus();
|
|
862
894
|
} else {
|
|
863
|
-
//
|
|
864
|
-
//
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
895
|
+
// Focus inside the tap: iOS Safari brings up its keyboard only for a
|
|
896
|
+
// focus made while handling the touch, so a field the tap reaches
|
|
897
|
+
// unfocused gets its keyboard, as UIKit's clear button makes the
|
|
898
|
+
// field first responder. `preventScroll` keeps a scrolled page where
|
|
899
|
+
// it is.
|
|
900
|
+
inputRef.current?.focus({preventScroll: true});
|
|
868
901
|
}
|
|
869
902
|
},
|
|
870
903
|
[hasClear, onChange],
|
|
@@ -902,6 +935,7 @@ export function NumberInput({
|
|
|
902
935
|
hasNumberSteppers && styles.wrapperWithNumberSteppers,
|
|
903
936
|
sizeStyles[size],
|
|
904
937
|
isDisabled && inputWrapperStyles.disabled,
|
|
938
|
+
isDisabled && inputDisabledFocusStyles.ring,
|
|
905
939
|
status && inputStatusBorderStyles[status.type],
|
|
906
940
|
status && !isDisabled && inputStatusHoverShadowStyles[status.type],
|
|
907
941
|
status && inputStatusFocusWithinStyles[status.type],
|
|
@@ -914,7 +948,7 @@ export function NumberInput({
|
|
|
914
948
|
{startIcon && renderIconSlot(startIcon, {size: 'sm', color: 'secondary'})}
|
|
915
949
|
{inputGroup && <VisuallyHidden id={inputLabelID}>{label}</VisuallyHidden>}
|
|
916
950
|
<input
|
|
917
|
-
{...
|
|
951
|
+
{...fieldProps}
|
|
918
952
|
ref={mergedInputRef}
|
|
919
953
|
id={id}
|
|
920
954
|
name={isDisabled || formatValue ? undefined : htmlName}
|
|
@@ -928,12 +962,11 @@ export function NumberInput({
|
|
|
928
962
|
onBlur={handleBlur}
|
|
929
963
|
onKeyDown={handleKeyDown}
|
|
930
964
|
placeholder={placeholder}
|
|
931
|
-
//
|
|
932
|
-
//
|
|
933
|
-
//
|
|
934
|
-
disabled={isDisabled
|
|
935
|
-
|
|
936
|
-
readOnly={isReadOnly || showsDisabledMessage || undefined}
|
|
965
|
+
// A disabled input keeps its place in the tab order (spec:AST-085):
|
|
966
|
+
// aria-disabled instead of the native attribute, with readOnly + the
|
|
967
|
+
// handler guards keeping the value from changing.
|
|
968
|
+
aria-disabled={isDisabled ? 'true' : undefined}
|
|
969
|
+
readOnly={isReadOnly || isDisabled || undefined}
|
|
937
970
|
autoFocus={hasAutoFocus}
|
|
938
971
|
data-autofocus={hasAutoFocus || undefined}
|
|
939
972
|
aria-valuemin={min ?? undefined}
|
|
@@ -992,10 +1025,17 @@ export function NumberInput({
|
|
|
992
1025
|
type="button"
|
|
993
1026
|
tabIndex={-1}
|
|
994
1027
|
{...pressable}
|
|
995
|
-
disabled={
|
|
1028
|
+
aria-disabled={
|
|
1029
|
+
isDisabled || isReadOnly || !canIncrement || undefined
|
|
1030
|
+
}
|
|
996
1031
|
aria-label={t('@astryx.numberInput.incrementLabel', {label})}
|
|
997
1032
|
onPointerDown={event => event.preventDefault()}
|
|
998
1033
|
onClick={() => {
|
|
1034
|
+
// An aria-disabled stepper does nothing, as a natively disabled
|
|
1035
|
+
// one did (spec:AST-085 FR2).
|
|
1036
|
+
if (isDisabled || isReadOnly || !canIncrement) {
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
999
1039
|
inputRef.current?.focus();
|
|
1000
1040
|
stepValue(1);
|
|
1001
1041
|
}}
|
|
@@ -1016,10 +1056,17 @@ export function NumberInput({
|
|
|
1016
1056
|
type="button"
|
|
1017
1057
|
tabIndex={-1}
|
|
1018
1058
|
{...pressable}
|
|
1019
|
-
disabled={
|
|
1059
|
+
aria-disabled={
|
|
1060
|
+
isDisabled || isReadOnly || !canDecrement || undefined
|
|
1061
|
+
}
|
|
1020
1062
|
aria-label={t('@astryx.numberInput.decrementLabel', {label})}
|
|
1021
1063
|
onPointerDown={event => event.preventDefault()}
|
|
1022
1064
|
onClick={() => {
|
|
1065
|
+
// An aria-disabled stepper does nothing, as a natively disabled
|
|
1066
|
+
// one did (spec:AST-085 FR2).
|
|
1067
|
+
if (isDisabled || isReadOnly || !canDecrement) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1023
1070
|
inputRef.current?.focus();
|
|
1024
1071
|
stepValue(-1);
|
|
1025
1072
|
}}
|
|
@@ -965,7 +965,7 @@ describe('Pagination', () => {
|
|
|
965
965
|
/>,
|
|
966
966
|
);
|
|
967
967
|
const box = screen.getByRole('spinbutton', {name: 'Go to page'});
|
|
968
|
-
expect(box).
|
|
968
|
+
expect(box).toHaveAttribute('aria-disabled', 'true');
|
|
969
969
|
// Disabled input never fires a change.
|
|
970
970
|
await user.type(box, '5{Enter}');
|
|
971
971
|
expect(onChange).not.toHaveBeenCalled();
|
|
@@ -999,7 +999,7 @@ describe('Pagination', () => {
|
|
|
999
999
|
// editable box is inert rather than accepting entries it can't resolve.
|
|
1000
1000
|
expect(
|
|
1001
1001
|
screen.getByRole('spinbutton', {name: 'Go to page'}),
|
|
1002
|
-
).
|
|
1002
|
+
).toHaveAttribute('aria-disabled', 'true');
|
|
1003
1003
|
});
|
|
1004
1004
|
|
|
1005
1005
|
it('renders the localized "Page" label by default and a custom pageLabel', () => {
|
|
@@ -668,18 +668,27 @@ describe('SideNavHeading headerEndContent', () => {
|
|
|
668
668
|
expect(screen.getByTestId('end-badge')).toBeInTheDocument();
|
|
669
669
|
});
|
|
670
670
|
|
|
671
|
-
it('renders headerEndContent
|
|
671
|
+
it('renders headerEndContent beside the link, not inside it, in isWholeHeadingLink path', () => {
|
|
672
|
+
const onPress = vi.fn();
|
|
672
673
|
render(
|
|
673
674
|
<SideNavHeading
|
|
674
675
|
heading="My App"
|
|
675
676
|
headingHref="/home"
|
|
676
|
-
headerEndContent={
|
|
677
|
+
headerEndContent={
|
|
678
|
+
<button type="button" onClick={onPress}>
|
|
679
|
+
Create
|
|
680
|
+
</button>
|
|
681
|
+
}
|
|
677
682
|
/>,
|
|
678
683
|
);
|
|
679
|
-
const
|
|
680
|
-
expect(
|
|
681
|
-
//
|
|
682
|
-
|
|
684
|
+
const link = screen.getByRole('link', {name: 'My App'});
|
|
685
|
+
expect(link).toHaveAttribute('href', '/home');
|
|
686
|
+
// A control inside a link is invalid and its press would follow the link.
|
|
687
|
+
const button = screen.getByRole('button', {name: 'Create'});
|
|
688
|
+
expect(button.closest('a')).toBeNull();
|
|
689
|
+
expect(link.parentElement).toBe(button.parentElement?.parentElement);
|
|
690
|
+
fireEvent.click(button);
|
|
691
|
+
expect(onPress).toHaveBeenCalledTimes(1);
|
|
683
692
|
});
|
|
684
693
|
|
|
685
694
|
it('renders headerEndContent in isWholeHeadingTrigger path', () => {
|
|
@@ -189,6 +189,17 @@ const styles = stylex.create({
|
|
|
189
189
|
// today. The 28px min box still wins over Icon's width/height.
|
|
190
190
|
fontSize: 'inherit',
|
|
191
191
|
},
|
|
192
|
+
// The link part of a whole-heading link row that also has end content.
|
|
193
|
+
linkBesideEndContent: {
|
|
194
|
+
display: 'flex',
|
|
195
|
+
alignItems: 'center',
|
|
196
|
+
alignSelf: 'stretch',
|
|
197
|
+
gap: spacingVars['--spacing-2'],
|
|
198
|
+
flexGrow: 1,
|
|
199
|
+
minWidth: 0,
|
|
200
|
+
textDecoration: 'none',
|
|
201
|
+
color: 'inherit',
|
|
202
|
+
},
|
|
192
203
|
headerEndContent: {
|
|
193
204
|
flexShrink: 0,
|
|
194
205
|
display: 'flex',
|
|
@@ -640,6 +651,36 @@ export function SideNavHeading({
|
|
|
640
651
|
</button>
|
|
641
652
|
);
|
|
642
653
|
|
|
654
|
+
// Whole heading is a link (no menu, single headingHref). End content may
|
|
655
|
+
// be a control, which must not sit inside the link (no interactive content
|
|
656
|
+
// in an <a>), so with end content the row is a div holding the link and the
|
|
657
|
+
// end content side by side, as the mixed mode does.
|
|
658
|
+
if (isWholeHeadingLink && headingHref && headerEndContentElement) {
|
|
659
|
+
return (
|
|
660
|
+
<div
|
|
661
|
+
ref={ref}
|
|
662
|
+
data-testid={testId}
|
|
663
|
+
{...mergeProps(
|
|
664
|
+
themeProps('side-nav-heading'),
|
|
665
|
+
stylex.props(styles.root, xstyle),
|
|
666
|
+
className,
|
|
667
|
+
style,
|
|
668
|
+
)}>
|
|
669
|
+
<LinkComponent
|
|
670
|
+
href={headingHref}
|
|
671
|
+
{...focusOutlineProps.focusVisible(
|
|
672
|
+
styles.linkBesideEndContent,
|
|
673
|
+
styles.menuTrigger,
|
|
674
|
+
)}
|
|
675
|
+
{...(props as React.AnchorHTMLAttributes<HTMLAnchorElement>)}>
|
|
676
|
+
{icon && <span {...stylex.props(styles.icon)}>{icon}</span>}
|
|
677
|
+
{renderTextContent()}
|
|
678
|
+
</LinkComponent>
|
|
679
|
+
{headerEndContentElement}
|
|
680
|
+
</div>
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
|
|
643
684
|
// Whole heading is a link (no menu, single headingHref)
|
|
644
685
|
if (isWholeHeadingLink && headingHref) {
|
|
645
686
|
return (
|
|
@@ -3,7 +3,63 @@
|
|
|
3
3
|
import {describe, it, expect} from 'vitest';
|
|
4
4
|
import {render, screen} from '@testing-library/react';
|
|
5
5
|
import {Skeleton} from './Skeleton';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
getAllInjectedCss,
|
|
8
|
+
getForcedColorsRules,
|
|
9
|
+
} from '../__tests__/forcedColors';
|
|
10
|
+
|
|
11
|
+
/** The declarations the element's atomic classes carry, as `prop: value`. */
|
|
12
|
+
function declarationsOf(el: Element, css: string): string[] {
|
|
13
|
+
const out: string[] = [];
|
|
14
|
+
for (const cls of Array.from(el.classList)) {
|
|
15
|
+
const re = new RegExp(`\\.${cls}\\b[^{]*\\{([^}]*)\\}`, 'g');
|
|
16
|
+
for (const match of css.matchAll(re)) {
|
|
17
|
+
out.push(
|
|
18
|
+
...match[1]
|
|
19
|
+
.split(';')
|
|
20
|
+
.map(d => d.trim())
|
|
21
|
+
.filter(Boolean),
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The whole `@keyframes <name> { … }` rule, braces matched. */
|
|
29
|
+
function keyframesRule(css: string, name: string): string {
|
|
30
|
+
const start = css.search(new RegExp(`@keyframes ${name}\\b`, 'i'));
|
|
31
|
+
expect(start).toBeGreaterThanOrEqual(0);
|
|
32
|
+
let depth = 0;
|
|
33
|
+
for (let i = css.indexOf('{', start); i < css.length; i += 1) {
|
|
34
|
+
if (css[i] === '{') {
|
|
35
|
+
depth += 1;
|
|
36
|
+
}
|
|
37
|
+
if (css[i] === '}' && --depth === 0) {
|
|
38
|
+
return css.slice(start, i + 1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`unterminated @keyframes ${name}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The named animation's opacity keyframes as [offset 0..1, opacity], in order. */
|
|
45
|
+
function opacityKeyframes(css: string, name: string): [number, number][] {
|
|
46
|
+
return Array.from(
|
|
47
|
+
keyframesRule(css, name).matchAll(/([\d.]+)%\s*\{\s*opacity:\s*([\d.]+)/g),
|
|
48
|
+
m => [Number(m[1]) / 100, Number(m[2])] as [number, number],
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Opacity at iteration progress x, linear between keyframes. */
|
|
53
|
+
function opacityAt(frames: [number, number][], x: number): number {
|
|
54
|
+
for (let i = 1; i < frames.length; i += 1) {
|
|
55
|
+
const [x0, y0] = frames[i - 1];
|
|
56
|
+
const [x1, y1] = frames[i];
|
|
57
|
+
if (x <= x1) {
|
|
58
|
+
return x1 === x0 ? y1 : y0 + ((y1 - y0) * (x - x0)) / (x1 - x0);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return frames[frames.length - 1][1];
|
|
62
|
+
}
|
|
7
63
|
|
|
8
64
|
describe('Skeleton', () => {
|
|
9
65
|
it('renders a placeholder element', () => {
|
|
@@ -25,6 +81,57 @@ describe('Skeleton', () => {
|
|
|
25
81
|
});
|
|
26
82
|
});
|
|
27
83
|
|
|
84
|
+
describe('pulse', () => {
|
|
85
|
+
function pulse() {
|
|
86
|
+
render(<Skeleton width={200} height={20} data-testid="sk" />);
|
|
87
|
+
const css = getAllInjectedCss();
|
|
88
|
+
const declarations = declarationsOf(screen.getByTestId('sk'), css);
|
|
89
|
+
const value = (prop: string) =>
|
|
90
|
+
declarations
|
|
91
|
+
.filter(d => d.startsWith(`${prop}:`))
|
|
92
|
+
.map(d => d.slice(prop.length + 1).trim());
|
|
93
|
+
return {css, value};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// WebKit runs no animation with a steps() timing function on the
|
|
97
|
+
// compositor, so a stepped pulse would freeze in Safari while a script runs.
|
|
98
|
+
it('keeps steps() out of the timing function so every engine can composite it', () => {
|
|
99
|
+
const {css, value} = pulse();
|
|
100
|
+
expect(value('animation-timing-function')).toEqual(['linear']);
|
|
101
|
+
expect(value('animation-direction')).toEqual(['alternate']);
|
|
102
|
+
expect(value('animation-iteration-count')).toEqual(['infinite']);
|
|
103
|
+
const name = value('animation-name').find(v => v !== 'none');
|
|
104
|
+
expect(name).toBeTruthy();
|
|
105
|
+
const rule = keyframesRule(css, name ?? '');
|
|
106
|
+
expect(rule).toMatch(/opacity/);
|
|
107
|
+
expect(rule).not.toMatch(/steps\(|animation-timing-function/);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('climbs and falls through the same ten opacity steps at the same times', () => {
|
|
111
|
+
const {css, value} = pulse();
|
|
112
|
+
const name = value('animation-name').find(v => v !== 'none') ?? '';
|
|
113
|
+
const frames = opacityKeyframes(css, name);
|
|
114
|
+
expect(frames[0]).toEqual([0, 0.25]);
|
|
115
|
+
// The previous pulse: 0.25 → 1 through steps(10, end), played back down
|
|
116
|
+
// by `alternate`. Sample each tenth away from its edges.
|
|
117
|
+
for (let step = 0; step < 10; step += 1) {
|
|
118
|
+
for (const within of [0.02, 0.5, 0.98]) {
|
|
119
|
+
const x = (step + within) / 10;
|
|
120
|
+
const expected = 0.25 + 0.75 * (step / 10);
|
|
121
|
+
expect(opacityAt(frames, x)).toBeCloseTo(expected, 6);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Each change between steps takes 0.01% of an iteration.
|
|
125
|
+
for (let i = 1; i < frames.length; i += 1) {
|
|
126
|
+
const [x0, y0] = frames[i - 1];
|
|
127
|
+
const [x1, y1] = frames[i];
|
|
128
|
+
if (y1 !== y0) {
|
|
129
|
+
expect(x1 - x0).toBeCloseTo(0.0001, 6);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
28
135
|
// jsdom cannot emulate forced-colors rendering, so these assert that the
|
|
29
136
|
// compiled output includes the forced-colors rules; visual behavior needs
|
|
30
137
|
// manual verification under Windows High Contrast.
|