@headlessui/vue
Advanced tools
Comparing version 0.0.0-alpha.1 to 0.0.0-fc42dde
@@ -13,5 +13,5 @@ import { Ref } from 'vue'; | ||
as: string; | ||
} & {}>, Readonly<{} & { | ||
as?: string | undefined; | ||
}>>; | ||
} & {}>, { | ||
as: string; | ||
}>; | ||
export declare const MenuButton: import("vue").DefineComponent<{ | ||
@@ -26,10 +26,9 @@ as: { | ||
handleKeyDown: (event: KeyboardEvent) => void; | ||
handlePointerDown: (event: PointerEvent) => void; | ||
handlePointerUp: () => void; | ||
handlePointerUp: (event: MouseEvent) => void; | ||
handleFocus: () => void; | ||
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{ | ||
as: string; | ||
} & {}>, Readonly<{} & { | ||
as?: string | undefined; | ||
}>>; | ||
} & {}>, { | ||
as: string; | ||
}>; | ||
export declare const MenuItems: import("vue").DefineComponent<{ | ||
@@ -51,6 +50,6 @@ as: { | ||
static: boolean; | ||
} & {}>, Readonly<{} & { | ||
as?: string | undefined; | ||
static?: boolean | undefined; | ||
}>>; | ||
} & {}>, { | ||
as: string; | ||
static: boolean; | ||
}>; | ||
export declare const MenuItem: import("vue").DefineComponent<{ | ||
@@ -73,6 +72,2 @@ as: { | ||
}; | ||
onClick: { | ||
type: FunctionConstructor; | ||
required: false; | ||
}; | ||
}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, { | ||
@@ -88,9 +83,5 @@ [key: string]: any; | ||
className?: string | Function | undefined; | ||
onClick?: Function | undefined; | ||
}>, Readonly<{} & { | ||
as?: string | undefined; | ||
disabled?: boolean | undefined; | ||
class?: string | Function | undefined; | ||
className?: string | Function | undefined; | ||
onClick?: Function | undefined; | ||
}>>; | ||
}>, { | ||
as: string; | ||
disabled: boolean; | ||
}>; |
@@ -101,2 +101,20 @@ 'use strict'; | ||
// TODO: This must already exist somewhere, right? 🤔 | ||
// Ref: https://www.w3.org/TR/uievents-key/#named-key-attribute-values | ||
var Keys; | ||
(function (Keys) { | ||
Keys["Space"] = " "; | ||
Keys["Enter"] = "Enter"; | ||
Keys["Escape"] = "Escape"; | ||
Keys["Backspace"] = "Backspace"; | ||
Keys["ArrowUp"] = "ArrowUp"; | ||
Keys["ArrowDown"] = "ArrowDown"; | ||
Keys["Home"] = "Home"; | ||
Keys["End"] = "End"; | ||
Keys["PageUp"] = "PageUp"; | ||
Keys["PageDown"] = "PageDown"; | ||
Keys["Tab"] = "Tab"; | ||
})(Keys || (Keys = {})); | ||
var MenuStates; | ||
@@ -107,22 +125,4 @@ | ||
MenuStates[MenuStates["Closed"] = 1] = "Closed"; | ||
})(MenuStates || (MenuStates = {})); // TODO: This must already exist somewhere, right? 🤔 | ||
// Ref: https://www.w3.org/TR/uievents-key/#named-key-attribute-values | ||
})(MenuStates || (MenuStates = {})); | ||
var Key; | ||
(function (Key) { | ||
Key["Space"] = " "; | ||
Key["Enter"] = "Enter"; | ||
Key["Escape"] = "Escape"; | ||
Key["Backspace"] = "Backspace"; | ||
Key["ArrowUp"] = "ArrowUp"; | ||
Key["ArrowDown"] = "ArrowDown"; | ||
Key["Home"] = "Home"; | ||
Key["End"] = "End"; | ||
Key["PageUp"] = "PageUp"; | ||
Key["PageDown"] = "PageDown"; | ||
Key["Tab"] = "Tab"; | ||
})(Key || (Key = {})); | ||
var Focus; | ||
@@ -215,7 +215,2 @@ | ||
activeItemIndex: activeItemIndex, | ||
toggleMenu: function toggleMenu() { | ||
var _match2; | ||
menuState.value = match(menuState.value, (_match2 = {}, _match2[MenuStates.Closed] = MenuStates.Open, _match2[MenuStates.Open] = MenuStates.Closed, _match2)); | ||
}, | ||
closeMenu: function closeMenu() { | ||
@@ -275,20 +270,21 @@ return menuState.value = MenuStates.Closed; | ||
function handler(event) { | ||
var _itemsRef$value; | ||
var _buttonRef$value, _itemsRef$value; | ||
if (event.defaultPrevented) return; | ||
if (menuState.value !== MenuStates.Open) return; | ||
if ((_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.contains(event.target)) return; | ||
if (!((_itemsRef$value = itemsRef.value) === null || _itemsRef$value === void 0 ? void 0 : _itemsRef$value.contains(event.target))) { | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _buttonRef$value; | ||
} | ||
return (_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.focus(); | ||
}); | ||
} | ||
if (!event.defaultPrevented) vue.nextTick(function () { | ||
var _buttonRef$value2; | ||
return (_buttonRef$value2 = buttonRef.value) === null || _buttonRef$value2 === void 0 ? void 0 : _buttonRef$value2.focus(); | ||
}); | ||
} | ||
window.addEventListener('pointerdown', handler); | ||
window.addEventListener('click', handler); | ||
vue.onUnmounted(function () { | ||
return window.removeEventListener('pointerdown', handler); | ||
return window.removeEventListener('click', handler); | ||
}); | ||
@@ -334,4 +330,3 @@ }); // @ts-expect-error Types of property 'dataRef' are incompatible. | ||
onFocus: this.handleFocus, | ||
onPointerUp: this.handlePointerUp, | ||
onPointerDown: this.handlePointerDown | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
@@ -352,5 +347,5 @@ return render({ | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-13 | ||
case Key.Space: | ||
case Key.Enter: | ||
case Key.ArrowDown: | ||
case Keys.Space: | ||
case Keys.Enter: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
@@ -366,3 +361,3 @@ api.openMenu(); | ||
case Key.ArrowUp: | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
@@ -380,15 +375,19 @@ api.openMenu(); | ||
function handlePointerDown(event) { | ||
// We have a `pointerdown` event listener in the menu for the 'outside click', so we just want | ||
// to prevent going there if we happen to click this button. | ||
event.preventDefault(); | ||
} | ||
function handlePointerUp(event) { | ||
if (api.menuState.value === MenuStates.Open) { | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value; | ||
function handlePointerUp() { | ||
api.toggleMenu(); | ||
vue.nextTick(function () { | ||
var _api$itemsRef$value4; | ||
return (_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.focus(); | ||
}); | ||
} else { | ||
event.preventDefault(); | ||
api.openMenu(); | ||
vue.nextTick(function () { | ||
var _api$itemsRef$value4; | ||
return (_api$itemsRef$value4 = api.itemsRef.value) === null || _api$itemsRef$value4 === void 0 ? void 0 : _api$itemsRef$value4.focus(); | ||
}); | ||
return (_api$itemsRef$value4 = api.itemsRef.value) === null || _api$itemsRef$value4 === void 0 ? void 0 : _api$itemsRef$value4.focus(); | ||
}); | ||
} | ||
} | ||
@@ -406,3 +405,2 @@ | ||
handleKeyDown: handleKeyDown, | ||
handlePointerDown: handlePointerDown, | ||
handlePointerUp: handlePointerUp, | ||
@@ -425,3 +423,3 @@ handleFocus: handleFocus | ||
render: function render$1() { | ||
var _api$items$value$api$, _api$buttonRef$value; | ||
var _api$items$value$api$, _api$buttonRef$value2; | ||
@@ -440,3 +438,3 @@ var api = useMenuContext('MenuItems'); // `static` is a reserved keyword, therefore aliasing it... | ||
'aria-activedescendant': api.activeItemIndex.value === null ? undefined : (_api$items$value$api$ = api.items.value[api.activeItemIndex.value]) === null || _api$items$value$api$ === void 0 ? void 0 : _api$items$value$api$.id, | ||
'aria-labelledby': (_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.id, | ||
'aria-labelledby': (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.id, | ||
id: this.id, | ||
@@ -465,3 +463,13 @@ onKeyDown: this.handleKeyDown, | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12 | ||
case Key.Enter: | ||
// @ts-expect-error Fallthrough is expected here | ||
case Keys.Space: | ||
if (api.searchQuery.value !== '') { | ||
event.preventDefault(); | ||
return api.search(event.key); | ||
} | ||
// When in type ahead mode, fallthrough | ||
case Keys.Enter: | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
@@ -474,35 +482,40 @@ | ||
(_document$getElementB = document.getElementById(_id)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.click(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value2; | ||
return (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.focus(); | ||
}); | ||
} | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value3; | ||
return (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.focus(); | ||
}); | ||
break; | ||
case Key.ArrowDown: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.NextItem); | ||
case Key.ArrowUp: | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.PreviousItem); | ||
case Key.Home: | ||
case Key.PageUp: | ||
case Keys.Home: | ||
case Keys.PageUp: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.FirstItem); | ||
case Key.End: | ||
case Key.PageDown: | ||
case Keys.End: | ||
case Keys.PageDown: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.LastItem); | ||
case Key.Escape: | ||
case Keys.Escape: | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value3; | ||
var _api$buttonRef$value4; | ||
return (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.focus(); | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
}); | ||
break; | ||
case Key.Tab: | ||
case Keys.Tab: | ||
return event.preventDefault(); | ||
@@ -546,6 +559,2 @@ | ||
required: false | ||
}, | ||
onClick: { | ||
type: Function, | ||
required: false | ||
} | ||
@@ -582,5 +591,10 @@ }, | ||
function handlePointerEnter() { | ||
if (disabled) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
function handleClick(event) { | ||
if (disabled) return event.preventDefault(); | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value5; | ||
return (_api$buttonRef$value5 = api.buttonRef.value) === null || _api$buttonRef$value5 === void 0 ? void 0 : _api$buttonRef$value5.focus(); | ||
}); | ||
} | ||
@@ -593,32 +607,635 @@ | ||
function handlePointerMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
} | ||
function handlePointerLeave() { | ||
if (disabled) return; | ||
if (!active.value) return; | ||
api.goToItem(Focus.Nothing); | ||
} | ||
function handleMouseMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
return function () { | ||
var slot = { | ||
active: active.value, | ||
disabled: disabled | ||
}; | ||
var propsWeControl = { | ||
id: id, | ||
role: 'menuitem', | ||
tabIndex: -1, | ||
"class": resolvePropValue(className, slot), | ||
'aria-disabled': disabled === true ? true : undefined, | ||
onClick: handleClick, | ||
onFocus: handleFocus, | ||
onPointerMove: handlePointerMove, | ||
onPointerLeave: handlePointerLeave | ||
}; | ||
return render({ | ||
props: _extends({}, props, propsWeControl), | ||
slot: slot, | ||
attrs: attrs, | ||
slots: slots | ||
}); | ||
}; | ||
} | ||
}); | ||
function resolvePropValue(property, bag) { | ||
if (property === undefined) return undefined; | ||
if (typeof property === 'function') return property(bag); | ||
return property; | ||
} | ||
var ListboxStates; | ||
(function (ListboxStates) { | ||
ListboxStates[ListboxStates["Open"] = 0] = "Open"; | ||
ListboxStates[ListboxStates["Closed"] = 1] = "Closed"; | ||
})(ListboxStates || (ListboxStates = {})); | ||
var Focus$1; | ||
(function (Focus) { | ||
Focus[Focus["First"] = 0] = "First"; | ||
Focus[Focus["Previous"] = 1] = "Previous"; | ||
Focus[Focus["Next"] = 2] = "Next"; | ||
Focus[Focus["Last"] = 3] = "Last"; | ||
Focus[Focus["Specific"] = 4] = "Specific"; | ||
Focus[Focus["Nothing"] = 5] = "Nothing"; | ||
})(Focus$1 || (Focus$1 = {})); | ||
var ListboxContext = /*#__PURE__*/Symbol('ListboxContext'); | ||
function useListboxContext(component) { | ||
var context = vue.inject(ListboxContext); | ||
if (context === undefined) { | ||
var err = new Error("<" + component + " /> is missing a parent <Listbox /> component."); | ||
if (Error.captureStackTrace) Error.captureStackTrace(err, useListboxContext); | ||
throw err; | ||
} | ||
return context; | ||
} // --- | ||
var Listbox = /*#__PURE__*/vue.defineComponent({ | ||
name: 'Listbox', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'template' | ||
}, | ||
modelValue: { | ||
type: [Object, String], | ||
"default": null | ||
} | ||
}, | ||
setup: function setup(props, _ref) { | ||
var slots = _ref.slots, | ||
attrs = _ref.attrs, | ||
emit = _ref.emit; | ||
var passThroughProps = _objectWithoutPropertiesLoose(props, ["modelValue"]); | ||
var listboxState = vue.ref(ListboxStates.Closed); | ||
var labelRef = vue.ref(null); | ||
var buttonRef = vue.ref(null); | ||
var optionsRef = vue.ref(null); | ||
var options = vue.ref([]); | ||
var searchQuery = vue.ref(''); | ||
var activeOptionIndex = vue.ref(null); | ||
var value = vue.computed(function () { | ||
return props.modelValue; | ||
}); | ||
function calculateActiveOptionIndex(focus, id) { | ||
var _activeOptionIndex$va, _match; | ||
if (options.value.length <= 0) return null; | ||
var currentActiveOptionIndex = (_activeOptionIndex$va = activeOptionIndex.value) !== null && _activeOptionIndex$va !== void 0 ? _activeOptionIndex$va : -1; | ||
var nextActiveIndex = match(focus, (_match = {}, _match[Focus$1.First] = function () { | ||
return options.value.findIndex(function (option) { | ||
return !option.dataRef.disabled; | ||
}); | ||
}, _match[Focus$1.Previous] = function () { | ||
var idx = options.value.slice().reverse().findIndex(function (option, idx, all) { | ||
if (currentActiveOptionIndex !== -1 && all.length - idx - 1 >= currentActiveOptionIndex) return false; | ||
return !option.dataRef.disabled; | ||
}); | ||
if (idx === -1) return idx; | ||
return options.value.length - 1 - idx; | ||
}, _match[Focus$1.Next] = function () { | ||
return options.value.findIndex(function (option, idx) { | ||
if (idx <= currentActiveOptionIndex) return false; | ||
return !option.dataRef.disabled; | ||
}); | ||
}, _match[Focus$1.Last] = function () { | ||
var idx = options.value.slice().reverse().findIndex(function (option) { | ||
return !option.dataRef.disabled; | ||
}); | ||
if (idx === -1) return idx; | ||
return options.value.length - 1 - idx; | ||
}, _match[Focus$1.Specific] = function () { | ||
return options.value.findIndex(function (option) { | ||
return option.id === id; | ||
}); | ||
}, _match[Focus$1.Nothing] = function () { | ||
return null; | ||
}, _match)); | ||
if (nextActiveIndex === -1) return activeOptionIndex.value; | ||
return nextActiveIndex; | ||
} | ||
var api = { | ||
listboxState: listboxState, | ||
value: value, | ||
labelRef: labelRef, | ||
buttonRef: buttonRef, | ||
optionsRef: optionsRef, | ||
options: options, | ||
searchQuery: searchQuery, | ||
activeOptionIndex: activeOptionIndex, | ||
closeListbox: function closeListbox() { | ||
return listboxState.value = ListboxStates.Closed; | ||
}, | ||
openListbox: function openListbox() { | ||
return listboxState.value = ListboxStates.Open; | ||
}, | ||
goToOption: function goToOption(focus, id) { | ||
var nextActiveOptionIndex = calculateActiveOptionIndex(focus, id); | ||
if (searchQuery.value === '' && activeOptionIndex.value === nextActiveOptionIndex) return; | ||
searchQuery.value = ''; | ||
activeOptionIndex.value = nextActiveOptionIndex; | ||
}, | ||
search: function search(value) { | ||
searchQuery.value += value; | ||
var match = options.value.findIndex(function (option) { | ||
return !option.dataRef.disabled && option.dataRef.textValue.startsWith(searchQuery.value); | ||
}); | ||
if (match === -1 || match === activeOptionIndex.value) { | ||
return; | ||
} | ||
activeOptionIndex.value = match; | ||
}, | ||
clearSearch: function clearSearch() { | ||
searchQuery.value = ''; | ||
}, | ||
registerOption: function registerOption(id, dataRef) { | ||
// @ts-expect-error The expected type comes from property 'dataRef' which is declared here on type '{ id: string; dataRef: { textValue: string; disabled: boolean; }; }' | ||
options.value.push({ | ||
id: id, | ||
dataRef: dataRef | ||
}); | ||
}, | ||
unregisterOption: function unregisterOption(id) { | ||
var nextOptions = options.value.slice(); | ||
var currentActiveOption = activeOptionIndex.value !== null ? nextOptions[activeOptionIndex.value] : null; | ||
var idx = nextOptions.findIndex(function (a) { | ||
return a.id === id; | ||
}); | ||
if (idx !== -1) nextOptions.splice(idx, 1); | ||
options.value = nextOptions; | ||
activeOptionIndex.value = function () { | ||
if (idx === activeOptionIndex.value) return null; | ||
if (currentActiveOption === null) return null; // If we removed the option before the actual active index, then it would be out of sync. To | ||
// fix this, we will find the correct (new) index position. | ||
return nextOptions.indexOf(currentActiveOption); | ||
}(); | ||
}, | ||
select: function select(value) { | ||
emit('update:modelValue', value); | ||
} | ||
}; | ||
vue.onMounted(function () { | ||
function handler(event) { | ||
var _buttonRef$value, _optionsRef$value; | ||
if (listboxState.value !== ListboxStates.Open) return; | ||
if ((_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.contains(event.target)) return; | ||
if (!((_optionsRef$value = optionsRef.value) === null || _optionsRef$value === void 0 ? void 0 : _optionsRef$value.contains(event.target))) { | ||
api.closeListbox(); | ||
} | ||
if (!event.defaultPrevented) vue.nextTick(function () { | ||
var _buttonRef$value2; | ||
return (_buttonRef$value2 = buttonRef.value) === null || _buttonRef$value2 === void 0 ? void 0 : _buttonRef$value2.focus(); | ||
}); | ||
} | ||
window.addEventListener('click', handler); | ||
vue.onUnmounted(function () { | ||
return window.removeEventListener('click', handler); | ||
}); | ||
}); // @ts-expect-error Types of property 'dataRef' are incompatible. | ||
vue.provide(ListboxContext, api); | ||
return function () { | ||
var slot = { | ||
open: listboxState.value === ListboxStates.Open | ||
}; | ||
return render({ | ||
props: passThroughProps, | ||
slot: slot, | ||
slots: slots, | ||
attrs: attrs | ||
}); | ||
}; | ||
} | ||
}); // --- | ||
var ListboxLabel = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxLabel', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'label' | ||
} | ||
}, | ||
render: function render$1() { | ||
var api = useListboxContext('ListboxLabel'); | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open | ||
}; | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: 'el', | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxLabel'); | ||
var id = "headlessui-listbox-label-" + useId(); | ||
return { | ||
id: id, | ||
el: api.labelRef, | ||
handlePointerUp: function handlePointerUp() { | ||
var _api$buttonRef$value; | ||
(_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.focus(); | ||
} | ||
}; | ||
} | ||
}); // --- | ||
var ListboxButton = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxButton', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'button' | ||
} | ||
}, | ||
render: function render$1() { | ||
var _api$optionsRef$value; | ||
var api = useListboxContext('ListboxButton'); | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open, | ||
focused: this.focused | ||
}; | ||
var propsWeControl = { | ||
ref: 'el', | ||
id: this.id, | ||
type: 'button', | ||
'aria-haspopup': true, | ||
'aria-controls': (_api$optionsRef$value = api.optionsRef.value) === null || _api$optionsRef$value === void 0 ? void 0 : _api$optionsRef$value.id, | ||
'aria-expanded': api.listboxState.value === ListboxStates.Open ? true : undefined, | ||
'aria-labelledby': api.labelRef.value ? [api.labelRef.value.id, this.id].join(' ') : undefined, | ||
onKeyDown: this.handleKeyDown, | ||
onFocus: this.handleFocus, | ||
onBlur: this.handleBlur, | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxButton'); | ||
var id = "headlessui-listbox-button-" + useId(); | ||
var focused = vue.ref(false); | ||
function handleKeyDown(event) { | ||
switch (event.key) { | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-13 | ||
case Keys.Space: | ||
case Keys.Enter: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
api.openListbox(); | ||
vue.nextTick(function () { | ||
var _api$optionsRef$value2; | ||
(_api$optionsRef$value2 = api.optionsRef.value) === null || _api$optionsRef$value2 === void 0 ? void 0 : _api$optionsRef$value2.focus(); | ||
if (!api.value.value) api.goToOption(Focus$1.First); | ||
}); | ||
break; | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
api.openListbox(); | ||
vue.nextTick(function () { | ||
var _api$optionsRef$value3; | ||
(_api$optionsRef$value3 = api.optionsRef.value) === null || _api$optionsRef$value3 === void 0 ? void 0 : _api$optionsRef$value3.focus(); | ||
if (!api.value.value) api.goToOption(Focus$1.Last); | ||
}); | ||
break; | ||
} | ||
} | ||
function handlePointerUp(event) { | ||
if (disabled) return; | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
if (api.listboxState.value === ListboxStates.Open) { | ||
api.closeListbox(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value2; | ||
return (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.focus(); | ||
}); | ||
} else { | ||
event.preventDefault(); | ||
api.openListbox(); | ||
vue.nextTick(function () { | ||
var _api$optionsRef$value4; | ||
return (_api$optionsRef$value4 = api.optionsRef.value) === null || _api$optionsRef$value4 === void 0 ? void 0 : _api$optionsRef$value4.focus(); | ||
}); | ||
} | ||
} | ||
function handleFocus() { | ||
var _api$optionsRef$value5; | ||
if (api.listboxState.value === ListboxStates.Open) return (_api$optionsRef$value5 = api.optionsRef.value) === null || _api$optionsRef$value5 === void 0 ? void 0 : _api$optionsRef$value5.focus(); | ||
focused.value = true; | ||
} | ||
function handleBlur() { | ||
focused.value = false; | ||
} | ||
return { | ||
id: id, | ||
el: api.buttonRef, | ||
focused: focused, | ||
handleKeyDown: handleKeyDown, | ||
handlePointerUp: handlePointerUp, | ||
handleFocus: handleFocus, | ||
handleBlur: handleBlur | ||
}; | ||
} | ||
}); // --- | ||
var ListboxOptions = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxOptions', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'ul' | ||
}, | ||
"static": { | ||
type: Boolean, | ||
"default": false | ||
} | ||
}, | ||
render: function render$1() { | ||
var _api$options$value$ap, _api$labelRef$value$i, _api$labelRef$value, _api$buttonRef$value3; | ||
var api = useListboxContext('ListboxOptions'); // `static` is a reserved keyword, therefore aliasing it... | ||
var _this$$props = this.$props, | ||
isStatic = _this$$props["static"], | ||
passThroughProps = _objectWithoutPropertiesLoose(_this$$props, ["static"]); | ||
if (!isStatic && api.listboxState.value === ListboxStates.Closed) return null; | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open | ||
}; | ||
var propsWeControl = { | ||
'aria-activedescendant': api.activeOptionIndex.value === null ? undefined : (_api$options$value$ap = api.options.value[api.activeOptionIndex.value]) === null || _api$options$value$ap === void 0 ? void 0 : _api$options$value$ap.id, | ||
'aria-labelledby': (_api$labelRef$value$i = (_api$labelRef$value = api.labelRef.value) === null || _api$labelRef$value === void 0 ? void 0 : _api$labelRef$value.id) !== null && _api$labelRef$value$i !== void 0 ? _api$labelRef$value$i : (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.id, | ||
id: this.id, | ||
onKeyDown: this.handleKeyDown, | ||
role: 'listbox', | ||
tabIndex: 0, | ||
ref: 'el' | ||
}; | ||
return render({ | ||
props: _extends({}, passThroughProps, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxOptions'); | ||
var id = "headlessui-listbox-options-" + useId(); | ||
var searchDebounce = vue.ref(null); | ||
function handleKeyDown(event) { | ||
if (searchDebounce.value) clearTimeout(searchDebounce.value); | ||
switch (event.key) { | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12 | ||
// @ts-expect-error Fallthrough is expected here | ||
case Keys.Space: | ||
if (api.searchQuery.value !== '') { | ||
event.preventDefault(); | ||
return api.search(event.key); | ||
} | ||
// When in type ahead mode, fallthrough | ||
case Keys.Enter: | ||
event.preventDefault(); | ||
api.closeListbox(); | ||
if (api.activeOptionIndex.value !== null) { | ||
var dataRef = api.options.value[api.activeOptionIndex.value].dataRef; | ||
api.select(dataRef.value); | ||
} | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value4; | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
}); | ||
break; | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Next); | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Previous); | ||
case Keys.Home: | ||
case Keys.PageUp: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.First); | ||
case Keys.End: | ||
case Keys.PageDown: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Last); | ||
case Keys.Escape: | ||
event.preventDefault(); | ||
api.closeListbox(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value5; | ||
return (_api$buttonRef$value5 = api.buttonRef.value) === null || _api$buttonRef$value5 === void 0 ? void 0 : _api$buttonRef$value5.focus(); | ||
}); | ||
break; | ||
case Keys.Tab: | ||
return event.preventDefault(); | ||
default: | ||
if (event.key.length === 1) { | ||
api.search(event.key); | ||
searchDebounce.value = setTimeout(function () { | ||
return api.clearSearch(); | ||
}, 350); | ||
} | ||
break; | ||
} | ||
} | ||
return { | ||
id: id, | ||
el: api.optionsRef, | ||
handleKeyDown: handleKeyDown | ||
}; | ||
} | ||
}); | ||
var ListboxOption = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxOption', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'li' | ||
}, | ||
value: { | ||
type: [Object, String], | ||
"default": null | ||
}, | ||
disabled: { | ||
type: Boolean, | ||
"default": false | ||
}, | ||
"class": { | ||
type: [String, Function], | ||
required: false | ||
}, | ||
className: { | ||
type: [String, Function], | ||
required: false | ||
} | ||
}, | ||
setup: function setup(props, _ref2) { | ||
var slots = _ref2.slots, | ||
attrs = _ref2.attrs; | ||
var api = useListboxContext('ListboxOption'); | ||
var id = "headlessui-listbox-option-" + useId(); | ||
var disabled = props.disabled, | ||
defaultClass = props["class"], | ||
_props$className = props.className, | ||
className = _props$className === void 0 ? defaultClass : _props$className, | ||
value = props.value; | ||
var active = vue.computed(function () { | ||
return api.activeOptionIndex.value !== null ? api.options.value[api.activeOptionIndex.value].id === id : false; | ||
}); | ||
var selected = vue.computed(function () { | ||
return vue.toRaw(api.value.value) === vue.toRaw(value); | ||
}); | ||
var dataRef = vue.ref({ | ||
disabled: disabled, | ||
value: value, | ||
textValue: '' | ||
}); | ||
vue.onMounted(function () { | ||
var _document$getElementB, _document$getElementB2; | ||
var textValue = (_document$getElementB = document.getElementById(id)) === null || _document$getElementB === void 0 ? void 0 : (_document$getElementB2 = _document$getElementB.textContent) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.toLowerCase().trim(); | ||
if (textValue !== undefined) dataRef.value.textValue = textValue; | ||
}); | ||
vue.onMounted(function () { | ||
return api.registerOption(id, dataRef); | ||
}); | ||
vue.onUnmounted(function () { | ||
return api.unregisterOption(id); | ||
}); | ||
vue.onMounted(function () { | ||
var _document$getElementB3, _document$getElementB4; | ||
if (!selected.value) return; | ||
api.goToOption(Focus$1.Specific, id); | ||
(_document$getElementB3 = document.getElementById(id)) === null || _document$getElementB3 === void 0 ? void 0 : (_document$getElementB4 = _document$getElementB3.focus) === null || _document$getElementB4 === void 0 ? void 0 : _document$getElementB4.call(_document$getElementB3); | ||
}); | ||
vue.watchEffect(function () { | ||
if (!active.value) return; | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value4; | ||
var _document$getElementB5, _document$getElementB6; | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
return (_document$getElementB5 = document.getElementById(id)) === null || _document$getElementB5 === void 0 ? void 0 : (_document$getElementB6 = _document$getElementB5.scrollIntoView) === null || _document$getElementB6 === void 0 ? void 0 : _document$getElementB6.call(_document$getElementB5, { | ||
block: 'nearest' | ||
}); | ||
}); | ||
} | ||
}); | ||
function handleClick(event) { | ||
if (disabled) return event.preventDefault(); | ||
if (props.onClick) return props.onClick(event); | ||
api.select(value); | ||
api.closeListbox(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value6; | ||
return (_api$buttonRef$value6 = api.buttonRef.value) === null || _api$buttonRef$value6 === void 0 ? void 0 : _api$buttonRef$value6.focus(); | ||
}); | ||
} | ||
function handleFocus() { | ||
if (disabled) return api.goToOption(Focus$1.Nothing); | ||
api.goToOption(Focus$1.Specific, id); | ||
} | ||
function handlePointerMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToOption(Focus$1.Specific, id); | ||
} | ||
function handlePointerLeave() { | ||
if (disabled) return; | ||
if (!active.value) return; | ||
api.goToOption(Focus$1.Nothing); | ||
} | ||
return function () { | ||
var slot = { | ||
active: active.value, | ||
selected: selected.value, | ||
disabled: disabled | ||
@@ -628,13 +1245,11 @@ }; | ||
id: id, | ||
role: 'menuitem', | ||
role: 'option', | ||
tabIndex: -1, | ||
"class": resolvePropValue(className, slot), | ||
disabled: disabled === true ? disabled : undefined, | ||
'aria-disabled': disabled === true ? disabled : undefined, | ||
"class": resolvePropValue$1(className, slot), | ||
'aria-disabled': disabled === true ? true : undefined, | ||
'aria-selected': selected.value === true ? selected.value : undefined, | ||
onClick: handleClick, | ||
onFocus: handleFocus, | ||
onMouseMove: handleMouseMove, | ||
onPointerEnter: handlePointerEnter, | ||
onPointerLeave: handlePointerLeave, | ||
onPointerUp: handlePointerUp | ||
onPointerMove: handlePointerMove, | ||
onPointerLeave: handlePointerLeave | ||
}; | ||
@@ -649,5 +1264,5 @@ return render({ | ||
} | ||
}); | ||
}); // --- | ||
function resolvePropValue(property, bag) { | ||
function resolvePropValue$1(property, bag) { | ||
if (property === undefined) return undefined; | ||
@@ -658,2 +1273,172 @@ if (typeof property === 'function') return property(bag); | ||
var GroupContext = /*#__PURE__*/Symbol('GroupContext'); | ||
function useGroupContext(component) { | ||
var context = vue.inject(GroupContext, null); | ||
if (context === null) { | ||
var err = new Error("<" + component + " /> is missing a parent <SwitchGroup /> component."); | ||
if (Error.captureStackTrace) Error.captureStackTrace(err, useGroupContext); | ||
throw err; | ||
} | ||
return context; | ||
} // --- | ||
var SwitchGroup = /*#__PURE__*/vue.defineComponent({ | ||
name: 'SwitchGroup', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'template' | ||
} | ||
}, | ||
setup: function setup(props, _ref) { | ||
var slots = _ref.slots, | ||
attrs = _ref.attrs; | ||
var switchRef = vue.ref(null); | ||
var labelRef = vue.ref(null); | ||
var api = { | ||
switchRef: switchRef, | ||
labelRef: labelRef | ||
}; | ||
vue.provide(GroupContext, api); | ||
return function () { | ||
return render({ | ||
props: props, | ||
slot: {}, | ||
slots: slots, | ||
attrs: attrs | ||
}); | ||
}; | ||
} | ||
}); // --- | ||
var Switch = /*#__PURE__*/vue.defineComponent({ | ||
name: 'Switch', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'button' | ||
}, | ||
modelValue: { | ||
type: [Object, Boolean], | ||
"default": null | ||
}, | ||
"class": { | ||
type: [String, Function], | ||
required: false | ||
}, | ||
className: { | ||
type: [String, Function], | ||
required: false | ||
} | ||
}, | ||
render: function render$1() { | ||
var api = vue.inject(GroupContext, null); | ||
var _this$$props = this.$props, | ||
defaultClass = _this$$props["class"], | ||
_this$$props$classNam = _this$$props.className, | ||
className = _this$$props$classNam === void 0 ? defaultClass : _this$$props$classNam; | ||
var labelledby = vue.computed(function () { | ||
var _api$labelRef$value; | ||
return api === null || api === void 0 ? void 0 : (_api$labelRef$value = api.labelRef.value) === null || _api$labelRef$value === void 0 ? void 0 : _api$labelRef$value.id; | ||
}); | ||
var slot = { | ||
checked: this.$props.modelValue | ||
}; | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: api === null ? undefined : api.switchRef, | ||
role: 'switch', | ||
tabIndex: 0, | ||
"class": resolvePropValue$2(className, slot), | ||
'aria-checked': this.$props.modelValue, | ||
'aria-labelledby': labelledby.value, | ||
onClick: this.handleClick, | ||
onKeyUp: this.handleKeyUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup(props, _ref2) { | ||
var emit = _ref2.emit; | ||
var api = vue.inject(GroupContext, null); | ||
var id = "headlessui-switch-" + useId(); | ||
function toggle() { | ||
emit('update:modelValue', !props.modelValue); | ||
} | ||
return { | ||
id: id, | ||
el: api === null || api === void 0 ? void 0 : api.switchRef, | ||
handleClick: function handleClick(event) { | ||
event.preventDefault(); | ||
toggle(); | ||
}, | ||
handleKeyUp: function handleKeyUp(event) { | ||
if (event.key === Keys.Space) { | ||
event.preventDefault(); | ||
toggle(); | ||
} | ||
} | ||
}; | ||
} | ||
}); // --- | ||
var SwitchLabel = /*#__PURE__*/vue.defineComponent({ | ||
name: 'SwitchLabel', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'label' | ||
} | ||
}, | ||
render: function render$1() { | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: 'el', | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: {}, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useGroupContext('SwitchLabel'); | ||
var id = "headlessui-switch-label-" + useId(); | ||
return { | ||
id: id, | ||
el: api.labelRef, | ||
handlePointerUp: function handlePointerUp() { | ||
var _api$switchRef$value, _api$switchRef$value2; | ||
(_api$switchRef$value = api.switchRef.value) === null || _api$switchRef$value === void 0 ? void 0 : _api$switchRef$value.click(); | ||
(_api$switchRef$value2 = api.switchRef.value) === null || _api$switchRef$value2 === void 0 ? void 0 : _api$switchRef$value2.focus(); | ||
} | ||
}; | ||
} | ||
}); // --- | ||
function resolvePropValue$2(property, bag) { | ||
if (property === undefined) return undefined; | ||
if (typeof property === 'function') return property(bag); | ||
return property; | ||
} | ||
exports.Listbox = Listbox; | ||
exports.ListboxButton = ListboxButton; | ||
exports.ListboxLabel = ListboxLabel; | ||
exports.ListboxOption = ListboxOption; | ||
exports.ListboxOptions = ListboxOptions; | ||
exports.Menu = Menu; | ||
@@ -663,2 +1448,5 @@ exports.MenuButton = MenuButton; | ||
exports.MenuItems = MenuItems; | ||
exports.Switch = Switch; | ||
exports.SwitchGroup = SwitchGroup; | ||
exports.SwitchLabel = SwitchLabel; | ||
//# sourceMappingURL=headlessui.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue");function t(){return(t=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e}).apply(this,arguments)}function n(e,t){if(null==e)return{};var n,o,r={},u=Object.keys(e);for(o=0;o<u.length;o++)t.indexOf(n=u[o])>=0||(r[n]=e[n]);return r}function o(e,t){if(e in t){for(var n=t[e],r=arguments.length,u=new Array(r>2?r-2:0),a=2;a<r;a++)u[a-2]=arguments[a];return"function"==typeof n?n.apply(void 0,u):n}var i=new Error('Tried to handle "'+e+'" but there is no handler defined. Only defined handlers are: '+Object.keys(t).map((function(e){return'"'+e+'"'})).join(", ")+".");throw Error.captureStackTrace&&Error.captureStackTrace(i,o),i}function r(t){var o,r=t.props,u=t.attrs,a=t.slots,i=t.slot,l=r.as,s=n(r,["as"]),c=null===(o=a.default)||void 0===o?void 0:o.call(a,i);if("template"===l){if(Object.keys(s).length>0||"class"in u){var d=null!=c?c:[],v=d[0];if(d.slice(1).length>0)throw new Error('You should only render 1 child or use the `as="..."` prop');return e.cloneVNode(v,s)}return c}return e.h(l,s,c)}var u,a,i,l=0;function s(){return++l}!function(e){e[e.Open=0]="Open",e[e.Closed=1]="Closed"}(u||(u={})),function(e){e.Space=" ",e.Enter="Enter",e.Escape="Escape",e.Backspace="Backspace",e.ArrowUp="ArrowUp",e.ArrowDown="ArrowDown",e.Home="Home",e.End="End",e.PageUp="PageUp",e.PageDown="PageDown",e.Tab="Tab"}(a||(a={})),function(e){e[e.FirstItem=0]="FirstItem",e[e.PreviousItem=1]="PreviousItem",e[e.NextItem=2]="NextItem",e[e.LastItem=3]="LastItem",e[e.SpecificItem=4]="SpecificItem",e[e.Nothing=5]="Nothing"}(i||(i={}));var c=Symbol("MenuContext");function d(t){var n=e.inject(c);if(void 0===n){var o=new Error("<"+t+" /> is missing a parent <Menu /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,d),o}return n}var v=e.defineComponent({props:{as:{type:[Object,String],default:"template"}},setup:function(t,n){var a=n.slots,l=n.attrs,s=e.ref(u.Closed),d=e.ref(null),v=e.ref(null),f=e.ref([]),p=e.ref(""),m=e.ref(null),I={menuState:s,buttonRef:d,itemsRef:v,items:f,searchQuery:p,activeItemIndex:m,toggleMenu:function(){var e;s.value=o(s.value,((e={})[u.Closed]=u.Open,e[u.Open]=u.Closed,e))},closeMenu:function(){return s.value=u.Closed},openMenu:function(){return s.value=u.Open},goToItem:function(e,t){var n=function(e,t){var n,r;if(f.value.length<=0)return null;var u=null!==(n=m.value)&&void 0!==n?n:-1,a=o(e,((r={})[i.FirstItem]=function(){return f.value.findIndex((function(e){return!e.dataRef.disabled}))},r[i.PreviousItem]=function(){var e=f.value.slice().reverse().findIndex((function(e,t,n){return!(-1!==u&&n.length-t-1>=u||e.dataRef.disabled)}));return-1===e?e:f.value.length-1-e},r[i.NextItem]=function(){return f.value.findIndex((function(e,t){return!(t<=u||e.dataRef.disabled)}))},r[i.LastItem]=function(){var e=f.value.slice().reverse().findIndex((function(e){return!e.dataRef.disabled}));return-1===e?e:f.value.length-1-e},r[i.SpecificItem]=function(){return f.value.findIndex((function(e){return e.id===t}))},r[i.Nothing]=function(){return null},r));return-1===a?m.value:a}(e,t);""===p.value&&m.value===n||(p.value="",m.value=n)},search:function(e){p.value+=e;var t=f.value.findIndex((function(e){return e.dataRef.textValue.startsWith(p.value)&&!e.dataRef.disabled}));-1!==t&&t!==m.value&&(m.value=t)},clearSearch:function(){p.value=""},registerItem:function(e,t){f.value.push({id:e,dataRef:t})},unregisterItem:function(e){var t=f.value.slice(),n=null!==m.value?t[m.value]:null,o=t.findIndex((function(t){return t.id===e}));-1!==o&&t.splice(o,1),f.value=t,m.value=o===m.value||null===n?null:t.indexOf(n)}};return e.onMounted((function(){function t(t){var n;t.defaultPrevented||s.value===u.Open&&((null===(n=v.value)||void 0===n?void 0:n.contains(t.target))||(I.closeMenu(),e.nextTick((function(){var e;return null===(e=d.value)||void 0===e?void 0:e.focus()}))))}window.addEventListener("pointerdown",t),e.onUnmounted((function(){return window.removeEventListener("pointerdown",t)}))})),e.provide(c,I),function(){return r({props:t,slot:{open:s.value===u.Open},slots:a,attrs:l})}}}),f=e.defineComponent({props:{as:{type:[Object,String],default:"button"}},render:function(){var e,n=d("MenuButton"),o={open:n.menuState.value===u.Open},a={ref:"el",id:this.id,type:"button","aria-haspopup":!0,"aria-controls":null===(e=n.itemsRef.value)||void 0===e?void 0:e.id,"aria-expanded":n.menuState.value===u.Open||void 0,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onPointerUp:this.handlePointerUp,onPointerDown:this.handlePointerDown};return r({props:t({},this.$props,a),slot:o,attrs:this.$attrs,slots:this.$slots})},setup:function(){var t=d("MenuButton");return{id:"headlessui-menu-button-"+s(),el:t.buttonRef,handleKeyDown:function(n){switch(n.key){case a.Space:case a.Enter:case a.ArrowDown:n.preventDefault(),t.openMenu(),e.nextTick((function(){var e;null===(e=t.itemsRef.value)||void 0===e||e.focus(),t.goToItem(i.FirstItem)}));break;case a.ArrowUp:n.preventDefault(),t.openMenu(),e.nextTick((function(){var e;null===(e=t.itemsRef.value)||void 0===e||e.focus(),t.goToItem(i.LastItem)}))}},handlePointerDown:function(e){e.preventDefault()},handlePointerUp:function(){t.toggleMenu(),e.nextTick((function(){var e;return null===(e=t.itemsRef.value)||void 0===e?void 0:e.focus()}))},handleFocus:function(){var e;t.menuState.value===u.Open&&(null===(e=t.itemsRef.value)||void 0===e||e.focus())}}}}),p=e.defineComponent({props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1}},render:function(){var e,o,a=d("MenuItems"),i=this.$props,l=i.static,s=n(i,["static"]);if(!l&&a.menuState.value===u.Closed)return null;var c={open:a.menuState.value===u.Open};return r({props:t({},s,{"aria-activedescendant":null===a.activeItemIndex.value||null===(e=a.items.value[a.activeItemIndex.value])||void 0===e?void 0:e.id,"aria-labelledby":null===(o=a.buttonRef.value)||void 0===o?void 0:o.id,id:this.id,onKeyDown:this.handleKeyDown,role:"menu",tabIndex:0,ref:"el"}),slot:c,attrs:this.$attrs,slots:this.$slots})},setup:function(){var t=d("MenuItems"),n="headlessui-menu-items-"+s(),o=e.ref(null);return{id:n,el:t.itemsRef,handleKeyDown:function(n){switch(o.value&&clearTimeout(o.value),n.key){case a.Enter:var r;t.closeMenu(),null!==t.activeItemIndex.value&&(null===(r=document.getElementById(t.items.value[t.activeItemIndex.value].id))||void 0===r||r.click(),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()})));break;case a.ArrowDown:return t.goToItem(i.NextItem);case a.ArrowUp:return t.goToItem(i.PreviousItem);case a.Home:case a.PageUp:return t.goToItem(i.FirstItem);case a.End:case a.PageDown:return t.goToItem(i.LastItem);case a.Escape:t.closeMenu(),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()}));break;case a.Tab:return n.preventDefault();default:1===n.key.length&&(t.search(n.key),o.value=setTimeout((function(){return t.clearSearch()}),350))}}}}}),m=e.defineComponent({props:{as:{type:[Object,String],default:"template"},disabled:{type:Boolean,default:!1},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1},onClick:{type:Function,required:!1}},setup:function(n,o){var u=o.slots,a=o.attrs,l=d("MenuItem"),c="headlessui-menu-item-"+s(),v=n.disabled,f=n.className,p=void 0===f?n.class:f,m=e.computed((function(){return null!==l.activeItemIndex.value&&l.items.value[l.activeItemIndex.value].id===c})),h=e.ref({disabled:v,textValue:""});function g(){v||l.goToItem(i.SpecificItem,c)}function b(){if(v)return l.goToItem(i.Nothing);l.goToItem(i.SpecificItem,c)}function w(){v||l.goToItem(i.Nothing)}function x(){v||m.value||l.goToItem(i.SpecificItem,c)}function y(t){v||(t.preventDefault(),l.closeMenu(),e.nextTick((function(){var e;return null===(e=l.buttonRef.value)||void 0===e?void 0:e.focus()})))}function T(e){return v?e.preventDefault():n.onClick?n.onClick(e):void 0}return e.onMounted((function(){var e,t,n=null===(e=document.getElementById(c))||void 0===e||null===(t=e.textContent)||void 0===t?void 0:t.toLowerCase().trim();void 0!==n&&(h.value.textValue=n)})),e.onMounted((function(){return l.registerItem(c,h)})),e.onUnmounted((function(){return l.unregisterItem(c)})),function(){var e={active:m.value,disabled:v},o={id:c,role:"menuitem",tabIndex:-1,class:I(p,e),disabled:!0===v?v:void 0,"aria-disabled":!0===v?v:void 0,onClick:T,onFocus:b,onMouseMove:x,onPointerEnter:g,onPointerLeave:w,onPointerUp:y};return r({props:t({},n,o),slot:e,attrs:a,slots:u})}}});function I(e,t){if(void 0!==e)return"function"==typeof e?e(t):e}exports.Menu=v,exports.MenuButton=f,exports.MenuItem=m,exports.MenuItems=p; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue");function t(){return(t=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e}).apply(this,arguments)}function n(e,t){if(null==e)return{};var n,o,u={},i=Object.keys(e);for(o=0;o<i.length;o++)t.indexOf(n=i[o])>=0||(u[n]=e[n]);return u}function o(e,t){if(e in t){for(var n=t[e],u=arguments.length,i=new Array(u>2?u-2:0),r=2;r<u;r++)i[r-2]=arguments[r];return"function"==typeof n?n.apply(void 0,i):n}var a=new Error('Tried to handle "'+e+'" but there is no handler defined. Only defined handlers are: '+Object.keys(t).map((function(e){return'"'+e+'"'})).join(", ")+".");throw Error.captureStackTrace&&Error.captureStackTrace(a,o),a}function u(t){var o,u=t.props,i=t.attrs,r=t.slots,a=t.slot,l=u.as,s=n(u,["as"]),c=null===(o=r.default)||void 0===o?void 0:o.call(r,a);if("template"===l){if(Object.keys(s).length>0||"class"in i){var d=null!=c?c:[],v=d[0];if(d.slice(1).length>0)throw new Error('You should only render 1 child or use the `as="..."` prop');return e.cloneVNode(v,s)}return c}return e.h(l,s,c)}var i,r,a,l=0;function s(){return++l}!function(e){e.Space=" ",e.Enter="Enter",e.Escape="Escape",e.Backspace="Backspace",e.ArrowUp="ArrowUp",e.ArrowDown="ArrowDown",e.Home="Home",e.End="End",e.PageUp="PageUp",e.PageDown="PageDown",e.Tab="Tab"}(i||(i={})),function(e){e[e.Open=0]="Open",e[e.Closed=1]="Closed"}(r||(r={})),function(e){e[e.FirstItem=0]="FirstItem",e[e.PreviousItem=1]="PreviousItem",e[e.NextItem=2]="NextItem",e[e.LastItem=3]="LastItem",e[e.SpecificItem=4]="SpecificItem",e[e.Nothing=5]="Nothing"}(a||(a={}));var c=Symbol("MenuContext");function d(t){var n=e.inject(c);if(void 0===n){var o=new Error("<"+t+" /> is missing a parent <Menu /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,d),o}return n}var v,f,p=e.defineComponent({props:{as:{type:[Object,String],default:"template"}},setup:function(t,n){var i=n.slots,l=n.attrs,s=e.ref(r.Closed),d=e.ref(null),v=e.ref(null),f=e.ref([]),p=e.ref(""),h=e.ref(null),m={menuState:s,buttonRef:d,itemsRef:v,items:f,searchQuery:p,activeItemIndex:h,closeMenu:function(){return s.value=r.Closed},openMenu:function(){return s.value=r.Open},goToItem:function(e,t){var n=function(e,t){var n,u;if(f.value.length<=0)return null;var i=null!==(n=h.value)&&void 0!==n?n:-1,r=o(e,((u={})[a.FirstItem]=function(){return f.value.findIndex((function(e){return!e.dataRef.disabled}))},u[a.PreviousItem]=function(){var e=f.value.slice().reverse().findIndex((function(e,t,n){return!(-1!==i&&n.length-t-1>=i||e.dataRef.disabled)}));return-1===e?e:f.value.length-1-e},u[a.NextItem]=function(){return f.value.findIndex((function(e,t){return!(t<=i||e.dataRef.disabled)}))},u[a.LastItem]=function(){var e=f.value.slice().reverse().findIndex((function(e){return!e.dataRef.disabled}));return-1===e?e:f.value.length-1-e},u[a.SpecificItem]=function(){return f.value.findIndex((function(e){return e.id===t}))},u[a.Nothing]=function(){return null},u));return-1===r?h.value:r}(e,t);""===p.value&&h.value===n||(p.value="",h.value=n)},search:function(e){p.value+=e;var t=f.value.findIndex((function(e){return e.dataRef.textValue.startsWith(p.value)&&!e.dataRef.disabled}));-1!==t&&t!==h.value&&(h.value=t)},clearSearch:function(){p.value=""},registerItem:function(e,t){f.value.push({id:e,dataRef:t})},unregisterItem:function(e){var t=f.value.slice(),n=null!==h.value?t[h.value]:null,o=t.findIndex((function(t){return t.id===e}));-1!==o&&t.splice(o,1),f.value=t,h.value=o===h.value||null===n?null:t.indexOf(n)}};return e.onMounted((function(){function t(t){var n,o;s.value===r.Open&&((null===(n=d.value)||void 0===n?void 0:n.contains(t.target))||((null===(o=v.value)||void 0===o?void 0:o.contains(t.target))||m.closeMenu(),t.defaultPrevented||e.nextTick((function(){var e;return null===(e=d.value)||void 0===e?void 0:e.focus()}))))}window.addEventListener("click",t),e.onUnmounted((function(){return window.removeEventListener("click",t)}))})),e.provide(c,m),function(){return u({props:t,slot:{open:s.value===r.Open},slots:i,attrs:l})}}}),h=e.defineComponent({props:{as:{type:[Object,String],default:"button"}},render:function(){var e,n=d("MenuButton"),o={open:n.menuState.value===r.Open},i={ref:"el",id:this.id,type:"button","aria-haspopup":!0,"aria-controls":null===(e=n.itemsRef.value)||void 0===e?void 0:e.id,"aria-expanded":n.menuState.value===r.Open||void 0,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onPointerUp:this.handlePointerUp};return u({props:t({},this.$props,i),slot:o,attrs:this.$attrs,slots:this.$slots})},setup:function(){var t=d("MenuButton");return{id:"headlessui-menu-button-"+s(),el:t.buttonRef,handleKeyDown:function(n){switch(n.key){case i.Space:case i.Enter:case i.ArrowDown:n.preventDefault(),t.openMenu(),e.nextTick((function(){var e;null===(e=t.itemsRef.value)||void 0===e||e.focus(),t.goToItem(a.FirstItem)}));break;case i.ArrowUp:n.preventDefault(),t.openMenu(),e.nextTick((function(){var e;null===(e=t.itemsRef.value)||void 0===e||e.focus(),t.goToItem(a.LastItem)}))}},handlePointerUp:function(n){t.menuState.value===r.Open?(t.closeMenu(),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()}))):(n.preventDefault(),t.openMenu(),e.nextTick((function(){var e;return null===(e=t.itemsRef.value)||void 0===e?void 0:e.focus()})))},handleFocus:function(){var e;t.menuState.value===r.Open&&(null===(e=t.itemsRef.value)||void 0===e||e.focus())}}}}),m=e.defineComponent({props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1}},render:function(){var e,o,i=d("MenuItems"),a=this.$props,l=a.static,s=n(a,["static"]);if(!l&&i.menuState.value===r.Closed)return null;var c={open:i.menuState.value===r.Open};return u({props:t({},s,{"aria-activedescendant":null===i.activeItemIndex.value||null===(e=i.items.value[i.activeItemIndex.value])||void 0===e?void 0:e.id,"aria-labelledby":null===(o=i.buttonRef.value)||void 0===o?void 0:o.id,id:this.id,onKeyDown:this.handleKeyDown,role:"menu",tabIndex:0,ref:"el"}),slot:c,attrs:this.$attrs,slots:this.$slots})},setup:function(){var t=d("MenuItems"),n="headlessui-menu-items-"+s(),o=e.ref(null);return{id:n,el:t.itemsRef,handleKeyDown:function(n){switch(o.value&&clearTimeout(o.value),n.key){case i.Space:if(""!==t.searchQuery.value)return n.preventDefault(),t.search(n.key);case i.Enter:var u;n.preventDefault(),t.closeMenu(),null!==t.activeItemIndex.value&&(null===(u=document.getElementById(t.items.value[t.activeItemIndex.value].id))||void 0===u||u.click()),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()}));break;case i.ArrowDown:return n.preventDefault(),t.goToItem(a.NextItem);case i.ArrowUp:return n.preventDefault(),t.goToItem(a.PreviousItem);case i.Home:case i.PageUp:return n.preventDefault(),t.goToItem(a.FirstItem);case i.End:case i.PageDown:return n.preventDefault(),t.goToItem(a.LastItem);case i.Escape:n.preventDefault(),t.closeMenu(),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()}));break;case i.Tab:return n.preventDefault();default:1===n.key.length&&(t.search(n.key),o.value=setTimeout((function(){return t.clearSearch()}),350))}}}}}),b=e.defineComponent({props:{as:{type:[Object,String],default:"template"},disabled:{type:Boolean,default:!1},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1}},setup:function(n,o){var i=o.slots,r=o.attrs,l=d("MenuItem"),c="headlessui-menu-item-"+s(),v=n.disabled,f=n.className,p=void 0===f?n.class:f,h=e.computed((function(){return null!==l.activeItemIndex.value&&l.items.value[l.activeItemIndex.value].id===c})),m=e.ref({disabled:v,textValue:""});function b(t){if(v)return t.preventDefault();l.closeMenu(),e.nextTick((function(){var e;return null===(e=l.buttonRef.value)||void 0===e?void 0:e.focus()}))}function g(){if(v)return l.goToItem(a.Nothing);l.goToItem(a.SpecificItem,c)}function I(){v||h.value||l.goToItem(a.SpecificItem,c)}function y(){v||h.value&&l.goToItem(a.Nothing)}return e.onMounted((function(){var e,t,n=null===(e=document.getElementById(c))||void 0===e||null===(t=e.textContent)||void 0===t?void 0:t.toLowerCase().trim();void 0!==n&&(m.value.textValue=n)})),e.onMounted((function(){return l.registerItem(c,m)})),e.onUnmounted((function(){return l.unregisterItem(c)})),function(){var e={active:h.value,disabled:v},o={id:c,role:"menuitem",tabIndex:-1,class:x(p,e),"aria-disabled":!0===v||void 0,onClick:b,onFocus:g,onPointerMove:I,onPointerLeave:y};return u({props:t({},n,o),slot:e,attrs:r,slots:i})}}});function x(e,t){if(void 0!==e)return"function"==typeof e?e(t):e}!function(e){e[e.Open=0]="Open",e[e.Closed=1]="Closed"}(v||(v={})),function(e){e[e.First=0]="First",e[e.Previous=1]="Previous",e[e.Next=2]="Next",e[e.Last=3]="Last",e[e.Specific=4]="Specific",e[e.Nothing=5]="Nothing"}(f||(f={}));var g=Symbol("ListboxContext");function I(t){var n=e.inject(g);if(void 0===n){var o=new Error("<"+t+" /> is missing a parent <Listbox /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,I),o}return n}var y=e.defineComponent({name:"Listbox",props:{as:{type:[Object,String],default:"template"},modelValue:{type:[Object,String],default:null}},setup:function(t,i){var r=i.slots,a=i.attrs,l=i.emit,s=n(t,["modelValue"]),c=e.ref(v.Closed),d=e.ref(null),p=e.ref(null),h=e.ref(null),m=e.ref([]),b=e.ref(""),x=e.ref(null),I=e.computed((function(){return t.modelValue})),y={listboxState:c,value:I,labelRef:d,buttonRef:p,optionsRef:h,options:m,searchQuery:b,activeOptionIndex:x,closeListbox:function(){return c.value=v.Closed},openListbox:function(){return c.value=v.Open},goToOption:function(e,t){var n=function(e,t){var n,u;if(m.value.length<=0)return null;var i=null!==(n=x.value)&&void 0!==n?n:-1,r=o(e,((u={})[f.First]=function(){return m.value.findIndex((function(e){return!e.dataRef.disabled}))},u[f.Previous]=function(){var e=m.value.slice().reverse().findIndex((function(e,t,n){return!(-1!==i&&n.length-t-1>=i||e.dataRef.disabled)}));return-1===e?e:m.value.length-1-e},u[f.Next]=function(){return m.value.findIndex((function(e,t){return!(t<=i||e.dataRef.disabled)}))},u[f.Last]=function(){var e=m.value.slice().reverse().findIndex((function(e){return!e.dataRef.disabled}));return-1===e?e:m.value.length-1-e},u[f.Specific]=function(){return m.value.findIndex((function(e){return e.id===t}))},u[f.Nothing]=function(){return null},u));return-1===r?x.value:r}(e,t);""===b.value&&x.value===n||(b.value="",x.value=n)},search:function(e){b.value+=e;var t=m.value.findIndex((function(e){return!e.dataRef.disabled&&e.dataRef.textValue.startsWith(b.value)}));-1!==t&&t!==x.value&&(x.value=t)},clearSearch:function(){b.value=""},registerOption:function(e,t){m.value.push({id:e,dataRef:t})},unregisterOption:function(e){var t=m.value.slice(),n=null!==x.value?t[x.value]:null,o=t.findIndex((function(t){return t.id===e}));-1!==o&&t.splice(o,1),m.value=t,x.value=o===x.value||null===n?null:t.indexOf(n)},select:function(e){l("update:modelValue",e)}};return e.onMounted((function(){function t(t){var n,o;c.value===v.Open&&((null===(n=p.value)||void 0===n?void 0:n.contains(t.target))||((null===(o=h.value)||void 0===o?void 0:o.contains(t.target))||y.closeListbox(),t.defaultPrevented||e.nextTick((function(){var e;return null===(e=p.value)||void 0===e?void 0:e.focus()}))))}window.addEventListener("click",t),e.onUnmounted((function(){return window.removeEventListener("click",t)}))})),e.provide(g,y),function(){return u({props:s,slot:{open:c.value===v.Open},slots:r,attrs:a})}}}),w=e.defineComponent({name:"ListboxLabel",props:{as:{type:[Object,String],default:"label"}},render:function(){var e={open:I("ListboxLabel").listboxState.value===v.Open};return u({props:t({},this.$props,{id:this.id,ref:"el",onPointerUp:this.handlePointerUp}),slot:e,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=I("ListboxLabel");return{id:"headlessui-listbox-label-"+s(),el:e.labelRef,handlePointerUp:function(){var t;null===(t=e.buttonRef.value)||void 0===t||t.focus()}}}}),O=e.defineComponent({name:"ListboxButton",props:{as:{type:[Object,String],default:"button"}},render:function(){var e,n=I("ListboxButton"),o={open:n.listboxState.value===v.Open,focused:this.focused},i={ref:"el",id:this.id,type:"button","aria-haspopup":!0,"aria-controls":null===(e=n.optionsRef.value)||void 0===e?void 0:e.id,"aria-expanded":n.listboxState.value===v.Open||void 0,"aria-labelledby":n.labelRef.value?[n.labelRef.value.id,this.id].join(" "):void 0,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onBlur:this.handleBlur,onPointerUp:this.handlePointerUp};return u({props:t({},this.$props,i),slot:o,attrs:this.$attrs,slots:this.$slots})},setup:function(){var t=I("ListboxButton"),n="headlessui-listbox-button-"+s(),o=e.ref(!1);return{id:n,el:t.buttonRef,focused:o,handleKeyDown:function(n){switch(n.key){case i.Space:case i.Enter:case i.ArrowDown:n.preventDefault(),t.openListbox(),e.nextTick((function(){var e;null===(e=t.optionsRef.value)||void 0===e||e.focus(),t.value.value||t.goToOption(f.First)}));break;case i.ArrowUp:n.preventDefault(),t.openListbox(),e.nextTick((function(){var e;null===(e=t.optionsRef.value)||void 0===e||e.focus(),t.value.value||t.goToOption(f.Last)}))}},handlePointerUp:function(n){t.listboxState.value===v.Open?(t.closeListbox(),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()}))):(n.preventDefault(),t.openListbox(),e.nextTick((function(){var e;return null===(e=t.optionsRef.value)||void 0===e?void 0:e.focus()})))},handleFocus:function(){var e;if(t.listboxState.value===v.Open)return null===(e=t.optionsRef.value)||void 0===e?void 0:e.focus();o.value=!0},handleBlur:function(){o.value=!1}}}}),S=e.defineComponent({name:"ListboxOptions",props:{as:{type:[Object,String],default:"ul"},static:{type:Boolean,default:!1}},render:function(){var e,o,i,r,a=I("ListboxOptions"),l=this.$props,s=l.static,c=n(l,["static"]);if(!s&&a.listboxState.value===v.Closed)return null;var d={open:a.listboxState.value===v.Open};return u({props:t({},c,{"aria-activedescendant":null===a.activeOptionIndex.value||null===(e=a.options.value[a.activeOptionIndex.value])||void 0===e?void 0:e.id,"aria-labelledby":null!==(o=null===(i=a.labelRef.value)||void 0===i?void 0:i.id)&&void 0!==o?o:null===(r=a.buttonRef.value)||void 0===r?void 0:r.id,id:this.id,onKeyDown:this.handleKeyDown,role:"listbox",tabIndex:0,ref:"el"}),slot:d,attrs:this.$attrs,slots:this.$slots})},setup:function(){var t=I("ListboxOptions"),n="headlessui-listbox-options-"+s(),o=e.ref(null);return{id:n,el:t.optionsRef,handleKeyDown:function(n){switch(o.value&&clearTimeout(o.value),n.key){case i.Space:if(""!==t.searchQuery.value)return n.preventDefault(),t.search(n.key);case i.Enter:n.preventDefault(),t.closeListbox(),null!==t.activeOptionIndex.value&&t.select(t.options.value[t.activeOptionIndex.value].dataRef.value),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()}));break;case i.ArrowDown:return n.preventDefault(),t.goToOption(f.Next);case i.ArrowUp:return n.preventDefault(),t.goToOption(f.Previous);case i.Home:case i.PageUp:return n.preventDefault(),t.goToOption(f.First);case i.End:case i.PageDown:return n.preventDefault(),t.goToOption(f.Last);case i.Escape:n.preventDefault(),t.closeListbox(),e.nextTick((function(){var e;return null===(e=t.buttonRef.value)||void 0===e?void 0:e.focus()}));break;case i.Tab:return n.preventDefault();default:1===n.key.length&&(t.search(n.key),o.value=setTimeout((function(){return t.clearSearch()}),350))}}}}}),k=e.defineComponent({name:"ListboxOption",props:{as:{type:[Object,String],default:"li"},value:{type:[Object,String],default:null},disabled:{type:Boolean,default:!1},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1}},setup:function(n,o){var i=o.slots,r=o.attrs,a=I("ListboxOption"),l="headlessui-listbox-option-"+s(),c=n.disabled,d=n.className,v=void 0===d?n.class:d,p=n.value,h=e.computed((function(){return null!==a.activeOptionIndex.value&&a.options.value[a.activeOptionIndex.value].id===l})),m=e.computed((function(){return e.toRaw(a.value.value)===e.toRaw(p)})),b=e.ref({disabled:c,value:p,textValue:""});function x(t){if(c)return t.preventDefault();a.select(p),a.closeListbox(),e.nextTick((function(){var e;return null===(e=a.buttonRef.value)||void 0===e?void 0:e.focus()}))}function g(){if(c)return a.goToOption(f.Nothing);a.goToOption(f.Specific,l)}function y(){c||h.value||a.goToOption(f.Specific,l)}function w(){c||h.value&&a.goToOption(f.Nothing)}return e.onMounted((function(){var e,t,n=null===(e=document.getElementById(l))||void 0===e||null===(t=e.textContent)||void 0===t?void 0:t.toLowerCase().trim();void 0!==n&&(b.value.textValue=n)})),e.onMounted((function(){return a.registerOption(l,b)})),e.onUnmounted((function(){return a.unregisterOption(l)})),e.onMounted((function(){var e,t;m.value&&(a.goToOption(f.Specific,l),null===(e=document.getElementById(l))||void 0===e||null===(t=e.focus)||void 0===t||t.call(e))})),e.watchEffect((function(){h.value&&e.nextTick((function(){var e,t;return null===(e=document.getElementById(l))||void 0===e||null===(t=e.scrollIntoView)||void 0===t?void 0:t.call(e,{block:"nearest"})}))})),function(){var e={active:h.value,selected:m.value,disabled:c},o={id:l,role:"option",tabIndex:-1,class:R(v,e),"aria-disabled":!0===c||void 0,"aria-selected":!0===m.value?m.value:void 0,onClick:x,onFocus:g,onPointerMove:y,onPointerLeave:w};return u({props:t({},n,o),slot:e,attrs:r,slots:i})}}});function R(e,t){if(void 0!==e)return"function"==typeof e?e(t):e}var T=Symbol("GroupContext");function L(t){var n=e.inject(T,null);if(null===n){var o=new Error("<"+t+" /> is missing a parent <SwitchGroup /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,L),o}return n}var D=e.defineComponent({name:"SwitchGroup",props:{as:{type:[Object,String],default:"template"}},setup:function(t,n){var o=n.slots,i=n.attrs,r=e.ref(null),a=e.ref(null);return e.provide(T,{switchRef:r,labelRef:a}),function(){return u({props:t,slot:{},slots:o,attrs:i})}}}),E=e.defineComponent({name:"Switch",props:{as:{type:[Object,String],default:"button"},modelValue:{type:[Object,Boolean],default:null},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1}},render:function(){var n=e.inject(T,null),o=this.$props,i=o.className,r=void 0===i?o.class:i,a=e.computed((function(){var e;return null==n||null===(e=n.labelRef.value)||void 0===e?void 0:e.id})),l={checked:this.$props.modelValue},s={id:this.id,ref:null===n?void 0:n.switchRef,role:"switch",tabIndex:0,class:C(r,l),"aria-checked":this.$props.modelValue,"aria-labelledby":a.value,onClick:this.handleClick,onKeyUp:this.handleKeyUp};return u({props:t({},this.$props,s),slot:l,attrs:this.$attrs,slots:this.$slots})},setup:function(t,n){var o=n.emit,u=e.inject(T,null);function r(){o("update:modelValue",!t.modelValue)}return{id:"headlessui-switch-"+s(),el:null==u?void 0:u.switchRef,handleClick:function(e){e.preventDefault(),r()},handleKeyUp:function(e){e.key===i.Space&&(e.preventDefault(),r())}}}}),P=e.defineComponent({name:"SwitchLabel",props:{as:{type:[Object,String],default:"label"}},render:function(){return u({props:t({},this.$props,{id:this.id,ref:"el",onPointerUp:this.handlePointerUp}),slot:{},attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=L("SwitchLabel");return{id:"headlessui-switch-label-"+s(),el:e.labelRef,handlePointerUp:function(){var t,n;null===(t=e.switchRef.value)||void 0===t||t.click(),null===(n=e.switchRef.value)||void 0===n||n.focus()}}}});function C(e,t){if(void 0!==e)return"function"==typeof e?e(t):e}exports.Listbox=y,exports.ListboxButton=O,exports.ListboxLabel=w,exports.ListboxOption=k,exports.ListboxOptions=S,exports.Menu=p,exports.MenuButton=h,exports.MenuItem=b,exports.MenuItems=m,exports.Switch=E,exports.SwitchGroup=D,exports.SwitchLabel=P; | ||
//# sourceMappingURL=headlessui.cjs.production.min.js.map |
@@ -1,2 +0,2 @@ | ||
import { cloneVNode, h, defineComponent, ref, onMounted, onUnmounted, provide, computed, inject, nextTick } from 'vue'; | ||
import { cloneVNode, h, defineComponent, ref, onMounted, onUnmounted, provide, computed, inject, nextTick, toRaw, watchEffect } from 'vue'; | ||
@@ -97,2 +97,20 @@ function _extends() { | ||
// TODO: This must already exist somewhere, right? 🤔 | ||
// Ref: https://www.w3.org/TR/uievents-key/#named-key-attribute-values | ||
var Keys; | ||
(function (Keys) { | ||
Keys["Space"] = " "; | ||
Keys["Enter"] = "Enter"; | ||
Keys["Escape"] = "Escape"; | ||
Keys["Backspace"] = "Backspace"; | ||
Keys["ArrowUp"] = "ArrowUp"; | ||
Keys["ArrowDown"] = "ArrowDown"; | ||
Keys["Home"] = "Home"; | ||
Keys["End"] = "End"; | ||
Keys["PageUp"] = "PageUp"; | ||
Keys["PageDown"] = "PageDown"; | ||
Keys["Tab"] = "Tab"; | ||
})(Keys || (Keys = {})); | ||
var MenuStates; | ||
@@ -103,22 +121,4 @@ | ||
MenuStates[MenuStates["Closed"] = 1] = "Closed"; | ||
})(MenuStates || (MenuStates = {})); // TODO: This must already exist somewhere, right? 🤔 | ||
// Ref: https://www.w3.org/TR/uievents-key/#named-key-attribute-values | ||
})(MenuStates || (MenuStates = {})); | ||
var Key; | ||
(function (Key) { | ||
Key["Space"] = " "; | ||
Key["Enter"] = "Enter"; | ||
Key["Escape"] = "Escape"; | ||
Key["Backspace"] = "Backspace"; | ||
Key["ArrowUp"] = "ArrowUp"; | ||
Key["ArrowDown"] = "ArrowDown"; | ||
Key["Home"] = "Home"; | ||
Key["End"] = "End"; | ||
Key["PageUp"] = "PageUp"; | ||
Key["PageDown"] = "PageDown"; | ||
Key["Tab"] = "Tab"; | ||
})(Key || (Key = {})); | ||
var Focus; | ||
@@ -211,7 +211,2 @@ | ||
activeItemIndex: activeItemIndex, | ||
toggleMenu: function toggleMenu() { | ||
var _match2; | ||
menuState.value = match(menuState.value, (_match2 = {}, _match2[MenuStates.Closed] = MenuStates.Open, _match2[MenuStates.Open] = MenuStates.Closed, _match2)); | ||
}, | ||
closeMenu: function closeMenu() { | ||
@@ -271,20 +266,21 @@ return menuState.value = MenuStates.Closed; | ||
function handler(event) { | ||
var _itemsRef$value; | ||
var _buttonRef$value, _itemsRef$value; | ||
if (event.defaultPrevented) return; | ||
if (menuState.value !== MenuStates.Open) return; | ||
if ((_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.contains(event.target)) return; | ||
if (!((_itemsRef$value = itemsRef.value) === null || _itemsRef$value === void 0 ? void 0 : _itemsRef$value.contains(event.target))) { | ||
api.closeMenu(); | ||
nextTick(function () { | ||
var _buttonRef$value; | ||
} | ||
return (_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.focus(); | ||
}); | ||
} | ||
if (!event.defaultPrevented) nextTick(function () { | ||
var _buttonRef$value2; | ||
return (_buttonRef$value2 = buttonRef.value) === null || _buttonRef$value2 === void 0 ? void 0 : _buttonRef$value2.focus(); | ||
}); | ||
} | ||
window.addEventListener('pointerdown', handler); | ||
window.addEventListener('click', handler); | ||
onUnmounted(function () { | ||
return window.removeEventListener('pointerdown', handler); | ||
return window.removeEventListener('click', handler); | ||
}); | ||
@@ -330,4 +326,3 @@ }); // @ts-expect-error Types of property 'dataRef' are incompatible. | ||
onFocus: this.handleFocus, | ||
onPointerUp: this.handlePointerUp, | ||
onPointerDown: this.handlePointerDown | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
@@ -348,5 +343,5 @@ return render({ | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-13 | ||
case Key.Space: | ||
case Key.Enter: | ||
case Key.ArrowDown: | ||
case Keys.Space: | ||
case Keys.Enter: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
@@ -362,3 +357,3 @@ api.openMenu(); | ||
case Key.ArrowUp: | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
@@ -376,15 +371,19 @@ api.openMenu(); | ||
function handlePointerDown(event) { | ||
// We have a `pointerdown` event listener in the menu for the 'outside click', so we just want | ||
// to prevent going there if we happen to click this button. | ||
event.preventDefault(); | ||
} | ||
function handlePointerUp(event) { | ||
if (api.menuState.value === MenuStates.Open) { | ||
api.closeMenu(); | ||
nextTick(function () { | ||
var _api$buttonRef$value; | ||
function handlePointerUp() { | ||
api.toggleMenu(); | ||
nextTick(function () { | ||
var _api$itemsRef$value4; | ||
return (_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.focus(); | ||
}); | ||
} else { | ||
event.preventDefault(); | ||
api.openMenu(); | ||
nextTick(function () { | ||
var _api$itemsRef$value4; | ||
return (_api$itemsRef$value4 = api.itemsRef.value) === null || _api$itemsRef$value4 === void 0 ? void 0 : _api$itemsRef$value4.focus(); | ||
}); | ||
return (_api$itemsRef$value4 = api.itemsRef.value) === null || _api$itemsRef$value4 === void 0 ? void 0 : _api$itemsRef$value4.focus(); | ||
}); | ||
} | ||
} | ||
@@ -402,3 +401,2 @@ | ||
handleKeyDown: handleKeyDown, | ||
handlePointerDown: handlePointerDown, | ||
handlePointerUp: handlePointerUp, | ||
@@ -421,3 +419,3 @@ handleFocus: handleFocus | ||
render: function render$1() { | ||
var _api$items$value$api$, _api$buttonRef$value; | ||
var _api$items$value$api$, _api$buttonRef$value2; | ||
@@ -436,3 +434,3 @@ var api = useMenuContext('MenuItems'); // `static` is a reserved keyword, therefore aliasing it... | ||
'aria-activedescendant': api.activeItemIndex.value === null ? undefined : (_api$items$value$api$ = api.items.value[api.activeItemIndex.value]) === null || _api$items$value$api$ === void 0 ? void 0 : _api$items$value$api$.id, | ||
'aria-labelledby': (_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.id, | ||
'aria-labelledby': (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.id, | ||
id: this.id, | ||
@@ -461,3 +459,13 @@ onKeyDown: this.handleKeyDown, | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12 | ||
case Key.Enter: | ||
// @ts-expect-error Fallthrough is expected here | ||
case Keys.Space: | ||
if (api.searchQuery.value !== '') { | ||
event.preventDefault(); | ||
return api.search(event.key); | ||
} | ||
// When in type ahead mode, fallthrough | ||
case Keys.Enter: | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
@@ -470,35 +478,40 @@ | ||
(_document$getElementB = document.getElementById(_id)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.click(); | ||
nextTick(function () { | ||
var _api$buttonRef$value2; | ||
return (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.focus(); | ||
}); | ||
} | ||
nextTick(function () { | ||
var _api$buttonRef$value3; | ||
return (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.focus(); | ||
}); | ||
break; | ||
case Key.ArrowDown: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.NextItem); | ||
case Key.ArrowUp: | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.PreviousItem); | ||
case Key.Home: | ||
case Key.PageUp: | ||
case Keys.Home: | ||
case Keys.PageUp: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.FirstItem); | ||
case Key.End: | ||
case Key.PageDown: | ||
case Keys.End: | ||
case Keys.PageDown: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.LastItem); | ||
case Key.Escape: | ||
case Keys.Escape: | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
nextTick(function () { | ||
var _api$buttonRef$value3; | ||
var _api$buttonRef$value4; | ||
return (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.focus(); | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
}); | ||
break; | ||
case Key.Tab: | ||
case Keys.Tab: | ||
return event.preventDefault(); | ||
@@ -542,6 +555,2 @@ | ||
required: false | ||
}, | ||
onClick: { | ||
type: Function, | ||
required: false | ||
} | ||
@@ -578,5 +587,10 @@ }, | ||
function handlePointerEnter() { | ||
if (disabled) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
function handleClick(event) { | ||
if (disabled) return event.preventDefault(); | ||
api.closeMenu(); | ||
nextTick(function () { | ||
var _api$buttonRef$value5; | ||
return (_api$buttonRef$value5 = api.buttonRef.value) === null || _api$buttonRef$value5 === void 0 ? void 0 : _api$buttonRef$value5.focus(); | ||
}); | ||
} | ||
@@ -589,32 +603,635 @@ | ||
function handlePointerMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
} | ||
function handlePointerLeave() { | ||
if (disabled) return; | ||
if (!active.value) return; | ||
api.goToItem(Focus.Nothing); | ||
} | ||
function handleMouseMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
return function () { | ||
var slot = { | ||
active: active.value, | ||
disabled: disabled | ||
}; | ||
var propsWeControl = { | ||
id: id, | ||
role: 'menuitem', | ||
tabIndex: -1, | ||
"class": resolvePropValue(className, slot), | ||
'aria-disabled': disabled === true ? true : undefined, | ||
onClick: handleClick, | ||
onFocus: handleFocus, | ||
onPointerMove: handlePointerMove, | ||
onPointerLeave: handlePointerLeave | ||
}; | ||
return render({ | ||
props: _extends({}, props, propsWeControl), | ||
slot: slot, | ||
attrs: attrs, | ||
slots: slots | ||
}); | ||
}; | ||
} | ||
}); | ||
function resolvePropValue(property, bag) { | ||
if (property === undefined) return undefined; | ||
if (typeof property === 'function') return property(bag); | ||
return property; | ||
} | ||
var ListboxStates; | ||
(function (ListboxStates) { | ||
ListboxStates[ListboxStates["Open"] = 0] = "Open"; | ||
ListboxStates[ListboxStates["Closed"] = 1] = "Closed"; | ||
})(ListboxStates || (ListboxStates = {})); | ||
var Focus$1; | ||
(function (Focus) { | ||
Focus[Focus["First"] = 0] = "First"; | ||
Focus[Focus["Previous"] = 1] = "Previous"; | ||
Focus[Focus["Next"] = 2] = "Next"; | ||
Focus[Focus["Last"] = 3] = "Last"; | ||
Focus[Focus["Specific"] = 4] = "Specific"; | ||
Focus[Focus["Nothing"] = 5] = "Nothing"; | ||
})(Focus$1 || (Focus$1 = {})); | ||
var ListboxContext = /*#__PURE__*/Symbol('ListboxContext'); | ||
function useListboxContext(component) { | ||
var context = inject(ListboxContext); | ||
if (context === undefined) { | ||
var err = new Error("<" + component + " /> is missing a parent <Listbox /> component."); | ||
if (Error.captureStackTrace) Error.captureStackTrace(err, useListboxContext); | ||
throw err; | ||
} | ||
return context; | ||
} // --- | ||
var Listbox = /*#__PURE__*/defineComponent({ | ||
name: 'Listbox', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'template' | ||
}, | ||
modelValue: { | ||
type: [Object, String], | ||
"default": null | ||
} | ||
}, | ||
setup: function setup(props, _ref) { | ||
var slots = _ref.slots, | ||
attrs = _ref.attrs, | ||
emit = _ref.emit; | ||
var passThroughProps = _objectWithoutPropertiesLoose(props, ["modelValue"]); | ||
var listboxState = ref(ListboxStates.Closed); | ||
var labelRef = ref(null); | ||
var buttonRef = ref(null); | ||
var optionsRef = ref(null); | ||
var options = ref([]); | ||
var searchQuery = ref(''); | ||
var activeOptionIndex = ref(null); | ||
var value = computed(function () { | ||
return props.modelValue; | ||
}); | ||
function calculateActiveOptionIndex(focus, id) { | ||
var _activeOptionIndex$va, _match; | ||
if (options.value.length <= 0) return null; | ||
var currentActiveOptionIndex = (_activeOptionIndex$va = activeOptionIndex.value) !== null && _activeOptionIndex$va !== void 0 ? _activeOptionIndex$va : -1; | ||
var nextActiveIndex = match(focus, (_match = {}, _match[Focus$1.First] = function () { | ||
return options.value.findIndex(function (option) { | ||
return !option.dataRef.disabled; | ||
}); | ||
}, _match[Focus$1.Previous] = function () { | ||
var idx = options.value.slice().reverse().findIndex(function (option, idx, all) { | ||
if (currentActiveOptionIndex !== -1 && all.length - idx - 1 >= currentActiveOptionIndex) return false; | ||
return !option.dataRef.disabled; | ||
}); | ||
if (idx === -1) return idx; | ||
return options.value.length - 1 - idx; | ||
}, _match[Focus$1.Next] = function () { | ||
return options.value.findIndex(function (option, idx) { | ||
if (idx <= currentActiveOptionIndex) return false; | ||
return !option.dataRef.disabled; | ||
}); | ||
}, _match[Focus$1.Last] = function () { | ||
var idx = options.value.slice().reverse().findIndex(function (option) { | ||
return !option.dataRef.disabled; | ||
}); | ||
if (idx === -1) return idx; | ||
return options.value.length - 1 - idx; | ||
}, _match[Focus$1.Specific] = function () { | ||
return options.value.findIndex(function (option) { | ||
return option.id === id; | ||
}); | ||
}, _match[Focus$1.Nothing] = function () { | ||
return null; | ||
}, _match)); | ||
if (nextActiveIndex === -1) return activeOptionIndex.value; | ||
return nextActiveIndex; | ||
} | ||
var api = { | ||
listboxState: listboxState, | ||
value: value, | ||
labelRef: labelRef, | ||
buttonRef: buttonRef, | ||
optionsRef: optionsRef, | ||
options: options, | ||
searchQuery: searchQuery, | ||
activeOptionIndex: activeOptionIndex, | ||
closeListbox: function closeListbox() { | ||
return listboxState.value = ListboxStates.Closed; | ||
}, | ||
openListbox: function openListbox() { | ||
return listboxState.value = ListboxStates.Open; | ||
}, | ||
goToOption: function goToOption(focus, id) { | ||
var nextActiveOptionIndex = calculateActiveOptionIndex(focus, id); | ||
if (searchQuery.value === '' && activeOptionIndex.value === nextActiveOptionIndex) return; | ||
searchQuery.value = ''; | ||
activeOptionIndex.value = nextActiveOptionIndex; | ||
}, | ||
search: function search(value) { | ||
searchQuery.value += value; | ||
var match = options.value.findIndex(function (option) { | ||
return !option.dataRef.disabled && option.dataRef.textValue.startsWith(searchQuery.value); | ||
}); | ||
if (match === -1 || match === activeOptionIndex.value) { | ||
return; | ||
} | ||
activeOptionIndex.value = match; | ||
}, | ||
clearSearch: function clearSearch() { | ||
searchQuery.value = ''; | ||
}, | ||
registerOption: function registerOption(id, dataRef) { | ||
// @ts-expect-error The expected type comes from property 'dataRef' which is declared here on type '{ id: string; dataRef: { textValue: string; disabled: boolean; }; }' | ||
options.value.push({ | ||
id: id, | ||
dataRef: dataRef | ||
}); | ||
}, | ||
unregisterOption: function unregisterOption(id) { | ||
var nextOptions = options.value.slice(); | ||
var currentActiveOption = activeOptionIndex.value !== null ? nextOptions[activeOptionIndex.value] : null; | ||
var idx = nextOptions.findIndex(function (a) { | ||
return a.id === id; | ||
}); | ||
if (idx !== -1) nextOptions.splice(idx, 1); | ||
options.value = nextOptions; | ||
activeOptionIndex.value = function () { | ||
if (idx === activeOptionIndex.value) return null; | ||
if (currentActiveOption === null) return null; // If we removed the option before the actual active index, then it would be out of sync. To | ||
// fix this, we will find the correct (new) index position. | ||
return nextOptions.indexOf(currentActiveOption); | ||
}(); | ||
}, | ||
select: function select(value) { | ||
emit('update:modelValue', value); | ||
} | ||
}; | ||
onMounted(function () { | ||
function handler(event) { | ||
var _buttonRef$value, _optionsRef$value; | ||
if (listboxState.value !== ListboxStates.Open) return; | ||
if ((_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.contains(event.target)) return; | ||
if (!((_optionsRef$value = optionsRef.value) === null || _optionsRef$value === void 0 ? void 0 : _optionsRef$value.contains(event.target))) { | ||
api.closeListbox(); | ||
} | ||
if (!event.defaultPrevented) nextTick(function () { | ||
var _buttonRef$value2; | ||
return (_buttonRef$value2 = buttonRef.value) === null || _buttonRef$value2 === void 0 ? void 0 : _buttonRef$value2.focus(); | ||
}); | ||
} | ||
window.addEventListener('click', handler); | ||
onUnmounted(function () { | ||
return window.removeEventListener('click', handler); | ||
}); | ||
}); // @ts-expect-error Types of property 'dataRef' are incompatible. | ||
provide(ListboxContext, api); | ||
return function () { | ||
var slot = { | ||
open: listboxState.value === ListboxStates.Open | ||
}; | ||
return render({ | ||
props: passThroughProps, | ||
slot: slot, | ||
slots: slots, | ||
attrs: attrs | ||
}); | ||
}; | ||
} | ||
}); // --- | ||
var ListboxLabel = /*#__PURE__*/defineComponent({ | ||
name: 'ListboxLabel', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'label' | ||
} | ||
}, | ||
render: function render$1() { | ||
var api = useListboxContext('ListboxLabel'); | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open | ||
}; | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: 'el', | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxLabel'); | ||
var id = "headlessui-listbox-label-" + useId(); | ||
return { | ||
id: id, | ||
el: api.labelRef, | ||
handlePointerUp: function handlePointerUp() { | ||
var _api$buttonRef$value; | ||
(_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.focus(); | ||
} | ||
}; | ||
} | ||
}); // --- | ||
var ListboxButton = /*#__PURE__*/defineComponent({ | ||
name: 'ListboxButton', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'button' | ||
} | ||
}, | ||
render: function render$1() { | ||
var _api$optionsRef$value; | ||
var api = useListboxContext('ListboxButton'); | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open, | ||
focused: this.focused | ||
}; | ||
var propsWeControl = { | ||
ref: 'el', | ||
id: this.id, | ||
type: 'button', | ||
'aria-haspopup': true, | ||
'aria-controls': (_api$optionsRef$value = api.optionsRef.value) === null || _api$optionsRef$value === void 0 ? void 0 : _api$optionsRef$value.id, | ||
'aria-expanded': api.listboxState.value === ListboxStates.Open ? true : undefined, | ||
'aria-labelledby': api.labelRef.value ? [api.labelRef.value.id, this.id].join(' ') : undefined, | ||
onKeyDown: this.handleKeyDown, | ||
onFocus: this.handleFocus, | ||
onBlur: this.handleBlur, | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxButton'); | ||
var id = "headlessui-listbox-button-" + useId(); | ||
var focused = ref(false); | ||
function handleKeyDown(event) { | ||
switch (event.key) { | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-13 | ||
case Keys.Space: | ||
case Keys.Enter: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
api.openListbox(); | ||
nextTick(function () { | ||
var _api$optionsRef$value2; | ||
(_api$optionsRef$value2 = api.optionsRef.value) === null || _api$optionsRef$value2 === void 0 ? void 0 : _api$optionsRef$value2.focus(); | ||
if (!api.value.value) api.goToOption(Focus$1.First); | ||
}); | ||
break; | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
api.openListbox(); | ||
nextTick(function () { | ||
var _api$optionsRef$value3; | ||
(_api$optionsRef$value3 = api.optionsRef.value) === null || _api$optionsRef$value3 === void 0 ? void 0 : _api$optionsRef$value3.focus(); | ||
if (!api.value.value) api.goToOption(Focus$1.Last); | ||
}); | ||
break; | ||
} | ||
} | ||
function handlePointerUp(event) { | ||
if (disabled) return; | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
if (api.listboxState.value === ListboxStates.Open) { | ||
api.closeListbox(); | ||
nextTick(function () { | ||
var _api$buttonRef$value2; | ||
return (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.focus(); | ||
}); | ||
} else { | ||
event.preventDefault(); | ||
api.openListbox(); | ||
nextTick(function () { | ||
var _api$optionsRef$value4; | ||
return (_api$optionsRef$value4 = api.optionsRef.value) === null || _api$optionsRef$value4 === void 0 ? void 0 : _api$optionsRef$value4.focus(); | ||
}); | ||
} | ||
} | ||
function handleFocus() { | ||
var _api$optionsRef$value5; | ||
if (api.listboxState.value === ListboxStates.Open) return (_api$optionsRef$value5 = api.optionsRef.value) === null || _api$optionsRef$value5 === void 0 ? void 0 : _api$optionsRef$value5.focus(); | ||
focused.value = true; | ||
} | ||
function handleBlur() { | ||
focused.value = false; | ||
} | ||
return { | ||
id: id, | ||
el: api.buttonRef, | ||
focused: focused, | ||
handleKeyDown: handleKeyDown, | ||
handlePointerUp: handlePointerUp, | ||
handleFocus: handleFocus, | ||
handleBlur: handleBlur | ||
}; | ||
} | ||
}); // --- | ||
var ListboxOptions = /*#__PURE__*/defineComponent({ | ||
name: 'ListboxOptions', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'ul' | ||
}, | ||
"static": { | ||
type: Boolean, | ||
"default": false | ||
} | ||
}, | ||
render: function render$1() { | ||
var _api$options$value$ap, _api$labelRef$value$i, _api$labelRef$value, _api$buttonRef$value3; | ||
var api = useListboxContext('ListboxOptions'); // `static` is a reserved keyword, therefore aliasing it... | ||
var _this$$props = this.$props, | ||
isStatic = _this$$props["static"], | ||
passThroughProps = _objectWithoutPropertiesLoose(_this$$props, ["static"]); | ||
if (!isStatic && api.listboxState.value === ListboxStates.Closed) return null; | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open | ||
}; | ||
var propsWeControl = { | ||
'aria-activedescendant': api.activeOptionIndex.value === null ? undefined : (_api$options$value$ap = api.options.value[api.activeOptionIndex.value]) === null || _api$options$value$ap === void 0 ? void 0 : _api$options$value$ap.id, | ||
'aria-labelledby': (_api$labelRef$value$i = (_api$labelRef$value = api.labelRef.value) === null || _api$labelRef$value === void 0 ? void 0 : _api$labelRef$value.id) !== null && _api$labelRef$value$i !== void 0 ? _api$labelRef$value$i : (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.id, | ||
id: this.id, | ||
onKeyDown: this.handleKeyDown, | ||
role: 'listbox', | ||
tabIndex: 0, | ||
ref: 'el' | ||
}; | ||
return render({ | ||
props: _extends({}, passThroughProps, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxOptions'); | ||
var id = "headlessui-listbox-options-" + useId(); | ||
var searchDebounce = ref(null); | ||
function handleKeyDown(event) { | ||
if (searchDebounce.value) clearTimeout(searchDebounce.value); | ||
switch (event.key) { | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12 | ||
// @ts-expect-error Fallthrough is expected here | ||
case Keys.Space: | ||
if (api.searchQuery.value !== '') { | ||
event.preventDefault(); | ||
return api.search(event.key); | ||
} | ||
// When in type ahead mode, fallthrough | ||
case Keys.Enter: | ||
event.preventDefault(); | ||
api.closeListbox(); | ||
if (api.activeOptionIndex.value !== null) { | ||
var dataRef = api.options.value[api.activeOptionIndex.value].dataRef; | ||
api.select(dataRef.value); | ||
} | ||
nextTick(function () { | ||
var _api$buttonRef$value4; | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
}); | ||
break; | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Next); | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Previous); | ||
case Keys.Home: | ||
case Keys.PageUp: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.First); | ||
case Keys.End: | ||
case Keys.PageDown: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Last); | ||
case Keys.Escape: | ||
event.preventDefault(); | ||
api.closeListbox(); | ||
nextTick(function () { | ||
var _api$buttonRef$value5; | ||
return (_api$buttonRef$value5 = api.buttonRef.value) === null || _api$buttonRef$value5 === void 0 ? void 0 : _api$buttonRef$value5.focus(); | ||
}); | ||
break; | ||
case Keys.Tab: | ||
return event.preventDefault(); | ||
default: | ||
if (event.key.length === 1) { | ||
api.search(event.key); | ||
searchDebounce.value = setTimeout(function () { | ||
return api.clearSearch(); | ||
}, 350); | ||
} | ||
break; | ||
} | ||
} | ||
return { | ||
id: id, | ||
el: api.optionsRef, | ||
handleKeyDown: handleKeyDown | ||
}; | ||
} | ||
}); | ||
var ListboxOption = /*#__PURE__*/defineComponent({ | ||
name: 'ListboxOption', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'li' | ||
}, | ||
value: { | ||
type: [Object, String], | ||
"default": null | ||
}, | ||
disabled: { | ||
type: Boolean, | ||
"default": false | ||
}, | ||
"class": { | ||
type: [String, Function], | ||
required: false | ||
}, | ||
className: { | ||
type: [String, Function], | ||
required: false | ||
} | ||
}, | ||
setup: function setup(props, _ref2) { | ||
var slots = _ref2.slots, | ||
attrs = _ref2.attrs; | ||
var api = useListboxContext('ListboxOption'); | ||
var id = "headlessui-listbox-option-" + useId(); | ||
var disabled = props.disabled, | ||
defaultClass = props["class"], | ||
_props$className = props.className, | ||
className = _props$className === void 0 ? defaultClass : _props$className, | ||
value = props.value; | ||
var active = computed(function () { | ||
return api.activeOptionIndex.value !== null ? api.options.value[api.activeOptionIndex.value].id === id : false; | ||
}); | ||
var selected = computed(function () { | ||
return toRaw(api.value.value) === toRaw(value); | ||
}); | ||
var dataRef = ref({ | ||
disabled: disabled, | ||
value: value, | ||
textValue: '' | ||
}); | ||
onMounted(function () { | ||
var _document$getElementB, _document$getElementB2; | ||
var textValue = (_document$getElementB = document.getElementById(id)) === null || _document$getElementB === void 0 ? void 0 : (_document$getElementB2 = _document$getElementB.textContent) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.toLowerCase().trim(); | ||
if (textValue !== undefined) dataRef.value.textValue = textValue; | ||
}); | ||
onMounted(function () { | ||
return api.registerOption(id, dataRef); | ||
}); | ||
onUnmounted(function () { | ||
return api.unregisterOption(id); | ||
}); | ||
onMounted(function () { | ||
var _document$getElementB3, _document$getElementB4; | ||
if (!selected.value) return; | ||
api.goToOption(Focus$1.Specific, id); | ||
(_document$getElementB3 = document.getElementById(id)) === null || _document$getElementB3 === void 0 ? void 0 : (_document$getElementB4 = _document$getElementB3.focus) === null || _document$getElementB4 === void 0 ? void 0 : _document$getElementB4.call(_document$getElementB3); | ||
}); | ||
watchEffect(function () { | ||
if (!active.value) return; | ||
nextTick(function () { | ||
var _api$buttonRef$value4; | ||
var _document$getElementB5, _document$getElementB6; | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
return (_document$getElementB5 = document.getElementById(id)) === null || _document$getElementB5 === void 0 ? void 0 : (_document$getElementB6 = _document$getElementB5.scrollIntoView) === null || _document$getElementB6 === void 0 ? void 0 : _document$getElementB6.call(_document$getElementB5, { | ||
block: 'nearest' | ||
}); | ||
}); | ||
} | ||
}); | ||
function handleClick(event) { | ||
if (disabled) return event.preventDefault(); | ||
if (props.onClick) return props.onClick(event); | ||
api.select(value); | ||
api.closeListbox(); | ||
nextTick(function () { | ||
var _api$buttonRef$value6; | ||
return (_api$buttonRef$value6 = api.buttonRef.value) === null || _api$buttonRef$value6 === void 0 ? void 0 : _api$buttonRef$value6.focus(); | ||
}); | ||
} | ||
function handleFocus() { | ||
if (disabled) return api.goToOption(Focus$1.Nothing); | ||
api.goToOption(Focus$1.Specific, id); | ||
} | ||
function handlePointerMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToOption(Focus$1.Specific, id); | ||
} | ||
function handlePointerLeave() { | ||
if (disabled) return; | ||
if (!active.value) return; | ||
api.goToOption(Focus$1.Nothing); | ||
} | ||
return function () { | ||
var slot = { | ||
active: active.value, | ||
selected: selected.value, | ||
disabled: disabled | ||
@@ -624,13 +1241,11 @@ }; | ||
id: id, | ||
role: 'menuitem', | ||
role: 'option', | ||
tabIndex: -1, | ||
"class": resolvePropValue(className, slot), | ||
disabled: disabled === true ? disabled : undefined, | ||
'aria-disabled': disabled === true ? disabled : undefined, | ||
"class": resolvePropValue$1(className, slot), | ||
'aria-disabled': disabled === true ? true : undefined, | ||
'aria-selected': selected.value === true ? selected.value : undefined, | ||
onClick: handleClick, | ||
onFocus: handleFocus, | ||
onMouseMove: handleMouseMove, | ||
onPointerEnter: handlePointerEnter, | ||
onPointerLeave: handlePointerLeave, | ||
onPointerUp: handlePointerUp | ||
onPointerMove: handlePointerMove, | ||
onPointerLeave: handlePointerLeave | ||
}; | ||
@@ -645,5 +1260,5 @@ return render({ | ||
} | ||
}); | ||
}); // --- | ||
function resolvePropValue(property, bag) { | ||
function resolvePropValue$1(property, bag) { | ||
if (property === undefined) return undefined; | ||
@@ -654,3 +1269,168 @@ if (typeof property === 'function') return property(bag); | ||
export { Menu, MenuButton, MenuItem, MenuItems }; | ||
var GroupContext = /*#__PURE__*/Symbol('GroupContext'); | ||
function useGroupContext(component) { | ||
var context = inject(GroupContext, null); | ||
if (context === null) { | ||
var err = new Error("<" + component + " /> is missing a parent <SwitchGroup /> component."); | ||
if (Error.captureStackTrace) Error.captureStackTrace(err, useGroupContext); | ||
throw err; | ||
} | ||
return context; | ||
} // --- | ||
var SwitchGroup = /*#__PURE__*/defineComponent({ | ||
name: 'SwitchGroup', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'template' | ||
} | ||
}, | ||
setup: function setup(props, _ref) { | ||
var slots = _ref.slots, | ||
attrs = _ref.attrs; | ||
var switchRef = ref(null); | ||
var labelRef = ref(null); | ||
var api = { | ||
switchRef: switchRef, | ||
labelRef: labelRef | ||
}; | ||
provide(GroupContext, api); | ||
return function () { | ||
return render({ | ||
props: props, | ||
slot: {}, | ||
slots: slots, | ||
attrs: attrs | ||
}); | ||
}; | ||
} | ||
}); // --- | ||
var Switch = /*#__PURE__*/defineComponent({ | ||
name: 'Switch', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'button' | ||
}, | ||
modelValue: { | ||
type: [Object, Boolean], | ||
"default": null | ||
}, | ||
"class": { | ||
type: [String, Function], | ||
required: false | ||
}, | ||
className: { | ||
type: [String, Function], | ||
required: false | ||
} | ||
}, | ||
render: function render$1() { | ||
var api = inject(GroupContext, null); | ||
var _this$$props = this.$props, | ||
defaultClass = _this$$props["class"], | ||
_this$$props$classNam = _this$$props.className, | ||
className = _this$$props$classNam === void 0 ? defaultClass : _this$$props$classNam; | ||
var labelledby = computed(function () { | ||
var _api$labelRef$value; | ||
return api === null || api === void 0 ? void 0 : (_api$labelRef$value = api.labelRef.value) === null || _api$labelRef$value === void 0 ? void 0 : _api$labelRef$value.id; | ||
}); | ||
var slot = { | ||
checked: this.$props.modelValue | ||
}; | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: api === null ? undefined : api.switchRef, | ||
role: 'switch', | ||
tabIndex: 0, | ||
"class": resolvePropValue$2(className, slot), | ||
'aria-checked': this.$props.modelValue, | ||
'aria-labelledby': labelledby.value, | ||
onClick: this.handleClick, | ||
onKeyUp: this.handleKeyUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup(props, _ref2) { | ||
var emit = _ref2.emit; | ||
var api = inject(GroupContext, null); | ||
var id = "headlessui-switch-" + useId(); | ||
function toggle() { | ||
emit('update:modelValue', !props.modelValue); | ||
} | ||
return { | ||
id: id, | ||
el: api === null || api === void 0 ? void 0 : api.switchRef, | ||
handleClick: function handleClick(event) { | ||
event.preventDefault(); | ||
toggle(); | ||
}, | ||
handleKeyUp: function handleKeyUp(event) { | ||
if (event.key === Keys.Space) { | ||
event.preventDefault(); | ||
toggle(); | ||
} | ||
} | ||
}; | ||
} | ||
}); // --- | ||
var SwitchLabel = /*#__PURE__*/defineComponent({ | ||
name: 'SwitchLabel', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'label' | ||
} | ||
}, | ||
render: function render$1() { | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: 'el', | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: {}, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useGroupContext('SwitchLabel'); | ||
var id = "headlessui-switch-label-" + useId(); | ||
return { | ||
id: id, | ||
el: api.labelRef, | ||
handlePointerUp: function handlePointerUp() { | ||
var _api$switchRef$value, _api$switchRef$value2; | ||
(_api$switchRef$value = api.switchRef.value) === null || _api$switchRef$value === void 0 ? void 0 : _api$switchRef$value.click(); | ||
(_api$switchRef$value2 = api.switchRef.value) === null || _api$switchRef$value2 === void 0 ? void 0 : _api$switchRef$value2.focus(); | ||
} | ||
}; | ||
} | ||
}); // --- | ||
function resolvePropValue$2(property, bag) { | ||
if (property === undefined) return undefined; | ||
if (typeof property === 'function') return property(bag); | ||
return property; | ||
} | ||
export { Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions, Menu, MenuButton, MenuItem, MenuItems, Switch, SwitchGroup, SwitchLabel }; | ||
//# sourceMappingURL=headlessui.esm.js.map |
@@ -101,2 +101,20 @@ (function (global, factory) { | ||
// TODO: This must already exist somewhere, right? 🤔 | ||
// Ref: https://www.w3.org/TR/uievents-key/#named-key-attribute-values | ||
var Keys; | ||
(function (Keys) { | ||
Keys["Space"] = " "; | ||
Keys["Enter"] = "Enter"; | ||
Keys["Escape"] = "Escape"; | ||
Keys["Backspace"] = "Backspace"; | ||
Keys["ArrowUp"] = "ArrowUp"; | ||
Keys["ArrowDown"] = "ArrowDown"; | ||
Keys["Home"] = "Home"; | ||
Keys["End"] = "End"; | ||
Keys["PageUp"] = "PageUp"; | ||
Keys["PageDown"] = "PageDown"; | ||
Keys["Tab"] = "Tab"; | ||
})(Keys || (Keys = {})); | ||
var MenuStates; | ||
@@ -107,22 +125,4 @@ | ||
MenuStates[MenuStates["Closed"] = 1] = "Closed"; | ||
})(MenuStates || (MenuStates = {})); // TODO: This must already exist somewhere, right? 🤔 | ||
// Ref: https://www.w3.org/TR/uievents-key/#named-key-attribute-values | ||
})(MenuStates || (MenuStates = {})); | ||
var Key; | ||
(function (Key) { | ||
Key["Space"] = " "; | ||
Key["Enter"] = "Enter"; | ||
Key["Escape"] = "Escape"; | ||
Key["Backspace"] = "Backspace"; | ||
Key["ArrowUp"] = "ArrowUp"; | ||
Key["ArrowDown"] = "ArrowDown"; | ||
Key["Home"] = "Home"; | ||
Key["End"] = "End"; | ||
Key["PageUp"] = "PageUp"; | ||
Key["PageDown"] = "PageDown"; | ||
Key["Tab"] = "Tab"; | ||
})(Key || (Key = {})); | ||
var Focus; | ||
@@ -215,7 +215,2 @@ | ||
activeItemIndex: activeItemIndex, | ||
toggleMenu: function toggleMenu() { | ||
var _match2; | ||
menuState.value = match(menuState.value, (_match2 = {}, _match2[MenuStates.Closed] = MenuStates.Open, _match2[MenuStates.Open] = MenuStates.Closed, _match2)); | ||
}, | ||
closeMenu: function closeMenu() { | ||
@@ -275,20 +270,21 @@ return menuState.value = MenuStates.Closed; | ||
function handler(event) { | ||
var _itemsRef$value; | ||
var _buttonRef$value, _itemsRef$value; | ||
if (event.defaultPrevented) return; | ||
if (menuState.value !== MenuStates.Open) return; | ||
if ((_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.contains(event.target)) return; | ||
if (!((_itemsRef$value = itemsRef.value) === null || _itemsRef$value === void 0 ? void 0 : _itemsRef$value.contains(event.target))) { | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _buttonRef$value; | ||
} | ||
return (_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.focus(); | ||
}); | ||
} | ||
if (!event.defaultPrevented) vue.nextTick(function () { | ||
var _buttonRef$value2; | ||
return (_buttonRef$value2 = buttonRef.value) === null || _buttonRef$value2 === void 0 ? void 0 : _buttonRef$value2.focus(); | ||
}); | ||
} | ||
window.addEventListener('pointerdown', handler); | ||
window.addEventListener('click', handler); | ||
vue.onUnmounted(function () { | ||
return window.removeEventListener('pointerdown', handler); | ||
return window.removeEventListener('click', handler); | ||
}); | ||
@@ -334,4 +330,3 @@ }); // @ts-expect-error Types of property 'dataRef' are incompatible. | ||
onFocus: this.handleFocus, | ||
onPointerUp: this.handlePointerUp, | ||
onPointerDown: this.handlePointerDown | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
@@ -352,5 +347,5 @@ return render({ | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-13 | ||
case Key.Space: | ||
case Key.Enter: | ||
case Key.ArrowDown: | ||
case Keys.Space: | ||
case Keys.Enter: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
@@ -366,3 +361,3 @@ api.openMenu(); | ||
case Key.ArrowUp: | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
@@ -380,15 +375,19 @@ api.openMenu(); | ||
function handlePointerDown(event) { | ||
// We have a `pointerdown` event listener in the menu for the 'outside click', so we just want | ||
// to prevent going there if we happen to click this button. | ||
event.preventDefault(); | ||
} | ||
function handlePointerUp(event) { | ||
if (api.menuState.value === MenuStates.Open) { | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value; | ||
function handlePointerUp() { | ||
api.toggleMenu(); | ||
vue.nextTick(function () { | ||
var _api$itemsRef$value4; | ||
return (_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.focus(); | ||
}); | ||
} else { | ||
event.preventDefault(); | ||
api.openMenu(); | ||
vue.nextTick(function () { | ||
var _api$itemsRef$value4; | ||
return (_api$itemsRef$value4 = api.itemsRef.value) === null || _api$itemsRef$value4 === void 0 ? void 0 : _api$itemsRef$value4.focus(); | ||
}); | ||
return (_api$itemsRef$value4 = api.itemsRef.value) === null || _api$itemsRef$value4 === void 0 ? void 0 : _api$itemsRef$value4.focus(); | ||
}); | ||
} | ||
} | ||
@@ -406,3 +405,2 @@ | ||
handleKeyDown: handleKeyDown, | ||
handlePointerDown: handlePointerDown, | ||
handlePointerUp: handlePointerUp, | ||
@@ -425,3 +423,3 @@ handleFocus: handleFocus | ||
render: function render$1() { | ||
var _api$items$value$api$, _api$buttonRef$value; | ||
var _api$items$value$api$, _api$buttonRef$value2; | ||
@@ -440,3 +438,3 @@ var api = useMenuContext('MenuItems'); // `static` is a reserved keyword, therefore aliasing it... | ||
'aria-activedescendant': api.activeItemIndex.value === null ? undefined : (_api$items$value$api$ = api.items.value[api.activeItemIndex.value]) === null || _api$items$value$api$ === void 0 ? void 0 : _api$items$value$api$.id, | ||
'aria-labelledby': (_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.id, | ||
'aria-labelledby': (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.id, | ||
id: this.id, | ||
@@ -465,3 +463,13 @@ onKeyDown: this.handleKeyDown, | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12 | ||
case Key.Enter: | ||
// @ts-expect-error Fallthrough is expected here | ||
case Keys.Space: | ||
if (api.searchQuery.value !== '') { | ||
event.preventDefault(); | ||
return api.search(event.key); | ||
} | ||
// When in type ahead mode, fallthrough | ||
case Keys.Enter: | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
@@ -474,35 +482,40 @@ | ||
(_document$getElementB = document.getElementById(_id)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.click(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value2; | ||
return (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.focus(); | ||
}); | ||
} | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value3; | ||
return (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.focus(); | ||
}); | ||
break; | ||
case Key.ArrowDown: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.NextItem); | ||
case Key.ArrowUp: | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.PreviousItem); | ||
case Key.Home: | ||
case Key.PageUp: | ||
case Keys.Home: | ||
case Keys.PageUp: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.FirstItem); | ||
case Key.End: | ||
case Key.PageDown: | ||
case Keys.End: | ||
case Keys.PageDown: | ||
event.preventDefault(); | ||
return api.goToItem(Focus.LastItem); | ||
case Key.Escape: | ||
case Keys.Escape: | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value3; | ||
var _api$buttonRef$value4; | ||
return (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.focus(); | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
}); | ||
break; | ||
case Key.Tab: | ||
case Keys.Tab: | ||
return event.preventDefault(); | ||
@@ -546,6 +559,2 @@ | ||
required: false | ||
}, | ||
onClick: { | ||
type: Function, | ||
required: false | ||
} | ||
@@ -582,5 +591,10 @@ }, | ||
function handlePointerEnter() { | ||
if (disabled) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
function handleClick(event) { | ||
if (disabled) return event.preventDefault(); | ||
api.closeMenu(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value5; | ||
return (_api$buttonRef$value5 = api.buttonRef.value) === null || _api$buttonRef$value5 === void 0 ? void 0 : _api$buttonRef$value5.focus(); | ||
}); | ||
} | ||
@@ -593,32 +607,635 @@ | ||
function handlePointerMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
} | ||
function handlePointerLeave() { | ||
if (disabled) return; | ||
if (!active.value) return; | ||
api.goToItem(Focus.Nothing); | ||
} | ||
function handleMouseMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToItem(Focus.SpecificItem, id); | ||
return function () { | ||
var slot = { | ||
active: active.value, | ||
disabled: disabled | ||
}; | ||
var propsWeControl = { | ||
id: id, | ||
role: 'menuitem', | ||
tabIndex: -1, | ||
"class": resolvePropValue(className, slot), | ||
'aria-disabled': disabled === true ? true : undefined, | ||
onClick: handleClick, | ||
onFocus: handleFocus, | ||
onPointerMove: handlePointerMove, | ||
onPointerLeave: handlePointerLeave | ||
}; | ||
return render({ | ||
props: _extends({}, props, propsWeControl), | ||
slot: slot, | ||
attrs: attrs, | ||
slots: slots | ||
}); | ||
}; | ||
} | ||
}); | ||
function resolvePropValue(property, bag) { | ||
if (property === undefined) return undefined; | ||
if (typeof property === 'function') return property(bag); | ||
return property; | ||
} | ||
var ListboxStates; | ||
(function (ListboxStates) { | ||
ListboxStates[ListboxStates["Open"] = 0] = "Open"; | ||
ListboxStates[ListboxStates["Closed"] = 1] = "Closed"; | ||
})(ListboxStates || (ListboxStates = {})); | ||
var Focus$1; | ||
(function (Focus) { | ||
Focus[Focus["First"] = 0] = "First"; | ||
Focus[Focus["Previous"] = 1] = "Previous"; | ||
Focus[Focus["Next"] = 2] = "Next"; | ||
Focus[Focus["Last"] = 3] = "Last"; | ||
Focus[Focus["Specific"] = 4] = "Specific"; | ||
Focus[Focus["Nothing"] = 5] = "Nothing"; | ||
})(Focus$1 || (Focus$1 = {})); | ||
var ListboxContext = /*#__PURE__*/Symbol('ListboxContext'); | ||
function useListboxContext(component) { | ||
var context = vue.inject(ListboxContext); | ||
if (context === undefined) { | ||
var err = new Error("<" + component + " /> is missing a parent <Listbox /> component."); | ||
if (Error.captureStackTrace) Error.captureStackTrace(err, useListboxContext); | ||
throw err; | ||
} | ||
return context; | ||
} // --- | ||
var Listbox = /*#__PURE__*/vue.defineComponent({ | ||
name: 'Listbox', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'template' | ||
}, | ||
modelValue: { | ||
type: [Object, String], | ||
"default": null | ||
} | ||
}, | ||
setup: function setup(props, _ref) { | ||
var slots = _ref.slots, | ||
attrs = _ref.attrs, | ||
emit = _ref.emit; | ||
var passThroughProps = _objectWithoutPropertiesLoose(props, ["modelValue"]); | ||
var listboxState = vue.ref(ListboxStates.Closed); | ||
var labelRef = vue.ref(null); | ||
var buttonRef = vue.ref(null); | ||
var optionsRef = vue.ref(null); | ||
var options = vue.ref([]); | ||
var searchQuery = vue.ref(''); | ||
var activeOptionIndex = vue.ref(null); | ||
var value = vue.computed(function () { | ||
return props.modelValue; | ||
}); | ||
function calculateActiveOptionIndex(focus, id) { | ||
var _activeOptionIndex$va, _match; | ||
if (options.value.length <= 0) return null; | ||
var currentActiveOptionIndex = (_activeOptionIndex$va = activeOptionIndex.value) !== null && _activeOptionIndex$va !== void 0 ? _activeOptionIndex$va : -1; | ||
var nextActiveIndex = match(focus, (_match = {}, _match[Focus$1.First] = function () { | ||
return options.value.findIndex(function (option) { | ||
return !option.dataRef.disabled; | ||
}); | ||
}, _match[Focus$1.Previous] = function () { | ||
var idx = options.value.slice().reverse().findIndex(function (option, idx, all) { | ||
if (currentActiveOptionIndex !== -1 && all.length - idx - 1 >= currentActiveOptionIndex) return false; | ||
return !option.dataRef.disabled; | ||
}); | ||
if (idx === -1) return idx; | ||
return options.value.length - 1 - idx; | ||
}, _match[Focus$1.Next] = function () { | ||
return options.value.findIndex(function (option, idx) { | ||
if (idx <= currentActiveOptionIndex) return false; | ||
return !option.dataRef.disabled; | ||
}); | ||
}, _match[Focus$1.Last] = function () { | ||
var idx = options.value.slice().reverse().findIndex(function (option) { | ||
return !option.dataRef.disabled; | ||
}); | ||
if (idx === -1) return idx; | ||
return options.value.length - 1 - idx; | ||
}, _match[Focus$1.Specific] = function () { | ||
return options.value.findIndex(function (option) { | ||
return option.id === id; | ||
}); | ||
}, _match[Focus$1.Nothing] = function () { | ||
return null; | ||
}, _match)); | ||
if (nextActiveIndex === -1) return activeOptionIndex.value; | ||
return nextActiveIndex; | ||
} | ||
var api = { | ||
listboxState: listboxState, | ||
value: value, | ||
labelRef: labelRef, | ||
buttonRef: buttonRef, | ||
optionsRef: optionsRef, | ||
options: options, | ||
searchQuery: searchQuery, | ||
activeOptionIndex: activeOptionIndex, | ||
closeListbox: function closeListbox() { | ||
return listboxState.value = ListboxStates.Closed; | ||
}, | ||
openListbox: function openListbox() { | ||
return listboxState.value = ListboxStates.Open; | ||
}, | ||
goToOption: function goToOption(focus, id) { | ||
var nextActiveOptionIndex = calculateActiveOptionIndex(focus, id); | ||
if (searchQuery.value === '' && activeOptionIndex.value === nextActiveOptionIndex) return; | ||
searchQuery.value = ''; | ||
activeOptionIndex.value = nextActiveOptionIndex; | ||
}, | ||
search: function search(value) { | ||
searchQuery.value += value; | ||
var match = options.value.findIndex(function (option) { | ||
return !option.dataRef.disabled && option.dataRef.textValue.startsWith(searchQuery.value); | ||
}); | ||
if (match === -1 || match === activeOptionIndex.value) { | ||
return; | ||
} | ||
activeOptionIndex.value = match; | ||
}, | ||
clearSearch: function clearSearch() { | ||
searchQuery.value = ''; | ||
}, | ||
registerOption: function registerOption(id, dataRef) { | ||
// @ts-expect-error The expected type comes from property 'dataRef' which is declared here on type '{ id: string; dataRef: { textValue: string; disabled: boolean; }; }' | ||
options.value.push({ | ||
id: id, | ||
dataRef: dataRef | ||
}); | ||
}, | ||
unregisterOption: function unregisterOption(id) { | ||
var nextOptions = options.value.slice(); | ||
var currentActiveOption = activeOptionIndex.value !== null ? nextOptions[activeOptionIndex.value] : null; | ||
var idx = nextOptions.findIndex(function (a) { | ||
return a.id === id; | ||
}); | ||
if (idx !== -1) nextOptions.splice(idx, 1); | ||
options.value = nextOptions; | ||
activeOptionIndex.value = function () { | ||
if (idx === activeOptionIndex.value) return null; | ||
if (currentActiveOption === null) return null; // If we removed the option before the actual active index, then it would be out of sync. To | ||
// fix this, we will find the correct (new) index position. | ||
return nextOptions.indexOf(currentActiveOption); | ||
}(); | ||
}, | ||
select: function select(value) { | ||
emit('update:modelValue', value); | ||
} | ||
}; | ||
vue.onMounted(function () { | ||
function handler(event) { | ||
var _buttonRef$value, _optionsRef$value; | ||
if (listboxState.value !== ListboxStates.Open) return; | ||
if ((_buttonRef$value = buttonRef.value) === null || _buttonRef$value === void 0 ? void 0 : _buttonRef$value.contains(event.target)) return; | ||
if (!((_optionsRef$value = optionsRef.value) === null || _optionsRef$value === void 0 ? void 0 : _optionsRef$value.contains(event.target))) { | ||
api.closeListbox(); | ||
} | ||
if (!event.defaultPrevented) vue.nextTick(function () { | ||
var _buttonRef$value2; | ||
return (_buttonRef$value2 = buttonRef.value) === null || _buttonRef$value2 === void 0 ? void 0 : _buttonRef$value2.focus(); | ||
}); | ||
} | ||
window.addEventListener('click', handler); | ||
vue.onUnmounted(function () { | ||
return window.removeEventListener('click', handler); | ||
}); | ||
}); // @ts-expect-error Types of property 'dataRef' are incompatible. | ||
vue.provide(ListboxContext, api); | ||
return function () { | ||
var slot = { | ||
open: listboxState.value === ListboxStates.Open | ||
}; | ||
return render({ | ||
props: passThroughProps, | ||
slot: slot, | ||
slots: slots, | ||
attrs: attrs | ||
}); | ||
}; | ||
} | ||
}); // --- | ||
var ListboxLabel = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxLabel', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'label' | ||
} | ||
}, | ||
render: function render$1() { | ||
var api = useListboxContext('ListboxLabel'); | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open | ||
}; | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: 'el', | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxLabel'); | ||
var id = "headlessui-listbox-label-" + useId(); | ||
return { | ||
id: id, | ||
el: api.labelRef, | ||
handlePointerUp: function handlePointerUp() { | ||
var _api$buttonRef$value; | ||
(_api$buttonRef$value = api.buttonRef.value) === null || _api$buttonRef$value === void 0 ? void 0 : _api$buttonRef$value.focus(); | ||
} | ||
}; | ||
} | ||
}); // --- | ||
var ListboxButton = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxButton', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'button' | ||
} | ||
}, | ||
render: function render$1() { | ||
var _api$optionsRef$value; | ||
var api = useListboxContext('ListboxButton'); | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open, | ||
focused: this.focused | ||
}; | ||
var propsWeControl = { | ||
ref: 'el', | ||
id: this.id, | ||
type: 'button', | ||
'aria-haspopup': true, | ||
'aria-controls': (_api$optionsRef$value = api.optionsRef.value) === null || _api$optionsRef$value === void 0 ? void 0 : _api$optionsRef$value.id, | ||
'aria-expanded': api.listboxState.value === ListboxStates.Open ? true : undefined, | ||
'aria-labelledby': api.labelRef.value ? [api.labelRef.value.id, this.id].join(' ') : undefined, | ||
onKeyDown: this.handleKeyDown, | ||
onFocus: this.handleFocus, | ||
onBlur: this.handleBlur, | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxButton'); | ||
var id = "headlessui-listbox-button-" + useId(); | ||
var focused = vue.ref(false); | ||
function handleKeyDown(event) { | ||
switch (event.key) { | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-13 | ||
case Keys.Space: | ||
case Keys.Enter: | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
api.openListbox(); | ||
vue.nextTick(function () { | ||
var _api$optionsRef$value2; | ||
(_api$optionsRef$value2 = api.optionsRef.value) === null || _api$optionsRef$value2 === void 0 ? void 0 : _api$optionsRef$value2.focus(); | ||
if (!api.value.value) api.goToOption(Focus$1.First); | ||
}); | ||
break; | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
api.openListbox(); | ||
vue.nextTick(function () { | ||
var _api$optionsRef$value3; | ||
(_api$optionsRef$value3 = api.optionsRef.value) === null || _api$optionsRef$value3 === void 0 ? void 0 : _api$optionsRef$value3.focus(); | ||
if (!api.value.value) api.goToOption(Focus$1.Last); | ||
}); | ||
break; | ||
} | ||
} | ||
function handlePointerUp(event) { | ||
if (disabled) return; | ||
event.preventDefault(); | ||
api.closeMenu(); | ||
if (api.listboxState.value === ListboxStates.Open) { | ||
api.closeListbox(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value2; | ||
return (_api$buttonRef$value2 = api.buttonRef.value) === null || _api$buttonRef$value2 === void 0 ? void 0 : _api$buttonRef$value2.focus(); | ||
}); | ||
} else { | ||
event.preventDefault(); | ||
api.openListbox(); | ||
vue.nextTick(function () { | ||
var _api$optionsRef$value4; | ||
return (_api$optionsRef$value4 = api.optionsRef.value) === null || _api$optionsRef$value4 === void 0 ? void 0 : _api$optionsRef$value4.focus(); | ||
}); | ||
} | ||
} | ||
function handleFocus() { | ||
var _api$optionsRef$value5; | ||
if (api.listboxState.value === ListboxStates.Open) return (_api$optionsRef$value5 = api.optionsRef.value) === null || _api$optionsRef$value5 === void 0 ? void 0 : _api$optionsRef$value5.focus(); | ||
focused.value = true; | ||
} | ||
function handleBlur() { | ||
focused.value = false; | ||
} | ||
return { | ||
id: id, | ||
el: api.buttonRef, | ||
focused: focused, | ||
handleKeyDown: handleKeyDown, | ||
handlePointerUp: handlePointerUp, | ||
handleFocus: handleFocus, | ||
handleBlur: handleBlur | ||
}; | ||
} | ||
}); // --- | ||
var ListboxOptions = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxOptions', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'ul' | ||
}, | ||
"static": { | ||
type: Boolean, | ||
"default": false | ||
} | ||
}, | ||
render: function render$1() { | ||
var _api$options$value$ap, _api$labelRef$value$i, _api$labelRef$value, _api$buttonRef$value3; | ||
var api = useListboxContext('ListboxOptions'); // `static` is a reserved keyword, therefore aliasing it... | ||
var _this$$props = this.$props, | ||
isStatic = _this$$props["static"], | ||
passThroughProps = _objectWithoutPropertiesLoose(_this$$props, ["static"]); | ||
if (!isStatic && api.listboxState.value === ListboxStates.Closed) return null; | ||
var slot = { | ||
open: api.listboxState.value === ListboxStates.Open | ||
}; | ||
var propsWeControl = { | ||
'aria-activedescendant': api.activeOptionIndex.value === null ? undefined : (_api$options$value$ap = api.options.value[api.activeOptionIndex.value]) === null || _api$options$value$ap === void 0 ? void 0 : _api$options$value$ap.id, | ||
'aria-labelledby': (_api$labelRef$value$i = (_api$labelRef$value = api.labelRef.value) === null || _api$labelRef$value === void 0 ? void 0 : _api$labelRef$value.id) !== null && _api$labelRef$value$i !== void 0 ? _api$labelRef$value$i : (_api$buttonRef$value3 = api.buttonRef.value) === null || _api$buttonRef$value3 === void 0 ? void 0 : _api$buttonRef$value3.id, | ||
id: this.id, | ||
onKeyDown: this.handleKeyDown, | ||
role: 'listbox', | ||
tabIndex: 0, | ||
ref: 'el' | ||
}; | ||
return render({ | ||
props: _extends({}, passThroughProps, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useListboxContext('ListboxOptions'); | ||
var id = "headlessui-listbox-options-" + useId(); | ||
var searchDebounce = vue.ref(null); | ||
function handleKeyDown(event) { | ||
if (searchDebounce.value) clearTimeout(searchDebounce.value); | ||
switch (event.key) { | ||
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12 | ||
// @ts-expect-error Fallthrough is expected here | ||
case Keys.Space: | ||
if (api.searchQuery.value !== '') { | ||
event.preventDefault(); | ||
return api.search(event.key); | ||
} | ||
// When in type ahead mode, fallthrough | ||
case Keys.Enter: | ||
event.preventDefault(); | ||
api.closeListbox(); | ||
if (api.activeOptionIndex.value !== null) { | ||
var dataRef = api.options.value[api.activeOptionIndex.value].dataRef; | ||
api.select(dataRef.value); | ||
} | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value4; | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
}); | ||
break; | ||
case Keys.ArrowDown: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Next); | ||
case Keys.ArrowUp: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Previous); | ||
case Keys.Home: | ||
case Keys.PageUp: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.First); | ||
case Keys.End: | ||
case Keys.PageDown: | ||
event.preventDefault(); | ||
return api.goToOption(Focus$1.Last); | ||
case Keys.Escape: | ||
event.preventDefault(); | ||
api.closeListbox(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value5; | ||
return (_api$buttonRef$value5 = api.buttonRef.value) === null || _api$buttonRef$value5 === void 0 ? void 0 : _api$buttonRef$value5.focus(); | ||
}); | ||
break; | ||
case Keys.Tab: | ||
return event.preventDefault(); | ||
default: | ||
if (event.key.length === 1) { | ||
api.search(event.key); | ||
searchDebounce.value = setTimeout(function () { | ||
return api.clearSearch(); | ||
}, 350); | ||
} | ||
break; | ||
} | ||
} | ||
return { | ||
id: id, | ||
el: api.optionsRef, | ||
handleKeyDown: handleKeyDown | ||
}; | ||
} | ||
}); | ||
var ListboxOption = /*#__PURE__*/vue.defineComponent({ | ||
name: 'ListboxOption', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'li' | ||
}, | ||
value: { | ||
type: [Object, String], | ||
"default": null | ||
}, | ||
disabled: { | ||
type: Boolean, | ||
"default": false | ||
}, | ||
"class": { | ||
type: [String, Function], | ||
required: false | ||
}, | ||
className: { | ||
type: [String, Function], | ||
required: false | ||
} | ||
}, | ||
setup: function setup(props, _ref2) { | ||
var slots = _ref2.slots, | ||
attrs = _ref2.attrs; | ||
var api = useListboxContext('ListboxOption'); | ||
var id = "headlessui-listbox-option-" + useId(); | ||
var disabled = props.disabled, | ||
defaultClass = props["class"], | ||
_props$className = props.className, | ||
className = _props$className === void 0 ? defaultClass : _props$className, | ||
value = props.value; | ||
var active = vue.computed(function () { | ||
return api.activeOptionIndex.value !== null ? api.options.value[api.activeOptionIndex.value].id === id : false; | ||
}); | ||
var selected = vue.computed(function () { | ||
return vue.toRaw(api.value.value) === vue.toRaw(value); | ||
}); | ||
var dataRef = vue.ref({ | ||
disabled: disabled, | ||
value: value, | ||
textValue: '' | ||
}); | ||
vue.onMounted(function () { | ||
var _document$getElementB, _document$getElementB2; | ||
var textValue = (_document$getElementB = document.getElementById(id)) === null || _document$getElementB === void 0 ? void 0 : (_document$getElementB2 = _document$getElementB.textContent) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.toLowerCase().trim(); | ||
if (textValue !== undefined) dataRef.value.textValue = textValue; | ||
}); | ||
vue.onMounted(function () { | ||
return api.registerOption(id, dataRef); | ||
}); | ||
vue.onUnmounted(function () { | ||
return api.unregisterOption(id); | ||
}); | ||
vue.onMounted(function () { | ||
var _document$getElementB3, _document$getElementB4; | ||
if (!selected.value) return; | ||
api.goToOption(Focus$1.Specific, id); | ||
(_document$getElementB3 = document.getElementById(id)) === null || _document$getElementB3 === void 0 ? void 0 : (_document$getElementB4 = _document$getElementB3.focus) === null || _document$getElementB4 === void 0 ? void 0 : _document$getElementB4.call(_document$getElementB3); | ||
}); | ||
vue.watchEffect(function () { | ||
if (!active.value) return; | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value4; | ||
var _document$getElementB5, _document$getElementB6; | ||
return (_api$buttonRef$value4 = api.buttonRef.value) === null || _api$buttonRef$value4 === void 0 ? void 0 : _api$buttonRef$value4.focus(); | ||
return (_document$getElementB5 = document.getElementById(id)) === null || _document$getElementB5 === void 0 ? void 0 : (_document$getElementB6 = _document$getElementB5.scrollIntoView) === null || _document$getElementB6 === void 0 ? void 0 : _document$getElementB6.call(_document$getElementB5, { | ||
block: 'nearest' | ||
}); | ||
}); | ||
} | ||
}); | ||
function handleClick(event) { | ||
if (disabled) return event.preventDefault(); | ||
if (props.onClick) return props.onClick(event); | ||
api.select(value); | ||
api.closeListbox(); | ||
vue.nextTick(function () { | ||
var _api$buttonRef$value6; | ||
return (_api$buttonRef$value6 = api.buttonRef.value) === null || _api$buttonRef$value6 === void 0 ? void 0 : _api$buttonRef$value6.focus(); | ||
}); | ||
} | ||
function handleFocus() { | ||
if (disabled) return api.goToOption(Focus$1.Nothing); | ||
api.goToOption(Focus$1.Specific, id); | ||
} | ||
function handlePointerMove() { | ||
if (disabled) return; | ||
if (active.value) return; | ||
api.goToOption(Focus$1.Specific, id); | ||
} | ||
function handlePointerLeave() { | ||
if (disabled) return; | ||
if (!active.value) return; | ||
api.goToOption(Focus$1.Nothing); | ||
} | ||
return function () { | ||
var slot = { | ||
active: active.value, | ||
selected: selected.value, | ||
disabled: disabled | ||
@@ -628,13 +1245,11 @@ }; | ||
id: id, | ||
role: 'menuitem', | ||
role: 'option', | ||
tabIndex: -1, | ||
"class": resolvePropValue(className, slot), | ||
disabled: disabled === true ? disabled : undefined, | ||
'aria-disabled': disabled === true ? disabled : undefined, | ||
"class": resolvePropValue$1(className, slot), | ||
'aria-disabled': disabled === true ? true : undefined, | ||
'aria-selected': selected.value === true ? selected.value : undefined, | ||
onClick: handleClick, | ||
onFocus: handleFocus, | ||
onMouseMove: handleMouseMove, | ||
onPointerEnter: handlePointerEnter, | ||
onPointerLeave: handlePointerLeave, | ||
onPointerUp: handlePointerUp | ||
onPointerMove: handlePointerMove, | ||
onPointerLeave: handlePointerLeave | ||
}; | ||
@@ -649,5 +1264,5 @@ return render({ | ||
} | ||
}); | ||
}); // --- | ||
function resolvePropValue(property, bag) { | ||
function resolvePropValue$1(property, bag) { | ||
if (property === undefined) return undefined; | ||
@@ -658,2 +1273,172 @@ if (typeof property === 'function') return property(bag); | ||
var GroupContext = /*#__PURE__*/Symbol('GroupContext'); | ||
function useGroupContext(component) { | ||
var context = vue.inject(GroupContext, null); | ||
if (context === null) { | ||
var err = new Error("<" + component + " /> is missing a parent <SwitchGroup /> component."); | ||
if (Error.captureStackTrace) Error.captureStackTrace(err, useGroupContext); | ||
throw err; | ||
} | ||
return context; | ||
} // --- | ||
var SwitchGroup = /*#__PURE__*/vue.defineComponent({ | ||
name: 'SwitchGroup', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'template' | ||
} | ||
}, | ||
setup: function setup(props, _ref) { | ||
var slots = _ref.slots, | ||
attrs = _ref.attrs; | ||
var switchRef = vue.ref(null); | ||
var labelRef = vue.ref(null); | ||
var api = { | ||
switchRef: switchRef, | ||
labelRef: labelRef | ||
}; | ||
vue.provide(GroupContext, api); | ||
return function () { | ||
return render({ | ||
props: props, | ||
slot: {}, | ||
slots: slots, | ||
attrs: attrs | ||
}); | ||
}; | ||
} | ||
}); // --- | ||
var Switch = /*#__PURE__*/vue.defineComponent({ | ||
name: 'Switch', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'button' | ||
}, | ||
modelValue: { | ||
type: [Object, Boolean], | ||
"default": null | ||
}, | ||
"class": { | ||
type: [String, Function], | ||
required: false | ||
}, | ||
className: { | ||
type: [String, Function], | ||
required: false | ||
} | ||
}, | ||
render: function render$1() { | ||
var api = vue.inject(GroupContext, null); | ||
var _this$$props = this.$props, | ||
defaultClass = _this$$props["class"], | ||
_this$$props$classNam = _this$$props.className, | ||
className = _this$$props$classNam === void 0 ? defaultClass : _this$$props$classNam; | ||
var labelledby = vue.computed(function () { | ||
var _api$labelRef$value; | ||
return api === null || api === void 0 ? void 0 : (_api$labelRef$value = api.labelRef.value) === null || _api$labelRef$value === void 0 ? void 0 : _api$labelRef$value.id; | ||
}); | ||
var slot = { | ||
checked: this.$props.modelValue | ||
}; | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: api === null ? undefined : api.switchRef, | ||
role: 'switch', | ||
tabIndex: 0, | ||
"class": resolvePropValue$2(className, slot), | ||
'aria-checked': this.$props.modelValue, | ||
'aria-labelledby': labelledby.value, | ||
onClick: this.handleClick, | ||
onKeyUp: this.handleKeyUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: slot, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup(props, _ref2) { | ||
var emit = _ref2.emit; | ||
var api = vue.inject(GroupContext, null); | ||
var id = "headlessui-switch-" + useId(); | ||
function toggle() { | ||
emit('update:modelValue', !props.modelValue); | ||
} | ||
return { | ||
id: id, | ||
el: api === null || api === void 0 ? void 0 : api.switchRef, | ||
handleClick: function handleClick(event) { | ||
event.preventDefault(); | ||
toggle(); | ||
}, | ||
handleKeyUp: function handleKeyUp(event) { | ||
if (event.key === Keys.Space) { | ||
event.preventDefault(); | ||
toggle(); | ||
} | ||
} | ||
}; | ||
} | ||
}); // --- | ||
var SwitchLabel = /*#__PURE__*/vue.defineComponent({ | ||
name: 'SwitchLabel', | ||
props: { | ||
as: { | ||
type: [Object, String], | ||
"default": 'label' | ||
} | ||
}, | ||
render: function render$1() { | ||
var propsWeControl = { | ||
id: this.id, | ||
ref: 'el', | ||
onPointerUp: this.handlePointerUp | ||
}; | ||
return render({ | ||
props: _extends({}, this.$props, propsWeControl), | ||
slot: {}, | ||
attrs: this.$attrs, | ||
slots: this.$slots | ||
}); | ||
}, | ||
setup: function setup() { | ||
var api = useGroupContext('SwitchLabel'); | ||
var id = "headlessui-switch-label-" + useId(); | ||
return { | ||
id: id, | ||
el: api.labelRef, | ||
handlePointerUp: function handlePointerUp() { | ||
var _api$switchRef$value, _api$switchRef$value2; | ||
(_api$switchRef$value = api.switchRef.value) === null || _api$switchRef$value === void 0 ? void 0 : _api$switchRef$value.click(); | ||
(_api$switchRef$value2 = api.switchRef.value) === null || _api$switchRef$value2 === void 0 ? void 0 : _api$switchRef$value2.focus(); | ||
} | ||
}; | ||
} | ||
}); // --- | ||
function resolvePropValue$2(property, bag) { | ||
if (property === undefined) return undefined; | ||
if (typeof property === 'function') return property(bag); | ||
return property; | ||
} | ||
exports.Listbox = Listbox; | ||
exports.ListboxButton = ListboxButton; | ||
exports.ListboxLabel = ListboxLabel; | ||
exports.ListboxOption = ListboxOption; | ||
exports.ListboxOptions = ListboxOptions; | ||
exports.Menu = Menu; | ||
@@ -663,2 +1448,5 @@ exports.MenuButton = MenuButton; | ||
exports.MenuItems = MenuItems; | ||
exports.Switch = Switch; | ||
exports.SwitchGroup = SwitchGroup; | ||
exports.SwitchLabel = SwitchLabel; | ||
@@ -665,0 +1453,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
@@ -1,2 +0,2 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("vue")):"function"==typeof define&&define.amd?define(["exports","vue"],n):n((e=e||self).headlessui={},e.Vue)}(this,(function(e,n){"use strict";function t(){return(t=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e}).apply(this,arguments)}function o(e,n){if(null==e)return{};var t,o,u={},r=Object.keys(e);for(o=0;o<r.length;o++)n.indexOf(t=r[o])>=0||(u[t]=e[t]);return u}function u(e,n){if(e in n){for(var t=n[e],o=arguments.length,r=new Array(o>2?o-2:0),i=2;i<o;i++)r[i-2]=arguments[i];return"function"==typeof t?t.apply(void 0,r):t}var a=new Error('Tried to handle "'+e+'" but there is no handler defined. Only defined handlers are: '+Object.keys(n).map((function(e){return'"'+e+'"'})).join(", ")+".");throw Error.captureStackTrace&&Error.captureStackTrace(a,u),a}function r(e){var t,u=e.props,r=e.attrs,i=e.slots,a=e.slot,l=u.as,s=o(u,["as"]),c=null===(t=i.default)||void 0===t?void 0:t.call(i,a);if("template"===l){if(Object.keys(s).length>0||"class"in r){var d=null!=c?c:[],v=d[0];if(d.slice(1).length>0)throw new Error('You should only render 1 child or use the `as="..."` prop');return n.cloneVNode(v,s)}return c}return n.h(l,s,c)}var i,a,l,s=0;function c(){return++s}!function(e){e[e.Open=0]="Open",e[e.Closed=1]="Closed"}(i||(i={})),function(e){e.Space=" ",e.Enter="Enter",e.Escape="Escape",e.Backspace="Backspace",e.ArrowUp="ArrowUp",e.ArrowDown="ArrowDown",e.Home="Home",e.End="End",e.PageUp="PageUp",e.PageDown="PageDown",e.Tab="Tab"}(a||(a={})),function(e){e[e.FirstItem=0]="FirstItem",e[e.PreviousItem=1]="PreviousItem",e[e.NextItem=2]="NextItem",e[e.LastItem=3]="LastItem",e[e.SpecificItem=4]="SpecificItem",e[e.Nothing=5]="Nothing"}(l||(l={}));var d=Symbol("MenuContext");function v(e){var t=n.inject(d);if(void 0===t){var o=new Error("<"+e+" /> is missing a parent <Menu /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,v),o}return t}var f=n.defineComponent({props:{as:{type:[Object,String],default:"template"}},setup:function(e,t){var o=t.slots,a=t.attrs,s=n.ref(i.Closed),c=n.ref(null),v=n.ref(null),f=n.ref([]),p=n.ref(""),m=n.ref(null),I={menuState:s,buttonRef:c,itemsRef:v,items:f,searchQuery:p,activeItemIndex:m,toggleMenu:function(){var e;s.value=u(s.value,((e={})[i.Closed]=i.Open,e[i.Open]=i.Closed,e))},closeMenu:function(){return s.value=i.Closed},openMenu:function(){return s.value=i.Open},goToItem:function(e,n){var t=function(e,n){var t,o;if(f.value.length<=0)return null;var r=null!==(t=m.value)&&void 0!==t?t:-1,i=u(e,((o={})[l.FirstItem]=function(){return f.value.findIndex((function(e){return!e.dataRef.disabled}))},o[l.PreviousItem]=function(){var e=f.value.slice().reverse().findIndex((function(e,n,t){return!(-1!==r&&t.length-n-1>=r||e.dataRef.disabled)}));return-1===e?e:f.value.length-1-e},o[l.NextItem]=function(){return f.value.findIndex((function(e,n){return!(n<=r||e.dataRef.disabled)}))},o[l.LastItem]=function(){var e=f.value.slice().reverse().findIndex((function(e){return!e.dataRef.disabled}));return-1===e?e:f.value.length-1-e},o[l.SpecificItem]=function(){return f.value.findIndex((function(e){return e.id===n}))},o[l.Nothing]=function(){return null},o));return-1===i?m.value:i}(e,n);""===p.value&&m.value===t||(p.value="",m.value=t)},search:function(e){p.value+=e;var n=f.value.findIndex((function(e){return e.dataRef.textValue.startsWith(p.value)&&!e.dataRef.disabled}));-1!==n&&n!==m.value&&(m.value=n)},clearSearch:function(){p.value=""},registerItem:function(e,n){f.value.push({id:e,dataRef:n})},unregisterItem:function(e){var n=f.value.slice(),t=null!==m.value?n[m.value]:null,o=n.findIndex((function(n){return n.id===e}));-1!==o&&n.splice(o,1),f.value=n,m.value=o===m.value||null===t?null:n.indexOf(t)}};return n.onMounted((function(){function e(e){var t;e.defaultPrevented||s.value===i.Open&&((null===(t=v.value)||void 0===t?void 0:t.contains(e.target))||(I.closeMenu(),n.nextTick((function(){var e;return null===(e=c.value)||void 0===e?void 0:e.focus()}))))}window.addEventListener("pointerdown",e),n.onUnmounted((function(){return window.removeEventListener("pointerdown",e)}))})),n.provide(d,I),function(){return r({props:e,slot:{open:s.value===i.Open},slots:o,attrs:a})}}}),p=n.defineComponent({props:{as:{type:[Object,String],default:"button"}},render:function(){var e,n=v("MenuButton"),o={open:n.menuState.value===i.Open},u={ref:"el",id:this.id,type:"button","aria-haspopup":!0,"aria-controls":null===(e=n.itemsRef.value)||void 0===e?void 0:e.id,"aria-expanded":n.menuState.value===i.Open||void 0,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onPointerUp:this.handlePointerUp,onPointerDown:this.handlePointerDown};return r({props:t({},this.$props,u),slot:o,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=v("MenuButton");return{id:"headlessui-menu-button-"+c(),el:e.buttonRef,handleKeyDown:function(t){switch(t.key){case a.Space:case a.Enter:case a.ArrowDown:t.preventDefault(),e.openMenu(),n.nextTick((function(){var n;null===(n=e.itemsRef.value)||void 0===n||n.focus(),e.goToItem(l.FirstItem)}));break;case a.ArrowUp:t.preventDefault(),e.openMenu(),n.nextTick((function(){var n;null===(n=e.itemsRef.value)||void 0===n||n.focus(),e.goToItem(l.LastItem)}))}},handlePointerDown:function(e){e.preventDefault()},handlePointerUp:function(){e.toggleMenu(),n.nextTick((function(){var n;return null===(n=e.itemsRef.value)||void 0===n?void 0:n.focus()}))},handleFocus:function(){var n;e.menuState.value===i.Open&&(null===(n=e.itemsRef.value)||void 0===n||n.focus())}}}}),m=n.defineComponent({props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1}},render:function(){var e,n,u=v("MenuItems"),a=this.$props,l=a.static,s=o(a,["static"]);if(!l&&u.menuState.value===i.Closed)return null;var c={open:u.menuState.value===i.Open};return r({props:t({},s,{"aria-activedescendant":null===u.activeItemIndex.value||null===(e=u.items.value[u.activeItemIndex.value])||void 0===e?void 0:e.id,"aria-labelledby":null===(n=u.buttonRef.value)||void 0===n?void 0:n.id,id:this.id,onKeyDown:this.handleKeyDown,role:"menu",tabIndex:0,ref:"el"}),slot:c,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=v("MenuItems"),t="headlessui-menu-items-"+c(),o=n.ref(null);return{id:t,el:e.itemsRef,handleKeyDown:function(t){switch(o.value&&clearTimeout(o.value),t.key){case a.Enter:var u;e.closeMenu(),null!==e.activeItemIndex.value&&(null===(u=document.getElementById(e.items.value[e.activeItemIndex.value].id))||void 0===u||u.click(),n.nextTick((function(){var n;return null===(n=e.buttonRef.value)||void 0===n?void 0:n.focus()})));break;case a.ArrowDown:return e.goToItem(l.NextItem);case a.ArrowUp:return e.goToItem(l.PreviousItem);case a.Home:case a.PageUp:return e.goToItem(l.FirstItem);case a.End:case a.PageDown:return e.goToItem(l.LastItem);case a.Escape:e.closeMenu(),n.nextTick((function(){var n;return null===(n=e.buttonRef.value)||void 0===n?void 0:n.focus()}));break;case a.Tab:return t.preventDefault();default:1===t.key.length&&(e.search(t.key),o.value=setTimeout((function(){return e.clearSearch()}),350))}}}}}),I=n.defineComponent({props:{as:{type:[Object,String],default:"template"},disabled:{type:Boolean,default:!1},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1},onClick:{type:Function,required:!1}},setup:function(e,o){var u=o.slots,i=o.attrs,a=v("MenuItem"),s="headlessui-menu-item-"+c(),d=e.disabled,f=e.className,p=void 0===f?e.class:f,m=n.computed((function(){return null!==a.activeItemIndex.value&&a.items.value[a.activeItemIndex.value].id===s})),I=n.ref({disabled:d,textValue:""});function g(){d||a.goToItem(l.SpecificItem,s)}function b(){if(d)return a.goToItem(l.Nothing);a.goToItem(l.SpecificItem,s)}function w(){d||a.goToItem(l.Nothing)}function y(){d||m.value||a.goToItem(l.SpecificItem,s)}function x(e){d||(e.preventDefault(),a.closeMenu(),n.nextTick((function(){var e;return null===(e=a.buttonRef.value)||void 0===e?void 0:e.focus()})))}function T(n){return d?n.preventDefault():e.onClick?e.onClick(n):void 0}return n.onMounted((function(){var e,n,t=null===(e=document.getElementById(s))||void 0===e||null===(n=e.textContent)||void 0===n?void 0:n.toLowerCase().trim();void 0!==t&&(I.value.textValue=t)})),n.onMounted((function(){return a.registerItem(s,I)})),n.onUnmounted((function(){return a.unregisterItem(s)})),function(){var n={active:m.value,disabled:d},o={id:s,role:"menuitem",tabIndex:-1,class:h(p,n),disabled:!0===d?d:void 0,"aria-disabled":!0===d?d:void 0,onClick:T,onFocus:b,onMouseMove:y,onPointerEnter:g,onPointerLeave:w,onPointerUp:x};return r({props:t({},e,o),slot:n,attrs:i,slots:u})}}});function h(e,n){if(void 0!==e)return"function"==typeof e?e(n):e}e.Menu=f,e.MenuButton=p,e.MenuItem=I,e.MenuItems=m,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue")):"function"==typeof define&&define.amd?define(["exports","vue"],t):t((e=e||self).headlessui={},e.Vue)}(this,(function(e,t){"use strict";function n(){return(n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e}).apply(this,arguments)}function o(e,t){if(null==e)return{};var n,o,u={},i=Object.keys(e);for(o=0;o<i.length;o++)t.indexOf(n=i[o])>=0||(u[n]=e[n]);return u}function u(e,t){if(e in t){for(var n=t[e],o=arguments.length,i=new Array(o>2?o-2:0),r=2;r<o;r++)i[r-2]=arguments[r];return"function"==typeof n?n.apply(void 0,i):n}var a=new Error('Tried to handle "'+e+'" but there is no handler defined. Only defined handlers are: '+Object.keys(t).map((function(e){return'"'+e+'"'})).join(", ")+".");throw Error.captureStackTrace&&Error.captureStackTrace(a,u),a}function i(e){var n,u=e.props,i=e.attrs,r=e.slots,a=e.slot,l=u.as,s=o(u,["as"]),c=null===(n=r.default)||void 0===n?void 0:n.call(r,a);if("template"===l){if(Object.keys(s).length>0||"class"in i){var d=null!=c?c:[],v=d[0];if(d.slice(1).length>0)throw new Error('You should only render 1 child or use the `as="..."` prop');return t.cloneVNode(v,s)}return c}return t.h(l,s,c)}var r,a,l,s=0;function c(){return++s}!function(e){e.Space=" ",e.Enter="Enter",e.Escape="Escape",e.Backspace="Backspace",e.ArrowUp="ArrowUp",e.ArrowDown="ArrowDown",e.Home="Home",e.End="End",e.PageUp="PageUp",e.PageDown="PageDown",e.Tab="Tab"}(r||(r={})),function(e){e[e.Open=0]="Open",e[e.Closed=1]="Closed"}(a||(a={})),function(e){e[e.FirstItem=0]="FirstItem",e[e.PreviousItem=1]="PreviousItem",e[e.NextItem=2]="NextItem",e[e.LastItem=3]="LastItem",e[e.SpecificItem=4]="SpecificItem",e[e.Nothing=5]="Nothing"}(l||(l={}));var d=Symbol("MenuContext");function v(e){var n=t.inject(d);if(void 0===n){var o=new Error("<"+e+" /> is missing a parent <Menu /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,v),o}return n}var f,p,h=t.defineComponent({props:{as:{type:[Object,String],default:"template"}},setup:function(e,n){var o=n.slots,r=n.attrs,s=t.ref(a.Closed),c=t.ref(null),v=t.ref(null),f=t.ref([]),p=t.ref(""),h=t.ref(null),m={menuState:s,buttonRef:c,itemsRef:v,items:f,searchQuery:p,activeItemIndex:h,closeMenu:function(){return s.value=a.Closed},openMenu:function(){return s.value=a.Open},goToItem:function(e,t){var n=function(e,t){var n,o;if(f.value.length<=0)return null;var i=null!==(n=h.value)&&void 0!==n?n:-1,r=u(e,((o={})[l.FirstItem]=function(){return f.value.findIndex((function(e){return!e.dataRef.disabled}))},o[l.PreviousItem]=function(){var e=f.value.slice().reverse().findIndex((function(e,t,n){return!(-1!==i&&n.length-t-1>=i||e.dataRef.disabled)}));return-1===e?e:f.value.length-1-e},o[l.NextItem]=function(){return f.value.findIndex((function(e,t){return!(t<=i||e.dataRef.disabled)}))},o[l.LastItem]=function(){var e=f.value.slice().reverse().findIndex((function(e){return!e.dataRef.disabled}));return-1===e?e:f.value.length-1-e},o[l.SpecificItem]=function(){return f.value.findIndex((function(e){return e.id===t}))},o[l.Nothing]=function(){return null},o));return-1===r?h.value:r}(e,t);""===p.value&&h.value===n||(p.value="",h.value=n)},search:function(e){p.value+=e;var t=f.value.findIndex((function(e){return e.dataRef.textValue.startsWith(p.value)&&!e.dataRef.disabled}));-1!==t&&t!==h.value&&(h.value=t)},clearSearch:function(){p.value=""},registerItem:function(e,t){f.value.push({id:e,dataRef:t})},unregisterItem:function(e){var t=f.value.slice(),n=null!==h.value?t[h.value]:null,o=t.findIndex((function(t){return t.id===e}));-1!==o&&t.splice(o,1),f.value=t,h.value=o===h.value||null===n?null:t.indexOf(n)}};return t.onMounted((function(){function e(e){var n,o;s.value===a.Open&&((null===(n=c.value)||void 0===n?void 0:n.contains(e.target))||((null===(o=v.value)||void 0===o?void 0:o.contains(e.target))||m.closeMenu(),e.defaultPrevented||t.nextTick((function(){var e;return null===(e=c.value)||void 0===e?void 0:e.focus()}))))}window.addEventListener("click",e),t.onUnmounted((function(){return window.removeEventListener("click",e)}))})),t.provide(d,m),function(){return i({props:e,slot:{open:s.value===a.Open},slots:o,attrs:r})}}}),m=t.defineComponent({props:{as:{type:[Object,String],default:"button"}},render:function(){var e,t=v("MenuButton"),o={open:t.menuState.value===a.Open},u={ref:"el",id:this.id,type:"button","aria-haspopup":!0,"aria-controls":null===(e=t.itemsRef.value)||void 0===e?void 0:e.id,"aria-expanded":t.menuState.value===a.Open||void 0,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onPointerUp:this.handlePointerUp};return i({props:n({},this.$props,u),slot:o,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=v("MenuButton");return{id:"headlessui-menu-button-"+c(),el:e.buttonRef,handleKeyDown:function(n){switch(n.key){case r.Space:case r.Enter:case r.ArrowDown:n.preventDefault(),e.openMenu(),t.nextTick((function(){var t;null===(t=e.itemsRef.value)||void 0===t||t.focus(),e.goToItem(l.FirstItem)}));break;case r.ArrowUp:n.preventDefault(),e.openMenu(),t.nextTick((function(){var t;null===(t=e.itemsRef.value)||void 0===t||t.focus(),e.goToItem(l.LastItem)}))}},handlePointerUp:function(n){e.menuState.value===a.Open?(e.closeMenu(),t.nextTick((function(){var t;return null===(t=e.buttonRef.value)||void 0===t?void 0:t.focus()}))):(n.preventDefault(),e.openMenu(),t.nextTick((function(){var t;return null===(t=e.itemsRef.value)||void 0===t?void 0:t.focus()})))},handleFocus:function(){var t;e.menuState.value===a.Open&&(null===(t=e.itemsRef.value)||void 0===t||t.focus())}}}}),b=t.defineComponent({props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1}},render:function(){var e,t,u=v("MenuItems"),r=this.$props,l=r.static,s=o(r,["static"]);if(!l&&u.menuState.value===a.Closed)return null;var c={open:u.menuState.value===a.Open};return i({props:n({},s,{"aria-activedescendant":null===u.activeItemIndex.value||null===(e=u.items.value[u.activeItemIndex.value])||void 0===e?void 0:e.id,"aria-labelledby":null===(t=u.buttonRef.value)||void 0===t?void 0:t.id,id:this.id,onKeyDown:this.handleKeyDown,role:"menu",tabIndex:0,ref:"el"}),slot:c,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=v("MenuItems"),n="headlessui-menu-items-"+c(),o=t.ref(null);return{id:n,el:e.itemsRef,handleKeyDown:function(n){switch(o.value&&clearTimeout(o.value),n.key){case r.Space:if(""!==e.searchQuery.value)return n.preventDefault(),e.search(n.key);case r.Enter:var u;n.preventDefault(),e.closeMenu(),null!==e.activeItemIndex.value&&(null===(u=document.getElementById(e.items.value[e.activeItemIndex.value].id))||void 0===u||u.click()),t.nextTick((function(){var t;return null===(t=e.buttonRef.value)||void 0===t?void 0:t.focus()}));break;case r.ArrowDown:return n.preventDefault(),e.goToItem(l.NextItem);case r.ArrowUp:return n.preventDefault(),e.goToItem(l.PreviousItem);case r.Home:case r.PageUp:return n.preventDefault(),e.goToItem(l.FirstItem);case r.End:case r.PageDown:return n.preventDefault(),e.goToItem(l.LastItem);case r.Escape:n.preventDefault(),e.closeMenu(),t.nextTick((function(){var t;return null===(t=e.buttonRef.value)||void 0===t?void 0:t.focus()}));break;case r.Tab:return n.preventDefault();default:1===n.key.length&&(e.search(n.key),o.value=setTimeout((function(){return e.clearSearch()}),350))}}}}}),x=t.defineComponent({props:{as:{type:[Object,String],default:"template"},disabled:{type:Boolean,default:!1},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1}},setup:function(e,o){var u=o.slots,r=o.attrs,a=v("MenuItem"),s="headlessui-menu-item-"+c(),d=e.disabled,f=e.className,p=void 0===f?e.class:f,h=t.computed((function(){return null!==a.activeItemIndex.value&&a.items.value[a.activeItemIndex.value].id===s})),m=t.ref({disabled:d,textValue:""});function b(e){if(d)return e.preventDefault();a.closeMenu(),t.nextTick((function(){var e;return null===(e=a.buttonRef.value)||void 0===e?void 0:e.focus()}))}function x(){if(d)return a.goToItem(l.Nothing);a.goToItem(l.SpecificItem,s)}function I(){d||h.value||a.goToItem(l.SpecificItem,s)}function y(){d||h.value&&a.goToItem(l.Nothing)}return t.onMounted((function(){var e,t,n=null===(e=document.getElementById(s))||void 0===e||null===(t=e.textContent)||void 0===t?void 0:t.toLowerCase().trim();void 0!==n&&(m.value.textValue=n)})),t.onMounted((function(){return a.registerItem(s,m)})),t.onUnmounted((function(){return a.unregisterItem(s)})),function(){var t={active:h.value,disabled:d},o={id:s,role:"menuitem",tabIndex:-1,class:g(p,t),"aria-disabled":!0===d||void 0,onClick:b,onFocus:x,onPointerMove:I,onPointerLeave:y};return i({props:n({},e,o),slot:t,attrs:r,slots:u})}}});function g(e,t){if(void 0!==e)return"function"==typeof e?e(t):e}!function(e){e[e.Open=0]="Open",e[e.Closed=1]="Closed"}(f||(f={})),function(e){e[e.First=0]="First",e[e.Previous=1]="Previous",e[e.Next=2]="Next",e[e.Last=3]="Last",e[e.Specific=4]="Specific",e[e.Nothing=5]="Nothing"}(p||(p={}));var I=Symbol("ListboxContext");function y(e){var n=t.inject(I);if(void 0===n){var o=new Error("<"+e+" /> is missing a parent <Listbox /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,y),o}return n}var w=t.defineComponent({name:"Listbox",props:{as:{type:[Object,String],default:"template"},modelValue:{type:[Object,String],default:null}},setup:function(e,n){var r=n.slots,a=n.attrs,l=n.emit,s=o(e,["modelValue"]),c=t.ref(f.Closed),d=t.ref(null),v=t.ref(null),h=t.ref(null),m=t.ref([]),b=t.ref(""),x=t.ref(null),g=t.computed((function(){return e.modelValue})),y={listboxState:c,value:g,labelRef:d,buttonRef:v,optionsRef:h,options:m,searchQuery:b,activeOptionIndex:x,closeListbox:function(){return c.value=f.Closed},openListbox:function(){return c.value=f.Open},goToOption:function(e,t){var n=function(e,t){var n,o;if(m.value.length<=0)return null;var i=null!==(n=x.value)&&void 0!==n?n:-1,r=u(e,((o={})[p.First]=function(){return m.value.findIndex((function(e){return!e.dataRef.disabled}))},o[p.Previous]=function(){var e=m.value.slice().reverse().findIndex((function(e,t,n){return!(-1!==i&&n.length-t-1>=i||e.dataRef.disabled)}));return-1===e?e:m.value.length-1-e},o[p.Next]=function(){return m.value.findIndex((function(e,t){return!(t<=i||e.dataRef.disabled)}))},o[p.Last]=function(){var e=m.value.slice().reverse().findIndex((function(e){return!e.dataRef.disabled}));return-1===e?e:m.value.length-1-e},o[p.Specific]=function(){return m.value.findIndex((function(e){return e.id===t}))},o[p.Nothing]=function(){return null},o));return-1===r?x.value:r}(e,t);""===b.value&&x.value===n||(b.value="",x.value=n)},search:function(e){b.value+=e;var t=m.value.findIndex((function(e){return!e.dataRef.disabled&&e.dataRef.textValue.startsWith(b.value)}));-1!==t&&t!==x.value&&(x.value=t)},clearSearch:function(){b.value=""},registerOption:function(e,t){m.value.push({id:e,dataRef:t})},unregisterOption:function(e){var t=m.value.slice(),n=null!==x.value?t[x.value]:null,o=t.findIndex((function(t){return t.id===e}));-1!==o&&t.splice(o,1),m.value=t,x.value=o===x.value||null===n?null:t.indexOf(n)},select:function(e){l("update:modelValue",e)}};return t.onMounted((function(){function e(e){var n,o;c.value===f.Open&&((null===(n=v.value)||void 0===n?void 0:n.contains(e.target))||((null===(o=h.value)||void 0===o?void 0:o.contains(e.target))||y.closeListbox(),e.defaultPrevented||t.nextTick((function(){var e;return null===(e=v.value)||void 0===e?void 0:e.focus()}))))}window.addEventListener("click",e),t.onUnmounted((function(){return window.removeEventListener("click",e)}))})),t.provide(I,y),function(){return i({props:s,slot:{open:c.value===f.Open},slots:r,attrs:a})}}}),O=t.defineComponent({name:"ListboxLabel",props:{as:{type:[Object,String],default:"label"}},render:function(){var e={open:y("ListboxLabel").listboxState.value===f.Open};return i({props:n({},this.$props,{id:this.id,ref:"el",onPointerUp:this.handlePointerUp}),slot:e,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=y("ListboxLabel");return{id:"headlessui-listbox-label-"+c(),el:e.labelRef,handlePointerUp:function(){var t;null===(t=e.buttonRef.value)||void 0===t||t.focus()}}}}),S=t.defineComponent({name:"ListboxButton",props:{as:{type:[Object,String],default:"button"}},render:function(){var e,t=y("ListboxButton"),o={open:t.listboxState.value===f.Open,focused:this.focused},u={ref:"el",id:this.id,type:"button","aria-haspopup":!0,"aria-controls":null===(e=t.optionsRef.value)||void 0===e?void 0:e.id,"aria-expanded":t.listboxState.value===f.Open||void 0,"aria-labelledby":t.labelRef.value?[t.labelRef.value.id,this.id].join(" "):void 0,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onBlur:this.handleBlur,onPointerUp:this.handlePointerUp};return i({props:n({},this.$props,u),slot:o,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=y("ListboxButton"),n="headlessui-listbox-button-"+c(),o=t.ref(!1);return{id:n,el:e.buttonRef,focused:o,handleKeyDown:function(n){switch(n.key){case r.Space:case r.Enter:case r.ArrowDown:n.preventDefault(),e.openListbox(),t.nextTick((function(){var t;null===(t=e.optionsRef.value)||void 0===t||t.focus(),e.value.value||e.goToOption(p.First)}));break;case r.ArrowUp:n.preventDefault(),e.openListbox(),t.nextTick((function(){var t;null===(t=e.optionsRef.value)||void 0===t||t.focus(),e.value.value||e.goToOption(p.Last)}))}},handlePointerUp:function(n){e.listboxState.value===f.Open?(e.closeListbox(),t.nextTick((function(){var t;return null===(t=e.buttonRef.value)||void 0===t?void 0:t.focus()}))):(n.preventDefault(),e.openListbox(),t.nextTick((function(){var t;return null===(t=e.optionsRef.value)||void 0===t?void 0:t.focus()})))},handleFocus:function(){var t;if(e.listboxState.value===f.Open)return null===(t=e.optionsRef.value)||void 0===t?void 0:t.focus();o.value=!0},handleBlur:function(){o.value=!1}}}}),k=t.defineComponent({name:"ListboxOptions",props:{as:{type:[Object,String],default:"ul"},static:{type:Boolean,default:!1}},render:function(){var e,t,u,r,a=y("ListboxOptions"),l=this.$props,s=l.static,c=o(l,["static"]);if(!s&&a.listboxState.value===f.Closed)return null;var d={open:a.listboxState.value===f.Open};return i({props:n({},c,{"aria-activedescendant":null===a.activeOptionIndex.value||null===(e=a.options.value[a.activeOptionIndex.value])||void 0===e?void 0:e.id,"aria-labelledby":null!==(t=null===(u=a.labelRef.value)||void 0===u?void 0:u.id)&&void 0!==t?t:null===(r=a.buttonRef.value)||void 0===r?void 0:r.id,id:this.id,onKeyDown:this.handleKeyDown,role:"listbox",tabIndex:0,ref:"el"}),slot:d,attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=y("ListboxOptions"),n="headlessui-listbox-options-"+c(),o=t.ref(null);return{id:n,el:e.optionsRef,handleKeyDown:function(n){switch(o.value&&clearTimeout(o.value),n.key){case r.Space:if(""!==e.searchQuery.value)return n.preventDefault(),e.search(n.key);case r.Enter:n.preventDefault(),e.closeListbox(),null!==e.activeOptionIndex.value&&e.select(e.options.value[e.activeOptionIndex.value].dataRef.value),t.nextTick((function(){var t;return null===(t=e.buttonRef.value)||void 0===t?void 0:t.focus()}));break;case r.ArrowDown:return n.preventDefault(),e.goToOption(p.Next);case r.ArrowUp:return n.preventDefault(),e.goToOption(p.Previous);case r.Home:case r.PageUp:return n.preventDefault(),e.goToOption(p.First);case r.End:case r.PageDown:return n.preventDefault(),e.goToOption(p.Last);case r.Escape:n.preventDefault(),e.closeListbox(),t.nextTick((function(){var t;return null===(t=e.buttonRef.value)||void 0===t?void 0:t.focus()}));break;case r.Tab:return n.preventDefault();default:1===n.key.length&&(e.search(n.key),o.value=setTimeout((function(){return e.clearSearch()}),350))}}}}}),R=t.defineComponent({name:"ListboxOption",props:{as:{type:[Object,String],default:"li"},value:{type:[Object,String],default:null},disabled:{type:Boolean,default:!1},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1}},setup:function(e,o){var u=o.slots,r=o.attrs,a=y("ListboxOption"),l="headlessui-listbox-option-"+c(),s=e.disabled,d=e.className,v=void 0===d?e.class:d,f=e.value,h=t.computed((function(){return null!==a.activeOptionIndex.value&&a.options.value[a.activeOptionIndex.value].id===l})),m=t.computed((function(){return t.toRaw(a.value.value)===t.toRaw(f)})),b=t.ref({disabled:s,value:f,textValue:""});function x(e){if(s)return e.preventDefault();a.select(f),a.closeListbox(),t.nextTick((function(){var e;return null===(e=a.buttonRef.value)||void 0===e?void 0:e.focus()}))}function g(){if(s)return a.goToOption(p.Nothing);a.goToOption(p.Specific,l)}function I(){s||h.value||a.goToOption(p.Specific,l)}function w(){s||h.value&&a.goToOption(p.Nothing)}return t.onMounted((function(){var e,t,n=null===(e=document.getElementById(l))||void 0===e||null===(t=e.textContent)||void 0===t?void 0:t.toLowerCase().trim();void 0!==n&&(b.value.textValue=n)})),t.onMounted((function(){return a.registerOption(l,b)})),t.onUnmounted((function(){return a.unregisterOption(l)})),t.onMounted((function(){var e,t;m.value&&(a.goToOption(p.Specific,l),null===(e=document.getElementById(l))||void 0===e||null===(t=e.focus)||void 0===t||t.call(e))})),t.watchEffect((function(){h.value&&t.nextTick((function(){var e,t;return null===(e=document.getElementById(l))||void 0===e||null===(t=e.scrollIntoView)||void 0===t?void 0:t.call(e,{block:"nearest"})}))})),function(){var t={active:h.value,selected:m.value,disabled:s},o={id:l,role:"option",tabIndex:-1,class:T(v,t),"aria-disabled":!0===s||void 0,"aria-selected":!0===m.value?m.value:void 0,onClick:x,onFocus:g,onPointerMove:I,onPointerLeave:w};return i({props:n({},e,o),slot:t,attrs:r,slots:u})}}});function T(e,t){if(void 0!==e)return"function"==typeof e?e(t):e}var L=Symbol("GroupContext");function D(e){var n=t.inject(L,null);if(null===n){var o=new Error("<"+e+" /> is missing a parent <SwitchGroup /> component.");throw Error.captureStackTrace&&Error.captureStackTrace(o,D),o}return n}var E=t.defineComponent({name:"SwitchGroup",props:{as:{type:[Object,String],default:"template"}},setup:function(e,n){var o=n.slots,u=n.attrs,r=t.ref(null),a=t.ref(null);return t.provide(L,{switchRef:r,labelRef:a}),function(){return i({props:e,slot:{},slots:o,attrs:u})}}}),P=t.defineComponent({name:"Switch",props:{as:{type:[Object,String],default:"button"},modelValue:{type:[Object,Boolean],default:null},class:{type:[String,Function],required:!1},className:{type:[String,Function],required:!1}},render:function(){var e=t.inject(L,null),o=this.$props,u=o.className,r=void 0===u?o.class:u,a=t.computed((function(){var t;return null==e||null===(t=e.labelRef.value)||void 0===t?void 0:t.id})),l={checked:this.$props.modelValue},s={id:this.id,ref:null===e?void 0:e.switchRef,role:"switch",tabIndex:0,class:M(r,l),"aria-checked":this.$props.modelValue,"aria-labelledby":a.value,onClick:this.handleClick,onKeyUp:this.handleKeyUp};return i({props:n({},this.$props,s),slot:l,attrs:this.$attrs,slots:this.$slots})},setup:function(e,n){var o=n.emit,u=t.inject(L,null);function i(){o("update:modelValue",!e.modelValue)}return{id:"headlessui-switch-"+c(),el:null==u?void 0:u.switchRef,handleClick:function(e){e.preventDefault(),i()},handleKeyUp:function(e){e.key===r.Space&&(e.preventDefault(),i())}}}}),C=t.defineComponent({name:"SwitchLabel",props:{as:{type:[Object,String],default:"label"}},render:function(){return i({props:n({},this.$props,{id:this.id,ref:"el",onPointerUp:this.handlePointerUp}),slot:{},attrs:this.$attrs,slots:this.$slots})},setup:function(){var e=D("SwitchLabel");return{id:"headlessui-switch-label-"+c(),el:e.labelRef,handlePointerUp:function(){var t,n;null===(t=e.switchRef.value)||void 0===t||t.click(),null===(n=e.switchRef.value)||void 0===n||n.focus()}}}});function M(e,t){if(void 0!==e)return"function"==typeof e?e(t):e}e.Listbox=w,e.ListboxButton=S,e.ListboxLabel=O,e.ListboxOption=R,e.ListboxOptions=k,e.Menu=h,e.MenuButton=m,e.MenuItem=x,e.MenuItems=b,e.Switch=P,e.SwitchGroup=E,e.SwitchLabel=C,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=headlessui.umd.production.min.js.map |
export * from './components/menu/menu'; | ||
export * from './components/listbox/listbox'; | ||
export * from './components/switch/switch'; |
@@ -1,35 +0,76 @@ | ||
export declare enum MenuButtonState { | ||
export declare function getMenuButton(): HTMLElement | null; | ||
export declare function getMenuButtons(): HTMLElement[]; | ||
export declare function getMenu(): HTMLElement | null; | ||
export declare function getMenus(): HTMLElement[]; | ||
export declare function getMenuItems(): HTMLElement[]; | ||
export declare enum MenuState { | ||
Open = 0, | ||
Closed = 1 | ||
} | ||
export declare enum MenuState { | ||
export declare function assertMenuButton(options: { | ||
attributes?: Record<string, string | null>; | ||
textContent?: string; | ||
state: MenuState; | ||
}, button?: HTMLElement | null): void; | ||
export declare function assertMenuButtonLinkedWithMenu(button?: HTMLElement | null, menu?: HTMLElement | null): void; | ||
export declare function assertMenuLinkedWithMenuItem(item: HTMLElement | null, menu?: HTMLElement | null): void; | ||
export declare function assertNoActiveMenuItem(menu?: HTMLElement | null): void; | ||
export declare function assertMenu(options: { | ||
attributes?: Record<string, string | null>; | ||
textContent?: string; | ||
state: MenuState; | ||
}, menu?: HTMLElement | null): void; | ||
export declare function assertMenuItem(item: HTMLElement | null, options?: { | ||
tag?: string; | ||
attributes?: Record<string, string | null>; | ||
}): void; | ||
export declare function getListboxLabel(): HTMLElement | null; | ||
export declare function getListboxButton(): HTMLElement | null; | ||
export declare function getListboxButtons(): HTMLElement[]; | ||
export declare function getListbox(): HTMLElement | null; | ||
export declare function getListboxes(): HTMLElement[]; | ||
export declare function getListboxOptions(): HTMLElement[]; | ||
export declare enum ListboxState { | ||
Open = 0, | ||
Closed = 1 | ||
} | ||
declare type MenuButtonOptions = { | ||
export declare function assertListbox(options: { | ||
attributes?: Record<string, string | null>; | ||
textContent?: string; | ||
} & ({ | ||
state: MenuButtonState.Closed; | ||
} | { | ||
state: MenuButtonState.Open; | ||
}); | ||
export declare function assertMenuButton(button: HTMLElement | null, options: MenuButtonOptions): void; | ||
export declare function assertMenuButtonLinkedWithMenu(button: HTMLElement | null, menu: HTMLElement | null): void; | ||
export declare function assertMenuLinkedWithMenuItem(menu: HTMLElement | null, item: HTMLElement | null): void; | ||
export declare function assertNoActiveMenuItem(menu: HTMLElement | null): void; | ||
declare type MenuOptions = { | ||
state: ListboxState; | ||
}, listbox?: HTMLElement | null): void; | ||
export declare function assertListboxButton(options: { | ||
attributes?: Record<string, string | null>; | ||
} & ({ | ||
state: MenuState.Closed; | ||
} | { | ||
state: MenuState.Open; | ||
}); | ||
export declare function assertMenu(menu: HTMLElement | null, options: MenuOptions): void; | ||
declare type MenuItemOptions = { | ||
tag: string; | ||
textContent?: string; | ||
state: ListboxState; | ||
}, button?: HTMLElement | null): void; | ||
export declare function assertListboxLabel(options: { | ||
attributes?: Record<string, string | null>; | ||
}; | ||
export declare function assertMenuItem(item: HTMLElement | null, options?: MenuItemOptions): void; | ||
tag?: string; | ||
textContent?: string; | ||
}, label?: HTMLElement | null): void; | ||
export declare function assertListboxButtonLinkedWithListbox(button?: HTMLElement | null, listbox?: HTMLElement | null): void; | ||
export declare function assertListboxLabelLinkedWithListbox(label?: HTMLElement | null, listbox?: HTMLElement | null): void; | ||
export declare function assertListboxButtonLinkedWithListboxLabel(button?: HTMLElement | null, label?: HTMLElement | null): void; | ||
export declare function assertActiveListboxOption(item: HTMLElement | null, listbox?: HTMLElement | null): void; | ||
export declare function assertNoActiveListboxOption(listbox?: HTMLElement | null): void; | ||
export declare function assertNoSelectedListboxOption(items?: HTMLElement[]): void; | ||
export declare function assertListboxOption(item: HTMLElement | null, options?: { | ||
tag?: string; | ||
attributes?: Record<string, string | null>; | ||
selected?: boolean; | ||
}): void; | ||
export declare function getSwitch(): HTMLElement | null; | ||
export declare function getSwitchLabel(): HTMLElement | null; | ||
export declare enum SwitchState { | ||
On = 0, | ||
Off = 1 | ||
} | ||
export declare function assertSwitch(options: { | ||
state: SwitchState; | ||
tag?: string; | ||
textContent?: string; | ||
label?: string; | ||
}, switchElement?: HTMLElement | null): void; | ||
export declare function assertLabelValue(element: HTMLElement | null, value: string): void; | ||
export declare function assertActiveElement(element: HTMLElement | null): void; | ||
export {}; |
@@ -51,4 +51,4 @@ export declare const Keys: Record<string, Partial<KeyboardEvent>>; | ||
export declare function focus(element: Document | Element | Window | null): Promise<void>; | ||
export declare function mouseEnter(element: Document | Element | Window | null): Promise<void>; | ||
export declare function mouseMove(element: Document | Element | Window | null): Promise<void>; | ||
export declare function hover(element: Document | Element | Window | null): Promise<void>; | ||
export declare function unHover(element: Document | Element | Window | null): Promise<void>; | ||
export declare function mouseLeave(element: Document | Element | Window | null): Promise<void>; |
{ | ||
"name": "@headlessui/vue", | ||
"version": "0.0.0-alpha.1", | ||
"version": "0.0.0-fc42dde", | ||
"main": "dist/index.js", | ||
@@ -23,3 +23,5 @@ "typings": "dist/index.d.ts", | ||
"scripts": { | ||
"playground": "vite", | ||
"playground": "vite serve examples", | ||
"playground:build": "NODE_ENV=production vite build examples", | ||
"prepublishOnly": "npm run build", | ||
"build": "../../scripts/build.sh", | ||
@@ -30,18 +32,16 @@ "test": "../../scripts/test.sh", | ||
"peerDependencies": { | ||
"vue": "^3.0.0-rc.10" | ||
"vue": "^3.0.0-rc.13" | ||
}, | ||
"devDependencies": { | ||
"@popperjs/core": "^2.4.4", | ||
"@tailwindcss/ui": "^0.6.0", | ||
"@testing-library/vue": "^5.0.4", | ||
"@popperjs/core": "^2.5.3", | ||
"@testing-library/vue": "^5.1.0", | ||
"@types/debounce": "^1.2.0", | ||
"@types/node": "^14.6.4", | ||
"@vue/compiler-sfc": "^3.0.0-rc.10", | ||
"@vue/test-utils": "^2.0.0-beta.4", | ||
"@types/node": "^14.11.2", | ||
"@vue/compiler-sfc": "3.0.0", | ||
"@vue/test-utils": "^2.0.0-beta.6", | ||
"husky": "^4.3.0", | ||
"tailwindcss": "^1.8.8", | ||
"tsdx": "^0.13.3", | ||
"vite": "^1.0.0-rc.4", | ||
"vue": "^3.0.0-rc.10" | ||
"vue": "^3.0.0-rc.13", | ||
"vue-router": "^4.0.0-beta.12" | ||
} | ||
} |
@@ -52,5 +52,7 @@ <h3 align="center"> | ||
--- | ||
## Menu Button (Dropdown) | ||
[View complete demo on CodeSandbox](https://codesandbox.io/s/flamboyant-glade-b2jb4?file=/src/App.vue) | ||
[View live demo on CodeSandbox](https://codesandbox.io/s/headlessuivue-menu-example-70br3?file=/src/App.vue) | ||
@@ -73,20 +75,12 @@ The `Menu` component and related child components are used to quickly build custom dropdown components that are fully accessible out of the box, including correct ARIA attribute management and robust keyboard navigation support. | ||
<Menu> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
<MenuItems> | ||
<MenuItem v-slot="{ active }"> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> | ||
Account settings | ||
</a> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> Account settings </a> | ||
</MenuItem> | ||
<MenuItem v-slot="{ active }"> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> | ||
Documentation | ||
</a> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> Documentation </a> | ||
</MenuItem> | ||
<MenuItem v-slot="{ active }" disabled> | ||
<span :class="{ 'bg-blue-500': active }"> | ||
Invite a friend (coming soon!) | ||
</span> | ||
<span :class="{ 'bg-blue-500': active }"> Invite a friend (coming soon!) </span> | ||
</MenuItem> | ||
@@ -122,5 +116,3 @@ </MenuItems> | ||
<Menu> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
<MenuItems> | ||
@@ -146,5 +138,3 @@ <!-- Use the `active` state to conditionally style the active item. --> | ||
<Menu> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
@@ -154,5 +144,3 @@ <!-- By default, this will automatically show/hide when the MenuButton is pressed. --> | ||
<MenuItem v-slot="{ active }"> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> | ||
Account settings | ||
</a> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> Account settings </a> | ||
</MenuItem> | ||
@@ -170,5 +158,3 @@ <!-- ... --> | ||
<Menu v-slot="{ open }"> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
@@ -179,5 +165,3 @@ <div v-show="open"> | ||
<MenuItem v-slot="{ active }"> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> | ||
Account settings | ||
</a> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> Account settings </a> | ||
</MenuItem> | ||
@@ -198,5 +182,3 @@ <!-- ... --> | ||
<Menu> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
<MenuItems> | ||
@@ -219,5 +201,3 @@ <MenuItem disabled> | ||
<Menu> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
<transition | ||
@@ -233,5 +213,3 @@ enter-active-class="transition duration-100 ease-out" | ||
<MenuItem v-slot="{ active }"> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> | ||
Account settings | ||
</a> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> Account settings </a> | ||
</MenuItem> | ||
@@ -254,5 +232,3 @@ <!-- ... --> | ||
<Menu> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
<MenuItems> | ||
@@ -264,5 +240,3 @@ <div class="px-4 py-3"> | ||
<MenuItem v-slot="{ active }"> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> | ||
Account settings | ||
</a> | ||
<a :class="{ 'bg-blue-500': active }" href="/account-settings"> Account settings </a> | ||
</MenuItem> | ||
@@ -289,5 +263,3 @@ <!-- ... --> | ||
<Menu as="div"> | ||
<MenuButton> | ||
More | ||
</MenuButton> | ||
<MenuButton> More </MenuButton> | ||
<!-- Render a `ul` instead of a `div` --> | ||
@@ -297,5 +269,3 @@ <MenuItems as="ul"> | ||
<MenuItem as="li" v-slot="{ active }"> | ||
<a href="/account-settings" :class="{ 'bg-blue-500': active }"> | ||
Account settings | ||
</a> | ||
<a href="/account-settings" :class="{ 'bg-blue-500': active }"> Account settings </a> | ||
</MenuItem> | ||
@@ -315,11 +285,7 @@ <!-- ... --> | ||
<MenuButton as="template"> | ||
<button> | ||
More | ||
</button> | ||
<button>More</button> | ||
</MenuButton> | ||
<MenuItems> | ||
<MenuItem v-slot="{ active }"> | ||
<a href="/account-settings" :class="{ 'bg-blue-500': active }"> | ||
Account settings | ||
</a> | ||
<a href="/account-settings" :class="{ 'bg-blue-500': active }"> Account settings </a> | ||
</MenuItem> | ||
@@ -348,5 +314,5 @@ <!-- ... --> | ||
| Prop | Type | Default | Description | | ||
| ---- | ------------------- | --------------------------------- | ---------------------------------------------------------- | | ||
| `as` | String \| Component | `template` _(no wrapper element_) | The element or component the `MenuItems` should render as. | | ||
| Prop | Type | Default | Description | | ||
| ---- | ------------------- | --------------------------------- | ----------------------------------------------------- | | ||
| `as` | String \| Component | `template` _(no wrapper element_) | The element or component the `Menu` should render as. | | ||
@@ -370,5 +336,5 @@ ##### Slot props | ||
| Prop | Type | Default | Description | | ||
| ---- | ------------------- | -------- | ---------------------------------------------------------- | | ||
| `as` | String \| Component | `button` | The element or component the `MenuItems` should render as. | | ||
| Prop | Type | Default | Description | | ||
| ---- | ------------------- | -------- | ----------------------------------------------------------- | | ||
| `as` | String \| Component | `button` | The element or component the `MenuButton` should render as. | | ||
@@ -375,0 +341,0 @@ ##### Slot props |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
558882
10
26
4360
375
1