<BasePrimitiveField />
ยท A form control container.
<script setup lang="ts">
const value = ref('')
</script>
<template>
<BasePrimitiveField required>
<div class="relative">
<BasePrimitiveFieldController>
<BaseInput
v-model="value"
rounded="md"
placeholder="Username"
/>
</BasePrimitiveFieldController>
<div class="absolute z-0 end-4 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
</BasePrimitiveField>
</template>
This component is the atomic version of the Field
component. It is meant, unlike the field, to let you compose the structure of your inputs. It has a few sub-components that you can use to build your form fields the way you want them in your project. Take a look at the anatomy of the component:
<template>
<BasePrimitiveField>
<BasePrimitiveFieldLabel>
<!-- Your label here -->
<BasePrimitiveFieldRequiredIndicator />
</BasePrimitiveFieldLabel>
<BasePrimitiveFieldController>
<!-- Your input component here -->
</BasePrimitiveFieldController>
<div>
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
<BasePrimitiveFieldDescription>
<!-- Your description here -->
</BasePrimitiveFieldDescription>
</BasePrimitiveField>
</template>
This component has props that you can use to modify its visual style.
Each of the field related components has its own set of props and slots that are detailed in the API reference section. Use them to build your unique input fields.
Prop | Type |
---|---|
state default: "idle" | "error" | "idle" | "loading" | "success" |
id default: - | string |
name default: - | string |
required default: false | boolean |
disabled default: - | boolean |
fieldset default: - | boolean |
Slot | Type |
---|---|
#default | { inputRef: (el: any) => void; inputAttrs: Record<string, any>; } |
Slot | Type |
---|---|
#default | {} |
Slot | Type |
---|---|
#default | { inputRef: (el: any) => void; inputAttrs: { id?: undefined; name?: undefined; required?: undefined; disabled?: undefined; 'aria-labelledby'?: undefined; 'aria-describedby'?: undefined; 'aria-required'?: undefined; 'aria-invalid'?: undefined; 'aria-errormessage'?: undefined; } | { ...; }; } |
Slot | Type |
---|---|
#default | {} |
Your can override the component default CSS variables in your main.css
file.
@theme {
/* Field elements variables */
--color-field-label: var(--color-muted-600);
--color-field-description: var(--color-muted-500);
--color-field-loading: var(--color-muted-400);
}
Fields can be used with any input component. Fields handle all states an input component can go through, such as idle
, loading
, success
and error
. Here is an example using the BaseInput
component:
<script setup lang="ts">
const states = ['idle', 'loading', 'success', 'error'] as const
</script>
<template>
<BasePrimitiveField v-for="state in states" :key="state" :state="state">
<div class="w-full inline-flex">
<BasePrimitiveFieldLabel class="flex items-center justify-between w-full">
<div>
<span>Username</span>
<BasePrimitiveFieldRequiredIndicator />
</div>
</BasePrimitiveFieldLabel>
</div>
<div class="relative">
<BasePrimitiveFieldController>
<BaseInput placeholder="username..." />
</BasePrimitiveFieldController>
<div class="absolute z-0 end-4 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
<div class="mt-2 flex flex-col">
<BasePrimitiveFieldError class="mb-1 block">
The input is invalid because ...
</BasePrimitiveFieldError>
<BasePrimitiveFieldDescription>
Lorem ipsum dolor sit amet consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. ...
<BaseLink to="#" class="text-primary-600 dark:text-primary-400">
Learn more
</BaseLink>
</BasePrimitiveFieldDescription>
</div>
</BasePrimitiveField>
</template>
Fields can be used with any input component. Fields handle all states an input component can go through, such as idle
, loading
, success
and error
. Here is an example using the BaseSelect
component:
<script setup lang="ts">
const states = ['idle', 'loading', 'success', 'error'] as const
</script>
<template>
<BasePrimitiveField v-for="state in states" :key="state">
<div class="w-full inline-flex">
<BasePrimitiveFieldLabel class="flex items-center justify-between w-full">
<div>
<span>Select an option</span>
<BasePrimitiveFieldRequiredIndicator />
</div>
</BasePrimitiveFieldLabel>
</div>
<div class="relative">
<BasePrimitiveFieldController>
<BaseSelect v-model="value" placeholder="Select a value...">
<BaseSelectItem value="1">
Option 1
</BaseSelectItem>
<BaseSelectItem value="2">
Option 2
</BaseSelectItem>
<BaseSelectItem value="3">
Option 3
</BaseSelectItem>
<BaseSelectItem value="4">
Option 4
</BaseSelectItem>
</BaseSelect>
</BasePrimitiveFieldController>
<div class="absolute z-0 end-10 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
</BasePrimitiveField>
</template>
Fields can be used with any input component. Fields handle all states an input component can go through, such as idle
, loading
, success
and error
. Here is an example using the BaseAutocomplete
component:
<script setup lang="ts">
const states = ['idle', 'loading', 'success', 'error'] as const
</script>
<template>
<BasePrimitiveField v-for="state in states" :key="state" :state="state">
<div class="w-full inline-flex">
<BasePrimitiveFieldLabel class="flex items-center justify-between w-full">
<div>
<span>Choose an option</span>
<BasePrimitiveFieldRequiredIndicator />
</div>
</BasePrimitiveFieldLabel>
</div>
<div class="relative">
<BasePrimitiveFieldController>
<BaseAutocomplete
placeholder="autocomplete placeholder"
clearable
>
<BaseAutocompleteItem value="1">
Option 1
</BaseAutocompleteItem>
<BaseAutocompleteItem value="2">
Option 2
</BaseAutocompleteItem>
<BaseAutocompleteItem value="3">
Option 3
</BaseAutocompleteItem>
<BaseAutocompleteItem value="4">
Option 4
</BaseAutocompleteItem>
<BaseAutocompleteItem value="5">
Option 5
</BaseAutocompleteItem>
<BaseAutocompleteItem value="6">
Option 6
</BaseAutocompleteItem>
</BaseAutocomplete>
</BasePrimitiveFieldController>
<div class="absolute z-0 end-10 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
</BasePrimitiveField>
</template>
Fields can be used with any input component. Fields handle all states an input component can go through, such as idle
, loading
, success
and error
. Here is an example using the BaseInputFile
component:
<script setup lang="ts">
const states = ['idle', 'loading', 'success', 'error'] as const
</script>
<template>
<BasePrimitiveField v-for="state in states" :key="state" :state="state">
<div class="w-full inline-flex">
<BasePrimitiveFieldLabel class="flex items-center justify-between w-full">
<div>
<span>Upload file</span>
<BasePrimitiveFieldRequiredIndicator />
</div>
</BasePrimitiveFieldLabel>
</div>
<div class="relative">
<BasePrimitiveFieldController>
<BaseInputFile placeholder="placeholder" />
</BasePrimitiveFieldController>
<div class="absolute z-0 end-4 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
</BasePrimitiveField>
</template>
Fields can be used with any input component. Fields handle all states an input component can go through, such as idle
, loading
, success
and error
. Here is an example using the BaseInputNumber
component:
<script setup lang="ts">
const states = ['idle', 'loading', 'success', 'error'] as const
</script>
<template>
<BasePrimitiveField v-for="state in states" :key="state" :state="state">
<div class="w-full inline-flex">
<BasePrimitiveFieldLabel class="flex items-center justify-between w-full">
<div>
<span>Quantity</span>
<BasePrimitiveFieldRequiredIndicator />
</div>
</BasePrimitiveFieldLabel>
</div>
<div class="relative">
<BasePrimitiveFieldController>
<BaseInputNumber placeholder="placeholder" />
</BasePrimitiveFieldController>
<div class="absolute z-0 end-12 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
<div class="mt-2 flex flex-col">
<BasePrimitiveFieldError class="mb-1 block">
The input is invalid because ...
</BasePrimitiveFieldError>
<BasePrimitiveFieldDescription>
Lorem ipsum dolor sit amet consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. ...
<BaseLink to="#" class="text-primary-600 dark:text-primary-400">
Learn more
</BaseLink>
</BasePrimitiveFieldDescription>
</div>
</BasePrimitiveField>
</template>
Fields can be used with any input component. Fields handle all states an input component can go through, such as idle
, loading
, success
and error
. Here is an example using the BaseTextarea
component:
<script setup lang="ts">
const states = ['idle', 'loading', 'success', 'error'] as const
</script>
<template>
<BasePrimitiveField v-for="state in states" :key="state" :state="state">
<div class="w-full inline-flex">
<BasePrimitiveFieldLabel class="flex items-center justify-between w-full">
<div>
<span>Message</span>
<BasePrimitiveFieldRequiredIndicator />
</div>
</BasePrimitiveFieldLabel>
</div>
<div class="relative">
<BasePrimitiveFieldController>
<BaseTextarea placeholder="Write a message..." />
</BasePrimitiveFieldController>
<div class="absolute z-0 end-4 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
</BasePrimitiveField>
</template>
Fields can render in a horizontal orientation. Here is an example using the BaseInput
component:
<script setup lang="ts">
const states = ['idle', 'loading', 'success', 'error'] as const
</script>
<template>
<div class="grid grid-cols-3 gap-8 gap-x-10 max-w-2xl">
<BasePrimitiveField class="grid grid-cols-subgrid col-span-3" state="loading">
<div class="flex flex-col justify-center gap-1 relative">
<BasePrimitiveFieldLabel>
<span>Horizontal</span>
<BasePrimitiveFieldRequiredIndicator />
</BasePrimitiveFieldLabel>
<BasePrimitiveFieldDescription>
Lorem ipsum dolor sit amet consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. ...
<BaseLink to="#" class="text-primary-600 dark:text-primary-400">
Learn more
</BaseLink>
</BasePrimitiveFieldDescription>
<div class="absolute z-0 end-0 top-0 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
<div class="col-span-2">
<div class="relative">
<BasePrimitiveFieldController>
<BaseInput v-model="value" />
</BasePrimitiveFieldController>
<div class="absolute z-0 end-4 top-3 pointer-events-none">
<BasePrimitiveFieldLoadingIndicator />
<BasePrimitiveFieldSuccessIndicator />
<BasePrimitiveFieldErrorIndicator />
</div>
</div>
</div>
</BasePrimitiveField>
</div>
</template>