parent
13f3af96b7
commit
5976e255fb
@ -0,0 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/toolkit';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class'];
|
||||
defaultValue?: number | string;
|
||||
modelValue?: number | string;
|
||||
}>();
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'update:modelValue', payload: number | string): void;
|
||||
}>();
|
||||
|
||||
const modelValue = useVModel(props, 'modelValue', emits, {
|
||||
defaultValue: props.defaultValue,
|
||||
passive: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<input
|
||||
v-model="modelValue"
|
||||
:class="
|
||||
cn(
|
||||
'border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
@ -0,0 +1 @@
|
||||
export { default as Input } from './Input.vue';
|
||||
@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue';
|
||||
|
||||
import { type HTMLAttributes, computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/toolkit';
|
||||
|
||||
import { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{ class?: HTMLAttributes['class'] } & NumberFieldRootProps
|
||||
>();
|
||||
const emits = defineEmits<NumberFieldRootEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldRoot v-bind="forwarded" :class="cn('grid gap-1.5', props.class)">
|
||||
<slot></slot>
|
||||
</NumberFieldRoot>
|
||||
</template>
|
||||
@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/toolkit';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class'];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'relative [&>[data-slot=input]]:has-[[data-slot=decrement]]:pl-5 [&>[data-slot=input]]:has-[[data-slot=increment]]:pr-5',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldDecrementProps } from 'radix-vue';
|
||||
|
||||
import { type HTMLAttributes, computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/toolkit';
|
||||
|
||||
import { Minus } from 'lucide-vue-next';
|
||||
import { NumberFieldDecrement, useForwardProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{ class?: HTMLAttributes['class'] } & NumberFieldDecrementProps
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldDecrement
|
||||
data-slot="decrement"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'absolute left-0 top-1/2 -translate-y-1/2 p-3 disabled:cursor-not-allowed disabled:opacity-20',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot>
|
||||
<Minus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldDecrement>
|
||||
</template>
|
||||
@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldIncrementProps } from 'radix-vue';
|
||||
|
||||
import { type HTMLAttributes, computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/toolkit';
|
||||
|
||||
import { Plus } from 'lucide-vue-next';
|
||||
import { NumberFieldIncrement, useForwardProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{ class?: HTMLAttributes['class'] } & NumberFieldIncrementProps
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldIncrement
|
||||
data-slot="increment"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'absolute right-0 top-1/2 -translate-y-1/2 p-3 disabled:cursor-not-allowed disabled:opacity-20',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot>
|
||||
<Plus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldIncrement>
|
||||
</template>
|
||||
@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/toolkit';
|
||||
|
||||
import { NumberFieldInput } from 'radix-vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldInput
|
||||
:class="
|
||||
cn(
|
||||
'border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent py-1 text-center text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
)
|
||||
"
|
||||
data-slot="input"
|
||||
/>
|
||||
</template>
|
||||
@ -0,0 +1,5 @@
|
||||
export { default as NumberField } from './NumberField.vue';
|
||||
export { default as NumberFieldContent } from './NumberFieldContent.vue';
|
||||
export { default as NumberFieldDecrement } from './NumberFieldDecrement.vue';
|
||||
export { default as NumberFieldIncrement } from './NumberFieldIncrement.vue';
|
||||
export { default as NumberFieldInput } from './NumberFieldInput.vue';
|
||||
@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectListItem } from '@vben/types';
|
||||
|
||||
import { useSlots } from 'vue';
|
||||
|
||||
import { MdiQuestionMarkCircleOutline } from '@vben-core/iconify';
|
||||
import { Input, VbenTooltip } from '@vben-core/shadcn-ui';
|
||||
|
||||
defineOptions({
|
||||
name: 'PreferenceSelectItem',
|
||||
});
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
disabled?: boolean;
|
||||
items?: SelectListItem[];
|
||||
placeholder?: string;
|
||||
}>(),
|
||||
{
|
||||
disabled: false,
|
||||
placeholder: '',
|
||||
items: () => [],
|
||||
},
|
||||
);
|
||||
|
||||
const inputValue = defineModel<string>();
|
||||
|
||||
const slots = useSlots();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'hover:bg-accent': !slots.tip,
|
||||
'pointer-events-none opacity-50': disabled,
|
||||
}"
|
||||
class="my-1 flex w-full items-center justify-between rounded-md px-2 py-1"
|
||||
>
|
||||
<span class="flex items-center text-sm">
|
||||
<slot></slot>
|
||||
|
||||
<VbenTooltip v-if="slots.tip" side="bottom">
|
||||
<template #trigger>
|
||||
<MdiQuestionMarkCircleOutline class="ml-1 cursor-help" />
|
||||
</template>
|
||||
<slot name="tip"></slot>
|
||||
</VbenTooltip>
|
||||
</span>
|
||||
<Input v-model="inputValue" class="h-8 w-[160px]" />
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,65 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectListItem } from '@vben/types';
|
||||
|
||||
import { useSlots } from 'vue';
|
||||
|
||||
import { MdiQuestionMarkCircleOutline } from '@vben-core/iconify';
|
||||
import {
|
||||
NumberField,
|
||||
NumberFieldContent,
|
||||
NumberFieldDecrement,
|
||||
NumberFieldIncrement,
|
||||
NumberFieldInput,
|
||||
VbenTooltip,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
defineOptions({
|
||||
name: 'PreferenceSelectItem',
|
||||
});
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
disabled?: boolean;
|
||||
items?: SelectListItem[];
|
||||
placeholder?: string;
|
||||
}>(),
|
||||
{
|
||||
disabled: false,
|
||||
placeholder: '',
|
||||
items: () => [],
|
||||
},
|
||||
);
|
||||
|
||||
const inputValue = defineModel<number>();
|
||||
|
||||
const slots = useSlots();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'hover:bg-accent': !slots.tip,
|
||||
'pointer-events-none opacity-50': disabled,
|
||||
}"
|
||||
class="my-1 flex w-full items-center justify-between rounded-md px-2 py-1"
|
||||
>
|
||||
<span class="flex items-center text-sm">
|
||||
<slot></slot>
|
||||
|
||||
<VbenTooltip v-if="slots.tip" side="bottom">
|
||||
<template #trigger>
|
||||
<MdiQuestionMarkCircleOutline class="ml-1 cursor-help" />
|
||||
</template>
|
||||
<slot name="tip"></slot>
|
||||
</VbenTooltip>
|
||||
</span>
|
||||
|
||||
<NumberField v-model="inputValue" v-bind="$attrs" class="w-[160px]">
|
||||
<NumberFieldContent>
|
||||
<NumberFieldDecrement />
|
||||
<NumberFieldInput />
|
||||
<NumberFieldIncrement />
|
||||
</NumberFieldContent>
|
||||
</NumberField>
|
||||
</div>
|
||||
</template>
|
||||
Loading…
Reference in new issue