mirror of
https://github.com/wireadmin/wireadmin
synced 2025-06-04 03:36:55 +00:00
add shadcn
the form
component
This commit is contained in:
parent
eabab0e2f1
commit
ece632f7bb
@ -1,20 +1,22 @@
|
|||||||
{
|
{
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "all",
|
"trailingComma": "all",
|
||||||
"printWidth": 100,
|
"printWidth": 100,
|
||||||
"plugins": [
|
"jsxBracketSameLine": true,
|
||||||
"prettier-plugin-svelte"
|
|
||||||
],
|
|
||||||
"pluginSearchDirs": [
|
|
||||||
"."
|
|
||||||
],
|
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": "*.svelte",
|
"files": "*.svelte",
|
||||||
"options": {
|
"options": {
|
||||||
"parser": "svelte"
|
"parser": "svelte",
|
||||||
}
|
"plugins": [
|
||||||
}
|
"prettier-plugin-svelte"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pluginSearchDirs": [
|
||||||
|
"."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
BIN
web/bun.lockb
BIN
web/bun.lockb
Binary file not shown.
@ -3,7 +3,7 @@
|
|||||||
"style": "default",
|
"style": "default",
|
||||||
"tailwind": {
|
"tailwind": {
|
||||||
"config": "tailwind.config.js",
|
"config": "tailwind.config.js",
|
||||||
"css": "src/app.postcss",
|
"css": "src/app.css",
|
||||||
"baseColor": "gray"
|
"baseColor": "gray"
|
||||||
},
|
},
|
||||||
"aliases": {
|
"aliases": {
|
||||||
|
@ -24,16 +24,19 @@
|
|||||||
"prettier-plugin-svelte": "^2.10.1",
|
"prettier-plugin-svelte": "^2.10.1",
|
||||||
"svelte": "^4.0.5",
|
"svelte": "^4.0.5",
|
||||||
"svelte-check": "^3.4.3",
|
"svelte-check": "^3.4.3",
|
||||||
|
"sveltekit-superforms": "^1.9.0",
|
||||||
"tailwindcss": "^3.3.2",
|
"tailwindcss": "^3.3.2",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^4.4.2",
|
"vite": "^4.4.2",
|
||||||
"vitest": "^0.34.0"
|
"vitest": "^0.34.0",
|
||||||
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bits-ui": "^0.9.0",
|
"bits-ui": "^0.9.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
|
"formsnap": "^0.4.1",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lucide-svelte": "^0.292.0",
|
"lucide-svelte": "^0.292.0",
|
||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { Button as ButtonPrimitive } from 'bits-ui';
|
||||||
import { cn } from '$lib/utils';
|
import { cn } from '$lib/utils';
|
||||||
import { buttonVariants, type Events, type Props } from '.';
|
import { buttonVariants, type Props, type Events } from '.';
|
||||||
|
|
||||||
type $$Props = Props;
|
type $$Props = Props;
|
||||||
type $$Events = Events;
|
type $$Events = Events;
|
||||||
|
@ -7,9 +7,12 @@ const buttonVariants = tv({
|
|||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
||||||
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
destructive:
|
||||||
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
||||||
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
outline:
|
||||||
|
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
||||||
|
secondary:
|
||||||
|
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||||
link: 'text-primary underline-offset-4 hover:underline',
|
link: 'text-primary underline-offset-4 hover:underline',
|
||||||
},
|
},
|
||||||
|
34
web/src/lib/components/ui/checkbox/checkbox.svelte
Normal file
34
web/src/lib/components/ui/checkbox/checkbox.svelte
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Checkbox as CheckboxPrimitive } from 'bits-ui';
|
||||||
|
import { Check, Minus } from 'lucide-svelte';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = CheckboxPrimitive.Props;
|
||||||
|
type $$Events = CheckboxPrimitive.Events;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let checked: $$Props['checked'] = false;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<CheckboxPrimitive.Root
|
||||||
|
class={cn(
|
||||||
|
"box-content peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
bind:checked
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
>
|
||||||
|
<CheckboxPrimitive.Indicator
|
||||||
|
class={cn("flex items-center justify-center text-current h-4 w-4")}
|
||||||
|
let:isChecked
|
||||||
|
let:isIndeterminate
|
||||||
|
>
|
||||||
|
{#if isChecked}
|
||||||
|
<Check class="h-3.5 w-3.5" />
|
||||||
|
{:else if isIndeterminate}
|
||||||
|
<Minus class="h-3.5 w-3.5" />
|
||||||
|
{/if}
|
||||||
|
</CheckboxPrimitive.Indicator>
|
||||||
|
</CheckboxPrimitive.Root>
|
6
web/src/lib/components/ui/checkbox/index.ts
Normal file
6
web/src/lib/components/ui/checkbox/index.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import Root from './checkbox.svelte';
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Checkbox,
|
||||||
|
};
|
10
web/src/lib/components/ui/form/form-button.svelte
Normal file
10
web/src/lib/components/ui/form/form-button.svelte
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import * as Button from '$lib/components/ui/button';
|
||||||
|
|
||||||
|
type $$Props = Button.Props;
|
||||||
|
type $$Events = Button.Events;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Button.Root type="submit" {...$$restProps} on:click on:keydown>
|
||||||
|
<slot />
|
||||||
|
</Button.Root>
|
27
web/src/lib/components/ui/form/form-checkbox.svelte
Normal file
27
web/src/lib/components/ui/form/form-checkbox.svelte
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
import type { Checkbox as CheckboxPrimitive } from 'bits-ui';
|
||||||
|
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||||
|
|
||||||
|
type $$Props = CheckboxPrimitive.Props;
|
||||||
|
type $$Events = CheckboxPrimitive.Events;
|
||||||
|
|
||||||
|
export let onCheckedChange: $$Props['onCheckedChange'] = undefined;
|
||||||
|
|
||||||
|
const { name, setValue, attrStore, value } = getFormField();
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const { name: nameAttr, value: valueAttr, ...rest } = $attrStore;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Checkbox
|
||||||
|
{...rest}
|
||||||
|
checked={typeof $value === "boolean" ? $value : false}
|
||||||
|
onCheckedChange={(v) => {
|
||||||
|
onCheckedChange?.(v);
|
||||||
|
setValue(v);
|
||||||
|
}}
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
on:keydown
|
||||||
|
/>
|
||||||
|
<input hidden {name} value={$value} />
|
16
web/src/lib/components/ui/form/form-description.svelte
Normal file
16
web/src/lib/components/ui/form/form-description.svelte
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Form as FormPrimitive } from 'formsnap';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
type $$Props = HTMLAttributes<HTMLSpanElement>;
|
||||||
|
let className: string | undefined | null = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FormPrimitive.Description
|
||||||
|
class={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</FormPrimitive.Description>
|
28
web/src/lib/components/ui/form/form-input.svelte
Normal file
28
web/src/lib/components/ui/form/form-input.svelte
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
||||||
|
import { Input, type InputEvents } from '$lib/components/ui/input';
|
||||||
|
|
||||||
|
type $$Props = HTMLInputAttributes;
|
||||||
|
type $$Events = InputEvents;
|
||||||
|
|
||||||
|
const { attrStore, value } = getFormField();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
{...$attrStore}
|
||||||
|
bind:value={$value}
|
||||||
|
{...$$restProps}
|
||||||
|
on:blur
|
||||||
|
on:change
|
||||||
|
on:click
|
||||||
|
on:focus
|
||||||
|
on:keydown
|
||||||
|
on:keypress
|
||||||
|
on:keyup
|
||||||
|
on:mouseover
|
||||||
|
on:mouseenter
|
||||||
|
on:mouseleave
|
||||||
|
on:paste
|
||||||
|
on:input
|
||||||
|
/>
|
12
web/src/lib/components/ui/form/form-item.svelte
Normal file
12
web/src/lib/components/ui/form/form-item.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||||
|
let className: string | undefined | null = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class={cn("space-y-2", className)} {...$$restProps}>
|
||||||
|
<slot />
|
||||||
|
</div>
|
21
web/src/lib/components/ui/form/form-label.svelte
Normal file
21
web/src/lib/components/ui/form/form-label.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Label as LabelPrimitive } from 'bits-ui';
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import { Label } from '$lib/components/ui/label';
|
||||||
|
|
||||||
|
type $$Props = LabelPrimitive.Props;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
|
||||||
|
const { errors, ids } = getFormField();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Label
|
||||||
|
for={$ids.input}
|
||||||
|
class={cn($errors && "text-destructive", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</Label>
|
24
web/src/lib/components/ui/form/form-native-select.svelte
Normal file
24
web/src/lib/components/ui/form/form-native-select.svelte
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Form as FormPrimitive } from 'formsnap';
|
||||||
|
import { buttonVariants } from '$lib/components/ui/button';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import { ChevronDown } from 'lucide-svelte';
|
||||||
|
import type { HTMLSelectAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
type $$Props = HTMLSelectAttributes;
|
||||||
|
|
||||||
|
let className: string | undefined | null = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FormPrimitive.Select
|
||||||
|
class={cn(
|
||||||
|
buttonVariants({ variant: "outline" }),
|
||||||
|
"appearance-none bg-transparent font-normal",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</FormPrimitive.Select>
|
||||||
|
<ChevronDown class="absolute right-3 top-2.5 h-4 w-4 opacity-50" />
|
22
web/src/lib/components/ui/form/form-radio-group.svelte
Normal file
22
web/src/lib/components/ui/form/form-radio-group.svelte
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
import type { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
|
||||||
|
import * as RadioGroup from '$lib/components/ui/radio-group';
|
||||||
|
|
||||||
|
type $$Props = RadioGroupPrimitive.Props;
|
||||||
|
const { attrStore, setValue, name, value } = getFormField();
|
||||||
|
|
||||||
|
export let onValueChange: $$Props['onValueChange'] = undefined;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<RadioGroup.Root
|
||||||
|
{...$attrStore}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
onValueChange?.(v);
|
||||||
|
setValue(v);
|
||||||
|
}}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
<input hidden {name} value={$value} />
|
||||||
|
</RadioGroup.Root>
|
17
web/src/lib/components/ui/form/form-select-trigger.svelte
Normal file
17
web/src/lib/components/ui/form/form-select-trigger.svelte
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import * as Select from '$lib/components/ui/select';
|
||||||
|
import type { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.TriggerProps & {
|
||||||
|
placeholder?: string;
|
||||||
|
};
|
||||||
|
type $$Events = SelectPrimitive.TriggerEvents;
|
||||||
|
const { attrStore } = getFormField();
|
||||||
|
export let placeholder = '';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Select.Trigger {...$$restProps} {...$attrStore} on:click on:keydown>
|
||||||
|
<Select.Value {placeholder} />
|
||||||
|
<slot />
|
||||||
|
</Select.Trigger>
|
20
web/src/lib/components/ui/form/form-select.svelte
Normal file
20
web/src/lib/components/ui/form/form-select.svelte
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import * as Select from '$lib/components/ui/select';
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
import type { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.Props;
|
||||||
|
const { setValue, name, value } = getFormField();
|
||||||
|
export let onSelectedChange: $$Props['onSelectedChange'] = undefined;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Select.Root
|
||||||
|
onSelectedChange={(v) => {
|
||||||
|
onSelectedChange?.(v);
|
||||||
|
setValue(v ? v.value : undefined);
|
||||||
|
}}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
<input hidden {name} value={$value} />
|
||||||
|
</Select.Root>
|
25
web/src/lib/components/ui/form/form-switch.svelte
Normal file
25
web/src/lib/components/ui/form/form-switch.svelte
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
import type { Switch as SwitchPrimitive } from 'bits-ui';
|
||||||
|
import { Switch } from '$lib/components/ui/switch';
|
||||||
|
|
||||||
|
type $$Props = SwitchPrimitive.Props;
|
||||||
|
type $$Events = SwitchPrimitive.Events;
|
||||||
|
|
||||||
|
export let onCheckedChange: $$Props['onCheckedChange'] = undefined;
|
||||||
|
|
||||||
|
const { name, setValue, attrStore, value } = getFormField();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
{...$attrStore}
|
||||||
|
checked={typeof $value === "boolean" ? $value : false}
|
||||||
|
onCheckedChange={(v) => {
|
||||||
|
onCheckedChange?.(v);
|
||||||
|
setValue(v);
|
||||||
|
}}
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
on:keydown
|
||||||
|
/>
|
||||||
|
<input hidden {name} value={$value} />
|
32
web/src/lib/components/ui/form/form-textarea.svelte
Normal file
32
web/src/lib/components/ui/form/form-textarea.svelte
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getFormField } from 'formsnap';
|
||||||
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
||||||
|
import type { TextareaGetFormField } from '.';
|
||||||
|
import {
|
||||||
|
Textarea,
|
||||||
|
type TextareaEvents,
|
||||||
|
} from '$lib/components/ui/textarea';
|
||||||
|
|
||||||
|
type $$Props = HTMLTextareaAttributes;
|
||||||
|
type $$Events = TextareaEvents;
|
||||||
|
|
||||||
|
const { attrStore, value } = getFormField() as TextareaGetFormField;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Textarea
|
||||||
|
{...$attrStore}
|
||||||
|
bind:value={$value}
|
||||||
|
{...$$restProps}
|
||||||
|
on:blur
|
||||||
|
on:change
|
||||||
|
on:click
|
||||||
|
on:focus
|
||||||
|
on:keydown
|
||||||
|
on:keypress
|
||||||
|
on:keyup
|
||||||
|
on:mouseover
|
||||||
|
on:mouseenter
|
||||||
|
on:mouseleave
|
||||||
|
on:paste
|
||||||
|
on:input
|
||||||
|
/>
|
14
web/src/lib/components/ui/form/form-validation.svelte
Normal file
14
web/src/lib/components/ui/form/form-validation.svelte
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Form as FormPrimitive } from 'formsnap';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
type $$Props = HTMLAttributes<HTMLParagraphElement>;
|
||||||
|
let className: string | undefined | null = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FormPrimitive.Validation
|
||||||
|
class={cn("text-sm font-medium text-destructive", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
/>
|
85
web/src/lib/components/ui/form/index.ts
Normal file
85
web/src/lib/components/ui/form/index.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { Form as FormPrimitive, getFormField } from 'formsnap';
|
||||||
|
import * as RadioGroupComp from '$lib/components/ui/radio-group';
|
||||||
|
import * as SelectComp from '$lib/components/ui/select';
|
||||||
|
import type { Writable } from 'svelte/store';
|
||||||
|
import Item from './form-item.svelte';
|
||||||
|
import Input from './form-input.svelte';
|
||||||
|
import Textarea from './form-textarea.svelte';
|
||||||
|
import Description from './form-description.svelte';
|
||||||
|
import Label from './form-label.svelte';
|
||||||
|
import Validation from './form-validation.svelte';
|
||||||
|
import Checkbox from './form-checkbox.svelte';
|
||||||
|
import Switch from './form-switch.svelte';
|
||||||
|
import NativeSelect from './form-native-select.svelte';
|
||||||
|
import RadioGroup from './form-radio-group.svelte';
|
||||||
|
import Select from './form-select.svelte';
|
||||||
|
import SelectTrigger from './form-select-trigger.svelte';
|
||||||
|
import Button from './form-button.svelte';
|
||||||
|
|
||||||
|
const Root = FormPrimitive.Root;
|
||||||
|
const Field = FormPrimitive.Field;
|
||||||
|
const Control = FormPrimitive.Control;
|
||||||
|
const RadioItem = RadioGroupComp.Item;
|
||||||
|
const NativeRadio = FormPrimitive.Radio;
|
||||||
|
const SelectContent = SelectComp.Content;
|
||||||
|
const SelectLabel = SelectComp.Label;
|
||||||
|
const SelectGroup = SelectComp.Group;
|
||||||
|
const SelectItem = SelectComp.Item;
|
||||||
|
const SelectSeparator = SelectComp.Separator;
|
||||||
|
|
||||||
|
export type TextareaGetFormField = Omit<
|
||||||
|
ReturnType<typeof getFormField>,
|
||||||
|
'value'
|
||||||
|
> & {
|
||||||
|
value: Writable<string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Field,
|
||||||
|
Control,
|
||||||
|
Item,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Button,
|
||||||
|
Switch,
|
||||||
|
Select,
|
||||||
|
Checkbox,
|
||||||
|
Textarea,
|
||||||
|
Validation,
|
||||||
|
RadioGroup,
|
||||||
|
RadioItem,
|
||||||
|
Description,
|
||||||
|
SelectContent,
|
||||||
|
SelectLabel,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectSeparator,
|
||||||
|
SelectTrigger,
|
||||||
|
NativeSelect,
|
||||||
|
NativeRadio,
|
||||||
|
//
|
||||||
|
Root as Form,
|
||||||
|
Field as FormField,
|
||||||
|
Control as FormControl,
|
||||||
|
Item as FormItem,
|
||||||
|
Input as FormInput,
|
||||||
|
Textarea as FormTextarea,
|
||||||
|
Description as FormDescription,
|
||||||
|
Label as FormLabel,
|
||||||
|
Validation as FormValidation,
|
||||||
|
NativeSelect as FormNativeSelect,
|
||||||
|
NativeRadio as FormNativeRadio,
|
||||||
|
Checkbox as FormCheckbox,
|
||||||
|
Switch as FormSwitch,
|
||||||
|
RadioGroup as FormRadioGroup,
|
||||||
|
RadioItem as FormRadioItem,
|
||||||
|
Select as FormSelect,
|
||||||
|
SelectContent as FormSelectContent,
|
||||||
|
SelectLabel as FormSelectLabel,
|
||||||
|
SelectGroup as FormSelectGroup,
|
||||||
|
SelectItem as FormSelectItem,
|
||||||
|
SelectSeparator as FormSelectSeparator,
|
||||||
|
SelectTrigger as FormSelectTrigger,
|
||||||
|
Button as FormButton,
|
||||||
|
};
|
25
web/src/lib/components/ui/input/index.ts
Normal file
25
web/src/lib/components/ui/input/index.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import Root from './input.svelte';
|
||||||
|
|
||||||
|
type FormInputEvent<T extends Event = Event> = T & {
|
||||||
|
currentTarget: EventTarget & HTMLInputElement;
|
||||||
|
};
|
||||||
|
export type InputEvents = {
|
||||||
|
blur: FormInputEvent<FocusEvent>;
|
||||||
|
change: FormInputEvent<Event>;
|
||||||
|
click: FormInputEvent<MouseEvent>;
|
||||||
|
focus: FormInputEvent<FocusEvent>;
|
||||||
|
keydown: FormInputEvent<KeyboardEvent>;
|
||||||
|
keypress: FormInputEvent<KeyboardEvent>;
|
||||||
|
keyup: FormInputEvent<KeyboardEvent>;
|
||||||
|
mouseover: FormInputEvent<MouseEvent>;
|
||||||
|
mouseenter: FormInputEvent<MouseEvent>;
|
||||||
|
mouseleave: FormInputEvent<MouseEvent>;
|
||||||
|
paste: FormInputEvent<ClipboardEvent>;
|
||||||
|
input: FormInputEvent<InputEvent>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Input,
|
||||||
|
};
|
33
web/src/lib/components/ui/input/input.svelte
Normal file
33
web/src/lib/components/ui/input/input.svelte
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import type { InputEvents } from '.';
|
||||||
|
|
||||||
|
type $$Props = HTMLInputAttributes;
|
||||||
|
type $$Events = InputEvents;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let value: $$Props['value'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input
|
||||||
|
class={cn(
|
||||||
|
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-foreground file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
bind:value
|
||||||
|
on:blur
|
||||||
|
on:change
|
||||||
|
on:click
|
||||||
|
on:focus
|
||||||
|
on:keydown
|
||||||
|
on:keypress
|
||||||
|
on:keyup
|
||||||
|
on:mouseover
|
||||||
|
on:mouseenter
|
||||||
|
on:mouseleave
|
||||||
|
on:paste
|
||||||
|
on:input
|
||||||
|
{...$$restProps}
|
||||||
|
/>
|
7
web/src/lib/components/ui/label/index.ts
Normal file
7
web/src/lib/components/ui/label/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Root from './label.svelte';
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Label,
|
||||||
|
};
|
21
web/src/lib/components/ui/label/label.svelte
Normal file
21
web/src/lib/components/ui/label/label.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Label as LabelPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = LabelPrimitive.Props;
|
||||||
|
type $$Events = LabelPrimitive.Events;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<LabelPrimitive.Root
|
||||||
|
class={cn(
|
||||||
|
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
on:mousedown
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</LabelPrimitive.Root>
|
15
web/src/lib/components/ui/radio-group/index.ts
Normal file
15
web/src/lib/components/ui/radio-group/index.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
|
||||||
|
|
||||||
|
import Root from './radio-group.svelte';
|
||||||
|
import Item from './radio-group-item.svelte';
|
||||||
|
const Input = RadioGroupPrimitive.Input;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Input,
|
||||||
|
Item,
|
||||||
|
//
|
||||||
|
Root as RadioGroup,
|
||||||
|
Input as RadioGroupInput,
|
||||||
|
Item as RadioGroupItem,
|
||||||
|
};
|
@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
|
||||||
|
import { Circle } from 'lucide-svelte';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = RadioGroupPrimitive.ItemProps;
|
||||||
|
type $$Events = RadioGroupPrimitive.ItemEvents;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let value: $$Props['value'];
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<RadioGroupPrimitive.Item
|
||||||
|
{value}
|
||||||
|
class={cn(
|
||||||
|
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<RadioGroupPrimitive.ItemIndicator>
|
||||||
|
<Circle class="h-2.5 w-2.5 fill-current text-current" />
|
||||||
|
</RadioGroupPrimitive.ItemIndicator>
|
||||||
|
</div>
|
||||||
|
</RadioGroupPrimitive.Item>
|
18
web/src/lib/components/ui/radio-group/radio-group.svelte
Normal file
18
web/src/lib/components/ui/radio-group/radio-group.svelte
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = RadioGroupPrimitive.Props;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let value: $$Props['value'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<RadioGroupPrimitive.Root
|
||||||
|
bind:value
|
||||||
|
class={cn("grid gap-2", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</RadioGroupPrimitive.Root>
|
33
web/src/lib/components/ui/select/index.ts
Normal file
33
web/src/lib/components/ui/select/index.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
|
||||||
|
import Root from './select.svelte';
|
||||||
|
import Label from './select-label.svelte';
|
||||||
|
import Item from './select-item.svelte';
|
||||||
|
import Content from './select-content.svelte';
|
||||||
|
import Trigger from './select-trigger.svelte';
|
||||||
|
import Separator from './select-separator.svelte';
|
||||||
|
|
||||||
|
const Group = SelectPrimitive.Group;
|
||||||
|
const Input = SelectPrimitive.Input;
|
||||||
|
const Value = SelectPrimitive.Value;
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Group,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Item,
|
||||||
|
Value,
|
||||||
|
Content,
|
||||||
|
Trigger,
|
||||||
|
Separator,
|
||||||
|
//
|
||||||
|
Root as Select,
|
||||||
|
Group as SelectGroup,
|
||||||
|
Input as SelectInput,
|
||||||
|
Label as SelectLabel,
|
||||||
|
Item as SelectItem,
|
||||||
|
Value as SelectValue,
|
||||||
|
Content as SelectContent,
|
||||||
|
Trigger as SelectTrigger,
|
||||||
|
Separator as SelectSeparator,
|
||||||
|
};
|
36
web/src/lib/components/ui/select/select-content.svelte
Normal file
36
web/src/lib/components/ui/select/select-content.svelte
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
import { cn, flyAndScale } from '$lib/utils';
|
||||||
|
import { scale } from 'svelte/transition';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.ContentProps;
|
||||||
|
type $$Events = SelectPrimitive.ContentEvents;
|
||||||
|
export let inTransition: $$Props['inTransition'] = flyAndScale;
|
||||||
|
export let inTransitionConfig: $$Props['inTransitionConfig'] = undefined;
|
||||||
|
export let outTransition: $$Props['outTransition'] = scale;
|
||||||
|
export let outTransitionConfig: $$Props['outTransitionConfig'] = {
|
||||||
|
start: 0.95,
|
||||||
|
opacity: 0,
|
||||||
|
duration: 50,
|
||||||
|
};
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SelectPrimitive.Content
|
||||||
|
{inTransition}
|
||||||
|
{inTransitionConfig}
|
||||||
|
{outTransition}
|
||||||
|
{outTransitionConfig}
|
||||||
|
class={cn(
|
||||||
|
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
on:keydown
|
||||||
|
>
|
||||||
|
<div class="w-full p-1">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</SelectPrimitive.Content>
|
38
web/src/lib/components/ui/select/select-item.svelte
Normal file
38
web/src/lib/components/ui/select/select-item.svelte
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
import { Check } from 'lucide-svelte';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.ItemProps;
|
||||||
|
type $$Events = SelectPrimitive.ItemEvents;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let value: $$Props['value'];
|
||||||
|
export let label: $$Props['label'] = undefined;
|
||||||
|
export let disabled: $$Props['disabled'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SelectPrimitive.Item
|
||||||
|
{value}
|
||||||
|
{disabled}
|
||||||
|
{label}
|
||||||
|
class={cn(
|
||||||
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
on:keydown
|
||||||
|
on:focusin
|
||||||
|
on:focusout
|
||||||
|
on:pointerleave
|
||||||
|
on:pointermove
|
||||||
|
>
|
||||||
|
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<SelectPrimitive.ItemIndicator>
|
||||||
|
<Check class="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
<slot />
|
||||||
|
</SelectPrimitive.Item>
|
16
web/src/lib/components/ui/select/select-label.svelte
Normal file
16
web/src/lib/components/ui/select/select-label.svelte
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.LabelProps;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SelectPrimitive.Label
|
||||||
|
class={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</SelectPrimitive.Label>
|
14
web/src/lib/components/ui/select/select-separator.svelte
Normal file
14
web/src/lib/components/ui/select/select-separator.svelte
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.SeparatorProps;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SelectPrimitive.Separator
|
||||||
|
class={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
/>
|
27
web/src/lib/components/ui/select/select-trigger.svelte
Normal file
27
web/src/lib/components/ui/select/select-trigger.svelte
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
import { ChevronDown } from 'lucide-svelte';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.TriggerProps;
|
||||||
|
type $$Events = SelectPrimitive.TriggerEvents;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SelectPrimitive.Trigger
|
||||||
|
class={cn(
|
||||||
|
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
let:builder
|
||||||
|
on:click
|
||||||
|
on:keydown
|
||||||
|
>
|
||||||
|
<slot {builder} />
|
||||||
|
<div>
|
||||||
|
<ChevronDown class="h-4 w-4 opacity-50" />
|
||||||
|
</div>
|
||||||
|
</SelectPrimitive.Trigger>
|
12
web/src/lib/components/ui/select/select.svelte
Normal file
12
web/src/lib/components/ui/select/select.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Select as SelectPrimitive } from 'bits-ui';
|
||||||
|
|
||||||
|
type $$Props = SelectPrimitive.Props;
|
||||||
|
|
||||||
|
export let selected: $$Props['selected'] = undefined;
|
||||||
|
export let open: $$Props['open'] = undefined;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SelectPrimitive.Root bind:selected bind:open {...$$restProps}>
|
||||||
|
<slot />
|
||||||
|
</SelectPrimitive.Root>
|
7
web/src/lib/components/ui/switch/index.ts
Normal file
7
web/src/lib/components/ui/switch/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Root from './switch.svelte';
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Switch,
|
||||||
|
};
|
25
web/src/lib/components/ui/switch/switch.svelte
Normal file
25
web/src/lib/components/ui/switch/switch.svelte
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Switch as SwitchPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = SwitchPrimitive.Props;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let checked: $$Props['checked'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SwitchPrimitive.Root
|
||||||
|
bind:checked
|
||||||
|
class={cn(
|
||||||
|
"peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<SwitchPrimitive.Thumb
|
||||||
|
class={cn(
|
||||||
|
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</SwitchPrimitive.Root>
|
28
web/src/lib/components/ui/textarea/index.ts
Normal file
28
web/src/lib/components/ui/textarea/index.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import Root from './textarea.svelte';
|
||||||
|
|
||||||
|
type FormTextareaEvent<T extends Event = Event> = T & {
|
||||||
|
currentTarget: EventTarget & HTMLTextAreaElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TextareaEvents = {
|
||||||
|
blur: FormTextareaEvent<FocusEvent>;
|
||||||
|
change: FormTextareaEvent<Event>;
|
||||||
|
click: FormTextareaEvent<MouseEvent>;
|
||||||
|
focus: FormTextareaEvent<FocusEvent>;
|
||||||
|
keydown: FormTextareaEvent<KeyboardEvent>;
|
||||||
|
keypress: FormTextareaEvent<KeyboardEvent>;
|
||||||
|
keyup: FormTextareaEvent<KeyboardEvent>;
|
||||||
|
mouseover: FormTextareaEvent<MouseEvent>;
|
||||||
|
mouseenter: FormTextareaEvent<MouseEvent>;
|
||||||
|
mouseleave: FormTextareaEvent<MouseEvent>;
|
||||||
|
paste: FormTextareaEvent<ClipboardEvent>;
|
||||||
|
input: FormTextareaEvent<InputEvent>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Textarea,
|
||||||
|
type TextareaEvents,
|
||||||
|
type FormTextareaEvent,
|
||||||
|
};
|
31
web/src/lib/components/ui/textarea/textarea.svelte
Normal file
31
web/src/lib/components/ui/textarea/textarea.svelte
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
type $$Props = HTMLTextareaAttributes;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let value: $$Props['value'] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
class={cn(
|
||||||
|
"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
bind:value
|
||||||
|
on:blur
|
||||||
|
on:change
|
||||||
|
on:click
|
||||||
|
on:focus
|
||||||
|
on:keydown
|
||||||
|
on:keypress
|
||||||
|
on:keyup
|
||||||
|
on:mouseover
|
||||||
|
on:mouseenter
|
||||||
|
on:mouseleave
|
||||||
|
on:paste
|
||||||
|
on:input
|
||||||
|
{...$$restProps}
|
||||||
|
/>
|
Loading…
Reference in New Issue
Block a user