Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/app/components/scn/button/ShadButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/utils/shadcn'
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',
variant: 'default',
size: 'default',
class: '',
})
</script>

<template>
<Primitive
:as="as"
:as-child="asChild"
:class="cn(buttonVariants({ variant, size }), props.class)"
>
<slot />
</Primitive>
</template>
35 changes: 35 additions & 0 deletions src/app/components/scn/button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { cva, type VariantProps } from 'class-variance-authority'

export { default as ShadButton } from './ShadButton.vue'

export const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 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 border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
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',
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 rounded-md px-3 text-xs',
lg: 'h-10 rounded-md px-8',
icon: 'h-9 w-9',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
)

export type ButtonVariants = VariantProps<typeof buttonVariants>
86 changes: 86 additions & 0 deletions src/app/components/scn/calendar/Calendar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<script lang="ts" setup>
import { cn } from '@/utils/shadcn'
import {
CalendarRoot,
type CalendarRootEmits,
type CalendarRootProps,
useForwardPropsEmits,
} from 'reka-ui'
import { computed, type HTMLAttributes } from 'vue'
import {
CalendarCell,
CalendarCellTrigger,
CalendarGrid,
CalendarGridBody,
CalendarGridHead,
CalendarGridRow,
CalendarHeadCell,
CalendarHeader,
CalendarHeading,
CalendarNextButton,
CalendarPrevButton,
} from '.'

const props = defineProps<
CalendarRootProps & { class?: HTMLAttributes['class'] }
>()
const emits = defineEmits<CalendarRootEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>

<template>
<CalendarRoot
v-slot="{ grid, weekDays }"
:class="cn('p-3', props.class)"
v-bind="forwarded"
>
<CalendarHeader
class="flex items-center justify-between rounded-t-lg bg-blue-400 p-4 text-white"
>
<CalendarPrevButton class="rounded p-2 hover:bg-blue-500" />
<CalendarHeading class="text-xl" />
<CalendarNextButton class="rounded p-2 hover:bg-blue-500" />
</CalendarHeader>

<div class="mt-4">
<CalendarGrid v-for="month in grid" :key="month.value.toString()">
<CalendarGridHead>
<CalendarGridRow class="grid grid-cols-7 bg-gray-100 py-2">
<CalendarHeadCell
v-for="day in weekDays"
:key="day"
class="text-center text-gray-800"
>
{{ day }}
</CalendarHeadCell>
</CalendarGridRow>
</CalendarGridHead>

<CalendarGridBody>
<CalendarGridRow
v-for="(weekDates, index) in month.rows"
:key="`weekDate-${index}`"
class="mt-4 grid grid-cols-7 gap-2"
>
<CalendarCell
v-for="weekDate in weekDates"
:key="weekDate.toString()"
:date="weekDate"
class="text-center"
>
<CalendarCellTrigger
:day="weekDate"
:month="month.value"
class="flex h-10 w-10 items-center justify-center rounded-lg text-gray-800 hover:bg-gray-100 data-[selected=true]:bg-blue-500 data-[selected=true]:text-white"
/>
</CalendarCell>
</CalendarGridRow>
</CalendarGridBody>
</CalendarGrid>
</div>
</CalendarRoot>
</template>
31 changes: 31 additions & 0 deletions src/app/components/scn/calendar/CalendarCell.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script lang="ts" setup>
import { cn } from '@/utils/shadcn'
import { CalendarCell, type CalendarCellProps, useForwardProps } from 'reka-ui'
import { computed, type HTMLAttributes } from 'vue'

const props = defineProps<
CalendarCellProps & { class?: HTMLAttributes['class'] }
>()

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props

return delegated
})

const forwardedProps = useForwardProps(delegatedProps)
</script>

<template>
<CalendarCell
:class="
cn(
'[&:has([data-selected])]:bg-accent [&:has([data-selected][data-outside-view])]:bg-accent/50 relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md',
props.class,
)
"
v-bind="forwardedProps"
>
<slot />
</CalendarCell>
</template>
46 changes: 46 additions & 0 deletions src/app/components/scn/calendar/CalendarCellTrigger.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script lang="ts" setup>
import { buttonVariants } from '~/components/scn/button'
import { cn } from '@/utils/shadcn'
import {
CalendarCellTrigger,
type CalendarCellTriggerProps,
useForwardProps,
} from 'reka-ui'
import { computed, type HTMLAttributes } from 'vue'

