forked from FoundKeyGang/FoundKey
🎨
This commit is contained in:
parent
90b62a3e95
commit
9d11c29c3b
6 changed files with 75 additions and 12 deletions
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
||||||
import MkButton from '../ui/button.vue';
|
import MkButton from '@client/components/ui/button.vue';
|
||||||
import { debounce } from 'throttle-debounce';
|
import { debounce } from 'throttle-debounce';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="vblkjoeq">
|
<div class="vblkjoeq">
|
||||||
<div class="label" @click="focus"><slot name="label"></slot></div>
|
<div class="label" @click="focus"><slot name="label"></slot></div>
|
||||||
<div class="input" :class="{ inline, disabled, focused }">
|
<div class="input" :class="{ inline, disabled, focused }" @click.prevent="onClick" ref="container">
|
||||||
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
|
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
|
||||||
<select ref="inputEl"
|
<select class="select" ref="inputEl"
|
||||||
v-model="v"
|
v-model="v"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:required="required"
|
:required="required"
|
||||||
|
@ -25,7 +25,8 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
||||||
import MkButton from '../ui/button.vue';
|
import MkButton from '@client/components/ui/button.vue';
|
||||||
|
import * as os from '@client/os';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -81,6 +82,7 @@ export default defineComponent({
|
||||||
const inputEl = ref(null);
|
const inputEl = ref(null);
|
||||||
const prefixEl = ref(null);
|
const prefixEl = ref(null);
|
||||||
const suffixEl = ref(null);
|
const suffixEl = ref(null);
|
||||||
|
const container = ref(null);
|
||||||
|
|
||||||
const focus = () => inputEl.value.focus();
|
const focus = () => inputEl.value.focus();
|
||||||
const onInput = (ev) => {
|
const onInput = (ev) => {
|
||||||
|
@ -132,6 +134,47 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onClick = (ev: MouseEvent) => {
|
||||||
|
focused.value = true;
|
||||||
|
|
||||||
|
const menu = [];
|
||||||
|
let options = context.slots.default();
|
||||||
|
|
||||||
|
for (const optionOrOptgroup of options) {
|
||||||
|
if (optionOrOptgroup.type === 'optgroup') {
|
||||||
|
const optgroup = optionOrOptgroup;
|
||||||
|
menu.push({
|
||||||
|
type: 'label',
|
||||||
|
text: optgroup.props.label,
|
||||||
|
});
|
||||||
|
for (const option of optgroup.children) {
|
||||||
|
menu.push({
|
||||||
|
text: option.children,
|
||||||
|
active: v.value === option.props.value,
|
||||||
|
action: () => {
|
||||||
|
v.value = option.props.value;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const option = optionOrOptgroup;
|
||||||
|
menu.push({
|
||||||
|
text: option.children,
|
||||||
|
active: v.value === option.props.value,
|
||||||
|
action: () => {
|
||||||
|
v.value = option.props.value;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os.popupMenu(menu, container.value, {
|
||||||
|
width: container.value.offsetWidth,
|
||||||
|
}).then(() => {
|
||||||
|
focused.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
v,
|
v,
|
||||||
focused,
|
focused,
|
||||||
|
@ -141,8 +184,10 @@ export default defineComponent({
|
||||||
inputEl,
|
inputEl,
|
||||||
prefixEl,
|
prefixEl,
|
||||||
suffixEl,
|
suffixEl,
|
||||||
|
container,
|
||||||
focus,
|
focus,
|
||||||
onInput,
|
onInput,
|
||||||
|
onClick,
|
||||||
updated,
|
updated,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -174,8 +219,15 @@ export default defineComponent({
|
||||||
> .input {
|
> .input {
|
||||||
$height: 42px;
|
$height: 42px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
> select {
|
&:hover {
|
||||||
|
> .select {
|
||||||
|
border-color: var(--inputBorderHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .select {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -195,10 +247,7 @@ export default defineComponent({
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: border-color 0.1s ease-out;
|
transition: border-color 0.1s ease-out;
|
||||||
|
pointer-events: none;
|
||||||
&:hover {
|
|
||||||
border-color: var(--inputBorderHover);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> .prefix,
|
> .prefix,
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
||||||
import MkButton from '../ui/button.vue';
|
import MkButton from '@client/components/ui/button.vue';
|
||||||
import { debounce } from 'throttle-debounce';
|
import { debounce } from 'throttle-debounce';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="rrevdjwt" :class="{ center: align === 'center' }"
|
<div class="rrevdjwt" :class="{ center: align === 'center' }"
|
||||||
|
:style="{ width: width ? width + 'px' : null }"
|
||||||
ref="items"
|
ref="items"
|
||||||
@contextmenu.self="e => e.preventDefault()"
|
@contextmenu.self="e => e.preventDefault()"
|
||||||
v-hotkey="keymap"
|
v-hotkey="keymap"
|
||||||
|
@ -59,6 +60,10 @@ export default defineComponent({
|
||||||
type: String,
|
type: String,
|
||||||
requried: false
|
requried: false
|
||||||
},
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
},
|
},
|
||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<MkPopup ref="popup" :src="src" @closed="$emit('closed')">
|
<MkPopup ref="popup" :src="src" @closed="$emit('closed')">
|
||||||
<MkMenu :items="items" :align="align" @close="$refs.popup.close()" class="_popup _shadow"/>
|
<MkMenu :items="items" :align="align" :width="width" @close="$refs.popup.close()" class="_popup _shadow"/>
|
||||||
</MkPopup>
|
</MkPopup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -24,6 +24,10 @@ export default defineComponent({
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
viaKeyboard: {
|
viaKeyboard: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false
|
required: false
|
||||||
|
|
|
@ -372,12 +372,17 @@ export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function popupMenu(items: any[] | Ref<any[]>, src?: HTMLElement, options?: { align?: string; viaKeyboard?: boolean }) {
|
export function popupMenu(items: any[] | Ref<any[]>, src?: HTMLElement, options?: {
|
||||||
|
align?: string;
|
||||||
|
width?: number;
|
||||||
|
viaKeyboard?: boolean;
|
||||||
|
}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let dispose;
|
let dispose;
|
||||||
popup(import('@client/components/ui/popup-menu.vue'), {
|
popup(import('@client/components/ui/popup-menu.vue'), {
|
||||||
items,
|
items,
|
||||||
src,
|
src,
|
||||||
|
width: options?.width,
|
||||||
align: options?.align,
|
align: options?.align,
|
||||||
viaKeyboard: options?.viaKeyboard
|
viaKeyboard: options?.viaKeyboard
|
||||||
}, {
|
}, {
|
||||||
|
|
Loading…
Reference in a new issue