mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-15 03:32:15 +01:00
Add Field component system and migrate UI
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Primitive, type PrimitiveProps } from 'reka-ui';
|
||||
import { type ButtonVariants, buttonVariants } from '.';
|
||||
|
||||
interface Props extends PrimitiveProps {
|
||||
variant?: ButtonVariants['variant'];
|
||||
size?: ButtonVariants['size'];
|
||||
class?: HTMLAttributes['class'];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
as: 'button',
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn(buttonVariants({ variant, size }), props.class)">
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
@@ -1,36 +0,0 @@
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
|
||||
export { default as Button } from './Button.vue';
|
||||
|
||||
export const buttonVariants = cva(
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
||||
destructive:
|
||||
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
|
||||
outline:
|
||||
'border shadow-xs hover:text-text-primary bg-card-background dark:bg-transparent border-input dark:border-input hover:bg-white/5',
|
||||
secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
input: 'border-input-border border bg-input-background text-text-primary focus-visible:ring-2 focus-visible:ring-ring focus-visible:border-transparent shadow-sm',
|
||||
},
|
||||
size: {
|
||||
default: 'h-9 px-4 py-2',
|
||||
xs: 'h-7 rounded px-2',
|
||||
sm: 'h-8 rounded-md px-3 text-xs',
|
||||
lg: 'h-10 rounded-md px-8',
|
||||
icon: 'h-9 w-9',
|
||||
input: 'h-[42px] px-3 py-2 text-base',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
size: 'default',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export type ButtonVariants = VariantProps<typeof buttonVariants>;
|
||||
@@ -42,7 +42,6 @@ const organization = inject<ComputedRef<Organization>>('organization');
|
||||
<PopoverTrigger as-child>
|
||||
<Button
|
||||
variant="input"
|
||||
size="input"
|
||||
:class="[
|
||||
'w-full justify-start text-left font-normal',
|
||||
!model && 'text-muted-foreground',
|
||||
|
||||
24
resources/js/Components/ui/label/Label.vue
Normal file
24
resources/js/Components/ui/label/Label.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import type { LabelProps } from 'reka-ui';
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
import { reactiveOmit } from '@vueuse/core';
|
||||
import { Label } from 'reka-ui';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class');
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Label
|
||||
v-bind="delegatedProps"
|
||||
:class="
|
||||
cn(
|
||||
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
|
||||
props.class
|
||||
)
|
||||
">
|
||||
<slot />
|
||||
</Label>
|
||||
</template>
|
||||
1
resources/js/Components/ui/label/index.ts
Normal file
1
resources/js/Components/ui/label/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Label } from './Label.vue';
|
||||
@@ -13,7 +13,7 @@ const props = defineProps<{
|
||||
data-slot="input"
|
||||
:class="
|
||||
cn(
|
||||
'flex h-[42px] w-full rounded-md border border-input-border bg-input-background px-3 py-2.5 text-sm text-center shadow-sm transition-colors placeholder:text-muted-foreground focus:border-input-border focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'flex h-9 w-full rounded-md border border-input-border bg-input-background px-3 py-1 text-sm text-center shadow-sm transition-colors placeholder:text-muted-foreground focus:border-input-border focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
|
||||
props.class
|
||||
)
|
||||
" />
|
||||
|
||||
@@ -7,7 +7,7 @@ import { computed, type HTMLAttributes } from 'vue';
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
SelectTriggerProps & {
|
||||
size?: 'small';
|
||||
size?: 'default' | 'sm' | 'lg';
|
||||
class?: HTMLAttributes['class'];
|
||||
showChevron?: boolean;
|
||||
variant?: 'default' | 'outline';
|
||||
@@ -18,11 +18,19 @@ const props = withDefaults(
|
||||
showChevron: true,
|
||||
variant: 'default',
|
||||
active: false,
|
||||
size: 'default',
|
||||
}
|
||||
);
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, showChevron: __, variant: ___, active: ____, ...delegated } = props;
|
||||
const {
|
||||
class: _,
|
||||
showChevron: __,
|
||||
variant: ___,
|
||||
active: ____,
|
||||
size: _____,
|
||||
...delegated
|
||||
} = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
@@ -30,7 +38,14 @@ const delegatedProps = computed(() => {
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
|
||||
const sizeClasses = computed(() => {
|
||||
return props.size === 'small' ? 'h-8 text-xs' : 'h-[42px] w-full text-sm';
|
||||
switch (props.size) {
|
||||
case 'sm':
|
||||
return 'h-8 px-3 text-xs';
|
||||
case 'lg':
|
||||
return 'h-10 px-4 text-sm';
|
||||
default:
|
||||
return 'h-9 px-3 text-sm';
|
||||
}
|
||||
});
|
||||
|
||||
const variantClasses = computed(() => {
|
||||
@@ -49,7 +64,7 @@ const variantClasses = computed(() => {
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'flex items-center justify-between gap-3 whitespace-nowrap rounded-md px-3 py-2.5 data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:truncate text-start font-medium transition-colors',
|
||||
'flex items-center justify-between gap-3 whitespace-nowrap rounded-md data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:truncate text-start font-medium transition-colors',
|
||||
sizeClasses,
|
||||
variantClasses,
|
||||
props.class
|
||||
|
||||
Reference in New Issue
Block a user