@wordpress/components 32.5.0 → 32.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +40 -0
- package/README.md +18 -4
- package/build/alignment-matrix-control/cell.cjs +3 -3
- package/build/alignment-matrix-control/cell.cjs.map +2 -2
- package/build/alignment-matrix-control/index.cjs +3 -3
- package/build/alignment-matrix-control/index.cjs.map +2 -2
- package/build/autocomplete/autocompleter-ui.cjs +75 -79
- package/build/autocomplete/autocompleter-ui.cjs.map +2 -2
- package/build/autocomplete/get-autocomplete-match.cjs +91 -0
- package/build/autocomplete/get-autocomplete-match.cjs.map +7 -0
- package/build/autocomplete/index.cjs +104 -107
- package/build/autocomplete/index.cjs.map +3 -3
- package/build/box-control/index.cjs +0 -8
- package/build/box-control/index.cjs.map +2 -2
- package/build/box-control/utils.cjs +1 -10
- package/build/box-control/utils.cjs.map +2 -2
- package/build/calendar/utils/use-localization-props.cjs +3 -2
- package/build/calendar/utils/use-localization-props.cjs.map +2 -2
- package/build/custom-gradient-picker/index.cjs.map +2 -2
- package/build/custom-select-control/index.cjs.map +3 -3
- package/build/custom-select-control-v2/custom-select.cjs +2 -2
- package/build/custom-select-control-v2/custom-select.cjs.map +2 -2
- package/build/custom-select-control-v2/index.cjs.map +3 -3
- package/build/date-time/{date → date-picker}/index.cjs +6 -6
- package/build/date-time/{date → date-picker}/index.cjs.map +2 -2
- package/build/date-time/{date → date-picker}/styles.cjs +17 -17
- package/build/date-time/{date → date-picker}/styles.cjs.map +2 -2
- package/build/date-time/{date → date-picker}/use-lilius/index.cjs +1 -1
- package/build/date-time/{date → date-picker}/use-lilius/index.cjs.map +1 -1
- package/build/date-time/date-time/index.cjs +6 -6
- package/build/date-time/date-time/index.cjs.map +2 -2
- package/build/date-time/index.cjs +4 -4
- package/build/date-time/index.cjs.map +2 -2
- package/build/date-time/{time → time-picker}/index.cjs +6 -6
- package/build/date-time/time-picker/index.cjs.map +7 -0
- package/build/date-time/{time → time-picker}/styles.cjs +21 -21
- package/build/date-time/{time → time-picker}/styles.cjs.map +2 -2
- package/build/date-time/{time → time-picker}/time-input/index.cjs +1 -1
- package/build/date-time/{time → time-picker}/time-input/index.cjs.map +1 -1
- package/build/date-time/{time → time-picker}/timezone.cjs +1 -1
- package/build/date-time/{time → time-picker}/timezone.cjs.map +1 -1
- package/build/modal/index.cjs.map +2 -2
- package/build/palette-edit/index.cjs.map +2 -2
- package/build/radio-control/index.cjs +2 -0
- package/build/radio-control/index.cjs.map +2 -2
- package/build/sandbox/index.cjs +127 -3
- package/build/sandbox/index.cjs.map +2 -2
- package/build/textarea-control/styles/textarea-control-styles.cjs +3 -3
- package/build/textarea-control/styles/textarea-control-styles.cjs.map +2 -2
- package/build/validated-form-controls/control-with-error.cjs +12 -8
- package/build/validated-form-controls/control-with-error.cjs.map +2 -2
- package/build-module/alignment-matrix-control/cell.mjs +3 -3
- package/build-module/alignment-matrix-control/cell.mjs.map +2 -2
- package/build-module/alignment-matrix-control/index.mjs +3 -3
- package/build-module/alignment-matrix-control/index.mjs.map +2 -2
- package/build-module/autocomplete/autocompleter-ui.mjs +74 -78
- package/build-module/autocomplete/autocompleter-ui.mjs.map +2 -2
- package/build-module/autocomplete/get-autocomplete-match.mjs +56 -0
- package/build-module/autocomplete/get-autocomplete-match.mjs.map +7 -0
- package/build-module/autocomplete/index.mjs +103 -107
- package/build-module/autocomplete/index.mjs.map +3 -3
- package/build-module/box-control/index.mjs +1 -9
- package/build-module/box-control/index.mjs.map +2 -2
- package/build-module/box-control/utils.mjs +1 -9
- package/build-module/box-control/utils.mjs.map +2 -2
- package/build-module/calendar/utils/use-localization-props.mjs +3 -2
- package/build-module/calendar/utils/use-localization-props.mjs.map +2 -2
- package/build-module/custom-gradient-picker/index.mjs.map +2 -2
- package/build-module/custom-select-control/index.mjs +2 -2
- package/build-module/custom-select-control/index.mjs.map +2 -2
- package/build-module/custom-select-control-v2/custom-select.mjs +2 -2
- package/build-module/custom-select-control-v2/custom-select.mjs.map +2 -2
- package/build-module/custom-select-control-v2/index.mjs +2 -2
- package/build-module/custom-select-control-v2/index.mjs.map +2 -2
- package/build-module/date-time/{date → date-picker}/index.mjs +3 -3
- package/build-module/date-time/{date → date-picker}/index.mjs.map +2 -2
- package/build-module/date-time/{date → date-picker}/styles.mjs +17 -17
- package/build-module/date-time/{date → date-picker}/styles.mjs.map +2 -2
- package/build-module/date-time/{date → date-picker}/use-lilius/index.mjs +1 -1
- package/build-module/date-time/{date → date-picker}/use-lilius/index.mjs.map +1 -1
- package/build-module/date-time/date-time/index.mjs +2 -2
- package/build-module/date-time/date-time/index.mjs.map +1 -1
- package/build-module/date-time/index.mjs +2 -2
- package/build-module/date-time/index.mjs.map +1 -1
- package/build-module/date-time/{time → time-picker}/index.mjs +3 -3
- package/build-module/date-time/time-picker/index.mjs.map +7 -0
- package/build-module/date-time/{time → time-picker}/styles.mjs +21 -21
- package/build-module/date-time/{time → time-picker}/styles.mjs.map +2 -2
- package/build-module/date-time/{time → time-picker}/time-input/index.mjs +1 -1
- package/build-module/date-time/{time → time-picker}/time-input/index.mjs.map +1 -1
- package/build-module/date-time/{time → time-picker}/timezone.mjs +1 -1
- package/build-module/date-time/{time → time-picker}/timezone.mjs.map +1 -1
- package/build-module/modal/index.mjs.map +2 -2
- package/build-module/palette-edit/index.mjs.map +2 -2
- package/build-module/radio-control/index.mjs +2 -0
- package/build-module/radio-control/index.mjs.map +2 -2
- package/build-module/sandbox/index.mjs +128 -4
- package/build-module/sandbox/index.mjs.map +2 -2
- package/build-module/textarea-control/styles/textarea-control-styles.mjs +3 -3
- package/build-module/textarea-control/styles/textarea-control-styles.mjs.map +2 -2
- package/build-module/validated-form-controls/control-with-error.mjs +12 -8
- package/build-module/validated-form-controls/control-with-error.mjs.map +2 -2
- package/build-style/style-rtl.css +83 -26
- package/build-style/style.css +83 -26
- package/build-types/autocomplete/autocompleter-ui.d.ts +2 -2
- package/build-types/autocomplete/autocompleter-ui.d.ts.map +1 -1
- package/build-types/autocomplete/get-autocomplete-match.d.ts +11 -0
- package/build-types/autocomplete/get-autocomplete-match.d.ts.map +1 -0
- package/build-types/autocomplete/index.d.ts +8 -0
- package/build-types/autocomplete/index.d.ts.map +1 -1
- package/build-types/autocomplete/test/get-autocomplete-match.d.ts +2 -0
- package/build-types/autocomplete/test/get-autocomplete-match.d.ts.map +1 -0
- package/build-types/autocomplete/types.d.ts +23 -9
- package/build-types/autocomplete/types.d.ts.map +1 -1
- package/build-types/box-control/index.d.ts.map +1 -1
- package/build-types/box-control/utils.d.ts +7 -16
- package/build-types/box-control/utils.d.ts.map +1 -1
- package/build-types/button/stories/index.story.d.ts +0 -1
- package/build-types/button/stories/index.story.d.ts.map +1 -1
- package/build-types/calendar/utils/use-localization-props.d.ts +3 -3
- package/build-types/calendar/utils/use-localization-props.d.ts.map +1 -1
- package/build-types/checkbox-control/types.d.ts +4 -0
- package/build-types/checkbox-control/types.d.ts.map +1 -1
- package/build-types/custom-gradient-picker/constants.d.ts +2 -2
- package/build-types/custom-gradient-picker/index.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/custom-select.d.ts +3 -3
- package/build-types/custom-select-control-v2/custom-select.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/types.d.ts +1 -1
- package/build-types/custom-select-control-v2/types.d.ts.map +1 -1
- package/build-types/date-time/date-picker/index.d.ts.map +1 -0
- package/build-types/date-time/date-picker/styles.d.ts.map +1 -0
- package/build-types/date-time/date-picker/test/index.d.ts.map +1 -0
- package/build-types/date-time/date-picker/test/use-lilius.d.ts.map +1 -0
- package/build-types/date-time/date-picker/use-lilius/index.d.ts.map +1 -0
- package/build-types/date-time/date-time/index.d.ts +2 -2
- package/build-types/date-time/date-time/index.d.ts.map +1 -1
- package/build-types/date-time/index.d.ts +2 -2
- package/build-types/date-time/index.d.ts.map +1 -1
- package/build-types/date-time/stories/date.story.d.ts +1 -1
- package/build-types/date-time/stories/date.story.d.ts.map +1 -1
- package/build-types/date-time/stories/time.story.d.ts +1 -1
- package/build-types/date-time/stories/time.story.d.ts.map +1 -1
- package/build-types/date-time/{time → time-picker}/index.d.ts +1 -1
- package/build-types/date-time/time-picker/index.d.ts.map +1 -0
- package/build-types/date-time/time-picker/styles.d.ts.map +1 -0
- package/build-types/date-time/time-picker/test/index.d.ts.map +1 -0
- package/build-types/date-time/time-picker/time-input/index.d.ts.map +1 -0
- package/build-types/date-time/time-picker/time-input/test/index.d.ts.map +1 -0
- package/build-types/date-time/time-picker/timezone.d.ts.map +1 -0
- package/build-types/date-time/types.d.ts +1 -1
- package/build-types/date-time/types.d.ts.map +1 -1
- package/build-types/font-size-picker/constants.d.ts +2 -2
- package/build-types/font-size-picker/constants.d.ts.map +1 -1
- package/build-types/modal/index.d.ts.map +1 -1
- package/build-types/palette-edit/index.d.ts +1 -1
- package/build-types/palette-edit/index.d.ts.map +1 -1
- package/build-types/radio-control/index.d.ts.map +1 -1
- package/build-types/radio-control/types.d.ts +6 -0
- package/build-types/radio-control/types.d.ts.map +1 -1
- package/build-types/sandbox/index.d.ts +1 -1
- package/build-types/sandbox/index.d.ts.map +1 -1
- package/build-types/sandbox/types.d.ts +11 -0
- package/build-types/sandbox/types.d.ts.map +1 -1
- package/build-types/textarea-control/stories/index.story.d.ts.map +1 -1
- package/build-types/textarea-control/styles/textarea-control-styles.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/checkbox-control.d.ts +2 -1
- package/build-types/validated-form-controls/components/checkbox-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/radio-control.d.ts +2 -1
- package/build-types/validated-form-controls/components/radio-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/control-with-error.d.ts.map +1 -1
- package/package.json +21 -21
- package/src/alignment-matrix-control/README.md +1 -1
- package/src/alignment-matrix-control/style.module.scss +1 -1
- package/src/angle-picker-control/style.module.scss +1 -0
- package/src/autocomplete/README.md +2 -2
- package/src/autocomplete/autocompleter-ui.native.js +166 -173
- package/src/autocomplete/autocompleter-ui.tsx +114 -116
- package/src/autocomplete/get-autocomplete-match.ts +115 -0
- package/src/autocomplete/index.tsx +129 -208
- package/src/autocomplete/test/get-autocomplete-match.ts +338 -0
- package/src/autocomplete/test/index.tsx +112 -4
- package/src/autocomplete/types.ts +17 -10
- package/src/box-control/index.tsx +1 -19
- package/src/box-control/utils.ts +1 -19
- package/src/button/README.md +1 -1
- package/src/button/stories/index.story.tsx +0 -1
- package/src/button/style.scss +1 -7
- package/src/calendar/style.scss +3 -3
- package/src/calendar/utils/use-localization-props.ts +3 -4
- package/src/checkbox-control/style.scss +17 -5
- package/src/checkbox-control/types.ts +4 -0
- package/src/circular-option-picker/style.scss +1 -1
- package/src/color-palette/style.scss +1 -1
- package/src/css.d.ts +1 -0
- package/src/custom-gradient-picker/index.tsx +1 -0
- package/src/custom-select-control/index.tsx +3 -3
- package/src/custom-select-control-v2/custom-select.tsx +4 -4
- package/src/custom-select-control-v2/index.tsx +2 -2
- package/src/custom-select-control-v2/types.ts +1 -1
- package/src/date-time/README.md +3 -3
- package/src/date-time/date-picker/README.md +65 -0
- package/src/date-time/date-time/index.tsx +2 -2
- package/src/date-time/index.ts +2 -2
- package/src/date-time/stories/date.story.tsx +1 -1
- package/src/date-time/stories/time.story.tsx +1 -1
- package/src/date-time/time-picker/README.md +119 -0
- package/src/date-time/{time → time-picker}/index.tsx +1 -1
- package/src/date-time/types.ts +1 -1
- package/src/divider/README.md +5 -6
- package/src/dropdown-menu/style.scss +1 -1
- package/src/flex/stories/index.story.tsx +1 -1
- package/src/form-file-upload/README.md +3 -3
- package/src/form-toggle/style.scss +35 -2
- package/src/form-token-field/style.scss +12 -3
- package/src/gradient-picker/README.md +2 -2
- package/src/h-stack/README.md +10 -15
- package/src/h-stack/stories/index.story.tsx +2 -2
- package/src/heading/stories/index.story.tsx +1 -1
- package/src/higher-order/with-focus-outside/index.native.js +21 -20
- package/src/icon/README.md +1 -1
- package/src/menu/README.md +2 -2
- package/src/mobile/utils/get-px-from-css-unit.native.js +1 -1
- package/src/modal/index.tsx +1 -0
- package/src/palette-edit/index.tsx +1 -0
- package/src/radio-control/index.tsx +2 -0
- package/src/radio-control/style.scss +21 -2
- package/src/radio-control/test/index.tsx +10 -0
- package/src/radio-control/types.ts +6 -0
- package/src/sandbox/index.native.js +2 -2
- package/src/sandbox/index.tsx +191 -11
- package/src/sandbox/test/index.tsx +65 -24
- package/src/sandbox/types.ts +11 -0
- package/src/snackbar/style.scss +2 -2
- package/src/tab-panel/style.scss +1 -1
- package/src/tabs/README.md +6 -6
- package/src/text/stories/index.story.tsx +1 -1
- package/src/textarea-control/stories/index.story.tsx +3 -0
- package/src/textarea-control/styles/textarea-control-styles.ts +6 -0
- package/src/toggle-control/style.scss +1 -1
- package/src/toggle-control/test/index.tsx +8 -2
- package/src/toolbar/toolbar-button/toolbar-button-container.native.js +3 -1
- package/src/tree-select/README.md +1 -1
- package/src/v-stack/README.md +10 -15
- package/src/v-stack/stories/index.story.tsx +2 -2
- package/src/validated-form-controls/control-with-error.tsx +17 -12
- package/src/validated-form-controls/test/control-with-error.tsx +28 -1
- package/src/view/README.md +2 -5
- package/build/date-time/time/index.cjs.map +0 -7
- package/build-module/date-time/time/index.mjs.map +0 -7
- package/build-types/date-time/date/index.d.ts.map +0 -1
- package/build-types/date-time/date/styles.d.ts.map +0 -1
- package/build-types/date-time/date/test/index.d.ts.map +0 -1
- package/build-types/date-time/date/test/use-lilius.d.ts.map +0 -1
- package/build-types/date-time/date/use-lilius/index.d.ts.map +0 -1
- package/build-types/date-time/time/index.d.ts.map +0 -1
- package/build-types/date-time/time/styles.d.ts.map +0 -1
- package/build-types/date-time/time/test/index.d.ts.map +0 -1
- package/build-types/date-time/time/time-input/index.d.ts.map +0 -1
- package/build-types/date-time/time/time-input/test/index.d.ts.map +0 -1
- package/build-types/date-time/time/timezone.d.ts.map +0 -1
- package/src/button/stories/style.css +0 -8
- /package/build-types/date-time/{date → date-picker}/index.d.ts +0 -0
- /package/build-types/date-time/{date → date-picker}/styles.d.ts +0 -0
- /package/build-types/date-time/{date → date-picker}/test/index.d.ts +0 -0
- /package/build-types/date-time/{date → date-picker}/test/use-lilius.d.ts +0 -0
- /package/build-types/date-time/{date → date-picker}/use-lilius/index.d.ts +0 -0
- /package/build-types/date-time/{time → time-picker}/styles.d.ts +0 -0
- /package/build-types/date-time/{time → time-picker}/test/index.d.ts +0 -0
- /package/build-types/date-time/{time → time-picker}/time-input/index.d.ts +0 -0
- /package/build-types/date-time/{time → time-picker}/time-input/test/index.d.ts +0 -0
- /package/build-types/date-time/{time → time-picker}/timezone.d.ts +0 -0
- /package/src/date-time/{date → date-picker}/index.tsx +0 -0
- /package/src/date-time/{date → date-picker}/styles.ts +0 -0
- /package/src/date-time/{date → date-picker}/test/index.tsx +0 -0
- /package/src/date-time/{date → date-picker}/test/use-lilius.ts +0 -0
- /package/src/date-time/{date → date-picker}/use-lilius/index.ts +0 -0
- /package/src/date-time/{time → time-picker}/styles.ts +0 -0
- /package/src/date-time/{time → time-picker}/test/index.tsx +0 -0
- /package/src/date-time/{time → time-picker}/time-input/index.tsx +0 -0
- /package/src/date-time/{time → time-picker}/time-input/test/index.tsx +0 -0
- /package/src/date-time/{time → time-picker}/timezone.tsx +0 -0
|
@@ -41,92 +41,88 @@ function ListBox({
|
|
|
41
41
|
}, option.key))
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
-
function
|
|
44
|
+
function AutocompleterUI({
|
|
45
|
+
autocompleter,
|
|
46
|
+
filterValue,
|
|
47
|
+
instanceId,
|
|
48
|
+
listBoxId,
|
|
49
|
+
className,
|
|
50
|
+
selectedIndex,
|
|
51
|
+
onChangeOptions,
|
|
52
|
+
onSelect,
|
|
53
|
+
reset,
|
|
54
|
+
contentRef
|
|
55
|
+
}) {
|
|
45
56
|
const useItems = autocompleter.useItems ?? getDefaultUseItems(autocompleter);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
contentRef
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const debouncedSpeak = useDebounce(speak, 500);
|
|
72
|
-
function announce(options) {
|
|
73
|
-
if (!debouncedSpeak) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
if (!!options.length) {
|
|
77
|
-
if (filterValue) {
|
|
78
|
-
debouncedSpeak(sprintf(
|
|
79
|
-
/* translators: %d: number of results. */
|
|
80
|
-
_n("%d result found, use up and down arrow keys to navigate.", "%d results found, use up and down arrow keys to navigate.", options.length),
|
|
81
|
-
options.length
|
|
82
|
-
), "assertive");
|
|
83
|
-
} else {
|
|
84
|
-
debouncedSpeak(sprintf(
|
|
85
|
-
/* translators: %d: number of results. */
|
|
86
|
-
_n("Initial %d result loaded. Type to filter all available results. Use up and down arrow keys to navigate.", "Initial %d results loaded. Type to filter all available results. Use up and down arrow keys to navigate.", options.length),
|
|
87
|
-
options.length
|
|
88
|
-
), "assertive");
|
|
89
|
-
}
|
|
57
|
+
const [items] = useItems(filterValue);
|
|
58
|
+
const popoverAnchor = useAnchor({
|
|
59
|
+
editableContentElement: contentRef.current
|
|
60
|
+
});
|
|
61
|
+
const [needsA11yCompat, setNeedsA11yCompat] = useState(false);
|
|
62
|
+
const popoverRef = useRef(null);
|
|
63
|
+
const popoverRefs = useMergeRefs([popoverRef, useRefEffect((node) => {
|
|
64
|
+
if (!contentRef.current) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
setNeedsA11yCompat(node.ownerDocument !== contentRef.current.ownerDocument);
|
|
68
|
+
}, [contentRef])]);
|
|
69
|
+
useOnClickOutside(popoverRef, reset);
|
|
70
|
+
const debouncedSpeak = useDebounce(speak, 500);
|
|
71
|
+
function announce(options) {
|
|
72
|
+
if (!debouncedSpeak) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!!options.length) {
|
|
76
|
+
if (filterValue) {
|
|
77
|
+
debouncedSpeak(sprintf(
|
|
78
|
+
/* translators: %d: number of results. */
|
|
79
|
+
_n("%d result found, use up and down arrow keys to navigate.", "%d results found, use up and down arrow keys to navigate.", options.length),
|
|
80
|
+
options.length
|
|
81
|
+
), "assertive");
|
|
90
82
|
} else {
|
|
91
|
-
debouncedSpeak(
|
|
83
|
+
debouncedSpeak(sprintf(
|
|
84
|
+
/* translators: %d: number of results. */
|
|
85
|
+
_n("Initial %d result loaded. Type to filter all available results. Use up and down arrow keys to navigate.", "Initial %d results loaded. Type to filter all available results. Use up and down arrow keys to navigate.", options.length),
|
|
86
|
+
options.length
|
|
87
|
+
), "assertive");
|
|
92
88
|
}
|
|
89
|
+
} else {
|
|
90
|
+
debouncedSpeak(__("No results."), "assertive");
|
|
93
91
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
items,
|
|
112
|
-
onSelect,
|
|
113
|
-
selectedIndex,
|
|
114
|
-
instanceId,
|
|
115
|
-
listBoxId,
|
|
116
|
-
className
|
|
117
|
-
})
|
|
118
|
-
}), contentRef.current && needsA11yCompat && createPortal(/* @__PURE__ */ _jsx(ListBox, {
|
|
92
|
+
}
|
|
93
|
+
useLayoutEffect(() => {
|
|
94
|
+
onChangeOptions(items);
|
|
95
|
+
announce(items);
|
|
96
|
+
}, [items]);
|
|
97
|
+
if (items.length === 0) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
return /* @__PURE__ */ _jsxs(_Fragment, {
|
|
101
|
+
children: [/* @__PURE__ */ _jsx(Popover, {
|
|
102
|
+
offset: 8,
|
|
103
|
+
focusOnMount: false,
|
|
104
|
+
placement: "top-start",
|
|
105
|
+
className: "components-autocomplete__popover",
|
|
106
|
+
anchor: popoverAnchor,
|
|
107
|
+
ref: popoverRefs,
|
|
108
|
+
children: /* @__PURE__ */ _jsx(ListBox, {
|
|
119
109
|
items,
|
|
120
110
|
onSelect,
|
|
121
111
|
selectedIndex,
|
|
122
112
|
instanceId,
|
|
123
113
|
listBoxId,
|
|
124
|
-
className
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
114
|
+
className
|
|
115
|
+
})
|
|
116
|
+
}), contentRef.current && needsA11yCompat && createPortal(/* @__PURE__ */ _jsx(ListBox, {
|
|
117
|
+
items,
|
|
118
|
+
onSelect,
|
|
119
|
+
selectedIndex,
|
|
120
|
+
instanceId,
|
|
121
|
+
listBoxId,
|
|
122
|
+
className,
|
|
123
|
+
Component: VisuallyHidden
|
|
124
|
+
}), contentRef.current.ownerDocument.body)]
|
|
125
|
+
});
|
|
130
126
|
}
|
|
131
127
|
function useOnClickOutside(ref, handler) {
|
|
132
128
|
useEffect(() => {
|
|
@@ -145,6 +141,6 @@ function useOnClickOutside(ref, handler) {
|
|
|
145
141
|
}, [handler, ref]);
|
|
146
142
|
}
|
|
147
143
|
export {
|
|
148
|
-
|
|
144
|
+
AutocompleterUI
|
|
149
145
|
};
|
|
150
146
|
//# sourceMappingURL=autocompleter-ui.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/autocomplete/autocompleter-ui.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\nimport { createPortal } from 'react-dom';\n\n/**\n * WordPress dependencies\n */\nimport { useLayoutEffect, useRef, useEffect, useState } from '@wordpress/element';\nimport { useAnchor } from '@wordpress/rich-text';\nimport { useDebounce, useMergeRefs, useRefEffect } from '@wordpress/compose';\nimport { speak } from '@wordpress/a11y';\nimport { __, _n, sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport getDefaultUseItems from './get-default-use-items';\nimport Button from '../button';\nimport Popover from '../popover';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from \"react/jsx-runtime\";\nfunction ListBox({\n items,\n onSelect,\n selectedIndex,\n instanceId,\n listBoxId,\n className,\n Component = 'div'\n}) {\n return /*#__PURE__*/_jsx(Component, {\n id: listBoxId,\n role: \"listbox\",\n className: \"components-autocomplete__results\",\n children: items.map((option, index) => /*#__PURE__*/_jsx(Button, {\n id: `components-autocomplete-item-${instanceId}-${option.key}`,\n role: \"option\",\n __next40pxDefaultSize: true,\n \"aria-selected\": index === selectedIndex,\n accessibleWhenDisabled: true,\n disabled: option.isDisabled,\n className: clsx('components-autocomplete__result', className, {\n // Unused, for backwards compatibility.\n 'is-selected': index === selectedIndex\n }),\n variant: index === selectedIndex ? 'primary' : undefined,\n onClick: () => onSelect(option),\n children: option.label\n }, option.key))\n });\n}\nexport function
|
|
5
|
-
"mappings": ";AAGA,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAK7B,SAAS,iBAAiB,QAAQ,WAAW,gBAAgB;AAC7D,SAAS,iBAAiB;AAC1B,SAAS,aAAa,cAAc,oBAAoB;AACxD,SAAS,aAAa;AACtB,SAAS,IAAI,IAAI,eAAe;AAKhC,OAAO,wBAAwB;AAC/B,OAAO,YAAY;AACnB,OAAO,aAAa;AACpB,SAAS,sBAAsB;AAC/B,SAAS,OAAO,MAAM,YAAY,WAAW,QAAQ,aAAa;AAClE,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAAG;AACD,SAAoB,qBAAK,WAAW;AAAA,IAClC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,UAAU,MAAM,IAAI,CAAC,QAAQ,UAAuB,qBAAK,QAAQ;AAAA,MAC/D,IAAI,gCAAgC,UAAU,IAAI,OAAO,GAAG;AAAA,MAC5D,MAAM;AAAA,MACN,uBAAuB;AAAA,MACvB,iBAAiB,UAAU;AAAA,MAC3B,wBAAwB;AAAA,MACxB,UAAU,OAAO;AAAA,MACjB,WAAW,KAAK,mCAAmC,WAAW;AAAA;AAAA,QAE5D,eAAe,UAAU;AAAA,MAC3B,CAAC;AAAA,MACD,SAAS,UAAU,gBAAgB,YAAY;AAAA,MAC/C,SAAS,MAAM,SAAS,MAAM;AAAA,MAC9B,UAAU,OAAO;AAAA,IACnB,GAAG,OAAO,GAAG,CAAC;AAAA,EAChB,CAAC;AACH;AACO,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\nimport { createPortal } from 'react-dom';\n\n/**\n * WordPress dependencies\n */\nimport { useLayoutEffect, useRef, useEffect, useState } from '@wordpress/element';\nimport { useAnchor } from '@wordpress/rich-text';\nimport { useDebounce, useMergeRefs, useRefEffect } from '@wordpress/compose';\nimport { speak } from '@wordpress/a11y';\nimport { __, _n, sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport getDefaultUseItems from './get-default-use-items';\nimport Button from '../button';\nimport Popover from '../popover';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from \"react/jsx-runtime\";\nfunction ListBox({\n items,\n onSelect,\n selectedIndex,\n instanceId,\n listBoxId,\n className,\n Component = 'div'\n}) {\n return /*#__PURE__*/_jsx(Component, {\n id: listBoxId,\n role: \"listbox\",\n className: \"components-autocomplete__results\",\n children: items.map((option, index) => /*#__PURE__*/_jsx(Button, {\n id: `components-autocomplete-item-${instanceId}-${option.key}`,\n role: \"option\",\n __next40pxDefaultSize: true,\n \"aria-selected\": index === selectedIndex,\n accessibleWhenDisabled: true,\n disabled: option.isDisabled,\n className: clsx('components-autocomplete__result', className, {\n // Unused, for backwards compatibility.\n 'is-selected': index === selectedIndex\n }),\n variant: index === selectedIndex ? 'primary' : undefined,\n onClick: () => onSelect(option),\n children: option.label\n }, option.key))\n });\n}\nexport function AutocompleterUI({\n autocompleter,\n filterValue,\n instanceId,\n listBoxId,\n className,\n selectedIndex,\n onChangeOptions,\n onSelect,\n reset,\n contentRef\n}) {\n // The useItems hook is derived from the autocompleter prop. This is safe\n // because the parent renders this component with key={autocompleter.name},\n // ensuring a fresh mount (and stable hook identity) when the completer changes.\n const useItems = autocompleter.useItems ?? getDefaultUseItems(autocompleter);\n // eslint-disable-next-line react-compiler/react-compiler\n const [items] = useItems(filterValue);\n const popoverAnchor = useAnchor({\n editableContentElement: contentRef.current\n });\n const [needsA11yCompat, setNeedsA11yCompat] = useState(false);\n const popoverRef = useRef(null);\n const popoverRefs = useMergeRefs([popoverRef, useRefEffect(node => {\n if (!contentRef.current) {\n return;\n }\n\n // If the popover is rendered in a different document than\n // the content, we need to duplicate the options list in the\n // content document so that it's available to the screen\n // readers, which check the DOM ID based aria-* attributes.\n setNeedsA11yCompat(node.ownerDocument !== contentRef.current.ownerDocument);\n }, [contentRef])]);\n useOnClickOutside(popoverRef, reset);\n const debouncedSpeak = useDebounce(speak, 500);\n function announce(options) {\n if (!debouncedSpeak) {\n return;\n }\n if (!!options.length) {\n if (filterValue) {\n debouncedSpeak(sprintf(/* translators: %d: number of results. */\n _n('%d result found, use up and down arrow keys to navigate.', '%d results found, use up and down arrow keys to navigate.', options.length), options.length), 'assertive');\n } else {\n debouncedSpeak(sprintf(/* translators: %d: number of results. */\n _n('Initial %d result loaded. Type to filter all available results. Use up and down arrow keys to navigate.', 'Initial %d results loaded. Type to filter all available results. Use up and down arrow keys to navigate.', options.length), options.length), 'assertive');\n }\n } else {\n debouncedSpeak(__('No results.'), 'assertive');\n }\n }\n useLayoutEffect(() => {\n onChangeOptions(items);\n announce(items);\n // We want to avoid introducing unexpected side effects.\n // See https://github.com/WordPress/gutenberg/pull/41820\n }, [items]);\n if (items.length === 0) {\n return null;\n }\n return /*#__PURE__*/_jsxs(_Fragment, {\n children: [/*#__PURE__*/_jsx(Popover, {\n offset: 8,\n focusOnMount: false,\n placement: \"top-start\",\n className: \"components-autocomplete__popover\",\n anchor: popoverAnchor,\n ref: popoverRefs,\n children: /*#__PURE__*/_jsx(ListBox, {\n items: items,\n onSelect: onSelect,\n selectedIndex: selectedIndex,\n instanceId: instanceId,\n listBoxId: listBoxId,\n className: className\n })\n }), contentRef.current && needsA11yCompat && createPortal(/*#__PURE__*/_jsx(ListBox, {\n items: items,\n onSelect: onSelect,\n selectedIndex: selectedIndex,\n instanceId: instanceId,\n listBoxId: listBoxId,\n className: className,\n Component: VisuallyHidden\n }), contentRef.current.ownerDocument.body)]\n });\n}\nfunction useOnClickOutside(ref, handler) {\n useEffect(() => {\n const listener = event => {\n // Do nothing if clicking ref's element or descendent elements, or if the ref is not referencing an element\n if (!ref.current || ref.current.contains(event.target)) {\n return;\n }\n handler(event);\n };\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [handler, ref]);\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// packages/components/src/autocomplete/get-autocomplete-match.ts
|
|
2
|
+
import removeAccents from "remove-accents";
|
|
3
|
+
function getAutocompleteMatch(textContent, completers, filteredOptionsLength, isBackspacing, getTextAfterSelection) {
|
|
4
|
+
if (!textContent) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
let completer = null;
|
|
8
|
+
let triggerIndex = -1;
|
|
9
|
+
let matchedEndIndex = -1;
|
|
10
|
+
let matchedPrefixLength = 0;
|
|
11
|
+
for (const currentCompleter of completers) {
|
|
12
|
+
const currentIndex = textContent.lastIndexOf(currentCompleter.triggerPrefix);
|
|
13
|
+
if (currentIndex < 0) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const currentEndIndex = currentIndex + currentCompleter.triggerPrefix.length;
|
|
17
|
+
if (currentEndIndex > matchedEndIndex || currentEndIndex === matchedEndIndex && currentCompleter.triggerPrefix.length > matchedPrefixLength) {
|
|
18
|
+
completer = currentCompleter;
|
|
19
|
+
triggerIndex = currentIndex;
|
|
20
|
+
matchedEndIndex = currentEndIndex;
|
|
21
|
+
matchedPrefixLength = currentCompleter.triggerPrefix.length;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!completer) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const {
|
|
28
|
+
allowContext,
|
|
29
|
+
triggerPrefix
|
|
30
|
+
} = completer;
|
|
31
|
+
const textWithoutTrigger = textContent.slice(triggerIndex + triggerPrefix.length);
|
|
32
|
+
if (textWithoutTrigger.length > 50) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const mismatch = filteredOptionsLength === 0;
|
|
36
|
+
const wordsFromTrigger = textWithoutTrigger.split(/\s/);
|
|
37
|
+
const hasOneTriggerWord = wordsFromTrigger.length === 1;
|
|
38
|
+
const matchingWhileBackspacing = isBackspacing && wordsFromTrigger.length <= 3;
|
|
39
|
+
if (mismatch && !(matchingWhileBackspacing || hasOneTriggerWord)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
if (allowContext && !allowContext(textContent.slice(0, triggerIndex), getTextAfterSelection())) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (/^\s/.test(textWithoutTrigger) || /\s\s+$/.test(textWithoutTrigger)) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
completer,
|
|
50
|
+
filterValue: removeAccents(textWithoutTrigger)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
getAutocompleteMatch
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=get-autocomplete-match.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/autocomplete/get-autocomplete-match.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport removeAccents from 'remove-accents';\n\n/**\n * Internal dependencies\n */\n\nexport function getAutocompleteMatch(textContent, completers, filteredOptionsLength, isBackspacing, getTextAfterSelection) {\n if (!textContent) {\n return null;\n }\n\n // Find the completer whose trigger prefix ends closest to the cursor\n // (rightmost end position). Comparing end positions instead of start\n // positions correctly resolves overlapping prefixes like \"@\" and \"@@\".\n let completer = null;\n let triggerIndex = -1;\n let matchedEndIndex = -1;\n let matchedPrefixLength = 0;\n for (const currentCompleter of completers) {\n const currentIndex = textContent.lastIndexOf(currentCompleter.triggerPrefix);\n if (currentIndex < 0) {\n continue;\n }\n const currentEndIndex = currentIndex + currentCompleter.triggerPrefix.length;\n if (currentEndIndex > matchedEndIndex || currentEndIndex === matchedEndIndex && currentCompleter.triggerPrefix.length > matchedPrefixLength) {\n completer = currentCompleter;\n triggerIndex = currentIndex;\n matchedEndIndex = currentEndIndex;\n matchedPrefixLength = currentCompleter.triggerPrefix.length;\n }\n }\n if (!completer) {\n return null;\n }\n const {\n allowContext,\n triggerPrefix\n } = completer;\n const textWithoutTrigger = textContent.slice(triggerIndex + triggerPrefix.length);\n\n // Prevent matching with an extremely long string, which causes\n // the editor to slow-down significantly. This could happen, for\n // example, if `matchingWhileBackspacing` is true and one of the\n // \"words\" ends up being too long. Returning null here intentionally\n // resets the autocompleter state in the caller.\n if (textWithoutTrigger.length > 50) {\n return null;\n }\n const mismatch = filteredOptionsLength === 0;\n const wordsFromTrigger = textWithoutTrigger.split(/\\s/);\n\n // Allow matching when typing a trigger + the match string or when\n // clicking in an existing trigger word on the page.\n // E.g. \"Some text @a\" \u2014 \"@a\" is detected as a trigger word.\n const hasOneTriggerWord = wordsFromTrigger.length === 1;\n\n // Allow matching when backspacing near a trigger word (up to 3\n // words from the trigger character). This lets us recover from a\n // mismatch when backspacing while still imposing sane limits.\n // E.g. \"Some text @marcelo sekkkk\" \u2014 backspacing \"kkkk\" re-shows\n // the popup once the text matches again.\n const matchingWhileBackspacing = isBackspacing && wordsFromTrigger.length <= 3;\n if (mismatch && !(matchingWhileBackspacing || hasOneTriggerWord)) {\n return null;\n }\n if (allowContext && !allowContext(textContent.slice(0, triggerIndex), getTextAfterSelection())) {\n return null;\n }\n if (/^\\s/.test(textWithoutTrigger) || /\\s\\s+$/.test(textWithoutTrigger)) {\n return null;\n }\n return {\n completer,\n filterValue: removeAccents(textWithoutTrigger)\n };\n}"],
|
|
5
|
+
"mappings": ";AAGA,OAAO,mBAAmB;AAMnB,SAAS,qBAAqB,aAAa,YAAY,uBAAuB,eAAe,uBAAuB;AACzH,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAKA,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,kBAAkB;AACtB,MAAI,sBAAsB;AAC1B,aAAW,oBAAoB,YAAY;AACzC,UAAM,eAAe,YAAY,YAAY,iBAAiB,aAAa;AAC3E,QAAI,eAAe,GAAG;AACpB;AAAA,IACF;AACA,UAAM,kBAAkB,eAAe,iBAAiB,cAAc;AACtE,QAAI,kBAAkB,mBAAmB,oBAAoB,mBAAmB,iBAAiB,cAAc,SAAS,qBAAqB;AAC3I,kBAAY;AACZ,qBAAe;AACf,wBAAkB;AAClB,4BAAsB,iBAAiB,cAAc;AAAA,IACvD;AAAA,EACF;AACA,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AACA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,qBAAqB,YAAY,MAAM,eAAe,cAAc,MAAM;AAOhF,MAAI,mBAAmB,SAAS,IAAI;AAClC,WAAO;AAAA,EACT;AACA,QAAM,WAAW,0BAA0B;AAC3C,QAAM,mBAAmB,mBAAmB,MAAM,IAAI;AAKtD,QAAM,oBAAoB,iBAAiB,WAAW;AAOtD,QAAM,2BAA2B,iBAAiB,iBAAiB,UAAU;AAC7E,MAAI,YAAY,EAAE,4BAA4B,oBAAoB;AAChE,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,CAAC,aAAa,YAAY,MAAM,GAAG,YAAY,GAAG,sBAAsB,CAAC,GAAG;AAC9F,WAAO;AAAA,EACT;AACA,MAAI,MAAM,KAAK,kBAAkB,KAAK,SAAS,KAAK,kBAAkB,GAAG;AACvE,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA,aAAa,cAAc,kBAAkB;AAAA,EAC/C;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,17 +1,54 @@
|
|
|
1
1
|
// packages/components/src/autocomplete/index.tsx
|
|
2
|
-
import
|
|
3
|
-
import { renderToString, useEffect, useState, useRef, useMemo } from "@wordpress/element";
|
|
2
|
+
import { renderToString, useEffect, useMemo, useReducer, useRef } from "@wordpress/element";
|
|
4
3
|
import { useInstanceId, useMergeRefs, useRefEffect } from "@wordpress/compose";
|
|
5
4
|
import { create, slice, insert, isCollapsed, getTextContent } from "@wordpress/rich-text";
|
|
6
5
|
import { speak } from "@wordpress/a11y";
|
|
7
6
|
import { isAppleOS } from "@wordpress/keycodes";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
7
|
+
import { AutocompleterUI } from "./autocompleter-ui.mjs";
|
|
8
|
+
import { getAutocompleteMatch } from "./get-autocomplete-match.mjs";
|
|
10
9
|
import { withIgnoreIMEEvents } from "../utils/with-ignore-ime-events.mjs";
|
|
11
10
|
import getNodeText from "../utils/get-node-text.mjs";
|
|
12
11
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
12
|
var EMPTY_FILTERED_OPTIONS = [];
|
|
14
13
|
var AUTOCOMPLETE_HOOK_REFERENCE = {};
|
|
14
|
+
function getCompletionObject(completion) {
|
|
15
|
+
if (completion !== null && typeof completion === "object" && "action" in completion && completion.action !== void 0 && "value" in completion && completion.value !== void 0) {
|
|
16
|
+
return completion;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
action: "insert-at-caret",
|
|
20
|
+
value: completion
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
var initialState = {
|
|
24
|
+
selectedIndex: 0,
|
|
25
|
+
filteredOptions: EMPTY_FILTERED_OPTIONS,
|
|
26
|
+
filterValue: "",
|
|
27
|
+
autocompleter: null
|
|
28
|
+
};
|
|
29
|
+
function autocompleteReducer(state, action) {
|
|
30
|
+
switch (action.type) {
|
|
31
|
+
case "RESET":
|
|
32
|
+
return initialState;
|
|
33
|
+
case "SELECT":
|
|
34
|
+
return {
|
|
35
|
+
...state,
|
|
36
|
+
selectedIndex: action.index
|
|
37
|
+
};
|
|
38
|
+
case "OPTIONS":
|
|
39
|
+
return {
|
|
40
|
+
...state,
|
|
41
|
+
filteredOptions: action.options,
|
|
42
|
+
selectedIndex: action.options.length === state.filteredOptions.length ? state.selectedIndex : 0
|
|
43
|
+
};
|
|
44
|
+
case "MATCH":
|
|
45
|
+
return {
|
|
46
|
+
...state,
|
|
47
|
+
autocompleter: action.completer,
|
|
48
|
+
filterValue: action.query
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
15
52
|
function useAutocomplete({
|
|
16
53
|
record,
|
|
17
54
|
onChange,
|
|
@@ -20,11 +57,13 @@ function useAutocomplete({
|
|
|
20
57
|
contentRef
|
|
21
58
|
}) {
|
|
22
59
|
const instanceId = useInstanceId(AUTOCOMPLETE_HOOK_REFERENCE);
|
|
23
|
-
const [
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
60
|
+
const [state, dispatch] = useReducer(autocompleteReducer, initialState);
|
|
61
|
+
const {
|
|
62
|
+
selectedIndex,
|
|
63
|
+
filteredOptions,
|
|
64
|
+
filterValue,
|
|
65
|
+
autocompleter
|
|
66
|
+
} = state;
|
|
28
67
|
const backspacingRef = useRef(false);
|
|
29
68
|
function insertCompletion(replacement) {
|
|
30
69
|
if (autocompleter === null) {
|
|
@@ -45,14 +84,7 @@ function useAutocomplete({
|
|
|
45
84
|
return;
|
|
46
85
|
}
|
|
47
86
|
if (getOptionCompletion) {
|
|
48
|
-
const
|
|
49
|
-
const isCompletionObject = (obj) => {
|
|
50
|
-
return obj !== null && typeof obj === "object" && "action" in obj && obj.action !== void 0 && "value" in obj && obj.value !== void 0;
|
|
51
|
-
};
|
|
52
|
-
const completionObject = isCompletionObject(completion) ? completion : {
|
|
53
|
-
action: "insert-at-caret",
|
|
54
|
-
value: completion
|
|
55
|
-
};
|
|
87
|
+
const completionObject = getCompletionObject(getOptionCompletion(option.value, filterValue));
|
|
56
88
|
if ("replace" === completionObject.action) {
|
|
57
89
|
onReplace([completionObject.value]);
|
|
58
90
|
return;
|
|
@@ -60,19 +92,16 @@ function useAutocomplete({
|
|
|
60
92
|
insertCompletion(completionObject.value);
|
|
61
93
|
}
|
|
62
94
|
}
|
|
63
|
-
|
|
95
|
+
dispatch({
|
|
96
|
+
type: "RESET"
|
|
97
|
+
});
|
|
64
98
|
contentRef.current?.focus();
|
|
65
99
|
}
|
|
66
|
-
function reset() {
|
|
67
|
-
setSelectedIndex(0);
|
|
68
|
-
setFilteredOptions(EMPTY_FILTERED_OPTIONS);
|
|
69
|
-
setFilterValue("");
|
|
70
|
-
setAutocompleter(null);
|
|
71
|
-
setAutocompleterUI(null);
|
|
72
|
-
}
|
|
73
100
|
function onChangeOptions(options) {
|
|
74
|
-
|
|
75
|
-
|
|
101
|
+
dispatch({
|
|
102
|
+
type: "OPTIONS",
|
|
103
|
+
options
|
|
104
|
+
});
|
|
76
105
|
}
|
|
77
106
|
function handleKeyDown(event) {
|
|
78
107
|
backspacingRef.current = event.key === "Backspace";
|
|
@@ -86,25 +115,23 @@ function useAutocomplete({
|
|
|
86
115
|
return;
|
|
87
116
|
}
|
|
88
117
|
switch (event.key) {
|
|
89
|
-
case "ArrowUp":
|
|
90
|
-
const newIndex = (selectedIndex === 0 ? filteredOptions.length : selectedIndex) - 1;
|
|
91
|
-
setSelectedIndex(newIndex);
|
|
92
|
-
if (isAppleOS()) {
|
|
93
|
-
speak(getNodeText(filteredOptions[newIndex].label), "assertive");
|
|
94
|
-
}
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
118
|
+
case "ArrowUp":
|
|
97
119
|
case "ArrowDown": {
|
|
98
|
-
const
|
|
99
|
-
|
|
120
|
+
const offset = event.key === "ArrowUp" ? -1 : 1;
|
|
121
|
+
const newIndex = (selectedIndex + offset + filteredOptions.length) % filteredOptions.length;
|
|
122
|
+
dispatch({
|
|
123
|
+
type: "SELECT",
|
|
124
|
+
index: newIndex
|
|
125
|
+
});
|
|
100
126
|
if (isAppleOS()) {
|
|
101
127
|
speak(getNodeText(filteredOptions[newIndex].label), "assertive");
|
|
102
128
|
}
|
|
103
129
|
break;
|
|
104
130
|
}
|
|
105
131
|
case "Escape":
|
|
106
|
-
|
|
107
|
-
|
|
132
|
+
dispatch({
|
|
133
|
+
type: "RESET"
|
|
134
|
+
});
|
|
108
135
|
event.preventDefault();
|
|
109
136
|
break;
|
|
110
137
|
case "Enter":
|
|
@@ -112,7 +139,9 @@ function useAutocomplete({
|
|
|
112
139
|
break;
|
|
113
140
|
case "ArrowLeft":
|
|
114
141
|
case "ArrowRight":
|
|
115
|
-
|
|
142
|
+
dispatch({
|
|
143
|
+
type: "RESET"
|
|
144
|
+
});
|
|
116
145
|
return;
|
|
117
146
|
default:
|
|
118
147
|
return;
|
|
@@ -126,69 +155,27 @@ function useAutocomplete({
|
|
|
126
155
|
return "";
|
|
127
156
|
}, [record]);
|
|
128
157
|
useEffect(() => {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
reset();
|
|
132
|
-
}
|
|
133
|
-
return;
|
|
158
|
+
function getTextAfterSelection() {
|
|
159
|
+
return textContent ? getTextContent(slice(record, void 0, getTextContent(record).length)) : "";
|
|
134
160
|
}
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
const lastTriggerIndex = lastTrigger !== null ? textContent.lastIndexOf(lastTrigger.triggerPrefix) : -1;
|
|
138
|
-
return triggerIndex2 > lastTriggerIndex ? currentCompleter : lastTrigger;
|
|
139
|
-
}, null);
|
|
140
|
-
if (!completer) {
|
|
161
|
+
const match = getAutocompleteMatch(textContent, completers, filteredOptions.length, backspacingRef.current, getTextAfterSelection);
|
|
162
|
+
if (!match) {
|
|
141
163
|
if (autocompleter) {
|
|
142
|
-
|
|
164
|
+
dispatch({
|
|
165
|
+
type: "RESET"
|
|
166
|
+
});
|
|
143
167
|
}
|
|
144
168
|
return;
|
|
145
169
|
}
|
|
146
170
|
const {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
} =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
const mismatch = filteredOptions.length === 0;
|
|
157
|
-
const wordsFromTrigger = textWithoutTrigger.split(/\s/);
|
|
158
|
-
const hasOneTriggerWord = wordsFromTrigger.length === 1;
|
|
159
|
-
const matchingWhileBackspacing = backspacingRef.current && wordsFromTrigger.length <= 3;
|
|
160
|
-
if (mismatch && !(matchingWhileBackspacing || hasOneTriggerWord)) {
|
|
161
|
-
if (autocompleter) {
|
|
162
|
-
reset();
|
|
163
|
-
}
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
const textAfterSelection = getTextContent(slice(record, void 0, getTextContent(record).length));
|
|
167
|
-
if (allowContext && !allowContext(textContent.slice(0, triggerIndex), textAfterSelection)) {
|
|
168
|
-
if (autocompleter) {
|
|
169
|
-
reset();
|
|
170
|
-
}
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (/^\s/.test(textWithoutTrigger) || /\s\s+$/.test(textWithoutTrigger)) {
|
|
174
|
-
if (autocompleter) {
|
|
175
|
-
reset();
|
|
176
|
-
}
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
if (!/[\u0000-\uFFFF]*$/.test(textWithoutTrigger)) {
|
|
180
|
-
if (autocompleter) {
|
|
181
|
-
reset();
|
|
182
|
-
}
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const safeTrigger = escapeRegExp(completer.triggerPrefix);
|
|
186
|
-
const text = removeAccents(textContent);
|
|
187
|
-
const match = text.slice(text.lastIndexOf(completer.triggerPrefix)).match(new RegExp(`${safeTrigger}([\0-\uFFFF]*)$`));
|
|
188
|
-
const query = match && match[1];
|
|
189
|
-
setAutocompleter(completer);
|
|
190
|
-
setAutocompleterUI(() => completer !== autocompleter ? getAutoCompleterUI(completer) : AutocompleterUI);
|
|
191
|
-
setFilterValue(query === null ? "" : query);
|
|
171
|
+
completer,
|
|
172
|
+
filterValue: query
|
|
173
|
+
} = match;
|
|
174
|
+
dispatch({
|
|
175
|
+
type: "MATCH",
|
|
176
|
+
completer,
|
|
177
|
+
query
|
|
178
|
+
});
|
|
192
179
|
}, [textContent]);
|
|
193
180
|
const {
|
|
194
181
|
key: selectedKey = ""
|
|
@@ -200,12 +187,13 @@ function useAutocomplete({
|
|
|
200
187
|
const listBoxId = isExpanded ? `components-autocomplete-listbox-${instanceId}` : void 0;
|
|
201
188
|
const activeId = isExpanded ? `components-autocomplete-item-${instanceId}-${selectedKey}` : null;
|
|
202
189
|
const hasSelection = record.start !== void 0;
|
|
203
|
-
const showPopover = !!textContent && hasSelection && !!
|
|
190
|
+
const showPopover = !!textContent && hasSelection && !!autocompleter;
|
|
204
191
|
return {
|
|
205
192
|
listBoxId,
|
|
206
193
|
activeId,
|
|
207
194
|
onKeyDown: withIgnoreIMEEvents(handleKeyDown),
|
|
208
195
|
popover: showPopover && /* @__PURE__ */ _jsx(AutocompleterUI, {
|
|
196
|
+
autocompleter,
|
|
209
197
|
className,
|
|
210
198
|
filterValue,
|
|
211
199
|
instanceId,
|
|
@@ -213,19 +201,26 @@ function useAutocomplete({
|
|
|
213
201
|
selectedIndex,
|
|
214
202
|
onChangeOptions,
|
|
215
203
|
onSelect: select,
|
|
216
|
-
value: record,
|
|
217
204
|
contentRef,
|
|
218
|
-
reset
|
|
219
|
-
|
|
205
|
+
reset: () => dispatch({
|
|
206
|
+
type: "RESET"
|
|
207
|
+
})
|
|
208
|
+
}, autocompleter.name + autocompleter.triggerPrefix)
|
|
220
209
|
};
|
|
221
210
|
}
|
|
211
|
+
function recordValuesMatch(a, b) {
|
|
212
|
+
return a.text === b.text && a.start === b.start && a.end === b.end;
|
|
213
|
+
}
|
|
222
214
|
function useLastDifferentValue(value) {
|
|
223
|
-
const history = useRef(
|
|
224
|
-
history.current.
|
|
225
|
-
if (
|
|
226
|
-
history.current.
|
|
215
|
+
const history = useRef([]);
|
|
216
|
+
const lastEntry = history.current[history.current.length - 1];
|
|
217
|
+
if (!lastEntry || !recordValuesMatch(value, lastEntry)) {
|
|
218
|
+
history.current.push(value);
|
|
219
|
+
}
|
|
220
|
+
if (history.current.length > 2) {
|
|
221
|
+
history.current.shift();
|
|
227
222
|
}
|
|
228
|
-
return
|
|
223
|
+
return history.current[0];
|
|
229
224
|
}
|
|
230
225
|
function useAutocompleteProps(options) {
|
|
231
226
|
const ref = useRef(null);
|
|
@@ -283,6 +278,7 @@ function Autocomplete({
|
|
|
283
278
|
export {
|
|
284
279
|
Autocomplete as default,
|
|
285
280
|
useAutocomplete,
|
|
286
|
-
useAutocompleteProps
|
|
281
|
+
useAutocompleteProps,
|
|
282
|
+
useLastDifferentValue
|
|
287
283
|
};
|
|
288
284
|
//# sourceMappingURL=index.mjs.map
|