@astryxdesign/core 0.7.7-canary.fc68123 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +104 -0
- package/dist/AlertDialog/AlertDialog.d.ts +1 -4
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +6 -36
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +4 -23
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +1 -3
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +1 -17
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +2 -13
- package/dist/ComplexSelector/ComplexSelector.d.ts +1 -4
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +4 -14
- package/dist/ContextMenu/ContextMenu.js +2 -2
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +31 -7
- package/dist/Field/Field.js +2 -2
- package/dist/HoverCard/HoverCard.d.ts +3 -4
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -27
- package/dist/HoverCard/useHoverCard.d.ts +4 -5
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +31 -17
- package/dist/Icon/Icon.d.ts +1 -5
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +2 -5
- package/dist/Layer/usePressPin.d.ts +5 -17
- package/dist/Layer/usePressPin.d.ts.map +1 -1
- package/dist/Layer/usePressPin.js +12 -62
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +0 -18
- package/dist/PowerSearch/PowerSearch.d.ts +3 -36
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +127 -433
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts +1 -32
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +6 -17
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -38
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +61 -170
- package/dist/PowerSearch/formatFilterValue.d.ts +0 -7
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +1 -11
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +2 -3
- package/dist/RadioList/RadioListItem.d.ts +1 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +3 -5
- package/dist/Resizable/ResizeHandle.d.ts +1 -2
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +77 -99
- package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
- package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
- package/dist/Slider/sliderTouchController.js +2 -2
- package/dist/Spinner/Spinner.d.ts +1 -1
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +58 -60
- package/dist/Switch/useSwitchTouch.js +4 -4
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +8 -29
- package/dist/TextInput/TextInput.d.ts +2 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +7 -10
- package/dist/Toast/Toast.d.ts +1 -11
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +15 -25
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +34 -94
- package/dist/Toast/types.d.ts +3 -9
- package/dist/Toast/types.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +1 -19
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +53 -34
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -2
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/astryx.css +6 -35
- package/dist/gestures/PressTracker.d.ts.map +1 -1
- package/dist/gestures/PressTracker.js +3 -4
- package/dist/hooks/actionGroupTracker.d.ts +1 -4
- package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
- package/dist/hooks/actionGroupTracker.js +3 -13
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -1
- package/dist/hooks/useAttachment.d.ts +1 -1
- package/dist/hooks/useAttachment.js +1 -1
- package/dist/hooks/useInputStatusIcon.d.ts +1 -1
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
- package/dist/hooks/useInputStatusIcon.js +2 -2
- package/dist/hooks/useLongPress.d.ts +2 -6
- package/dist/hooks/useLongPress.d.ts.map +1 -1
- package/dist/hooks/useLongPress.js +15 -95
- package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +0 -6
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +0 -30
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +0 -30
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -4
- package/dist/motion/animatedLayout.d.ts.map +1 -1
- package/dist/motion/animatedLayout.js +6 -5
- package/dist/motion/animator.d.ts +14 -14
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +18 -41
- package/dist/utils/dateParser.d.ts.map +1 -1
- package/dist/utils/dateParser.js +0 -12
- package/dist/utils/focusReturn.d.ts +0 -15
- package/dist/utils/focusReturn.d.ts.map +1 -1
- package/dist/utils/focusReturn.js +0 -28
- package/dist/utils/interactionOverlay.stylex.d.ts +2 -3
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +2 -3
- package/dist/utils/pressFeedback.d.ts.map +1 -1
- package/dist/utils/pressFeedback.js +6 -19
- package/locales/en.json +0 -120
- package/locales/pseudo.json +0 -90
- package/package.json +5 -10
- package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
- package/src/AlertDialog/AlertDialog.tsx +5 -37
- package/src/BottomSheet/BottomSheetPanel.tsx +3 -37
- package/src/BottomSheet/useSheetGestures.ts +1 -3
- package/src/Button/Button.tsx +4 -26
- package/src/CheckboxInput/CheckboxInput.doc.mjs +0 -18
- package/src/CheckboxInput/CheckboxInput.tsx +9 -36
- package/src/ComplexSelector/ComplexSelector.tsx +5 -20
- package/src/ContextMenu/ContextMenu.tsx +2 -2
- package/src/Dialog/Dialog.tsx +31 -10
- package/src/Field/Field.tsx +2 -2
- package/src/HoverCard/HoverCard.doc.mjs +2 -4
- package/src/HoverCard/HoverCard.tsx +4 -35
- package/src/HoverCard/useHoverCard.doc.mjs +36 -178
- package/src/HoverCard/useHoverCard.tsx +52 -46
- package/src/Icon/Icon.doc.mjs +8 -49
- package/src/Icon/Icon.tsx +7 -15
- package/src/Layer/usePressPin.ts +15 -81
- package/src/Lightbox/Lightbox.tsx +0 -18
- package/src/PowerSearch/PowerSearch.doc.mjs +5 -54
- package/src/PowerSearch/PowerSearch.tsx +155 -609
- package/src/PowerSearch/PowerSearchEditPopover.tsx +6 -28
- package/src/PowerSearch/PowerSearchValueEditor.tsx +38 -203
- package/src/PowerSearch/formatFilterValue.ts +1 -18
- package/src/RadioList/RadioList.tsx +2 -3
- package/src/RadioList/RadioListItem.tsx +3 -5
- package/src/Resizable/Resizable.doc.mjs +4 -5
- package/src/Resizable/ResizeHandle.tsx +109 -167
- package/src/SegmentedControl/useSegmentedSelectionMotion.ts +3 -6
- package/src/Slider/sliderTouchController.ts +2 -2
- package/src/Spinner/Spinner.tsx +63 -77
- package/src/Switch/useSwitchTouch.ts +4 -4
- package/src/Table/BaseTable.tsx +12 -46
- package/src/TextInput/TextInput.tsx +10 -11
- package/src/Toast/Toast.doc.mjs +3 -4
- package/src/Toast/Toast.tsx +32 -52
- package/src/Toast/ToastViewport.tsx +35 -121
- package/src/Toast/types.ts +3 -9
- package/src/Tooltip/useTooltip.doc.mjs +0 -24
- package/src/Tooltip/useTooltip.tsx +56 -61
- package/src/Typeahead/TypeaheadItem.doc.mjs +3 -6
- package/src/Typeahead/TypeaheadItem.tsx +1 -2
- package/src/gestures/PressTracker.ts +3 -4
- package/src/gestures/README.md +1 -7
- package/src/hooks/actionGroupTracker.ts +5 -20
- package/src/hooks/index.ts +0 -2
- package/src/hooks/useAttachment.ts +1 -1
- package/src/hooks/useInputStatusIcon.tsx +2 -3
- package/src/hooks/useLongPress.doc.mjs +2 -2
- package/src/hooks/useLongPress.ts +15 -136
- package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +0 -6
- package/src/i18n/generated-locales/en.generated.ts +0 -41
- package/src/i18n/generated-locales/pseudo.generated.ts +0 -42
- package/src/index.ts +0 -13
- package/src/motion/README.md +5 -9
- package/src/motion/animatedLayout.ts +4 -5
- package/src/motion/animator.ts +29 -61
- package/src/utils/dateParser.ts +0 -16
- package/src/utils/focusReturn.ts +0 -30
- package/src/utils/interactionOverlay.stylex.ts +2 -3
- package/src/utils/pressFeedback.ts +6 -19
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +0 -100
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +0 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.js +0 -1913
- package/dist/PowerSearch/formatTokenValue.d.ts +0 -28
- package/dist/PowerSearch/formatTokenValue.d.ts.map +0 -1
- package/dist/PowerSearch/formatTokenValue.js +0 -160
- package/dist/PowerSearch/powerSearchSheetUtils.d.ts +0 -65
- package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +0 -1
- package/dist/PowerSearch/powerSearchSheetUtils.js +0 -168
- package/dist/animator/createAnimator.d.ts +0 -98
- package/dist/animator/createAnimator.d.ts.map +0 -1
- package/dist/animator/createAnimator.js +0 -259
- package/dist/hooks/pressGroupContext.d.ts +0 -6
- package/dist/hooks/pressGroupContext.d.ts.map +0 -1
- package/dist/hooks/pressGroupContext.js +0 -20
- package/dist/hooks/useActionGroupTracking.d.ts +0 -53
- package/dist/hooks/useActionGroupTracking.d.ts.map +0 -1
- package/dist/hooks/useActionGroupTracking.js +0 -174
- package/dist/hooks/useAnimator.d.ts +0 -41
- package/dist/hooks/useAnimator.d.ts.map +0 -1
- package/dist/hooks/useAnimator.js +0 -70
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +0 -8
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +0 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +0 -42
- package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +0 -8
- package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +0 -1
- package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +0 -14
- package/dist/internal/indicatorPress.stylex.d.ts +0 -20
- package/dist/internal/indicatorPress.stylex.d.ts.map +0 -1
- package/dist/internal/indicatorPress.stylex.js +0 -26
- package/dist/motion/progress.d.ts +0 -88
- package/dist/motion/progress.d.ts.map +0 -1
- package/dist/motion/progress.js +0 -128
- package/dist/motion/uikit/alert.d.ts +0 -41
- package/dist/motion/uikit/alert.d.ts.map +0 -1
- package/dist/motion/uikit/alert.js +0 -43
- package/dist/privateAttributes/pressGroupItem.stylex.d.ts +0 -15
- package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +0 -1
- package/dist/privateAttributes/pressGroupItem.stylex.js +0 -23
- package/dist/utils/triggerFocus.d.ts +0 -36
- package/dist/utils/triggerFocus.d.ts.map +0 -1
- package/dist/utils/triggerFocus.js +0 -65
- package/src/PowerSearch/PowerSearchBottomSheet.tsx +0 -2515
- package/src/PowerSearch/formatTokenValue.ts +0 -215
- package/src/PowerSearch/powerSearchSheetUtils.ts +0 -224
- package/src/animator/createAnimator.doc.mjs +0 -153
- package/src/animator/createAnimator.ts +0 -324
- package/src/hooks/pressGroupContext.ts +0 -21
- package/src/hooks/useActionGroupTracking.ts +0 -224
- package/src/hooks/useAnimator.doc.mjs +0 -109
- package/src/hooks/useAnimator.ts +0 -67
- package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +0 -43
- package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +0 -15
- package/src/internal/indicatorPress.stylex.ts +0 -24
- package/src/motion/progress.ts +0 -155
- package/src/motion/uikit/alert.ts +0 -43
- package/src/privateAttributes/pressGroupItem.stylex.ts +0 -23
- package/src/utils/triggerFocus.ts +0 -80
|
@@ -46,7 +46,6 @@ import {useTooltip} from '../Tooltip/useTooltip';
|
|
|
46
46
|
import {mergeProps} from '../utils/mergeProps';
|
|
47
47
|
import {rtlStyles} from '../utils/rtlStyles';
|
|
48
48
|
import {indicatorScope} from '../Indicator/indicator.markers.stylex';
|
|
49
|
-
import {indicatorPressScope} from '../internal/indicatorPress.stylex';
|
|
50
49
|
import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
|
|
51
50
|
import {useIndicatorFocusRing} from '../hooks/useIndicatorFocusRing';
|
|
52
51
|
import {useBusyAnnouncement} from '../hooks/useBusyAnnouncement';
|
|
@@ -64,11 +63,6 @@ import english from '../i18n/generated-english/CheckboxInput/CheckboxInput.gener
|
|
|
64
63
|
|
|
65
64
|
registerEnglishFallback(english);
|
|
66
65
|
|
|
67
|
-
/** Written by the touch press controller while the row is pressed. */
|
|
68
|
-
const PRESSED_ON = '[data-astryx-press="on"]';
|
|
69
|
-
/** Written by the touch press controller for the press's release. */
|
|
70
|
-
const PRESSED_FADING = '[data-astryx-press="fading"]';
|
|
71
|
-
|
|
72
66
|
// The touch press's paint, declared by the shared overlay styles on the
|
|
73
67
|
// element the controller writes to (`pressedAlpha`) at the press's strength,
|
|
74
68
|
// 1 while on and 1 → 0 over the release, and inherited resolved by the layer
|
|
@@ -84,20 +78,6 @@ const styles = stylex.create({
|
|
|
84
78
|
containerLabelHidden: {
|
|
85
79
|
gap: 0,
|
|
86
80
|
},
|
|
87
|
-
// An indicator in another package may not name this row's private press
|
|
88
|
-
// attribute. So the row hands its touch press image down to an indicator
|
|
89
|
-
// that paints its own press, but only in its own press states. A pressed
|
|
90
|
-
// ancestor row reaches it no more than it reaches the built-in box. The
|
|
91
|
-
// property has no default: a layered stylesheet ranks a default above the
|
|
92
|
-
// arms. Only this row declares it. A menu item paints its own press, so a
|
|
93
|
-
// mapped indicator there paints none.
|
|
94
|
-
indicatorPressImage: {
|
|
95
|
-
'--_indicator-press-image': {
|
|
96
|
-
default: null,
|
|
97
|
-
[PRESSED_ON]: 'var(--_press-paint-image)',
|
|
98
|
-
[PRESSED_FADING]: 'var(--_press-paint-image)',
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
81
|
checkboxWrapper: {
|
|
102
82
|
position: 'relative',
|
|
103
83
|
display: 'flex',
|
|
@@ -106,22 +86,15 @@ const styles = stylex.create({
|
|
|
106
86
|
flexShrink: 0,
|
|
107
87
|
isolation: 'isolate',
|
|
108
88
|
},
|
|
109
|
-
// The owner paints this layer over the resolved indicator, so a
|
|
110
|
-
// replacement
|
|
111
|
-
// `indicatorPressScope` paints its own press from what the row hands down,
|
|
112
|
-
// so this layer stays off over it.
|
|
89
|
+
// The owner paints this layer over the resolved indicator, so a theme
|
|
90
|
+
// replacement cannot accidentally drop the component's pressed contract.
|
|
113
91
|
// Two pointers, two press models (see interactionOverlay.stylex.ts): a
|
|
114
92
|
// mouse keeps `:active`; under a coarse pointer that arm is dropped and the
|
|
115
93
|
// touch press controller writes `data-astryx-press` on the row, which this layer
|
|
116
94
|
// reads off the same scope marker as the hover tint.
|
|
117
95
|
indicatorPressOverlay: {
|
|
118
96
|
'::after': {
|
|
119
|
-
|
|
120
|
-
// indicator.
|
|
121
|
-
content: {
|
|
122
|
-
default: '""',
|
|
123
|
-
[stylex.when.descendant(':is(*)', indicatorPressScope)]: 'none',
|
|
124
|
-
},
|
|
97
|
+
content: '""',
|
|
125
98
|
position: 'absolute',
|
|
126
99
|
inset: 0,
|
|
127
100
|
borderRadius: radiusVars['--radius-inner'],
|
|
@@ -139,14 +112,15 @@ const styles = stylex.create({
|
|
|
139
112
|
// what moves. Coarse pointers only, like the drop above.
|
|
140
113
|
backgroundImage: {
|
|
141
114
|
default: null,
|
|
142
|
-
[stylex.when.ancestor(
|
|
143
|
-
default: null,
|
|
144
|
-
'@media (pointer: coarse)': pressedOverlayImage,
|
|
145
|
-
},
|
|
146
|
-
[stylex.when.ancestor(PRESSED_FADING, indicatorScope)]: {
|
|
115
|
+
[stylex.when.ancestor('[data-astryx-press="on"]', indicatorScope)]: {
|
|
147
116
|
default: null,
|
|
148
117
|
'@media (pointer: coarse)': pressedOverlayImage,
|
|
149
118
|
},
|
|
119
|
+
[stylex.when.ancestor('[data-astryx-press="fading"]', indicatorScope)]:
|
|
120
|
+
{
|
|
121
|
+
default: null,
|
|
122
|
+
'@media (pointer: coarse)': pressedOverlayImage,
|
|
123
|
+
},
|
|
150
124
|
},
|
|
151
125
|
},
|
|
152
126
|
},
|
|
@@ -476,7 +450,6 @@ export function CheckboxInput({
|
|
|
476
450
|
// Hover and focus reach the checkbox visual through this ancestor
|
|
477
451
|
// marker rather than props, so the whole row drives it.
|
|
478
452
|
!isDisabled && indicatorScope,
|
|
479
|
-
!isDisabled && styles.indicatorPressImage,
|
|
480
453
|
// The touch press's strength and release live on the row the
|
|
481
454
|
// controller writes to; the layer over the checkbox box inherits
|
|
482
455
|
// and paints it.
|
|
@@ -35,7 +35,6 @@ import {
|
|
|
35
35
|
} from '../Field/fieldParts';
|
|
36
36
|
import {useDevWarning} from '../hooks/useDevWarning';
|
|
37
37
|
import {mergeRefs} from '../utils/mergeRefs';
|
|
38
|
-
import {isFocusLost} from '../utils/focusReturn';
|
|
39
38
|
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
40
39
|
import {useBusyAnnouncement} from '../hooks/useBusyAnnouncement';
|
|
41
40
|
import {Field, inputWrapperStyles} from '../Field';
|
|
@@ -348,10 +347,7 @@ export interface ComplexSelectorRenderState {
|
|
|
348
347
|
export interface ComplexSelectorHandle {
|
|
349
348
|
/** Open the selector surface. No-op when disabled or already open. */
|
|
350
349
|
open(): void;
|
|
351
|
-
/**
|
|
352
|
-
* Close the selector surface. Focus returns to the trigger only when it
|
|
353
|
-
* would otherwise be lost; a caller-rendered trigger always gets it back.
|
|
354
|
-
*/
|
|
350
|
+
/** Close the selector surface. Restores focus to the trigger. */
|
|
355
351
|
close(): void;
|
|
356
352
|
/** Toggle the selector surface open or closed. */
|
|
357
353
|
toggle(): void;
|
|
@@ -634,22 +630,12 @@ export function ComplexSelector<Value>({
|
|
|
634
630
|
onOpenChange?.(true);
|
|
635
631
|
}, [onOpenChange]);
|
|
636
632
|
|
|
637
|
-
// The popup's content element, read when it closes.
|
|
638
|
-
const popupContentRef = useRef<HTMLElement | null>(null);
|
|
639
|
-
const hasCallerTrigger = renderTrigger != null;
|
|
640
633
|
const handlePopoverHide = useCallback(() => {
|
|
641
|
-
|
|
642
|
-
//
|
|
643
|
-
|
|
644
|
-
// consumer that moves it from the callback wins.
|
|
645
|
-
if (
|
|
646
|
-
hasCallerTrigger ||
|
|
647
|
-
isFocusLost(popupContentRef.current, trigger?.ownerDocument)
|
|
648
|
-
) {
|
|
649
|
-
trigger?.focus();
|
|
650
|
-
}
|
|
634
|
+
// Focus is restored first so a consumer that moves focus elsewhere from
|
|
635
|
+
// the callback wins, instead of being overwritten a line later.
|
|
636
|
+
triggerRef.current?.focus();
|
|
651
637
|
onOpenChange?.(false);
|
|
652
|
-
}, [
|
|
638
|
+
}, [onOpenChange]);
|
|
653
639
|
|
|
654
640
|
const popover = usePopover({
|
|
655
641
|
dialogLabel: label,
|
|
@@ -659,7 +645,6 @@ export function ComplexSelector<Value>({
|
|
|
659
645
|
onShow: handlePopoverShow,
|
|
660
646
|
onHide: handlePopoverHide,
|
|
661
647
|
});
|
|
662
|
-
popupContentRef.current = popover.contentRef.current;
|
|
663
648
|
|
|
664
649
|
const isOpen = popover.isOpen;
|
|
665
650
|
|
|
@@ -712,14 +712,14 @@ export function ContextMenu({
|
|
|
712
712
|
);
|
|
713
713
|
const handleTriggerTouchEnd = useCallback(
|
|
714
714
|
(event: React.TouchEvent<HTMLElement>) => {
|
|
715
|
-
handleLongPressTouchEnd(
|
|
715
|
+
handleLongPressTouchEnd();
|
|
716
716
|
onTouchEndProp?.(event);
|
|
717
717
|
},
|
|
718
718
|
[handleLongPressTouchEnd, onTouchEndProp],
|
|
719
719
|
);
|
|
720
720
|
const handleTriggerTouchCancel = useCallback(
|
|
721
721
|
(event: React.TouchEvent<HTMLElement>) => {
|
|
722
|
-
handleLongPressTouchCancel(
|
|
722
|
+
handleLongPressTouchCancel();
|
|
723
723
|
onTouchCancelProp?.(event);
|
|
724
724
|
},
|
|
725
725
|
[handleLongPressTouchCancel, onTouchCancelProp],
|
package/src/Dialog/Dialog.tsx
CHANGED
|
@@ -81,10 +81,7 @@ import {themeProps} from '../utils/themeProps';
|
|
|
81
81
|
import type {DialogVariantMap} from './index';
|
|
82
82
|
import {focusOutlineProps} from '../utils/focusOutline.stylex';
|
|
83
83
|
import {useInteractionModalityTracking} from '../utils/interactionModality';
|
|
84
|
-
import {
|
|
85
|
-
focusForLastInput,
|
|
86
|
-
prepareFocusReturnOnRemoval,
|
|
87
|
-
} from '../utils/focusReturn';
|
|
84
|
+
import {focusForLastInput, isFocusLost} from '../utils/focusReturn';
|
|
88
85
|
import {ModalAnnounceProvider} from '../hooks/ModalAnnounceProvider';
|
|
89
86
|
|
|
90
87
|
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
@@ -656,15 +653,39 @@ export function Dialog({
|
|
|
656
653
|
}, [isOpen, isInline]);
|
|
657
654
|
|
|
658
655
|
// A dialog that unmounts while open (rendered only while open, or removed
|
|
659
|
-
// with the rest of a view) never runs the close branch above
|
|
660
|
-
//
|
|
656
|
+
// with the rest of a view) never runs the close branch above, and removing a
|
|
657
|
+
// <dialog> does not run the browser's own focus return. Focus left inside
|
|
658
|
+
// it, or dropped to the body by the removal, goes back to the opener.
|
|
661
659
|
useEffect(() => {
|
|
662
|
-
|
|
663
|
-
if (isInline || dialog == null) {
|
|
660
|
+
if (isInline) {
|
|
664
661
|
return;
|
|
665
662
|
}
|
|
666
|
-
const
|
|
667
|
-
|
|
663
|
+
const dialog = dialogRef.current;
|
|
664
|
+
// Read now: a removed iframe's document has no window, so its frame
|
|
665
|
+
// element can no longer be found once the dialog is gone.
|
|
666
|
+
const host = dialog?.ownerDocument.defaultView?.frameElement ?? null;
|
|
667
|
+
return () => {
|
|
668
|
+
const trigger = triggerElementRef.current;
|
|
669
|
+
if (dialog == null || trigger == null) {
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
// Checked once the commit has finished: StrictMode's simulated unmount
|
|
673
|
+
// leaves the dialog in the document, and only a real removal returns
|
|
674
|
+
// focus.
|
|
675
|
+
queueMicrotask(() => {
|
|
676
|
+
if (dialog.isConnected || !trigger.isConnected) {
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
// isFocusLost reads the dialog's own document. For a dialog in an
|
|
680
|
+
// iframe, the document that hosts the frame must also have lost focus
|
|
681
|
+
// or keep it on that frame, wherever the opener is: a control the
|
|
682
|
+
// user pressed outside the frame to remove the dialog, or the frame
|
|
683
|
+
// itself, keeps its focus.
|
|
684
|
+
if (isFocusLost(dialog) && (host == null || isFocusLost(host))) {
|
|
685
|
+
focusForLastInput(trigger);
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
};
|
|
668
689
|
}, [isInline]);
|
|
669
690
|
|
|
670
691
|
// Host app-global surfaces (toasts) inside this modal while it is open, so
|
package/src/Field/Field.tsx
CHANGED
|
@@ -25,11 +25,11 @@ import {FieldStatus} from '../FieldStatus/FieldStatus';
|
|
|
25
25
|
import {useFieldStatusAnnouncement} from '../FieldStatus/useFieldStatusAnnouncement';
|
|
26
26
|
import {spacingVars, borderVars, sizeVars} from '../theme/tokens.stylex';
|
|
27
27
|
import type {IconType} from '../Icon';
|
|
28
|
-
import {mergeProps} from '../utils
|
|
28
|
+
import {mergeProps} from '../utils';
|
|
29
29
|
import {useDevWarning} from '../hooks/useDevWarning';
|
|
30
30
|
import {FormLayoutContext} from '../FormLayout/FormLayoutContext';
|
|
31
31
|
import {Text} from '../Text/Text';
|
|
32
|
-
import {VisuallyHidden} from '../VisuallyHidden
|
|
32
|
+
import {VisuallyHidden} from '../VisuallyHidden';
|
|
33
33
|
import {themeProps} from '../utils/themeProps';
|
|
34
34
|
import type {FieldStatusPlacement} from './fieldStatusPlacement';
|
|
35
35
|
|
|
@@ -98,8 +98,7 @@ export const docs = {
|
|
|
98
98
|
{
|
|
99
99
|
name: 'focusTrigger',
|
|
100
100
|
type: "'auto' | 'always' | 'never'",
|
|
101
|
-
description:
|
|
102
|
-
'When focus should open the hover card. auto opens when the trigger itself takes focus, or focus lands inside a trigger that is focusable at that moment, so a roving-tabindex member opens when the arrow keys reach it.',
|
|
101
|
+
description: 'Controls when focus events trigger the hover card.',
|
|
103
102
|
default: "'auto'",
|
|
104
103
|
},
|
|
105
104
|
{
|
|
@@ -304,8 +303,7 @@ export const docsZh = {
|
|
|
304
303
|
{
|
|
305
304
|
name: 'focusTrigger',
|
|
306
305
|
type: "'auto' | 'always' | 'never'",
|
|
307
|
-
description:
|
|
308
|
-
'焦点何时打开悬浮卡片。auto 在触发元素自身获得焦点,或焦点落在当时可聚焦的触发元素内部时打开,因此方向键到达漫游 tabindex 成员时也会打开。',
|
|
306
|
+
description: '控制焦点事件何时触发悬浮卡片。',
|
|
309
307
|
default: "'auto'",
|
|
310
308
|
},
|
|
311
309
|
{
|
|
@@ -16,14 +16,7 @@
|
|
|
16
16
|
* - /packages/cli/assets/templates/blocks/components/HoverCard/ (showcase blocks)
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
useCallback,
|
|
21
|
-
useRef,
|
|
22
|
-
useState,
|
|
23
|
-
type ReactElement,
|
|
24
|
-
type ReactNode,
|
|
25
|
-
} from 'react';
|
|
26
|
-
import {observeMutations} from '../utils/sharedMutationObserver';
|
|
19
|
+
import {useCallback, useRef, type ReactElement, type ReactNode} from 'react';
|
|
27
20
|
import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect';
|
|
28
21
|
import * as stylex from '@stylexjs/stylex';
|
|
29
22
|
import {
|
|
@@ -155,10 +148,9 @@ export interface HoverCardProps extends Pick<
|
|
|
155
148
|
|
|
156
149
|
/**
|
|
157
150
|
* When to trigger on focus:
|
|
158
|
-
* - `auto`:
|
|
159
|
-
*
|
|
160
|
-
* - `
|
|
161
|
-
* - `never`: never on focus (for composite widgets)
|
|
151
|
+
* - `auto`: Only if element is naturally focusable
|
|
152
|
+
* - `always`: Always attach focus listeners
|
|
153
|
+
* - `never`: Never attach focus listeners (for composite widgets)
|
|
162
154
|
*
|
|
163
155
|
* @default 'auto'
|
|
164
156
|
*/
|
|
@@ -311,28 +303,6 @@ export function HoverCard({
|
|
|
311
303
|
onHide: handleHide,
|
|
312
304
|
});
|
|
313
305
|
|
|
314
|
-
// The wrapper's first element is the trigger, and it can be replaced after
|
|
315
|
-
// mount: by new children, or by a child component that swaps its own root
|
|
316
|
-
// without a render here. Syncs with the DOM: on a replacement the wiring
|
|
317
|
-
// below re-runs, so the old element is released before the new one is wired.
|
|
318
|
-
const [triggerReplacements, setTriggerReplacements] = useState(0);
|
|
319
|
-
const observedTriggerRef = useRef<Element | null>(null);
|
|
320
|
-
useIsomorphicLayoutEffect(() => {
|
|
321
|
-
const wrapper = wrapperRef.current;
|
|
322
|
-
if (textOnly || wrapper == null) {
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
observedTriggerRef.current = wrapper.firstElementChild;
|
|
326
|
-
return observeMutations(wrapper, {childList: true}, () => {
|
|
327
|
-
const trigger = wrapper.firstElementChild;
|
|
328
|
-
if (trigger === observedTriggerRef.current) {
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
observedTriggerRef.current = trigger;
|
|
332
|
-
setTriggerReplacements(count => count + 1);
|
|
333
|
-
});
|
|
334
|
-
}, [textOnly]);
|
|
335
|
-
|
|
336
306
|
// For element children with display:contents, attach ref to first child
|
|
337
307
|
useIsomorphicLayoutEffect(() => {
|
|
338
308
|
if (textOnly) {
|
|
@@ -437,7 +407,6 @@ export function HoverCard({
|
|
|
437
407
|
hoverCard.id,
|
|
438
408
|
hoverCard.isOpen,
|
|
439
409
|
hoverCard.describedBy,
|
|
440
|
-
triggerReplacements,
|
|
441
410
|
]);
|
|
442
411
|
|
|
443
412
|
// While closed, useLayer leaves only an inert <template> marker at this JSX
|
|
@@ -5,159 +5,37 @@ export const docs = {
|
|
|
5
5
|
name: 'useHoverCard',
|
|
6
6
|
displayName: 'useHoverCard',
|
|
7
7
|
group: 'HoverCard',
|
|
8
|
-
keywords: [
|
|
9
|
-
'hovercard',
|
|
10
|
-
'hover',
|
|
11
|
-
'preview',
|
|
12
|
-
'card',
|
|
13
|
-
'tooltip',
|
|
14
|
-
'popup',
|
|
15
|
-
'floating',
|
|
16
|
-
'anchor',
|
|
17
|
-
],
|
|
8
|
+
keywords: ['hovercard', 'hover', 'preview', 'card', 'tooltip', 'popup', 'floating', 'anchor'],
|
|
18
9
|
params: [
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
default: "'center'",
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
name: 'delay',
|
|
35
|
-
type: 'number',
|
|
36
|
-
description:
|
|
37
|
-
'Delay before showing the hover card on hover, in milliseconds.',
|
|
38
|
-
default: '300',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: 'hideDelay',
|
|
42
|
-
type: 'number',
|
|
43
|
-
description:
|
|
44
|
-
'Delay before hiding after mouse or focus leaves, in milliseconds.',
|
|
45
|
-
default: '200',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: 'focusTrigger',
|
|
49
|
-
type: "'auto' | 'always' | 'never'",
|
|
50
|
-
description:
|
|
51
|
-
'When focus should open the hover card. auto opens when the trigger itself takes focus, or focus lands inside a trigger that is focusable at that moment, so a roving-tabindex member opens when the arrow keys reach it.',
|
|
52
|
-
default: "'auto'",
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'touchTrigger',
|
|
56
|
-
type: "'auto' | 'tap' | 'none'",
|
|
57
|
-
description:
|
|
58
|
-
'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own (an aria-disabled control performs none); tap always opens; none never opens on touch.',
|
|
59
|
-
default: "'auto'",
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
name: 'isEnabled',
|
|
63
|
-
type: 'boolean',
|
|
64
|
-
description: 'Whether hover and focus triggers are enabled.',
|
|
65
|
-
default: 'true',
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: 'label',
|
|
69
|
-
type: 'string',
|
|
70
|
-
description:
|
|
71
|
-
'Accessible name for the hover card popup. When provided, the popup is exposed as a named role="dialog"; when omitted, it falls back to role="group" (a group may validly be unnamed).',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
name: 'isOpen',
|
|
75
|
-
type: 'boolean',
|
|
76
|
-
description:
|
|
77
|
-
'Controlled open state. true force-shows, false force-hides, undefined lets hover/focus manage visibility.',
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
name: 'isDefaultOpen',
|
|
81
|
-
type: 'boolean',
|
|
82
|
-
description: 'Whether the hover card should be shown on mount.',
|
|
83
|
-
default: 'false',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
name: 'onShow',
|
|
87
|
-
type: '() => void',
|
|
88
|
-
description: 'Callback fired when the hover card becomes visible.',
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
name: 'onHide',
|
|
92
|
-
type: '() => void',
|
|
93
|
-
description: 'Callback fired when the hover card is hidden.',
|
|
94
|
-
},
|
|
10
|
+
{name: 'placement', type: "'above' | 'below' | 'start' | 'end'", description: "Position relative to the trigger. Logical: start/end resolve against the popover\'s own inherited direction (RTL mirrors in pure CSS).", default: "'above'"},
|
|
11
|
+
{name: 'alignment', type: "'start' | 'center' | 'end'", description: "Alignment along the placement axis. Logical: start/end resolve against the popover\'s own inherited direction (RTL mirrors in pure CSS).", default: "'center'"},
|
|
12
|
+
{name: 'delay', type: 'number', description: 'Delay before showing the hover card on hover, in milliseconds.', default: '300'},
|
|
13
|
+
{name: 'hideDelay', type: 'number', description: 'Delay before hiding after mouse or focus leaves, in milliseconds.', default: '200'},
|
|
14
|
+
{name: 'focusTrigger', type: "'auto' | 'always' | 'never'", description: 'When focus should open the hover card. auto only attaches focus listeners to naturally focusable elements.', default: "'auto'"},
|
|
15
|
+
{name: 'touchTrigger', type: "'auto' | 'tap' | 'none'", description: 'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own (an aria-disabled control performs none); tap always opens; none never opens on touch.', default: "'auto'"},
|
|
16
|
+
{name: 'isEnabled', type: 'boolean', description: 'Whether hover and focus triggers are enabled.', default: 'true'},
|
|
17
|
+
{name: 'label', type: 'string', description: 'Accessible name for the hover card popup. When provided, the popup is exposed as a named role="dialog"; when omitted, it falls back to role="group" (a group may validly be unnamed).'},
|
|
18
|
+
{name: 'isOpen', type: 'boolean', description: 'Controlled open state. true force-shows, false force-hides, undefined lets hover/focus manage visibility.'},
|
|
19
|
+
{name: 'isDefaultOpen', type: 'boolean', description: 'Whether the hover card should be shown on mount.', default: 'false'},
|
|
20
|
+
{name: 'onShow', type: '() => void', description: 'Callback fired when the hover card becomes visible.'},
|
|
21
|
+
{name: 'onHide', type: '() => void', description: 'Callback fired when the hover card is hidden.'},
|
|
95
22
|
],
|
|
96
23
|
returns: [
|
|
97
|
-
{
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
type: 'RefCallback<HTMLElement>',
|
|
106
|
-
description:
|
|
107
|
-
'Ref for the positioning anchor element. Use when position and interaction live on different elements.',
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
name: 'interactionRef',
|
|
111
|
-
type: 'RefCallback<HTMLElement>',
|
|
112
|
-
description:
|
|
113
|
-
'Ref for the hover/focus interaction element. Use with positionRef for split trigger patterns.',
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
name: 'anchorId',
|
|
117
|
-
type: 'string',
|
|
118
|
-
description: 'CSS anchor name for advanced positioning cases.',
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
name: 'describedBy',
|
|
122
|
-
type: 'string',
|
|
123
|
-
description: 'ID to compose into aria-describedby on the trigger.',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'renderHoverCard',
|
|
127
|
-
type: "(children: ReactNode, props?: Omit<ContextRenderProps, 'positioning'>) => ReactNode",
|
|
128
|
-
description:
|
|
129
|
-
'Render function for the anchor-positioned hover card content. The positioning opt-out is excluded: the hover card always derives its position from placement/alignment.',
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
name: 'show',
|
|
133
|
-
type: '() => void',
|
|
134
|
-
description: 'Imperatively show the hover card immediately.',
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
name: 'hide',
|
|
138
|
-
type: '() => void',
|
|
139
|
-
description: 'Imperatively hide the hover card immediately.',
|
|
140
|
-
},
|
|
24
|
+
{name: 'ref', type: 'RefCallback<HTMLElement>', description: 'Combined ref that sets both position and interaction on the same trigger element.'},
|
|
25
|
+
{name: 'positionRef', type: 'RefCallback<HTMLElement>', description: 'Ref for the positioning anchor element. Use when position and interaction live on different elements.'},
|
|
26
|
+
{name: 'interactionRef', type: 'RefCallback<HTMLElement>', description: 'Ref for the hover/focus interaction element. Use with positionRef for split trigger patterns.'},
|
|
27
|
+
{name: 'anchorId', type: 'string', description: 'CSS anchor name for advanced positioning cases.'},
|
|
28
|
+
{name: 'describedBy', type: 'string', description: 'ID to compose into aria-describedby on the trigger.'},
|
|
29
|
+
{name: 'renderHoverCard', type: "(children: ReactNode, props?: Omit<ContextRenderProps, 'positioning'>) => ReactNode", description: 'Render function for the anchor-positioned hover card content. The positioning opt-out is excluded: the hover card always derives its position from placement/alignment.'},
|
|
30
|
+
{name: 'show', type: '() => void', description: 'Imperatively show the hover card immediately.'},
|
|
31
|
+
{name: 'hide', type: '() => void', description: 'Imperatively hide the hover card immediately.'},
|
|
141
32
|
],
|
|
142
33
|
usage: {
|
|
143
|
-
description:
|
|
144
|
-
'Headless hook for hover-triggered floating cards. Builds on useLayer with hover/focus intent detection, configurable delays, safe hover behavior, and accessible aria-describedby linking. Use for rich previews on hover when you need full control over the trigger or rendered content.',
|
|
34
|
+
description: 'Headless hook for hover-triggered floating cards. Builds on useLayer with hover/focus intent detection, configurable delays, safe hover behavior, and accessible aria-describedby linking. Use for rich previews on hover when you need full control over the trigger or rendered content.',
|
|
145
35
|
bestPractices: [
|
|
146
|
-
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
'Use for rich content previews such as user profiles, entity summaries, and link previews.',
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
guidance: true,
|
|
153
|
-
description:
|
|
154
|
-
'Prefer the HoverCard component for standard trigger-content pairs; use the hook for custom trigger patterns.',
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
guidance: false,
|
|
158
|
-
description:
|
|
159
|
-
'Use for simple text hints: use Tooltip or useTooltip instead.',
|
|
160
|
-
},
|
|
36
|
+
{guidance: true, description: 'Use for rich content previews such as user profiles, entity summaries, and link previews.'},
|
|
37
|
+
{guidance: true, description: 'Prefer the HoverCard component for standard trigger-content pairs; use the hook for custom trigger patterns.'},
|
|
38
|
+
{guidance: false, description: 'Use for simple text hints: use Tooltip or useTooltip instead.'},
|
|
161
39
|
],
|
|
162
40
|
},
|
|
163
41
|
relatedComponents: ['HoverCard', 'Tooltip', 'Popover'],
|
|
@@ -168,24 +46,17 @@ export const docs = {
|
|
|
168
46
|
|
|
169
47
|
/** @type {import('@astryxdesign/cli/authoring').HookTranslationDoc} */
|
|
170
48
|
export const docsDense = {
|
|
171
|
-
description:
|
|
172
|
-
'Headless hover-triggered floating cards. Builds on useLayer w/ hover/focus intent, delays, safe hover behavior, aria-describedby. Use for rich previews when trigger/content rendering needs full control.',
|
|
49
|
+
description: 'Headless hover-triggered floating cards. Builds on useLayer w/ hover/focus intent, delays, safe hover behavior, aria-describedby. Use for rich previews when trigger/content rendering needs full control.',
|
|
173
50
|
paramDescriptions: {
|
|
174
|
-
placement:
|
|
175
|
-
|
|
176
|
-
alignment:
|
|
177
|
-
"alignment along placement axis. logical: start/end follow the popover's inherited direction (RTL mirrors).",
|
|
51
|
+
placement: 'position relative to trigger. logical: start/end follow the popover\'s inherited direction (RTL mirrors).',
|
|
52
|
+
alignment: 'alignment along placement axis. logical: start/end follow the popover\'s inherited direction (RTL mirrors).',
|
|
178
53
|
delay: 'show delay in ms.',
|
|
179
54
|
hideDelay: 'hide delay after mouse/focus leave in ms.',
|
|
180
|
-
focusTrigger:
|
|
181
|
-
|
|
182
|
-
touchTrigger:
|
|
183
|
-
'tap behavior with no hover; auto = tap unless trigger acts, tap = always, none = never.',
|
|
55
|
+
focusTrigger: 'when focus opens hover card; auto = naturally focusable elements only.',
|
|
56
|
+
touchTrigger: 'tap behavior with no hover; auto = tap unless trigger acts, tap = always, none = never.',
|
|
184
57
|
isEnabled: 'whether hover/focus triggers are enabled.',
|
|
185
|
-
label:
|
|
186
|
-
|
|
187
|
-
isOpen:
|
|
188
|
-
'controlled open state: true force-show, false force-hide, undefined unmanaged.',
|
|
58
|
+
label: 'accessible name for popup. with label: named role="dialog"; without: role="group".',
|
|
59
|
+
isOpen: 'controlled open state: true force-show, false force-hide, undefined unmanaged.',
|
|
189
60
|
isDefaultOpen: 'show on mount.',
|
|
190
61
|
onShow: 'fires when hover card becomes visible.',
|
|
191
62
|
onHide: 'fires when hover card hides.',
|
|
@@ -201,24 +72,11 @@ export const docsDense = {
|
|
|
201
72
|
hide: 'hide immediately.',
|
|
202
73
|
},
|
|
203
74
|
usage: {
|
|
204
|
-
description:
|
|
205
|
-
'Headless hover-triggered floating cards. Builds on useLayer w/ hover/focus intent, delays, safe hover behavior, aria-describedby. Use for rich previews when trigger/content rendering needs full control.',
|
|
75
|
+
description: 'Headless hover-triggered floating cards. Builds on useLayer w/ hover/focus intent, delays, safe hover behavior, aria-describedby. Use for rich previews when trigger/content rendering needs full control.',
|
|
206
76
|
bestPractices: [
|
|
207
|
-
{
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
'Use for rich previews: profiles, entity summaries, link previews.',
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
guidance: true,
|
|
214
|
-
description:
|
|
215
|
-
'Prefer HoverCard for standard trigger-content pairs; use hook for custom trigger patterns.',
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
guidance: false,
|
|
219
|
-
description:
|
|
220
|
-
'Use for simple text hints: use Tooltip / useTooltip instead.',
|
|
221
|
-
},
|
|
77
|
+
{guidance: true, description: 'Use for rich previews: profiles, entity summaries, link previews.'},
|
|
78
|
+
{guidance: true, description: 'Prefer HoverCard for standard trigger-content pairs; use hook for custom trigger patterns.'},
|
|
79
|
+
{guidance: false, description: 'Use for simple text hints: use Tooltip / useTooltip instead.'},
|
|
222
80
|
],
|
|
223
81
|
},
|
|
224
82
|
};
|