const props = defineProps<
CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }
>()

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props

return delegated
})

const forwardedProps = useForwardProps(delegatedProps)
</script>

<template>
<CalendarCellTrigger
:class="
cn(
buttonVariants({ variant: 'ghost' }),
'h-9 w-9 p-0 font-normal',
'[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',
// Selected
'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground data-[selected]:opacity-100',
// Disabled
'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',
// Unavailable
'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',
// Outside months
'data-[outside-view]:text-muted-foreground [&[data-outside-view][data-selected]]:bg-accent/50 [&[data-outside-view][data-selected]]:text-muted-foreground data-[outside-view]:opacity-50 [&[data-outside-view][data-selected]]:opacity-30',
props.class,
)
"
v-bind="forwardedProps"
>
<slot />
</CalendarCellTrigger>
</template>
26 changes: 26 additions & 0 deletions src/app/components/scn/calendar/CalendarGrid.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script lang="ts" setup>
import { cn } from '@/utils/shadcn'
import { CalendarGrid, type CalendarGridProps, useForwardProps } from 'reka-ui'
import { computed, type HTMLAttributes } from 'vue'

const props = defineProps<
CalendarGridProps & { class?: HTMLAttributes['class'] }
>()

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props

return delegated
})

const forwardedProps = useForwardProps(delegatedProps)
</script>

<template>
<CalendarGrid
:class="cn('w-full border-collapse space-y-1', props.class)"
v-bind="forwardedProps"
>
<slot />
</CalendarGrid>
</template>
11 changes: 11 additions & 0 deletions src/app/components/scn/calendar/CalendarGridBody.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import { CalendarGridBody, type CalendarGridBodyProps } from 'reka-ui'

const props = defineProps<CalendarGridBodyProps>()
</script>

<template>
<CalendarGridBody v-bind="props">
<slot />
</CalendarGridBody>
</template>
11 changes: 11 additions & 0 deletions src/app/components/scn/calendar/CalendarGridHead.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import { CalendarGridHead, type CalendarGridHeadProps } from 'reka-ui'

const props = defineProps<CalendarGridHeadProps>()
</script>

<template>
<CalendarGridHead v-bind="props">
<slot />
</CalendarGridHead>
</template>
27 changes: 27 additions & 0 deletions src/app/components/scn/calendar/CalendarGridRow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script lang="ts" setup>
import { cn } from '@/utils/shadcn'
import {
CalendarGridRow,
type CalendarGridRowProps,
useForwardProps,
} from 'reka-ui'
import { computed, type HTMLAttributes } from 'vue'

const props = defineProps<
CalendarGridRowProps & { class?: HTMLAttributes['class'] }
>()

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props

return delegated
})

const forwardedProps = useForwardProps(delegatedProps)
</script>

<template>
<CalendarGridRow :class="cn('flex', props.class)" v-bind="forwardedProps">
<slot />
</CalendarGridRow>
</template>
35 changes: 35 additions & 0 deletions src/app/components/scn/calendar/CalendarHeadCell.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script lang="ts" setup>
import { cn } from '@/utils/shadcn'
import {
CalendarHeadCell,
type CalendarHeadCellProps,
useForwardProps,
} from 'reka-ui'
import { computed, type HTMLAttributes } from 'vue'

const props = defineProps<
CalendarHeadCellProps & { class?: HTMLAttributes['class'] }
>()

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props

return delegated
})

const forwardedProps = useForwardProps(delegatedProps)
</script>

<template>
<CalendarHeadCell
:class="
cn(
'text-muted-foreground w-9 rounded-md text-[0.8rem] font-normal',
props.class,
)
"
v-bind="forwardedProps"
>
<slot />
</CalendarHeadCell>
</template>
32 changes: 32 additions & 0 deletions src/app/components/scn/calendar/CalendarHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang="ts" setup>
import { cn } from '@/utils/shadcn'
import {
CalendarHeader,
type CalendarHeaderProps,
useForwardProps,
} from 'reka-ui'
import { computed, type HTMLAttributes } from 'vue'

const props = defineProps<
CalendarHeaderProps & { class?: HTMLAttributes['class'] }
>()

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props

return delegated
})

const forwardedProps = useForwardProps(delegatedProps)
</script>

<template>
<CalendarHeader
:class="
cn('relative flex w-full items-center justify-between pt-1', props.class)
"
v-bind="forwardedProps"
>
<slot />
</CalendarHeader>
</template>
Loading
Loading