mirror of
https://github.com/tenrok/vue-select.git
synced 2026-05-17 02:29:37 +03:00
Merge branch '@beta/listbox-poc' into @beta/dev
This commit is contained in:
+84
-28
@@ -1,43 +1,99 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<v-select v-model="selected" v-bind="config" />
|
||||
<div class="flex flex-col items-center space-y-10 justify-center pt-40">
|
||||
<StyledComboBox
|
||||
:label="({ label }) => label"
|
||||
v-model="selected"
|
||||
:options="config.options"
|
||||
>
|
||||
<ComboBoxOption
|
||||
@click="selected = country"
|
||||
v-for="country in config.options"
|
||||
:key="country.id"
|
||||
:class="['px-2 py-1']"
|
||||
:value="country"
|
||||
#default="{ isSelected }"
|
||||
>
|
||||
<span :class="{ 'text-indigo-600': isSelected }">
|
||||
{{ country.label }}
|
||||
</span>
|
||||
</ComboBoxOption>
|
||||
</StyledComboBox>
|
||||
|
||||
<ComboBox v-model="selected" class="text-left w-64 relative">
|
||||
<ComboBoxButton
|
||||
as="div"
|
||||
class="px-2 border flex rounded items-center justify-center h-12 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
||||
>
|
||||
<div class="flex-1">
|
||||
{{ selected?.label }}
|
||||
</div>
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</ComboBoxButton>
|
||||
|
||||
<ComboBoxMenu
|
||||
class="absolute mt-1 left-0 w-full h-64 overflow-y-scroll space-y-1 border rounded"
|
||||
>
|
||||
<ComboBoxOption
|
||||
@click="selected = country"
|
||||
v-for="country in config.options"
|
||||
as="button"
|
||||
:key="country.id"
|
||||
:class="['px-2 py-1 flex text-left hover:bg-gray-100 w-full']"
|
||||
:value="country"
|
||||
#default="{ isSelected }"
|
||||
>
|
||||
<span :class="{ 'text-indigo-600': isSelected }">
|
||||
{{ country.label }}
|
||||
</span>
|
||||
</ComboBoxOption>
|
||||
</ComboBoxMenu>
|
||||
</ComboBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import vSelect from '@/components/Select.vue'
|
||||
import countries from '../docs/.vuepress/data/countryCodes.js'
|
||||
import StyledComboBox from '@/components/ComboBox/StyledComboBox.vue'
|
||||
import ComboBoxOption from '@/components/ComboBox/ComboBoxOption.vue'
|
||||
import ComboBox from '@/components/ComboBox/ComboBox.vue'
|
||||
import ComboBoxMenu from '@/components/ComboBox/ComboBoxMenu.vue'
|
||||
import ComboBoxButton from '@/components/ComboBox/ComboBoxButton.vue'
|
||||
import ComboBoxInput from '@/components/ComboBox/ComboBoxInput.vue'
|
||||
|
||||
export default {
|
||||
components: { vSelect },
|
||||
components: {
|
||||
ComboBoxInput,
|
||||
ComboBoxButton,
|
||||
ComboBoxMenu,
|
||||
ComboBox,
|
||||
ComboBoxOption,
|
||||
StyledComboBox,
|
||||
},
|
||||
data: () => ({
|
||||
selected: null,
|
||||
selected: {
|
||||
styled: null,
|
||||
composed: null,
|
||||
},
|
||||
open: false,
|
||||
|
||||
config: {
|
||||
options: countries,
|
||||
},
|
||||
}),
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
font-family: -apple-system, sans-serif;
|
||||
}
|
||||
|
||||
#app {
|
||||
height: 100%;
|
||||
max-width: 20rem;
|
||||
margin: 10rem auto 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid #cacaca;
|
||||
margin-bottom: 1em;
|
||||
padding-top: 1em;
|
||||
width: 90%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
By default, the dropdown will open anytime the underlying search input has focus. The dropdown will
|
||||
open when clicked, or when it has received focus when tabbing through inputs.
|
||||
|
||||
## Customizing Dropdown Behaviour <Badge text="v3.12.0+" />
|
||||
## Customizing Dropdown Behaviour <Badge text="v4+" />
|
||||
|
||||
The `dropdownShouldOpen` prop allows for full customization of the open/close behaviour. The prop
|
||||
accepts a `function` that should return a `boolean` value. The returned boolean value will be used
|
||||
to determine if the dropdown should be `open`/`true` or `false`/`closed`. The function receives the
|
||||
instance of the component as the only argument.
|
||||
The `open` prop can control showing and hiding the dropdown menu from a parent component. If this prop is set, the component will always use the value of `props.open` to handle showing and hiding the dropdown. Vue Select will emit the `update:open` when the prop value should change, so you can use `<VueSelect v-model:open="open" />` to have control over the `open` state while preserving default behaviour.
|
||||
|
||||
#### Example: Open the dropdown when search text is present
|
||||
---
|
||||
|
||||
+4
-3
@@ -1,9 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vue Select Dev</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vue Select Dev</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
+100
-100
@@ -1,104 +1,104 @@
|
||||
{
|
||||
"name": "vue-select",
|
||||
"version": "4.0.0-beta.6",
|
||||
"description": "Everything you wish the HTML <select> element could do, wrapped up into a lightweight, extensible Vue component.",
|
||||
"author": "Jeff Sagal <sagalbot@gmail.com>",
|
||||
"homepage": "https://vue-select.org",
|
||||
"directories": {
|
||||
"doc": "docs",
|
||||
"test": "tests"
|
||||
"name": "vue-select",
|
||||
"version": "4.0.0-beta.6",
|
||||
"description": "Everything you wish the HTML <select> element could do, wrapped up into a lightweight, extensible Vue component.",
|
||||
"author": "Jeff Sagal <sagalbot@gmail.com>",
|
||||
"homepage": "https://vue-select.org",
|
||||
"directories": {
|
||||
"doc": "docs",
|
||||
"test": "tests"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/vue-select.umd.js",
|
||||
"module": "./dist/vue-select.es.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/vue-select.es.js",
|
||||
"require": "./dist/vue-select.umd.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/vue-select.umd.js",
|
||||
"module": "./dist/vue-select.es.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/vue-select.es.js",
|
||||
"require": "./dist/vue-select.umd.js"
|
||||
},
|
||||
"./dist/vue-select.css": {
|
||||
"import": "./dist/vue-select.css",
|
||||
"require": "./dist/vue-select.css",
|
||||
"style": "./dist/vue-select.css"
|
||||
}
|
||||
},
|
||||
"private": false,
|
||||
"license": "MIT",
|
||||
"prepare": "npm run build",
|
||||
"scripts": {
|
||||
"dev:docs": "cd docs && yarn dev",
|
||||
"build:docs": "cd docs && yarn generate",
|
||||
"semantic-release": "semantic-release",
|
||||
"commit": "git-cz",
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview --port 5050",
|
||||
"test": "vitest --environment jsdom",
|
||||
"coverage": "vitest --run --coverage --environment jsdom --silent",
|
||||
"typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sagalbot/vue-select.git"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.8.0",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@semantic-release/github": "^10.0.2",
|
||||
"@types/jsdom": "^21.1.6",
|
||||
"@types/node": "^20.11.30",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vitest/coverage-c8": "^0.33.0",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^13.0.0",
|
||||
"@vue/test-utils": "^2.4.5",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"bundlewatch": "^0.3.3",
|
||||
"commitizen": "^4.3.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.23.0",
|
||||
"jsdom": "^24.0.0",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"prettier": "^3.2.5",
|
||||
"semantic-release": "^23.0.5",
|
||||
"typescript": "^5.4.3",
|
||||
"vite": "^5.2.2",
|
||||
"vitest": "^1.4.0",
|
||||
"vue": "^3.4.21",
|
||||
"vue-tsc": "^2.0.7"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
},
|
||||
"bundlewatch": {
|
||||
"files": [
|
||||
{
|
||||
"path": "./dist/vue-select.es.js",
|
||||
"compression": "gzip",
|
||||
"maxSize": "8 KB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/vue-select.umd.js",
|
||||
"compression": "gzip",
|
||||
"maxSize": "7 KB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/vue-select.css",
|
||||
"compression": "gzip",
|
||||
"maxSize": "2 KB"
|
||||
}
|
||||
]
|
||||
"./dist/vue-select.css": {
|
||||
"import": "./dist/vue-select.css",
|
||||
"require": "./dist/vue-select.css",
|
||||
"style": "./dist/vue-select.css"
|
||||
}
|
||||
},
|
||||
"private": false,
|
||||
"license": "MIT",
|
||||
"prepare": "npm run build",
|
||||
"scripts": {
|
||||
"dev:docs": "cd docs && yarn dev",
|
||||
"build:docs": "cd docs && yarn generate",
|
||||
"semantic-release": "semantic-release",
|
||||
"commit": "git-cz",
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview --port 5050",
|
||||
"test": "vitest --environment jsdom",
|
||||
"coverage": "vitest --run --coverage --environment jsdom --silent",
|
||||
"typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sagalbot/vue-select.git"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.8.0",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@semantic-release/github": "^10.0.2",
|
||||
"@types/jsdom": "^21.1.6",
|
||||
"@types/node": "^20.11.30",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vitest/coverage-v8": "^1.4.0",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^13.0.0",
|
||||
"@vue/test-utils": "^2.4.5",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"bundlewatch": "^0.3.3",
|
||||
"commitizen": "^4.3.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.23.0",
|
||||
"jsdom": "^24.0.0",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"prettier": "^3.2.5",
|
||||
"semantic-release": "^23.0.5",
|
||||
"typescript": "^5.4.3",
|
||||
"vite": "^5.2.3",
|
||||
"vitest": "^1.4.0",
|
||||
"vue": "^3.4.21",
|
||||
"vue-tsc": "^2.0.7"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
},
|
||||
"bundlewatch": {
|
||||
"files": [
|
||||
{
|
||||
"path": "./dist/vue-select.es.js",
|
||||
"compression": "gzip",
|
||||
"maxSize": "8 KB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/vue-select.umd.js",
|
||||
"compression": "gzip",
|
||||
"maxSize": "7 KB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/vue-select.css",
|
||||
"compression": "gzip",
|
||||
"maxSize": "2 KB"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { ListBoxKey } from '@/keys'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import {
|
||||
provide,
|
||||
computed,
|
||||
reactive,
|
||||
watch,
|
||||
onMounted,
|
||||
ref,
|
||||
onUnmounted,
|
||||
} from 'vue'
|
||||
import { useClickAway } from '@/hooks/useClickAway'
|
||||
import type {
|
||||
InjectedListBoxProps,
|
||||
ListBoxProps,
|
||||
ResolvedListBoxProps,
|
||||
VueSelectValue,
|
||||
} from '@/types'
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'update:open', 'open', 'close'])
|
||||
|
||||
const props = withDefaults(defineProps<ListBoxProps>(), {
|
||||
open: undefined,
|
||||
})
|
||||
|
||||
const el = ref<HTMLElement>()
|
||||
const state = reactive<{
|
||||
open: boolean
|
||||
}>({
|
||||
open: props.open === undefined ? false : props.open,
|
||||
})
|
||||
|
||||
watch(
|
||||
() => state.open,
|
||||
(open) => emit('update:open', open),
|
||||
)
|
||||
|
||||
const inputText = ref('')
|
||||
|
||||
const isOpen = computed<boolean>(() => {
|
||||
if (props.open !== undefined) {
|
||||
return props.open
|
||||
}
|
||||
return state.open
|
||||
})
|
||||
|
||||
const { addClickAwayListener, removeClickAwayListener } = useClickAway(
|
||||
() => (state.open = false),
|
||||
)
|
||||
|
||||
onMounted(() => addClickAwayListener(el.value))
|
||||
onUnmounted(() => removeClickAwayListener(el.value))
|
||||
|
||||
provide<InjectedListBoxProps>(
|
||||
ListBoxKey,
|
||||
computed<ResolvedListBoxProps>(() => ({
|
||||
open: isOpen.value,
|
||||
modelValue: props.modelValue,
|
||||
inputText: inputText.value,
|
||||
toggleOpen: () => (state.open = !state.open),
|
||||
setModelValue: (modelValue) => emit('update:modelValue', modelValue),
|
||||
setInputText: (value: string) => (inputText.value = value),
|
||||
})),
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div tabindex="0" role="combobox" ref="el">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import { ListBoxKey } from '@/keys'
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
as?: string
|
||||
}>(),
|
||||
{
|
||||
as: 'button',
|
||||
},
|
||||
)
|
||||
|
||||
const listBoxProps = inject(ListBoxKey)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Component
|
||||
:is="as"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
aria-haspopup="true"
|
||||
:aria-expanded="listBoxProps.open"
|
||||
@click="listBoxProps.toggleOpen"
|
||||
>
|
||||
<slot></slot>
|
||||
</Component>
|
||||
</template>
|
||||
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import { ListBoxKey } from '@/keys'
|
||||
|
||||
const listBoxProps = inject(ListBoxKey)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<input
|
||||
type="search"
|
||||
@input="({ target }) => listBoxProps?.setInputText(target.value)"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { defineProps, inject } from 'vue'
|
||||
import { ListBoxKey } from '@/keys'
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
as?: string
|
||||
}>(),
|
||||
{
|
||||
as: 'div',
|
||||
},
|
||||
)
|
||||
|
||||
const listBoxProps = inject(ListBoxKey)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Component :is="as" v-show="listBoxProps.open">
|
||||
<slot></slot>
|
||||
</Component>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineProps, inject } from 'vue'
|
||||
import { ListBoxKey } from '@/keys'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
as?: string
|
||||
value: unknown
|
||||
}>(),
|
||||
{
|
||||
as: 'div',
|
||||
},
|
||||
)
|
||||
|
||||
const listBoxProps = inject(ListBoxKey)
|
||||
|
||||
const isSelected = computed(() => {
|
||||
return listBoxProps?.value.modelValue === props.value
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Component :is="as" @click="() => listBoxProps.setModelValue(value)">
|
||||
<slot v-bind="{ isSelected }"></slot>
|
||||
</Component>
|
||||
</template>
|
||||
@@ -0,0 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import ComboBox from '@/components/ComboBox/ComboBox.vue'
|
||||
import ComboBoxInput from '@/components/ComboBox/ComboBoxInput.vue'
|
||||
import ComboBoxMenu from '@/components/ComboBox/ComboBoxMenu.vue'
|
||||
import ComboBoxOption from '@/components/ComboBox/ComboBoxOption.vue'
|
||||
import ComboBoxButton from '@/components/ComboBox/ComboBoxButton.vue'
|
||||
import type { VueSelectOption } from '@/types'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: unknown
|
||||
label: (value: VueSelectOption) => string
|
||||
}>()
|
||||
|
||||
const emits = defineEmits(['update:modelValue'])
|
||||
|
||||
const value = ref(props.modelValue)
|
||||
|
||||
watch(value, (newValue) => emits('update:modelValue', newValue))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ComboBox v-model="value" class="w-64 relative">
|
||||
<div class="flex border border-gray-500 rounded">
|
||||
<ComboBoxInput v-bind="{ label }" class="pl-2 py-1 border-none rounded" />
|
||||
<ComboBoxButton as="button">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"
|
||||
/>
|
||||
</svg>
|
||||
</ComboBoxButton>
|
||||
</div>
|
||||
|
||||
<ComboBoxMenu
|
||||
class="absolute z-50 bg-white inset-0 top-12 w-full h-64 overflow-y-scroll space-y-1 border rounded"
|
||||
>
|
||||
<slot></slot>
|
||||
</ComboBoxMenu>
|
||||
</ComboBox>
|
||||
</template>
|
||||
@@ -0,0 +1,21 @@
|
||||
export function useClickAway(callback: () => void): {
|
||||
addClickAwayListener: (el: HTMLElement | undefined) => void
|
||||
removeClickAwayListener: (el: HTMLElement | undefined) => void
|
||||
} {
|
||||
function clickedOutside(el: HTMLElement | undefined, event: MouseEvent) {
|
||||
if (el && !(el == event.target || el?.contains(event.target))) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
addClickAwayListener: (el) =>
|
||||
document.addEventListener('click', (event: MouseEvent) =>
|
||||
clickedOutside(el, event)
|
||||
),
|
||||
removeClickAwayListener: (el) =>
|
||||
document.removeEventListener('click', (event: MouseEvent) =>
|
||||
clickedOutside(el, event)
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export function useModelValue<TypeProps>(
|
||||
props: Readonly<TypeProps>,
|
||||
key: string,
|
||||
emit: (name: string, ...args: any[]) => void
|
||||
) {}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { InjectionKey } from 'vue'
|
||||
import type { ResolvedListBoxProps } from '@/types'
|
||||
|
||||
export const ListBoxKey: InjectionKey<ResolvedListBoxProps> = Symbol(
|
||||
'ListBoxInjectionKey',
|
||||
)
|
||||
|
||||
export const ListBoxOptionInjectionKey = Symbol() as InjectionKey<string>
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ComputedRef, PropType } from 'vue'
|
||||
|
||||
export type VueSelectValue = PropType<unknown>
|
||||
export type VueSelectOption = PropType<unknown>
|
||||
|
||||
export interface ListBoxProps {
|
||||
modelValue: VueSelectValue
|
||||
open?: boolean | undefined
|
||||
}
|
||||
export interface ResolvedListBoxProps extends Omit<ListBoxProps, 'open'> {
|
||||
open: boolean
|
||||
inputText: string
|
||||
toggleOpen: () => boolean
|
||||
setInputText: (text: string) => void
|
||||
setModelValue: (value: unknown) => void
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.node.json",
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": ["vite.config.*"],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
|
||||
Reference in New Issue
Block a user