mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-25 01:06:15 -04:00
refactor(search): command palette design (#463)
This commit is contained in:
parent
732da08157
commit
bcb98b359c
18 changed files with 576 additions and 386 deletions
|
@ -29,6 +29,7 @@ const props = withDefaults(
|
|||
multiline?: boolean
|
||||
rows?: number | string
|
||||
autosize?: boolean
|
||||
autofocus?: boolean
|
||||
}>(),
|
||||
{
|
||||
value: '',
|
||||
|
@ -54,13 +55,14 @@ const props = withDefaults(
|
|||
multiline: false,
|
||||
rows: 3,
|
||||
autosize: false,
|
||||
autofocus: false,
|
||||
},
|
||||
);
|
||||
const emit = defineEmits(['update:value']);
|
||||
const value = useVModel(props, 'value', emit);
|
||||
const showPassword = ref(false);
|
||||
|
||||
const { id, placeholder, label, validationRules, labelPosition, labelWidth, labelAlign, autosize, readonly, disabled, clearable, type, multiline, rows, rawText } = toRefs(props);
|
||||
const { id, placeholder, label, validationRules, labelPosition, labelWidth, labelAlign, autosize, readonly, disabled, clearable, type, multiline, rows, rawText, autofocus } = toRefs(props);
|
||||
|
||||
const validation
|
||||
= props.validation
|
||||
|
@ -74,12 +76,9 @@ const theme = useTheme();
|
|||
const appTheme = useAppTheme();
|
||||
|
||||
const textareaRef = ref<HTMLTextAreaElement>();
|
||||
const inputRef = ref<HTMLInputElement>();
|
||||
const inputWrapperRef = ref<HTMLElement>();
|
||||
|
||||
defineExpose({
|
||||
inputWrapperRef,
|
||||
});
|
||||
|
||||
watch(
|
||||
value,
|
||||
() => {
|
||||
|
@ -107,6 +106,38 @@ const htmlInputType = computed(() => {
|
|||
|
||||
return 'text';
|
||||
});
|
||||
|
||||
function focus() {
|
||||
if (textareaRef.value) {
|
||||
textareaRef.value.focus();
|
||||
}
|
||||
|
||||
if (inputRef.value) {
|
||||
inputRef.value.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function blur() {
|
||||
if (textareaRef.value) {
|
||||
textareaRef.value.blur?.();
|
||||
}
|
||||
|
||||
if (inputRef.value) {
|
||||
inputRef.value.blur?.();
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (autofocus.value) {
|
||||
focus();
|
||||
}
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
inputWrapperRef,
|
||||
focus,
|
||||
blur,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -140,6 +171,7 @@ const htmlInputType = computed(() => {
|
|||
<input
|
||||
v-else
|
||||
:id="id"
|
||||
ref="inputRef"
|
||||
v-model="value"
|
||||
:type="htmlInputType"
|
||||
class="input"
|
||||
|
|
15
src/ui/c-modal/c-modal.demo.vue
Normal file
15
src/ui/c-modal/c-modal.demo.vue
Normal file
|
@ -0,0 +1,15 @@
|
|||
<script lang="ts" setup>
|
||||
const modal1 = ref();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<c-button @click="() => modal1?.open()">
|
||||
Open Modal
|
||||
</c-button>
|
||||
|
||||
<c-modal ref="modal1">
|
||||
Content
|
||||
</c-modal>
|
||||
</div>
|
||||
</template>
|
11
src/ui/c-modal/c-modal.theme.ts
Normal file
11
src/ui/c-modal/c-modal.theme.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { defineThemes } from '../theme/theme.models';
|
||||
import { appThemes } from '../theme/themes';
|
||||
|
||||
export const { useTheme } = defineThemes({
|
||||
dark: {
|
||||
background: appThemes.dark.background,
|
||||
},
|
||||
light: {
|
||||
background: appThemes.light.background,
|
||||
},
|
||||
});
|
74
src/ui/c-modal/c-modal.vue
Normal file
74
src/ui/c-modal/c-modal.vue
Normal file
|
@ -0,0 +1,74 @@
|
|||
<script setup lang="ts">
|
||||
import { useTheme } from './c-modal.theme';
|
||||
|
||||
const props = withDefaults(defineProps<{ open?: boolean; centered?: boolean }>(), {
|
||||
open: false,
|
||||
centered: true,
|
||||
});
|
||||
const emit = defineEmits(['update:open']);
|
||||
const isOpen = useVModel(props, 'open', emit, { passive: true });
|
||||
|
||||
const { centered } = toRefs(props);
|
||||
|
||||
function close() {
|
||||
isOpen.value = false;
|
||||
}
|
||||
|
||||
function open() {
|
||||
isOpen.value = true;
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
isOpen.value = !isOpen.value;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
close,
|
||||
open,
|
||||
toggle,
|
||||
isOpen,
|
||||
});
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const theme = useTheme();
|
||||
const modal = ref();
|
||||
|
||||
onClickOutside(modal, () => {
|
||||
if (isOpen.value) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition>
|
||||
<div v-if="isOpen" class="c-modal--overlay" fixed left-0 top-0 z-10 h-full w-full flex justify-center px-2 :class="{ 'items-center': centered }">
|
||||
<div ref="modal" class="c-modal--container" v-bind="$attrs" max-w-xl w-full flex-grow rounded-md pa-24px>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.c-modal--overlay {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.c-modal--container {
|
||||
background-color: v-bind('theme.background');
|
||||
}
|
||||
|
||||
.v-enter-active,
|
||||
.v-leave-active {
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.v-enter-from,
|
||||
.v-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
|
@ -2,6 +2,7 @@ import { defineThemes } from './theme.models';
|
|||
|
||||
export const { themes: appThemes, useTheme: useAppTheme } = defineThemes({
|
||||
light: {
|
||||
background: '#ffffff',
|
||||
text: {
|
||||
baseColor: '#333639',
|
||||
mutedColor: '#767c82',
|
||||
|
@ -37,6 +38,7 @@ export const { themes: appThemes, useTheme: useAppTheme } = defineThemes({
|
|||
},
|
||||
},
|
||||
dark: {
|
||||
background: '#1e1e1e',
|
||||
text: {
|
||||
baseColor: '#ffffffd1',
|
||||
mutedColor: '#ffffff80',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue