ropav 0.1.5 → 0.1.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/README.md +10 -0
- package/dist/accordion.css +17 -17
- package/dist/accordion.js +125 -154
- package/dist/alert.css +18 -18
- package/dist/alert.js +20 -20
- package/dist/aria.js +14 -0
- package/dist/aspect-ratio.js +1 -1
- package/dist/attributes.js +9 -0
- package/dist/attributes2.js +29 -0
- package/dist/avatar.css +19 -19
- package/dist/avatar.js +10 -18
- package/dist/badge.css +16 -16
- package/dist/badge.js +6 -6
- package/dist/base.css +18 -13
- package/dist/button-group.js +1 -1
- package/dist/button-link.js +13 -14
- package/dist/button.css +32 -27
- package/dist/button.js +13 -14
- package/dist/{useButtonColor.js → button.scss_vue_type_style_index_0_src_true_lang.js} +3 -2
- package/dist/card.js +1 -1
- package/dist/checkbox.css +32 -32
- package/dist/checkbox.js +23 -29
- package/dist/collapse.css +6 -6
- package/dist/collapse.js +8 -7
- package/dist/collectionNavigation.js +2 -99
- package/dist/color-input.css +19 -19
- package/dist/color-input.js +15 -14
- package/dist/color-picker.css +40 -40
- package/dist/color-picker.js +222 -202
- package/dist/color-picker2.js +1 -9
- package/dist/color-swatch.css +4 -4
- package/dist/color-swatch.js +7 -9
- package/dist/color.js +5 -10
- package/dist/componentColors.js +165 -84
- package/dist/componentRef.js +26 -0
- package/dist/components/accordion/accordionContext.d.ts +3 -0
- package/dist/components/accordion/accordionModel.d.ts +14 -0
- package/dist/components/accordion/index.d.ts +2 -1
- package/dist/components/accordion/index.js +1 -1
- package/dist/components/accordion/types.d.ts +1 -2
- package/dist/components/accordion/useAccordion.d.ts +2 -2
- package/dist/components/accordion/useAccordionItem.d.ts +2 -0
- package/dist/components/checkbox/useCheckbox.d.ts +2 -3
- package/dist/components/color-input/color-input.d.ts +2 -2
- package/dist/components/color-input/useColorInput.d.ts +1 -1
- package/dist/components/color-picker/index.js +2 -2
- package/dist/components/color-picker/types.d.ts +2 -2
- package/dist/components/color-picker/useColorPickerSaturation.d.ts +22 -0
- package/dist/components/color-picker/useColorPickerSlider.d.ts +20 -0
- package/dist/components/color-picker/useColorPickerValue.d.ts +1 -1
- package/dist/components/dialog/{dialog-core.d.ts → dialogContext.d.ts} +2 -6
- package/dist/components/dialog/useDialogContentInteractions.d.ts +18 -0
- package/dist/components/dialog/useDialogRootState.d.ts +19 -0
- package/dist/components/dropdown-menu/dropdown-menu-content.d.ts +2 -2
- package/dist/components/dropdown-menu/dropdown-menu-item-row.d.ts +1 -1
- package/dist/components/dropdown-menu/dropdown-menu-items.d.ts +1 -1
- package/dist/components/dropdown-menu/dropdown-menu-model.d.ts +8 -0
- package/dist/components/dropdown-menu/dropdown-menu-root.d.ts +2 -2
- package/dist/components/dropdown-menu/dropdown-menu-sub-content.d.ts +2 -2
- package/dist/components/dropdown-menu/dropdown-menu-sub-trigger.d.ts +1 -1
- package/dist/components/dropdown-menu/dropdown-menu-sub.d.ts +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +3 -3
- package/dist/components/dropdown-menu/{dropdown-menu-primitive-core.d.ts → dropdownMenuContext.d.ts} +17 -19
- package/dist/components/dropdown-menu/dropdownMenuDataModel.d.ts +20 -0
- package/dist/components/dropdown-menu/dropdownMenuInteraction.d.ts +3 -0
- package/dist/components/dropdown-menu/dropdownMenuInteractionNavigation.d.ts +24 -0
- package/dist/components/dropdown-menu/dropdownMenuInteractionRegistry.d.ts +42 -0
- package/dist/components/dropdown-menu/dropdownMenuInteractionTypes.d.ts +85 -0
- package/dist/components/dropdown-menu/useDropdownMenu.d.ts +11 -11
- package/dist/components/dropdown-menu/useDropdownMenuContextTrigger.d.ts +9 -0
- package/dist/components/dropdown-menu/useDropdownMenuDataController.d.ts +34 -0
- package/dist/components/dropdown-menu/useDropdownMenuDataRegistration.d.ts +22 -0
- package/dist/components/dropdown-menu/useDropdownMenuHoverIntent.d.ts +6 -5
- package/dist/components/dropdown-menu/useDropdownMenuInteractionDismissal.d.ts +17 -0
- package/dist/components/dropdown-menu/useDropdownMenuInteractionKeyboard.d.ts +19 -0
- package/dist/components/dropdown-menu/useDropdownMenuPortalPosition.d.ts +0 -1
- package/dist/components/dropdown-menu/useDropdownMenuPresentation.d.ts +29 -0
- package/dist/components/dropdown-menu/useDropdownMenuPrimitiveContent.d.ts +2 -2
- package/dist/components/dropdown-menu/useDropdownMenuRenderItems.d.ts +1 -1
- package/dist/components/dropdown-menu/useDropdownMenuTargetBindings.d.ts +19 -0
- package/dist/components/floating/hoverDisclosureInteractionModel.d.ts +42 -0
- package/dist/components/floating/index.js +1 -1
- package/dist/components/floating/useFloatingPosition.d.ts +0 -1
- package/dist/components/floating/useHoverDisclosureInteractions.d.ts +32 -0
- package/dist/components/floating/useHoverDisclosureOpenState.d.ts +25 -0
- package/dist/components/floating/useHoverDisclosureTargetBinding.d.ts +27 -0
- package/dist/components/input/useInput.d.ts +1 -1
- package/dist/components/number-input/numberInputModel.d.ts +15 -0
- package/dist/components/number-input/useNumberInput.d.ts +4 -18
- package/dist/components/pagination/index.d.ts +1 -1
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/pagination/paginationModel.d.ts +4 -0
- package/dist/components/pagination/types.d.ts +15 -0
- package/dist/components/pagination/usePagination.d.ts +3 -19
- package/dist/components/popover/usePopoverBindings.d.ts +16 -0
- package/dist/components/progress/progressModel.d.ts +8 -0
- package/dist/components/progress/useProgress.d.ts +1 -7
- package/dist/components/radio/useRadio.d.ts +3 -4
- package/dist/components/scroll-area/scroll-area.d.ts +1 -1
- package/dist/components/scroll-area/scrollAreaModel.d.ts +64 -0
- package/dist/components/scroll-area/types.d.ts +4 -0
- package/dist/components/scroll-area/useScrollArea.d.ts +70 -52
- package/dist/components/scroll-area/{useScrollAreaPresentation.d.ts → useScrollAreaAttributes.d.ts} +37 -14
- package/dist/components/scroll-area/useScrollAreaDerivedState.d.ts +8 -0
- package/dist/components/scroll-area/useScrollAreaMeasurement.d.ts +35 -0
- package/dist/components/scroll-area/useScrollAreaPointer.d.ts +10 -8
- package/dist/components/scroll-area/useScrollAreaVisibility.d.ts +15 -20
- package/dist/components/select/useSelect.d.ts +2 -1
- package/dist/components/select/useSelectNativeValue.d.ts +1 -7
- package/dist/components/slider/rangeSliderModel.d.ts +41 -0
- package/dist/components/slider/{sliderCore.d.ts → sliderModel.d.ts} +2 -2
- package/dist/components/slider/useRangeSlider.d.ts +9 -17
- package/dist/components/slider/useRangeSliderValueState.d.ts +40 -0
- package/dist/components/slider/useSlider.d.ts +8 -14
- package/dist/components/slider/useSliderPointerPreview.d.ts +22 -0
- package/dist/components/slider/useSliderTooltipState.d.ts +40 -0
- package/dist/components/slider/useSliderValueState.d.ts +33 -0
- package/dist/components/switch/useSwitch.d.ts +1 -1
- package/dist/components/teleport-provider/index.js +1 -1
- package/dist/components/teleport-provider/useTeleportTarget.d.ts +1 -2
- package/dist/components/textarea/useTextarea.d.ts +1 -1
- package/dist/components/toast/useToastLifecycle.d.ts +19 -0
- package/dist/components/tooltip/useTooltip.d.ts +1 -2
- package/dist/composables/index.d.ts +2 -0
- package/dist/composables/index.js +2 -0
- package/dist/composables/useControllableValue.d.ts +14 -0
- package/dist/css.js +12 -0
- package/dist/dialog.js +227 -216
- package/dist/dropdown-menu.js +1493 -1118
- package/dist/events.js +59 -0
- package/dist/field.css +8 -8
- package/dist/field.js +13 -25
- package/dist/floating.js +553 -312
- package/dist/floatingOffset.js +11 -0
- package/dist/focus-trap.js +7 -5
- package/dist/focusNavigation.js +37 -0
- package/dist/icon-button.css +12 -173
- package/dist/icon-button.js +8 -7
- package/dist/index.d.ts +5 -4
- package/dist/index.js +13 -11
- package/dist/input.css +24 -24
- package/dist/input.js +20 -32
- package/dist/interactive.js +18 -0
- package/dist/modal.js +11 -7
- package/dist/number-input.css +18 -18
- package/dist/number-input.js +15 -13
- package/dist/number.js +22 -0
- package/dist/overlay.js +3 -2
- package/dist/pagination.css +28 -28
- package/dist/pagination.js +67 -65
- package/dist/pointer.js +9 -0
- package/dist/popover.css +34 -34
- package/dist/popover.js +93 -91
- package/dist/progress.css +29 -21
- package/dist/progress.js +25 -21
- package/dist/query.js +40 -0
- package/dist/radio.css +18 -18
- package/dist/radio.js +31 -37
- package/dist/rafScheduler.js +34 -0
- package/dist/scroll-area.css +35 -26
- package/dist/scroll-area.js +553 -500
- package/dist/select.css +45 -45
- package/dist/select.js +70 -56
- package/dist/slider.css +191 -191
- package/dist/slider.js +695 -628
- package/dist/styles-api.d.ts +0 -1
- package/dist/styles-api.js +1 -4
- package/dist/switch.css +17 -17
- package/dist/switch.js +15 -16
- package/dist/tabs.css +46 -46
- package/dist/tabs.js +51 -68
- package/dist/text.js +17 -0
- package/dist/textarea.css +26 -26
- package/dist/textarea.js +22 -33
- package/dist/toast.css +26 -26
- package/dist/toast.js +157 -129
- package/dist/tooltip.css +12 -12
- package/dist/tooltip.js +46 -47
- package/dist/useCollapse.js +19 -17
- package/dist/useControlState.js +4 -7
- package/dist/useControllableValue.js +8 -2
- package/dist/useFloatingPosition.js +122 -1128
- package/dist/useFormControl.js +3 -2
- package/dist/useOverlayZIndex.js +2 -6
- package/dist/useRequiredInject.js +1 -1
- package/dist/useTeleportTarget.js +3 -14
- package/dist/useTypeahead.js +94 -0
- package/dist/utils/aria.d.ts +3 -0
- package/dist/utils/attributes.d.ts +2 -0
- package/dist/utils/bem.d.ts +3 -0
- package/dist/utils/collectionNavigation.d.ts +2 -0
- package/dist/utils/color.d.ts +7 -0
- package/dist/{components/color-picker/color-picker-utils.d.ts → utils/colorPicker.d.ts} +5 -4
- package/dist/utils/componentColors.d.ts +7 -0
- package/dist/utils/css.d.ts +3 -0
- package/dist/utils/dom/ancestry.d.ts +7 -0
- package/dist/utils/dom/attributes.d.ts +16 -0
- package/dist/utils/dom/componentRef.d.ts +4 -0
- package/dist/utils/dom/events.d.ts +5 -0
- package/dist/utils/dom/focusNavigation.d.ts +7 -0
- package/dist/utils/dom/interactive.d.ts +2 -0
- package/dist/utils/dom/pointer.d.ts +2 -0
- package/dist/utils/dom/query.d.ts +4 -0
- package/dist/utils/dom/scroll.d.ts +23 -0
- package/dist/utils/floatingOffset.d.ts +10 -0
- package/dist/utils/geometry.d.ts +14 -0
- package/dist/utils/indexPath.d.ts +6 -0
- package/dist/utils/number.d.ts +4 -0
- package/dist/utils/rafScheduler.d.ts +4 -0
- package/dist/utils/text.d.ts +2 -0
- package/docs/code-architecture.md +118 -0
- package/docs/public-composables-api.md +52 -0
- package/docs/public-floating-api.md +6 -5
- package/package.json +54 -46
- package/src/styles/_mixins.scss +4 -0
- package/src/styles/_tokens.scss +12 -12
- package/src/styles/_variables.scss +1 -1
- package/dist/button-link.css +0 -167
- package/dist/components/dropdown-menu/dropdown-menu-outside.d.ts +0 -3
- package/dist/components/dropdown-menu/dropdown-menu-utils.d.ts +0 -21
- package/dist/components/dropdown-menu/useDropdownMenuDisclosure.d.ts +0 -37
- package/dist/components/dropdown-menu/useDropdownMenuDom.d.ts +0 -29
- package/dist/components/dropdown-menu/useDropdownMenuInteractions.d.ts +0 -52
- package/dist/components/dropdown-menu/useDropdownMenuNavigation.d.ts +0 -17
- package/dist/components/dropdown-menu/useDropdownSubmenus.d.ts +0 -18
- package/dist/components/scroll-area/scrollAreaCore.d.ts +0 -25
- package/dist/components/scroll-area/useScrollAreaControls.d.ts +0 -25
- package/dist/components/scroll-area/useScrollAreaMetrics.d.ts +0 -35
- /package/dist/components/alert/{useAlertColor.d.ts → alertColor.d.ts} +0 -0
- /package/dist/components/avatar/{useAvatarColor.d.ts → avatarColor.d.ts} +0 -0
- /package/dist/components/badge/{useBadgeColor.d.ts → badgeColor.d.ts} +0 -0
- /package/dist/components/button/{useButtonColor.d.ts → buttonColor.d.ts} +0 -0
- /package/dist/components/color-swatch/{useColorSwatchColor.d.ts → colorSwatchColor.d.ts} +0 -0
- /package/dist/components/toast/{useToastColor.d.ts → toastColor.d.ts} +0 -0
- /package/dist/{composables → internal/composables}/useOverlayLayer.d.ts +0 -0
package/dist/useFormControl.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { inject, provide, watchEffect } from "vue";
|
|
2
|
-
//#region src/composables/useFormControl.ts
|
|
2
|
+
//#region src/internal/composables/useFormControl.ts
|
|
3
3
|
var nestedFormControlOwnerKey = Symbol("nestedFormControlOwner");
|
|
4
4
|
function provideNestedFormControlOwner() {
|
|
5
5
|
let claimed = false;
|
|
@@ -32,7 +32,8 @@ function useFormControl(options) {
|
|
|
32
32
|
if (documents.size === 0) return;
|
|
33
33
|
function onReset(event) {
|
|
34
34
|
const form = event.target;
|
|
35
|
-
|
|
35
|
+
const FormConstructor = event.currentTarget?.defaultView?.HTMLFormElement;
|
|
36
|
+
if (!FormConstructor || !(form instanceof FormConstructor)) return;
|
|
36
37
|
const elements = getElements(options).filter((element) => element.form === form);
|
|
37
38
|
if (elements.length === 0) return;
|
|
38
39
|
queueMicrotask(() => {
|
package/dist/useOverlayZIndex.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { n as isEventWithinElement } from "./events.js";
|
|
1
2
|
import { computed, inject, onBeforeUnmount, provide, readonly, ref, shallowRef, toValue, watch } from "vue";
|
|
2
|
-
//#region src/composables/useOverlayLayer.ts
|
|
3
|
+
//#region src/internal/composables/useOverlayLayer.ts
|
|
3
4
|
var overlayLayerKey = Symbol("overlay-layer");
|
|
4
5
|
var documentStates = /* @__PURE__ */ new WeakMap();
|
|
5
6
|
var layerMetadata = /* @__PURE__ */ new WeakMap();
|
|
@@ -38,11 +39,6 @@ function syncLayerZIndices(state) {
|
|
|
38
39
|
highestZIndex = zIndex;
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
|
-
function isEventWithinElement(event, element) {
|
|
42
|
-
const path = event.composedPath();
|
|
43
|
-
if (path.length > 0) return path.some((entry) => entry === element || typeof Node !== "undefined" && entry instanceof Node && element.contains(entry));
|
|
44
|
-
return typeof Node !== "undefined" && event.target instanceof Node && element.contains(event.target);
|
|
45
|
-
}
|
|
46
42
|
function restoreInertBackground(state) {
|
|
47
43
|
for (const [element, snapshot] of state.inertSnapshots) {
|
|
48
44
|
element.inert = snapshot.inert;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { inject } from "vue";
|
|
2
|
-
//#region src/composables/useRequiredInject.ts
|
|
2
|
+
//#region src/internal/composables/useRequiredInject.ts
|
|
3
3
|
function useRequiredInject(key, componentName) {
|
|
4
4
|
const value = inject(key);
|
|
5
5
|
if (value == null) throw new Error(`[Ropav] <${componentName}> must be used inside its parent provider component.`);
|
|
@@ -7,21 +7,14 @@ function readTeleportTarget(target) {
|
|
|
7
7
|
function hasTarget(target) {
|
|
8
8
|
return target != null && target !== "";
|
|
9
9
|
}
|
|
10
|
-
function provideTeleportTarget(props
|
|
10
|
+
function provideTeleportTarget(props) {
|
|
11
11
|
const parentContext = inject(teleportTargetKey, void 0);
|
|
12
12
|
const target = computed(() => {
|
|
13
13
|
const ownTarget = readTeleportTarget(props.teleportTo);
|
|
14
14
|
if (hasTarget(ownTarget)) return ownTarget;
|
|
15
15
|
return parentContext?.target.value ?? "body";
|
|
16
16
|
});
|
|
17
|
-
provide(teleportTargetKey, {
|
|
18
|
-
target,
|
|
19
|
-
positioningKey: computed(() => [
|
|
20
|
-
target.value,
|
|
21
|
-
toValue(positioningKey),
|
|
22
|
-
parentContext?.positioningKey.value
|
|
23
|
-
])
|
|
24
|
-
});
|
|
17
|
+
provide(teleportTargetKey, { target });
|
|
25
18
|
return target;
|
|
26
19
|
}
|
|
27
20
|
function useTeleportTarget(target) {
|
|
@@ -32,9 +25,5 @@ function useTeleportTarget(target) {
|
|
|
32
25
|
return providedContext?.target.value ?? "body";
|
|
33
26
|
});
|
|
34
27
|
}
|
|
35
|
-
function useTeleportPositioningKey() {
|
|
36
|
-
const providedContext = inject(teleportTargetKey, void 0);
|
|
37
|
-
return computed(() => providedContext?.positioningKey.value);
|
|
38
|
-
}
|
|
39
28
|
//#endregion
|
|
40
|
-
export {
|
|
29
|
+
export { useTeleportTarget as n, provideTeleportTarget as t };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { n as normalizeTypeaheadText } from "./text.js";
|
|
2
|
+
import { onBeforeUnmount } from "vue";
|
|
3
|
+
//#region src/internal/composables/useTypeahead.ts
|
|
4
|
+
var DEFAULT_TYPEAHEAD_TIMEOUT = 1e3;
|
|
5
|
+
function isRepeatedQuery(query) {
|
|
6
|
+
const characters = [...query];
|
|
7
|
+
return characters.length > 1 && characters.every((character) => character === characters[0]);
|
|
8
|
+
}
|
|
9
|
+
function useTypeahead(options) {
|
|
10
|
+
let buffer = "";
|
|
11
|
+
let timer;
|
|
12
|
+
let lastMatch;
|
|
13
|
+
let currentScope = options.scopeKey?.();
|
|
14
|
+
const isDisabled = options.isDisabled ?? (() => false);
|
|
15
|
+
function clearTimer() {
|
|
16
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
17
|
+
timer = void 0;
|
|
18
|
+
}
|
|
19
|
+
function reset() {
|
|
20
|
+
clearTimer();
|
|
21
|
+
buffer = "";
|
|
22
|
+
lastMatch = void 0;
|
|
23
|
+
currentScope = options.scopeKey?.();
|
|
24
|
+
}
|
|
25
|
+
function scheduleReset() {
|
|
26
|
+
clearTimer();
|
|
27
|
+
timer = setTimeout(reset, options.timeout ?? DEFAULT_TYPEAHEAD_TIMEOUT);
|
|
28
|
+
}
|
|
29
|
+
function hasBuffer() {
|
|
30
|
+
return buffer.length > 0;
|
|
31
|
+
}
|
|
32
|
+
function getMatchIndex(query, startIndex, keepCurrent) {
|
|
33
|
+
const items = options.items();
|
|
34
|
+
if (items.length === 0) return -1;
|
|
35
|
+
function matches(index) {
|
|
36
|
+
const item = items[index];
|
|
37
|
+
return Boolean(item && !isDisabled(item) && normalizeTypeaheadText(options.getTextValue(item)).startsWith(query));
|
|
38
|
+
}
|
|
39
|
+
if (keepCurrent && startIndex >= 0 && matches(startIndex)) return startIndex;
|
|
40
|
+
for (let offset = 1; offset <= items.length; offset += 1) {
|
|
41
|
+
const index = (startIndex + offset + items.length) % items.length;
|
|
42
|
+
if (matches(index)) return index;
|
|
43
|
+
}
|
|
44
|
+
return -1;
|
|
45
|
+
}
|
|
46
|
+
function getLastMatchIndex(items) {
|
|
47
|
+
const match = lastMatch;
|
|
48
|
+
if (!match) return -1;
|
|
49
|
+
if (Object.is(items[match.index], match.item)) return match.index;
|
|
50
|
+
const identityIndex = items.findIndex((item) => Object.is(item, match.item));
|
|
51
|
+
if (identityIndex >= 0) return identityIndex;
|
|
52
|
+
let keyIndex = -1;
|
|
53
|
+
for (let index = 0; index < items.length; index += 1) {
|
|
54
|
+
if (!Object.is(options.getKey(items[index]), match.key)) continue;
|
|
55
|
+
if (keyIndex >= 0) return -1;
|
|
56
|
+
keyIndex = index;
|
|
57
|
+
}
|
|
58
|
+
return keyIndex;
|
|
59
|
+
}
|
|
60
|
+
function handleKey(event) {
|
|
61
|
+
const nextScope = options.scopeKey?.();
|
|
62
|
+
if (!Object.is(currentScope, nextScope)) reset();
|
|
63
|
+
currentScope = nextScope;
|
|
64
|
+
if (event.ctrlKey || event.metaKey || event.altKey || event.isComposing || [...event.key].length !== 1 || event.key === " " && !hasBuffer()) return false;
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
buffer += event.key;
|
|
67
|
+
scheduleReset();
|
|
68
|
+
const normalizedBuffer = normalizeTypeaheadText(buffer);
|
|
69
|
+
if (!normalizedBuffer) return true;
|
|
70
|
+
const repeated = isRepeatedQuery(normalizedBuffer);
|
|
71
|
+
const query = repeated ? [...normalizedBuffer][0] : normalizedBuffer;
|
|
72
|
+
const items = options.items();
|
|
73
|
+
const lastMatchIndex = getLastMatchIndex(items);
|
|
74
|
+
const matchIndex = getMatchIndex(query, lastMatchIndex >= 0 ? lastMatchIndex : options.activeIndex(), !repeated && [...query].length > 1);
|
|
75
|
+
if (matchIndex < 0) return true;
|
|
76
|
+
const item = items[matchIndex];
|
|
77
|
+
if (!item) return true;
|
|
78
|
+
lastMatch = {
|
|
79
|
+
item,
|
|
80
|
+
index: matchIndex,
|
|
81
|
+
key: options.getKey(item)
|
|
82
|
+
};
|
|
83
|
+
options.onMatch(item, matchIndex);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
onBeforeUnmount(clearTimer);
|
|
87
|
+
return {
|
|
88
|
+
handleKey,
|
|
89
|
+
hasBuffer,
|
|
90
|
+
reset
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
export { useTypeahead as t };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function parseAriaIdRefs(value: string | null | undefined): string[];
|
|
2
|
+
export declare function hasAriaIdRef(value: string | null | undefined, id: string): boolean;
|
|
3
|
+
export declare function mergeAriaIdRefs(...values: Array<string | null | undefined>): string | undefined;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare function getEnabledIndexes<T>(items: readonly T[], isDisabled: (item: T) => boolean): number[];
|
|
2
|
+
export declare function getNextEnabledIndex<T>(items: readonly T[], currentIndex: number, direction: 1 | -1, isDisabled: (item: T) => boolean, loop?: boolean): number | undefined;
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
export declare const colorPickerFormats: readonly ["hex", "hexa", "rgb", "rgba", "hsl", "hsla"];
|
|
2
|
+
export type ColorPickerFormat = (typeof colorPickerFormats)[number];
|
|
2
3
|
export declare const DEFAULT_HUE = 0;
|
|
3
4
|
export declare const HUE_MAX = 359;
|
|
4
|
-
export declare const KEYBOARD_STEP = 1;
|
|
5
|
-
export declare const KEYBOARD_LARGE_STEP = 10;
|
|
6
5
|
export declare const DEFAULT_OPACITY = 100;
|
|
6
|
+
export declare const COLOR_PICKER_KEYBOARD_STEP = 1;
|
|
7
|
+
export declare const COLOR_PICKER_KEYBOARD_LARGE_STEP = 10;
|
|
7
8
|
export interface ColorPickerHsvColor {
|
|
8
9
|
hue: number;
|
|
9
10
|
saturation: number;
|
|
10
11
|
value: number;
|
|
11
12
|
opacity: number;
|
|
12
13
|
}
|
|
13
|
-
export declare function clamp(value: number, min: number, max: number): number;
|
|
14
14
|
export declare function clampPercent(value: number | undefined): number;
|
|
15
15
|
export declare function normalizeHue(value: number | undefined): number;
|
|
16
16
|
export declare function normalizeHueForColor(value: number | undefined): number;
|
|
17
17
|
export declare function clampHue(value: number): number;
|
|
18
18
|
export declare function clampOpacity(value: number | undefined): number;
|
|
19
19
|
export declare function roundPercent(value: number): number;
|
|
20
|
+
export declare function getColorPickerKeyboardValue(key: string, currentValue: number, maxValue: number, step?: number): number | undefined;
|
|
20
21
|
export declare function isColorPickerAlphaFormat(format: ColorPickerFormat): format is "hexa" | "rgba" | "hsla";
|
|
21
22
|
export declare function parseColorPickerValue(value: string): ColorPickerHsvColor | undefined;
|
|
22
23
|
export declare function formatColorPickerValue(color: ColorPickerHsvColor, format: ColorPickerFormat): string;
|
|
@@ -46,6 +46,12 @@ export interface ComponentVariantColorOptions extends ComponentContrastColorOpti
|
|
|
46
46
|
variant: ComponentColorVariant | undefined;
|
|
47
47
|
defaultColor?: ComponentColorValue;
|
|
48
48
|
}
|
|
49
|
+
export interface ComponentCheckedColorStyleOptions extends ComponentContrastColorOptions {
|
|
50
|
+
color: ComponentColorValue | undefined;
|
|
51
|
+
colorProperty: `--${string}`;
|
|
52
|
+
checkedColorProperty: `--${string}`;
|
|
53
|
+
defaultColor?: ComponentColorValue;
|
|
54
|
+
}
|
|
49
55
|
export type ParsedComponentColor = {
|
|
50
56
|
kind: 'empty';
|
|
51
57
|
} | {
|
|
@@ -68,6 +74,7 @@ export declare function isComponentPresetColor(color: ComponentColorValue | unde
|
|
|
68
74
|
export declare function parseComponentColor(color: ComponentColorValue | undefined): ParsedComponentColor;
|
|
69
75
|
export declare function getComponentColorValue(color: ComponentColorValue | undefined): string | undefined;
|
|
70
76
|
export declare function getComponentContrastColor(color: ComponentColorValue | undefined, options?: ComponentContrastColorOptions): string;
|
|
77
|
+
export declare function getComponentCheckedColorStyle({ color, colorProperty, checkedColorProperty, defaultColor, autoContrast, contrastColor, }: ComponentCheckedColorStyleOptions): Record<string, string> | undefined;
|
|
71
78
|
export declare function getComponentContrastColorRoles(color: ComponentColorValue | undefined, options?: ComponentContrastColorOptions): ComponentContrastColorRoles;
|
|
72
79
|
export declare function getComponentColorRoles(color: ComponentColorValue | undefined): ComponentColorRoles | undefined;
|
|
73
80
|
export declare function getComponentVariantColorRoles({ color, variant, defaultColor, autoContrast, contrastColor, }: ComponentVariantColorOptions): ComponentVariantColorRoles | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ObserveComposedAncestryOptions {
|
|
2
|
+
deferWhileDisconnected?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export declare function getComposedParent(node: Node): Node | null;
|
|
5
|
+
export declare function getComposedAncestry(node: Node | null | undefined): Node[];
|
|
6
|
+
export declare function areNodeListsIdentical(left: readonly Node[], right: readonly Node[]): boolean;
|
|
7
|
+
export declare function observeComposedAncestry(getNodes: () => readonly (Node | null | undefined)[], onChange: () => void, options?: ObserveComposedAncestryOptions): () => void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type AttributeSnapshot<Name extends string = string> = ReadonlyMap<Name, string | null>;
|
|
2
|
+
export interface CompatibilityAttributes {
|
|
3
|
+
class?: unknown;
|
|
4
|
+
style?: unknown;
|
|
5
|
+
}
|
|
6
|
+
export type EventHandler<EventType extends Event> = (event: EventType) => unknown;
|
|
7
|
+
export declare function splitCompatibilityAttributes<Attributes extends CompatibilityAttributes>(attributes: Attributes): {
|
|
8
|
+
compatibilityClass: Attributes['class'];
|
|
9
|
+
compatibilityStyle: Attributes['style'];
|
|
10
|
+
forwardedAttributes: Omit<Attributes, 'class' | 'style'>;
|
|
11
|
+
};
|
|
12
|
+
export declare function composeEventHandlers<EventType extends Event>(...handlers: ReadonlyArray<EventHandler<EventType> | undefined>): (event: EventType) => void;
|
|
13
|
+
export declare function parseAttributeTokens(value: string | null | undefined): string[];
|
|
14
|
+
export declare function hasAttributeToken(value: string | null | undefined, token: string): boolean;
|
|
15
|
+
export declare function snapshotAttributes<Name extends string>(element: Element, attributes: readonly Name[]): AttributeSnapshot<Name>;
|
|
16
|
+
export declare function restoreAttributes(element: Element, snapshot: AttributeSnapshot): void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ComponentPublicInstance, VaporComponentInstance } from 'vue';
|
|
2
|
+
export type ComponentElementRef = Element | ComponentPublicInstance | VaporComponentInstance | null;
|
|
3
|
+
export declare function toHTMLElement(value: ComponentElementRef, fallbackId?: string): HTMLElement | null;
|
|
4
|
+
export declare function resolveHTMLElementRef(value: ComponentElementRef, fallbackId: string, resolve: (element: HTMLElement | null) => void): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function isNodeWithinElement(value: unknown, element: unknown): value is Node;
|
|
2
|
+
export declare function isEventWithinElement(event: Event, element: Element): boolean;
|
|
3
|
+
export type EventContainmentTarget = string | Element | null | undefined;
|
|
4
|
+
export declare function isEventWithinTargets(event: Event, targets: readonly EventContainmentTarget[]): boolean;
|
|
5
|
+
export declare function createCancelableCustomEvent<T>(type: string, detail: T, originalEvent: Event): CustomEvent<T>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type FocusNavigationOrientation = 'horizontal' | 'vertical';
|
|
2
|
+
export interface FocusNavigationOptions {
|
|
3
|
+
itemSelector: string;
|
|
4
|
+
collectionSelector: string;
|
|
5
|
+
orientation: FocusNavigationOrientation;
|
|
6
|
+
}
|
|
7
|
+
export declare function getFocusNavigationTarget<ElementType extends HTMLElement>(event: Pick<KeyboardEvent, 'key' | 'target'>, collection: HTMLElement, options: FocusNavigationOptions): ElementType | undefined;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function isElement(value: unknown): value is Element;
|
|
2
|
+
export declare function matchesSelectorSafe(element: Element, selector: string): boolean;
|
|
3
|
+
export declare function querySelectorSafe<ElementType extends Element = Element>(selector: string, root?: ParentNode | null): ElementType | null;
|
|
4
|
+
export declare function querySelectorAllSafe<ElementType extends Element = Element>(selector: string, root?: ParentNode | null): ElementType[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ScrollAxis = 'x' | 'y';
|
|
2
|
+
export type ScrollDirection = 'ltr' | 'rtl';
|
|
3
|
+
export interface KeyboardScrollPositionOptions {
|
|
4
|
+
axis: ScrollAxis;
|
|
5
|
+
key: string;
|
|
6
|
+
current: number;
|
|
7
|
+
pageSize: number;
|
|
8
|
+
maxPosition: number;
|
|
9
|
+
direction: ScrollDirection;
|
|
10
|
+
lineStep: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function getScrollDirection(element: Element): ScrollDirection;
|
|
13
|
+
export declare function getLogicalHorizontalScrollPosition(scrollLeft: number, maxPosition: number, direction: ScrollDirection): number;
|
|
14
|
+
export declare function getRawHorizontalScrollPosition(position: number, maxPosition: number, direction: ScrollDirection): number;
|
|
15
|
+
export declare function getScrollThumbGeometry(trackSize: number, viewportSize: number, scrollSize: number, minimumSize: number): {
|
|
16
|
+
size: number;
|
|
17
|
+
offsetRatio: number;
|
|
18
|
+
};
|
|
19
|
+
export declare function getScrollThumbOffset(position: number, maxPosition: number, sizeRatio: number): number;
|
|
20
|
+
export declare function getKeyboardScrollPosition({ axis, key, current, pageSize, maxPosition, direction, lineStep, }: KeyboardScrollPositionOptions): number | undefined;
|
|
21
|
+
export declare function getWheelScrollDelta(axis: ScrollAxis, event: Pick<WheelEvent, 'deltaX' | 'deltaY'>, direction: ScrollDirection): number;
|
|
22
|
+
export declare function applyFallbackScrollPosition(element: Pick<HTMLElement, 'scrollLeft' | 'scrollTop'>, options: Pick<ScrollToOptions, 'left' | 'top'>, mode: 'absolute' | 'relative'): void;
|
|
23
|
+
export declare function getPointerAxisCoordinate(axis: ScrollAxis, event: Pick<PointerEvent, 'clientX' | 'clientY'>): number;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface FloatingOffsetAxes {
|
|
2
|
+
mainAxis?: number;
|
|
3
|
+
crossAxis?: number;
|
|
4
|
+
}
|
|
5
|
+
export type FloatingOffsetValue = number | FloatingOffsetAxes;
|
|
6
|
+
export interface FloatingOffsetProperties {
|
|
7
|
+
mainAxis: `--${string}`;
|
|
8
|
+
crossAxis: `--${string}`;
|
|
9
|
+
}
|
|
10
|
+
export declare function getFloatingOffsetStyle(offset: FloatingOffsetValue | null | undefined, properties: FloatingOffsetProperties): Record<string, string> | undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Point {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
}
|
|
5
|
+
export type Triangle = [Point, Point, Point];
|
|
6
|
+
type RectBounds = Pick<DOMRect, 'bottom' | 'height' | 'left' | 'right' | 'top' | 'width'>;
|
|
7
|
+
export declare function getClientPoint(event: Pick<MouseEvent, 'clientX' | 'clientY'>): Point;
|
|
8
|
+
export declare function hasMeasuredRect(rect: Pick<DOMRect, 'height' | 'width'>): boolean;
|
|
9
|
+
export declare function isPointInRect(point: Point, rect: RectBounds, padding?: number): boolean;
|
|
10
|
+
export declare function getTriangleArea(a: Point, b: Point, c: Point): number;
|
|
11
|
+
export declare function isPointInTriangle(point: Point, triangle: Triangle, tolerance?: number): boolean;
|
|
12
|
+
export declare function clampPointToRect(point: Point, rect: RectBounds): Point;
|
|
13
|
+
export declare function createPointRect(point: Point): DOMRect;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type IndexPath = number[];
|
|
2
|
+
export declare function getPathKey(path: IndexPath): string;
|
|
3
|
+
export declare function getParentPath(path: IndexPath): IndexPath;
|
|
4
|
+
export declare function arePathsEqual(a: IndexPath, b: IndexPath): boolean;
|
|
5
|
+
export declare function isPathPrefix(prefix: IndexPath, path: IndexPath): boolean;
|
|
6
|
+
export declare function normalizePath(indexOrPath: number | IndexPath): IndexPath;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function clamp(value: number, min: number, max: number): number;
|
|
2
|
+
export declare function getValuePercent(value: number, min: number, max: number): number;
|
|
3
|
+
export declare function normalizeDelay(value: number | null | undefined, fallback?: number): number;
|
|
4
|
+
export declare function roundTo(value: number, fractionDigits?: number): number;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Code architecture
|
|
2
|
+
|
|
3
|
+
This guide defines the source structure expected from contributors. The goal is a predictable
|
|
4
|
+
codebase where UI files describe rendering, behavior is testable through small interfaces, and
|
|
5
|
+
shared logic has one obvious home.
|
|
6
|
+
|
|
7
|
+
## Module seams
|
|
8
|
+
|
|
9
|
+
A module should hide a meaningful amount of behavior behind a small interface. Extract code around
|
|
10
|
+
a responsibility, not merely to reduce a line count. A useful extraction makes callers simpler and
|
|
11
|
+
lets tests exercise the same interface that production code uses.
|
|
12
|
+
|
|
13
|
+
Use this dependency direction:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
Vue components and component-local modules
|
|
17
|
+
-> internal composables
|
|
18
|
+
-> public composables
|
|
19
|
+
-> utilities
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
A higher layer may also import a lower layer directly. Lower layers must not import higher layers:
|
|
23
|
+
|
|
24
|
+
- `src/utils/` does not import components or composables.
|
|
25
|
+
- `src/composables/` does not import components or internal modules.
|
|
26
|
+
- `src/internal/` does not import components.
|
|
27
|
+
- Components may compose other components when the dependency remains acyclic.
|
|
28
|
+
|
|
29
|
+
## Where code belongs
|
|
30
|
+
|
|
31
|
+
| Location | Responsibility |
|
|
32
|
+
| ----------------------------------------- | --------------------------------------------------------------------- |
|
|
33
|
+
| `src/components/<name>/*.vue` | Template, bindings, slots, and lightweight view-derived state |
|
|
34
|
+
| `src/components/<name>/useX.ts` | Component-specific reactive state, lifecycle, and event orchestration |
|
|
35
|
+
| `src/components/<name>/<concern>Model.ts` | Pure behavior that encodes only that component's contract |
|
|
36
|
+
| `src/internal/composables/` | Shared reactive behavior that is not part of the package interface |
|
|
37
|
+
| `src/composables/` | Reusable public composables exported by the package |
|
|
38
|
+
| `src/utils/` | Reusable runtime helpers without component state or lifecycle |
|
|
39
|
+
| `src/utils/dom/` | Reusable helpers that operate on browser and DOM primitives |
|
|
40
|
+
| `tests/`, `tooling/`, `scripts/` | Test, build, and repository automation helpers |
|
|
41
|
+
|
|
42
|
+
Do not add catch-all `utils`, `helpers`, or `core` modules beside a component. Keep a pure helper
|
|
43
|
+
local when it expresses one component's contract, and give it a semantic name such as
|
|
44
|
+
`sliderModel`. Move it to `src/utils/` once more than one feature needs the behavior.
|
|
45
|
+
|
|
46
|
+
## Component shape
|
|
47
|
+
|
|
48
|
+
Production SFCs use `<script setup lang="ts" vapor>` and remain zero-VDOM. Do not use `h`, `VNode`,
|
|
49
|
+
`defineComponent`, `createVNode`, or related VDOM block helpers in production source.
|
|
50
|
+
|
|
51
|
+
Keep SFC blocks in this order:
|
|
52
|
+
|
|
53
|
+
1. `<template>`
|
|
54
|
+
2. `<script setup lang="ts" vapor>`
|
|
55
|
+
3. `<style>`
|
|
56
|
+
|
|
57
|
+
Within the script block, use this order:
|
|
58
|
+
|
|
59
|
+
1. Imports
|
|
60
|
+
2. `defineOptions`, props defaults, emits, and slots
|
|
61
|
+
3. Composable state and template refs
|
|
62
|
+
4. View-derived computed attributes
|
|
63
|
+
5. Small event adapters and `defineExpose`
|
|
64
|
+
|
|
65
|
+
A short computed value used only to bind the template can stay in the SFC. Move state transitions,
|
|
66
|
+
timers, document listeners, multi-step event handling, and reusable calculations behind a
|
|
67
|
+
composable or pure model interface.
|
|
68
|
+
|
|
69
|
+
## Function design
|
|
70
|
+
|
|
71
|
+
Oxlint enforces a conservative baseline of cyclomatic complexity 20, nesting depth 4, at most 5
|
|
72
|
+
parameters, and at most 250 non-blank, non-comment lines per function. These are upper bounds, not
|
|
73
|
+
targets.
|
|
74
|
+
|
|
75
|
+
- Give each function one reason to change.
|
|
76
|
+
- Prefer guard clauses over deeply nested branches.
|
|
77
|
+
- Use an options object when several parameters describe one concept.
|
|
78
|
+
- Split orchestration into named steps, while keeping the external interface small.
|
|
79
|
+
- Accept dependencies or callbacks at the module seam instead of constructing hard-to-test global
|
|
80
|
+
dependencies inside the implementation.
|
|
81
|
+
- Return observable results where practical; isolate side effects in lifecycle or event adapters.
|
|
82
|
+
|
|
83
|
+
Do not create shallow pass-through functions solely to satisfy a metric. A refactor should improve
|
|
84
|
+
the caller, the module interface, or the test surface.
|
|
85
|
+
|
|
86
|
+
## Imports and package interfaces
|
|
87
|
+
|
|
88
|
+
- Import utilities directly from their module, for example `@/utils/number`; do not add a utils
|
|
89
|
+
barrel.
|
|
90
|
+
- Component `index.ts` files define package-facing exports. Internal code should not import from the
|
|
91
|
+
root package barrel.
|
|
92
|
+
- Keep imports acyclic. If two modules need each other, move the shared behavior to the lowest
|
|
93
|
+
layer that owns the concept.
|
|
94
|
+
- Use `import type` for type-only dependencies.
|
|
95
|
+
|
|
96
|
+
## Testing
|
|
97
|
+
|
|
98
|
+
Test through the interface of the extracted module:
|
|
99
|
+
|
|
100
|
+
- Pure models and utilities use deterministic unit tests.
|
|
101
|
+
- Composables test returned state and commands, using the smallest host needed for lifecycle
|
|
102
|
+
behavior.
|
|
103
|
+
- Component tests cover DOM integration, events, accessibility, and public rendering contracts.
|
|
104
|
+
- Storybook tests cover visual and interaction scenarios that depend on real browser layout.
|
|
105
|
+
|
|
106
|
+
Tests should assert observable behavior rather than private implementation details. Refactoring a
|
|
107
|
+
module internally should not require rewriting its behavioral tests.
|
|
108
|
+
|
|
109
|
+
## Contributor checklist
|
|
110
|
+
|
|
111
|
+
Before opening a pull request:
|
|
112
|
+
|
|
113
|
+
- The SFC primarily adapts props, slots, and composable results to the template.
|
|
114
|
+
- New reusable helpers live in `src/utils/`; feature-only pure logic has a semantic local name.
|
|
115
|
+
- Dependency direction remains downward and acyclic.
|
|
116
|
+
- Functions stay below the enforced complexity, depth, length, and parameter limits.
|
|
117
|
+
- New behavior is tested at the module interface.
|
|
118
|
+
- `pnpm run verify` passes.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Public composables API
|
|
2
|
+
|
|
3
|
+
Ropav exposes framework-level composables from both the root package and the dedicated
|
|
4
|
+
`ropav/composables` entrypoint. Prefer the dedicated entrypoint when an application only needs
|
|
5
|
+
headless state behavior.
|
|
6
|
+
|
|
7
|
+
## `useControllableValue`
|
|
8
|
+
|
|
9
|
+
`useControllableValue` implements the controlled/uncontrolled value pattern used across Ropav
|
|
10
|
+
components and composables. A defined `modelValue` makes the value controlled; only `undefined`
|
|
11
|
+
selects internal state, so values such as `null` and `false` remain controlled values.
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { useControllableValue } from 'ropav/composables';
|
|
16
|
+
|
|
17
|
+
const props = withDefaults(
|
|
18
|
+
defineProps<{
|
|
19
|
+
modelValue?: string;
|
|
20
|
+
defaultValue?: string;
|
|
21
|
+
}>(),
|
|
22
|
+
{
|
|
23
|
+
modelValue: undefined,
|
|
24
|
+
defaultValue: '',
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits<{
|
|
29
|
+
'update:modelValue': [value: string];
|
|
30
|
+
}>();
|
|
31
|
+
|
|
32
|
+
const { value, isControlled, setValue, resetValue } = useControllableValue({
|
|
33
|
+
modelValue: () => props.modelValue,
|
|
34
|
+
defaultValue: () => props.defaultValue,
|
|
35
|
+
onChange: (value) => emit('update:modelValue', value),
|
|
36
|
+
});
|
|
37
|
+
</script>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`defaultValue()` is read once when the composable is created. `setValue()` updates internal state
|
|
41
|
+
only in uncontrolled mode and always calls `onChange`, including repeated requests for the same
|
|
42
|
+
value. In controlled mode, the parent remains responsible for updating `modelValue`, and a rejected
|
|
43
|
+
change request does not replace the internal fallback.
|
|
44
|
+
|
|
45
|
+
`resetValue(value)` updates uncontrolled state without calling `onChange`. Calling `resetValue()`
|
|
46
|
+
without an argument restores the initial default. A reset is a no-op while controlled. If a value
|
|
47
|
+
changes from controlled to uncontrolled, the latest defined controlled value becomes the internal
|
|
48
|
+
fallback synchronously. Releasing control does not call `onChange`.
|
|
49
|
+
|
|
50
|
+
The return value contains readonly `value` and `isControlled` computed refs, the captured
|
|
51
|
+
`initialValue`, and the `setValue()` and `resetValue()` commands. `undefined` is reserved as the
|
|
52
|
+
uncontrolled sentinel and should not be used as a controlled value.
|
|
@@ -42,7 +42,6 @@ const { actualPlacement, arrowStyle, floatingStyle } = useFloatingPosition({
|
|
|
42
42
|
open,
|
|
43
43
|
placement: 'bottom-start',
|
|
44
44
|
offset: 8,
|
|
45
|
-
restartKey: () => [teleport.value, teleportTo.value],
|
|
46
45
|
});
|
|
47
46
|
</script>
|
|
48
47
|
```
|
|
@@ -63,7 +62,7 @@ The composable accepts plain values, refs, computed refs or getters for reactive
|
|
|
63
62
|
| `shift` | `true` | Keeps the floating element inside the collision boundary. |
|
|
64
63
|
| `collisionPadding` | `8` | Padding between the floating element and viewport boundary. |
|
|
65
64
|
| `autoUpdateOptions.animationFrame` | `false` | Tracks transform animations and detached nested floating contexts. |
|
|
66
|
-
| `restartKey` | — |
|
|
65
|
+
| `restartKey` | — | Forces a rebind for reactive changes unrelated to DOM ancestry. |
|
|
67
66
|
|
|
68
67
|
Use `autoUpdateOptions.animationFrame` sparingly. It checks the reference position every animation
|
|
69
68
|
frame and is intended for references moving with CSS transforms or nested floating elements outside
|
|
@@ -78,9 +77,11 @@ The return value contains readonly `actualPlacement`, `floatingStyle`, `arrowSty
|
|
|
78
77
|
`isPositioned` refs, plus an async `update()` method for content-driven layout changes.
|
|
79
78
|
|
|
80
79
|
`useTeleportTarget()` resolves the nearest `TeleportProvider` target and falls back to `body`. Pass
|
|
81
|
-
a target value, ref or getter to override the provider for one floating element.
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
a target value, ref or getter to override the provider for one floating element. Positioning
|
|
81
|
+
automatically rebinds when the reference or floating element moves through the composed DOM,
|
|
82
|
+
including Teleport moves, temporary detachments and slot reassignment within an existing shadow
|
|
83
|
+
tree. Use `restartKey` when a reactive change outside observable DOM ancestry must recreate the
|
|
84
|
+
auto-update subscriptions, such as a host attaching a new shadow root after positioning starts.
|
|
84
85
|
|
|
85
86
|
Positioning does not add interaction or accessibility behavior. Custom overlays remain responsible
|
|
86
87
|
for keyboard handling, focus management, roles, labels, outside interaction and dismissal.
|