dev: compact styling

This commit is contained in:
2025-10-18 06:52:12 +07:00
parent e6717e2b6d
commit 723cd2c7b3
12 changed files with 101 additions and 23 deletions
@@ -41,11 +41,11 @@ onMounted(() => {
<div class="flex flex-col space-y-2">
<Popover>
<PopoverTrigger as-child>
<Button variant="outline" class="bg-white border-gray-400 font-normal text-right h-[40px] w-full">
<Button variant="outline" class="bg-white border-gray-400 font-normal text-right w-full h-8 2xl:h-9">
<div class="flex justify-between items-center w-full">
<p v-if="date">{{ format(date, 'PPP', { locale: localeID }) }}</p>
<p v-else class="text-sm text-black text-opacity-50">{{ props.placeholder || 'Tanggal' }}</p>
<Icon name="i-lucide-calendar" class="h-5 w-5" />
<p v-else class="text-black text-opacity-50">{{ props.placeholder || 'Tanggal' }}</p>
<Icon name="i-lucide-calendar"/>
</div>
</Button>
</PopoverTrigger>
+5 -5
View File
@@ -30,7 +30,7 @@ const getLabelSizeIdx = (size: string) => {
const settingClass = computed(() => {
const breakPointIdx = getBreakpointIdx(props.gridPoint)
let cls = breakpoints[breakPointIdx]
cls += ' gap-x-4 xl:gap-x-5 gap-y-2 xl:gap-y-3 ' + [
cls += ' gap-x-4 2xl:gap-x-5 ' + [
'grid-cols-1', 'grid-cols-2', 'grid-cols-3', 'grid-cols-4', 'grid-cols-5',
'grid-cols-6', 'grid-cols-7', 'grid-cols-8', 'grid-cols-9', 'grid-cols-10',
][props.colCount - 1]
@@ -44,7 +44,7 @@ const settingClass = computed(() => {
' [&_.cell]:mb-3 [&_.cell]:2xl:mb-0',
][breakPointIdx]
if (props.cellFlex) {
cls += ' ' + [
cls += ' gap-y-2 2xl:gap-y-3 ' + [
'[&_.cell]:flex',
'[&_.cell]:sm:flex',
'[&_.cell]:md:flex',
@@ -60,11 +60,11 @@ const settingClass = computed(() => {
'[&_.label]:md:w-44 [&_.label]:xl:w-52',
][getLabelSizeIdx(props.labelSize)]
} else {
cls += ' [&_.label]:pb-1 [&_.label]:!pt-0 ';
cls += ' gap-y-4 2xl:gap-y-5 [&_.label]:pb-1 [&_.label]:!pt-0 ';
}
cls += ' [&:not(.preview)_.height-default]:pt-2 [&:not(.preview)_.height-default]:2xl:!pt-1.5 [&:not(.preview)_.height-compact]:!pt-1 '
cls += '[&_textarea]:text-xs [&_textarea]:2xl:!text-sm '
cls += '[&_label]:text-xs [&_label]:2xl:!text-sm'
cls += '[&_textarea]:md:text-xs [&_textarea]:2xl:!text-sm '
cls += '[&_label]:md:text-xs [&_label]:md:text-xs [&_label]:2xl:!text-sm'
return cls
})
</script>
+1 -1
View File
@@ -9,6 +9,6 @@ const props = defineProps({
<template>
<div :class="`field ${props.defaultClass} ${props.class}`">
<slot />
<div v-if="props.errMessage" class="mt-1 md:text-xs 2xl:text-sm font-medium text-red-500">{{ props.errMessage }}</div>
<div v-if="props.errMessage" class="mt-1 md:!text-xs 2xl:!text-sm font-medium text-red-500">{{ props.errMessage }}</div>
</div>
</template>
@@ -0,0 +1,75 @@
<script setup lang="ts">
import type { FormErrors } from '~/types/error'
import FieldGroup from '~/components/pub/my-ui/form/field-group.vue'
import Field from '~/components/pub/my-ui/form/field.vue'
import Label from '~/components/pub/my-ui/form/label.vue'
import { Input } from '~/components/pub/ui/input'
import { cn } from '~/lib/utils'
import * as DE from '~/components/pub/my-ui/doc-entry'
const props = defineProps<{
fieldName: string
label?: string
placeholder?: string
hint?: string
modelValue?: File | null
accept?: string[]
maxSizeMb?: number
errors?: FormErrors
class?: string
isRequired?: boolean
isDisabled?: boolean
icons?: string
}>()
const hintMsg = computed(() => {
if (props.hint) return props.hint
if (props.accept) {
return `${props.accept.map((ext) => '.' + ext.replace(/^\./, '')).join(', ')}, maksimal ${props.maxSizeMb} MB`
}
return 'Gunakan file yang sesuai'
})
async function onFileChange(event: Event, handleChange: (value: any) => void) {
const target = event.target as HTMLInputElement
const file = target.files?.[0]
handleChange(file)
}
</script>
<template>
<DE.Cell>
<DE.Label
v-if="label !== ''"
:label-for="fieldName"
:is-required="isRequired && !isDisabled"
>
{{ label }} ({{ hintMsg }})
</DE.Label>
<DE.Field
:id="fieldName"
:errors="errors"
>
<FormField
v-slot="{ componentField, handleChange }"
:name="fieldName"
>
<FormItem>
<FormControl class="flex flex-col">
<Input
@change="onFileChange($event, handleChange)"
type="file"
:disabled="isDisabled"
v-bind="componentField"
:placeholder="placeholder"
:class="cn('focus:border-primary focus:ring-2 focus:ring-primary focus:ring-offset-0')"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
</DE.Field>
</DE.Cell>
</template>
+9 -6
View File
@@ -6,12 +6,15 @@ import Label from '~/components/pub/my-ui/form/label.vue'
import { Input } from '~/components/pub/ui/input'
import { cn } from '~/lib/utils'
import * as DE from '~/components/pub/my-ui/doc-entry'
const props = defineProps<{
fieldName: string
placeholder: string
label: string
errors?: FormErrors
class?: string
colSpan?: number
numericOnly?: boolean
maxLength?: number
isRequired?: boolean
@@ -42,15 +45,15 @@ function handleInput(event: Event) {
</script>
<template>
<FieldGroup>
<Label
<DE.Cell :col-span="colSpan || 1">
<DE.Label
v-if="label !== ''"
:label-for="fieldName"
:is-required="isRequired && !isDisabled"
>
{{ label }}
</Label>
<Field
</DE.Label>
<DE.Field
:id="fieldName"
:errors="errors"
>
@@ -77,6 +80,6 @@ function handleInput(event: Event) {
<FormMessage />
</FormItem>
</FormField>
</Field>
</FieldGroup>
</DE.Field>
</DE.Cell>
</template>
+1 -1
View File
@@ -46,7 +46,7 @@ const wrapperClass = computed(() => [
props.stacked ? '' : positionWrapMap[props.position],
])
const labelClass = computed(() => [props.stacked ? 'block mb-1 text-sm font-normal' : positionChildMap[props.position]])
const labelClass = computed(() => [props.stacked ? 'block mb-1 font-normal' : positionChildMap[props.position]])
</script>
<template>
+2 -2
View File
@@ -116,7 +116,7 @@ watch(
<SelectTrigger
:class="
cn(
'rounded-md px-3 py-2 focus:outline-none focus:ring-1 focus:ring-black dark:focus:ring-white',
'rounded-md focus:outline-none focus:ring-1 focus:ring-black dark:focus:ring-white',
{
'cursor-not-allowed bg-gray-100 opacity-50': isDisabled,
'bg-white text-black dark:bg-gray-800 dark:text-white': !isDisabled,
@@ -132,7 +132,7 @@ watch(
<SelectValue
:placeholder="placeholder || 'Pilih item'"
:class="
cn('text-sm', {
cn('', {
'text-gray-400': !props.modelValue,
'text-black dark:text-white': props.modelValue,
'text-gray-500': isDisabled,
+1 -1
View File
@@ -24,7 +24,7 @@ const modelValue = useVModel(props, 'modelValue', emits, {
v-model="modelValue"
:class="
cn(
'border-input dark:bg-slate-950 ring-offset-background placeholder:text-muted-foreground flex h-8 2xl:h-9 w-full rounded-md border border-gray-400 px-3 py-2 md:text-xs 2xl:text-sm file:border-0 file:bg-transparent md:file:text-xs xl:file:text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50',
'border-input dark:bg-slate-950 ring-offset-background placeholder:text-muted-foreground flex h-9 md:h-8 2xl:h-9 w-full rounded-md border border-gray-400 px-3 py-2 md:text-xs 2xl:text-sm file:border-0 file:bg-transparent md:file:!text-xs xl:file:!text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50',
props.class,
)
"
+1 -1
View File
@@ -35,7 +35,7 @@ const forwarded = useForwardPropsEmits(props, emits)
<SelectContent class="rounded border bg-white">
<SelectGroup>
<SelectLabel v-if="label" class="px-2 py-1 text-sm font-semibold">
<SelectLabel v-if="label" class="px-2 py-1 text-xs 2xl:text-sm font-semibold">
{{ label }}
</SelectLabel>
+1 -1
View File
@@ -27,7 +27,7 @@ const forwardedProps = useForwardProps(delegatedProps)
v-bind="forwardedProps"
:class="
cn(
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-xs 2xl:text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
props.class,
)
"
+1 -1
View File
@@ -8,7 +8,7 @@ const props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }
</script>
<template>
<SelectLabel :class="cn('px-2 py-1.5 text-sm font-semibold', props.class)">
<SelectLabel :class="cn('px-2 py-1.5 text-xs 2xl:text-sm font-semibold', props.class)">
<slot />
</SelectLabel>
</template>
@@ -21,7 +21,7 @@ const iconName = computed(() => props.iconName || 'i-radix-icons-caret-sort')
v-bind="forwardedProps"
:class="
cn(
'border-input ring-offset-background placeholder:text-muted-foreground relative flex h-9 md:h-8 xl:h-9 w-full rounded-md border border-gray-400 pl-3 pr-8 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50',
'border-input ring-offset-background placeholder:text-muted-foreground relative flex h-9 md:h-8 2xl:h-9 w-full rounded-md border border-gray-400 pl-3 pr-8 py-2 text-xs 2xl:text-sm file:border-0 file:bg-transparent file:text-xs file:font-medium disabled:cursor-not-allowed disabled:opacity-50',
props.class,
)
"