-
Notifications
You must be signed in to change notification settings - Fork 12
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
1 parent
7b4f61e
commit 25cfd69
Showing
13 changed files
with
309 additions
and
9 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,70 @@ | ||
<script lang="ts"> | ||
import { Icons } from '$lib/assets/icons'; | ||
import { cn } from '$lib/utils.js'; | ||
import { Checkbox as CheckboxPrimitive, type WithoutChildrenOrChild } from 'bits-ui'; | ||
import type { Snippet } from 'svelte'; | ||
type Props = WithoutChildrenOrChild<CheckboxPrimitive.RootProps> & { | ||
title: string; | ||
children?: Snippet; | ||
'aria-labelledby'?: string; | ||
description?: string; | ||
}; | ||
let { | ||
class: class_name = undefined, | ||
checked = $bindable(false), | ||
id = undefined, | ||
title, | ||
description, | ||
'aria-labelledby': aria_labelledby = undefined, | ||
children, | ||
...rest | ||
}: Props = $props(); | ||
</script> | ||
|
||
<label | ||
id={aria_labelledby} | ||
for={id} | ||
class={cn( | ||
'inline-flex w-full cursor-pointer items-center justify-between gap-2 rounded-md border p-3 transition-colors', | ||
"hover:border-gray-500 hover:bg-gray-100 hover:has-[button[aria-checked='true']]:bg-blue-200", | ||
"has-[button[aria-checked='true']]:border-blue-600 has-[button[aria-checked='true']]:bg-blue-100", | ||
// disabled | ||
"has-[button[disabled='']]:cursor-not-allowed has-[button[disabled='']]:hover:border-gray-400 has-[button[disabled='']]:hover:bg-transparent" | ||
)} | ||
> | ||
<CheckboxPrimitive.Root | ||
{id} | ||
class={cn( | ||
'peer order-2 box-content size-4 shrink-0 items-center gap-2 rounded-[4px] border border-gray-700 bg-background-100 ring-offset-background-200 transition-[border-color,background,box-shadow] delay-0 duration-200 ease-in-out hover:bg-gray-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-color focus-visible:ring-offset-2', | ||
// checked | ||
'data-[state=checked]:border-blue-900 data-[state=checked]:bg-blue-900 data-[state=checked]:text-background-200', | ||
// disabled | ||
'disabled:cursor-not-allowed disabled:border-gray-500 disabled:bg-gray-100 disabled:text-gray-500 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:border-gray-500 data-[disabled=true]:bg-gray-100 data-[disabled=true]:text-gray-500', | ||
// disabled & checked | ||
'data-[state=checked]:data-[disabled=true]:border-gray-600 data-[state=checked]:data-[disabled=true]:bg-gray-600 data-[state=checked]:data-[disabled=true]:text-background-200', | ||
class_name | ||
)} | ||
bind:checked | ||
{...rest} | ||
> | ||
{#snippet children({ checked })} | ||
<div class={cn('flex size-4 items-center justify-center p-0.5 text-current')}> | ||
{#if checked === true} | ||
<Icons.Check aria-hidden="true" class="size-4" /> | ||
{:else if checked === 'indeterminate'} | ||
<Icons.Minus aria-hidden="true" class="size-4" /> | ||
{/if} | ||
</div> | ||
{/snippet} | ||
</CheckboxPrimitive.Root> | ||
<div | ||
class="grid grow gap-2 text-sm transition-colors peer-disabled:text-gray-500 peer-aria-checked:text-blue-900 peer-disabled:[&_p]:text-gray-500 peer-aria-checked:[&_p]:text-blue-900" | ||
> | ||
<p class="font-medium">{title}</p> | ||
{#if description} | ||
<p class="text-gray-900">{description}</p> | ||
{/if} | ||
</div> | ||
</label> |
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,73 @@ | ||
<script lang="ts"> | ||
import { cn } from '$lib/utils.js'; | ||
import { RadioGroup as ChoiceboxRadioPrimitive, type WithoutChildrenOrChild } from 'bits-ui'; | ||
import type { Snippet } from 'svelte'; | ||
type Props = WithoutChildrenOrChild<ChoiceboxRadioPrimitive.ItemProps> & { | ||
title: string; | ||
description?: string; | ||
children?: Snippet; | ||
}; | ||
let { | ||
title, | ||
description, | ||
class: class_name = undefined, | ||
value, | ||
children, | ||
...rest | ||
}: Props = $props(); | ||
</script> | ||
|
||
<!-- TODO: Move focus ring from the dot to the parent --> | ||
<label | ||
for={value} | ||
class={cn( | ||
'group flex w-full cursor-pointer items-center gap-2 rounded-md border p-3 transition-colors', | ||
"hover:border-gray-500 hover:bg-gray-100 hover:has-[button[aria-checked='true']]:bg-blue-200", | ||
"has-[button[aria-checked='true']]:border-blue-600 has-[button[aria-checked='true']]:bg-blue-100", | ||
// disabled | ||
"has-[button[disabled='']]:cursor-not-allowed has-[button[disabled='']]:hover:border-gray-400 has-[button[disabled='']]:hover:bg-transparent" | ||
)} | ||
> | ||
<ChoiceboxRadioPrimitive.Item | ||
id={value} | ||
{value} | ||
class={cn( | ||
'peer order-2 aspect-square size-4 cursor-pointer rounded-full border border-gray-500 text-gray-1000 transition-[color,background-color] ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-color focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:border-gray-500 disabled:text-gray-500 disabled:hover:bg-transparent aria-checked:border-blue-900', | ||
'group-hover:bg-background-200', | ||
class_name | ||
)} | ||
{...rest} | ||
> | ||
{#snippet children({ checked })} | ||
<div class="flex items-center justify-center"> | ||
{#if checked === true} | ||
<svg | ||
width="24" | ||
height="24" | ||
viewBox="0 0 24 24" | ||
fill="none" | ||
stroke="currentColor" | ||
stroke-width="2" | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
class="size-2.5 fill-blue-900 text-blue-900" | ||
> | ||
<circle cx="12" cy="12" r="10"></circle> | ||
</svg> | ||
{/if} | ||
</div> | ||
{/snippet} | ||
</ChoiceboxRadioPrimitive.Item> | ||
<div | ||
class="grid grow gap-2 text-sm transition-colors peer-disabled:text-gray-500 peer-aria-checked:text-blue-900 peer-disabled:[&_p]:text-gray-500 peer-aria-checked:[&_p]:text-blue-900" | ||
> | ||
<p class="font-medium">{title}</p> | ||
{#if description} | ||
<p class="text-gray-900">{description}</p> | ||
{/if} | ||
</div> | ||
</label> | ||
|
||
<!-- TODO: Add a custom component prop here. Only issue is, how to access `checked` outside of the designated snippet --> |
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,57 @@ | ||
<script lang="ts"> | ||
import { cn } from '$lib/utils.js'; | ||
import { RadioGroup as ChoiceboxGroupPrimitive } from 'bits-ui'; | ||
// TODO: This is poor implementation of the choicebox. Needs to be re-written. | ||
type Props = ChoiceboxGroupPrimitive.RootProps & { | ||
direction?: 'row' | 'column'; | ||
type: 'radio' | 'checkbox'; | ||
label?: string; | ||
}; | ||
let { | ||
class: class_name = undefined, | ||
value = $bindable(undefined), | ||
direction = 'column', | ||
label = undefined, | ||
type, | ||
children, | ||
...rest | ||
}: Props = $props(); | ||
</script> | ||
|
||
<div class="grid gap-2"> | ||
{#if label} | ||
<span class="text-xs text-gray-700">{label}</span> | ||
{/if} | ||
{#if type === 'radio'} | ||
<ChoiceboxGroupPrimitive.Root | ||
bind:value | ||
class={cn( | ||
'flex gap-3', | ||
{ | ||
'flex-col': direction === 'column', | ||
'flex-row': direction === 'row' | ||
}, | ||
class_name | ||
)} | ||
{...rest} | ||
> | ||
{@render children?.()} | ||
</ChoiceboxGroupPrimitive.Root> | ||
{:else if type === 'checkbox'} | ||
<div | ||
class={cn( | ||
'flex gap-3', | ||
{ | ||
'flex-col': direction === 'column', | ||
'flex-row': direction === 'row' | ||
}, | ||
class_name | ||
)} | ||
{...rest} | ||
> | ||
{@render children?.()} | ||
</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,12 @@ | ||
import Checkbox from './choicebox-checkbox.svelte'; | ||
import Radio from './choicebox-radio.svelte'; | ||
import Root from './choicebox.svelte'; | ||
|
||
export { | ||
Checkbox, | ||
Checkbox as ChoiceboxCheckbox, | ||
Root as ChoiceboxGroup, | ||
Radio as ChoiceboxGroupRadio, | ||
Radio, | ||
Root | ||
}; |
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 |
---|---|---|
@@ -1 +1,26 @@ | ||
<h1>choicebox</h1> | ||
<script lang="ts"> | ||
import Demo from '$lib/components/shared/demo.svelte'; | ||
import PageWrapper from '$lib/components/shared/page-wrapper.svelte'; | ||
import Disabled from './disabled.svelte'; | ||
import disabled_code from './disabled.svelte?raw'; | ||
import MultiSelect from './multi-select.svelte'; | ||
import multi_select_code from './multi-select.svelte?raw'; | ||
import SingleSelect from './single-select.svelte'; | ||
import single_select_code from './single-select.svelte?raw'; | ||
let { data } = $props(); | ||
</script> | ||
|
||
<PageWrapper title={data.title} description={data.description}> | ||
<Demo id="single-select" class="space-y-2" code={single_select_code}> | ||
<SingleSelect /> | ||
</Demo> | ||
|
||
<Demo id="multi-select" class="space-y-2" code={multi_select_code}> | ||
<MultiSelect /> | ||
</Demo> | ||
|
||
<Demo id="disabled" class="space-y-2" code={disabled_code}> | ||
<Disabled /> | ||
</Demo> | ||
</PageWrapper> |
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,22 @@ | ||
import type { MetaTagsProps } from 'svelte-meta-tags'; | ||
|
||
export function load() { | ||
const title = 'Choicebox'; | ||
const description = | ||
'A larger form of Radio or Checkbox, where the user has a larger tap target and more details.'; | ||
|
||
const pageMetaTags = Object.freeze({ | ||
title, | ||
description, | ||
openGraph: { | ||
title, | ||
description | ||
} | ||
}) satisfies MetaTagsProps; | ||
|
||
return { | ||
pageMetaTags, | ||
title, | ||
description | ||
}; | ||
} |
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,26 @@ | ||
<script lang="ts"> | ||
import * as ChoiceboxGroup from '$lib/components/ui/choicebox'; | ||
</script> | ||
|
||
<div class="grid gap-6"> | ||
<ChoiceboxGroup.Root | ||
direction="row" | ||
disabled | ||
label="Choicebox group disabled" | ||
type="radio" | ||
value="" | ||
> | ||
<ChoiceboxGroup.Radio description="Free for two weeks" title="Pro Trial" value="trial_2" /> | ||
<ChoiceboxGroup.Radio description="Get started now" title="Pro" value="pro_2" /> | ||
</ChoiceboxGroup.Root> | ||
|
||
<ChoiceboxGroup.Root direction="row" label="Single input disabled" type="checkbox"> | ||
<ChoiceboxGroup.Checkbox | ||
description="Free for two weeks" | ||
disabled | ||
title="Pro Trial" | ||
value="trial_2" | ||
/> | ||
<ChoiceboxGroup.Checkbox description="Get started now" title="Pro" value="pro_2" /> | ||
</ChoiceboxGroup.Root> | ||
</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,8 @@ | ||
<script lang="ts"> | ||
import * as ChoiceboxGroup from '$lib/components/ui/choicebox'; | ||
</script> | ||
|
||
<ChoiceboxGroup.Root direction="row" type="checkbox"> | ||
<ChoiceboxGroup.Checkbox description="Free for two weeks" title="Pro Trial" value="trial" /> | ||
<ChoiceboxGroup.Checkbox description="Get started now" title="Pro" value="pro" /> | ||
</ChoiceboxGroup.Root> |
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,8 @@ | ||
<script lang="ts"> | ||
import * as ChoiceboxGroup from '$lib/components/ui/choicebox'; | ||
</script> | ||
|
||
<ChoiceboxGroup.Root value="trial" direction="row" type="radio"> | ||
<ChoiceboxGroup.Radio description="Free for two weeks" title="Pro Trial" value="trial" /> | ||
<ChoiceboxGroup.Radio description="Get started now" title="Pro" value="pro" /> | ||
</ChoiceboxGroup.Root> |