-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
298 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import type { FieldContext } from '$lib/types.js'; | ||
import { withPrefix } from '$lib/utils.js'; | ||
import { getContext, hasContext, setContext } from 'svelte'; | ||
|
||
const fieldKey = Symbol(withPrefix('field')); | ||
|
||
export const setFieldContext = (field: FieldContext) => setContext(fieldKey, field); | ||
export const hasFieldContext = (): boolean => hasContext(fieldKey); | ||
export const getFieldContext = (): FieldContext => (getContext(fieldKey) || {}) as FieldContext; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<script lang="ts"> | ||
import { setFieldContext } from '$lib/common/context.svelte.js'; | ||
import { withChildrenSnippets } from '$lib/common/use-child.svelte.js'; | ||
import { ChildKey } from '$lib/constants.js'; | ||
import type { FieldContext } from '$lib/types.js'; | ||
import { type Snippet } from 'svelte'; | ||
type Props = FieldContext & { | ||
children: Snippet; | ||
}; | ||
const { children, ...props }: Props = $props(); | ||
const state = $state(props); | ||
setFieldContext(state); | ||
const { getChildren: getChildSnippet } = withChildrenSnippets(ChildKey.Field); | ||
const helperTextChildren = $derived(getChildSnippet(ChildKey.HelperText)); | ||
</script> | ||
|
||
<div> | ||
{@render children()} | ||
{#if helperTextChildren} | ||
<div class="pt-1"> | ||
{@render helperTextChildren?.()} | ||
</div> | ||
{/if} | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<script lang="ts"> | ||
import Text from '$lib/components/Text/Text.svelte'; | ||
import { ChildKey } from '$lib/constants.js'; | ||
import Child from '$lib/internal/Child.svelte'; | ||
import type { Color } from '$lib/types.js'; | ||
import { cleanClass } from '$lib/utils.js'; | ||
import type { Snippet } from 'svelte'; | ||
type Props = { | ||
color?: Color; | ||
class?: string; | ||
children?: Snippet; | ||
}; | ||
let { class: className, children, color }: Props = $props(); | ||
</script> | ||
|
||
<Child for={ChildKey.Field} as={ChildKey.HelperText}> | ||
<div class={cleanClass(className)}> | ||
<Text {color} size="small"> | ||
{@render children?.()} | ||
</Text> | ||
</div> | ||
</Child> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,109 @@ | ||
<script lang="ts"> | ||
import { getFieldContext } from '$lib/common/context.svelte.js'; | ||
import type { Shape, Size } from '$lib/types.js'; | ||
import { cleanClass, generateId } from '$lib/utils.js'; | ||
import type { HTMLInputAttributes } from 'svelte/elements'; | ||
import type { WithElementRef } from 'bits-ui'; | ||
import { cleanClass } from '$lib/utils.js'; | ||
import { tv } from 'tailwind-variants'; | ||
type Props = { | ||
class?: string; | ||
value?: string; | ||
size?: Size; | ||
shape?: Shape; | ||
inputSize?: HTMLInputAttributes['size']; | ||
} & Omit<HTMLInputAttributes, 'size'>; | ||
let { | ||
ref = $bindable(null), | ||
value = $bindable(), | ||
shape = 'semi-round', | ||
size = 'medium', | ||
class: className, | ||
value = $bindable<string>(), | ||
...restProps | ||
}: WithElementRef<HTMLInputAttributes> = $props(); | ||
}: Props = $props(); | ||
const { | ||
label, | ||
readOnly = false, | ||
required = false, | ||
invalid = false, | ||
disabled = false, | ||
} = $derived(getFieldContext()); | ||
const labelStyles = tv({ | ||
base: '', | ||
variants: { | ||
size: { | ||
tiny: 'text-xs', | ||
small: 'text-sm', | ||
medium: 'text-md', | ||
large: 'text-lg', | ||
giant: 'text-xl', | ||
}, | ||
}, | ||
}); | ||
const inputStyles = tv({ | ||
base: 'outline-none disabled:cursor-not-allowed bg-gray-200 dark:bg-gray-600 disabled:bg-gray-300 disabled:text-gray-200 dark:disabled:bg-gray-800 aria-readonly:text-dark/50 dark:aria-readonly:text-dark/75', | ||
variants: { | ||
shape: { | ||
rectangle: 'rounded-none', | ||
'semi-round': '', | ||
round: 'rounded-full', | ||
}, | ||
padding: { | ||
base: 'px-3 py-2', | ||
round: 'px-4 py-2', | ||
}, | ||
roundedSize: { | ||
tiny: 'rounded-xl', | ||
small: 'rounded-xl', | ||
medium: 'rounded-2xl', | ||
large: 'rounded-2xl', | ||
giant: 'rounded-2xl', | ||
}, | ||
textSize: { | ||
tiny: 'text-xs', | ||
small: 'text-sm', | ||
medium: 'text-md', | ||
large: 'text-lg', | ||
giant: 'text-xl', | ||
}, | ||
invalid: { | ||
true: 'border border-danger/80', | ||
false: '', | ||
}, | ||
}, | ||
}); | ||
const id = generateId(); | ||
const inputId = `input-${id}`; | ||
const labelId = `label-${id}`; | ||
</script> | ||
|
||
<input | ||
bind:this={ref} | ||
class={cleanClass( | ||
'border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', | ||
className, | ||
)} | ||
bind:value | ||
{...restProps} | ||
/> | ||
<div class="flex flex-col gap-1"> | ||
{#if label} | ||
<label id={labelId} for={inputId} class={labelStyles({ size })}>{label}</label> | ||
{/if} | ||
<input | ||
id={label && inputId} | ||
aria-labelledby={label && labelId} | ||
{required} | ||
aria-required={required} | ||
{disabled} | ||
aria-disabled={disabled} | ||
readonly={readOnly} | ||
aria-readonly={readOnly} | ||
class={cleanClass( | ||
inputStyles({ | ||
shape, | ||
textSize: size, | ||
padding: shape === 'round' ? 'round' : 'base', | ||
roundedSize: shape === 'semi-round' ? size : undefined, | ||
invalid, | ||
}), | ||
className, | ||
)} | ||
bind:value | ||
{...restProps} | ||
/> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.