Skip to content

Commit d4215f1

Browse files
authored
accordion and checkbox updated (#131)
# Problem Need to update bitsui and shadcn components # Solution - update accordion, modal, select, checkbox, any any other affected components. - update affected styles ## Steps to Verify: 1. A setup step / beginning state 1. What to do next 1. Any other instructions 1. Expected behavior 1. Suggestions for testing ## Screenshots (optional):
1 parent c178cdd commit d4215f1

46 files changed

Lines changed: 1317 additions & 1079 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

components.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
"$schema": "https://shadcn-svelte.com/schema.json",
33
"style": "default",
44
"tailwind": {
5-
"config": "",
65
"css": "src/lib/styles/index.css",
7-
"baseColor": "slate"
6+
"baseColor": "slate",
7+
"cssVariables": true,
8+
"prefix": ""
89
},
910
"aliases": {
10-
"components": "$src/lib/shadcnComponents",
11-
"utils": "$src/utils"
11+
"components": "@/lib/shadcnComponents",
12+
"utils": "@/lib/utils/utils"
1213
},
1314
"typescript": true
1415
}

package-lock.json

Lines changed: 697 additions & 585 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"check": "svelte-check --tsconfig ./tsconfig.json"
3333
},
3434
"devDependencies": {
35+
"@internationalized/date": "3.9.0",
3536
"@storybook/addon-docs": "^8.6.4",
3637
"@storybook/addon-essentials": "^8.6.4",
3738
"@storybook/addon-interactions": "^8.6.4",
@@ -63,15 +64,16 @@
6364
"svelte-check": "^4.1.5",
6465
"svelte-loader": "^3.2.4",
6566
"tailwindcss": "^4.1.3",
67+
"tw-animate-css": "^1.3.8",
6668
"typescript-eslint": "^8.26.1",
6769
"vite": "^5.4.4"
6870
},
6971
"dependencies": {
70-
"bits-ui": "^0.22.0",
72+
"bits-ui": "^2.9.9",
7173
"class-variance-authority": "^0.7.1",
7274
"clsx": "^2.1.1",
7375
"svelte": "^5.0.0",
74-
"tailwind-merge": "^3.0.2",
76+
"tailwind-merge": "^3.3.1",
7577
"tailwindcss-animate": "^1.0.7"
7678
}
7779
}

src/lib/atoms/Close.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { Close } from '../shadcnComponents/ui/dialog';
2+
import Close from '../shadcnComponents/ui/dialog/dialog-close.svelte';
33
import type { HTMLAttributes } from 'svelte/elements';
44
55
interface Props extends HTMLAttributes<HTMLElement> {

src/lib/atoms/FormElement.svelte

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
<script lang="ts">
2+
import LoadingIcon from '../design-system/assets/icons/LoadingIcon.svelte';
23
import { Error } from '../design-system/assets/index';
34
45
interface Props {
56
label?: string;
67
isRequired?: boolean;
78
description?: string;
89
error: string | undefined;
10+
isLoading?: boolean;
911
elementId?: string | null;
1012
children?: import('svelte').Snippet;
1113
}
1214
13-
let { label = '', isRequired = false, description = '', error, elementId = '', children }: Props = $props();
15+
let {
16+
label = '',
17+
isRequired = false,
18+
description = '',
19+
error,
20+
isLoading = false,
21+
elementId = '',
22+
children,
23+
}: Props = $props();
1424
1525
const labelNoSpaces = label.split(' ').join('');
1626
const id = `form-element-${labelNoSpaces}`;
@@ -33,6 +43,8 @@
3343

3444
{#if error}
3545
<Error />
46+
{:else if isLoading}
47+
<LoadingIcon />
3648
{/if}
3749
</div>
3850

src/lib/atoms/Select.stories.svelte

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,26 @@
55
let label = 'Favorite Food';
66
let description = 'Choose your favorite food.';
77
let options = [
8-
{ optionLabel: 'Option 1', value: '1' },
9-
{ optionLabel: 'Option 2', value: '2' },
10-
{ optionLabel: 'Option 3', value: '3' },
8+
{ label: 'Option 1', value: '1' },
9+
{ label: 'Option 2', value: '2' },
10+
{ label: 'Option 3', value: '3' },
1111
];
12-
13-
let primarySelected = $state('');
14-
15-
let onSelectedChange = (value) => (primarySelected = value);
16-
17-
let isLoading = $state(false);
12+
let placeholder = 'Cheese Burger?';
13+
let value = $state();
1814
let disabled = $state(false);
15+
let error = $state();
1916
20-
let onSelectedChangeAsync = async (value) => {
21-
isLoading = true;
22-
primarySelected = value;
23-
24-
setTimeout(() => {
25-
isLoading = false;
26-
}, 2000);
27-
};
28-
29-
const { Story } = defineMeta({ title: 'UI Components/Atoms/Select', component: Select });
17+
const { Story } = defineMeta({
18+
title: 'UI Components/Atoms/Select',
19+
component: Select,
20+
});
3021
</script>
3122

32-
<Story name="Default Select" args={{ ...Select.props, label, description, options, disabled, onSelectedChange }}>
33-
{#snippet children(args)}
34-
<Select {...args} />
35-
{/snippet}
36-
</Story>
37-
3823
<Story
39-
name="Async Func Select"
40-
args={{ label, description, options, isLoading, disabled, onSelectedChange: onSelectedChangeAsync }}
24+
name="Default Select"
25+
args={{ ...Select.props, value, label, description, placeholder, options, disabled, error }}
4126
>
4227
{#snippet children(args)}
43-
<Select {...args} />
28+
<Select {...args} bind:value={args.value} />
4429
{/snippet}
4530
</Story>
46-
47-
<hr class="m-4" />
48-
<div>Selected Option: {JSON.stringify(primarySelected)}</div>

src/lib/atoms/Select.svelte

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,51 @@
11
<script lang="ts">
2-
import type { HTMLAttributes } from 'svelte/elements';
3-
import { Root, Trigger, Value, Content, Item, Label } from '../shadcnComponents/ui/select';
4-
import type { SelectProps } from 'bits-ui';
2+
import { Root, Trigger, Content, Item } from '../shadcnComponents/ui/select';
3+
import FormElement from './FormElement.svelte';
4+
import { cn } from '../utils/utils';
55
6-
interface Props extends SelectProps<string, false>, HTMLAttributes<HTMLSelectElement> {
7-
label: string;
8-
description?: string | undefined;
6+
interface Props {
7+
options: { label: string; value: string }[];
8+
value?: string;
99
isRequired?: boolean;
10-
error?: string | undefined;
10+
label: string;
11+
description?: string;
12+
placeholder?: string;
13+
error?: string;
1114
isLoading?: boolean;
12-
options: { optionLabel: string; value: string }[];
15+
disabled?: boolean;
16+
id?: string;
1317
}
1418
1519
let {
16-
id,
17-
label,
18-
description = undefined,
19-
placeholder,
20+
options,
21+
value = $bindable(),
2022
isRequired = false,
23+
label,
24+
description,
25+
placeholder = 'Select an option',
2126
error = undefined,
2227
isLoading = false,
23-
options,
24-
onSelectedChange,
25-
disabled,
28+
disabled = false,
29+
id = undefined,
2630
...rest
2731
}: Props = $props();
2832
</script>
2933

3034
<div class="flex flex-col">
31-
<Root {...rest} {onSelectedChange} {disabled}>
32-
<Label {isRequired}>{label}</Label>
33-
{#if description}
34-
<span class="form-item-description">{description}</span>
35-
{/if}
36-
<Trigger {error} {isLoading} {id}>
37-
<Value class="text-nowrap overflow-ellipsis" placeholder={placeholder || undefined} />
38-
</Trigger>
39-
<Content class="border-gray3 border">
40-
{#each options as option (option.value)}
41-
<Item value={option.value}>{option.optionLabel}</Item>
42-
{/each}
43-
</Content>
44-
{#if error}
45-
<span class="form-error">{error}</span>
46-
{/if}
47-
</Root>
35+
<FormElement {label} {isRequired} {description} {error} {isLoading} elementId={id} {...rest}>
36+
<div>
37+
<Root type="single" disabled={isLoading || disabled} bind:value>
38+
<Trigger {error} {id}>
39+
<span class={cn(!value && 'text-gray2')}
40+
>{options.find((o) => o.value === value)?.label ?? placeholder}
41+
</span>
42+
</Trigger>
43+
<Content>
44+
{#each options as option (option.value)}
45+
<Item value={option.value}>{option.label}</Item>
46+
{/each}
47+
</Content>
48+
</Root>
49+
</div>
50+
</FormElement>
4851
</div>

src/lib/features/Accordion.stories.svelte

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,57 @@
77
title: 'UI Components/Features',
88
component: Accordion,
99
});
10+
11+
const defaultItems = [
12+
{
13+
value: '1',
14+
title: 'What is the meaning of life?',
15+
content: 'To become a better person, to help others, and to leave the world a better place than you found it.',
16+
},
17+
{
18+
value: '2',
19+
title: 'How do I become a better person?',
20+
content: 'Read books, listen to podcasts, and surround yourself with people who inspire you.',
21+
},
22+
{
23+
value: '3',
24+
title: 'What is the best way to help others?',
25+
content: 'Give them your time, attention, and love.',
26+
},
27+
];
1028
</script>
1129

12-
<Story name="Default Accordion" args={{ ...Accordion.props, trigger: 'Hello world.', content: 'Hello there.' }}>
30+
<Story name="Default Accordion" args={{ ...Accordion.props, items: defaultItems }}>
31+
{#snippet children(args)}
32+
<Accordion {...args} />
33+
{/snippet}
34+
</Story>
35+
36+
{#snippet Content1()}
37+
<p class="bg-red-300">
38+
To become a better person, to help others, and to leave the world a better place than you found it.
39+
</p>
40+
{/snippet}
41+
42+
{#snippet Content2()}
43+
<p class="bg-yellow-300">Read books, listen to podcasts, and surround yourself with people who inspire you.</p>
44+
{/snippet}
45+
46+
{#snippet Content3()}
47+
<p class="bg-green-300">Give them your time, attention, and love.</p>
48+
{/snippet}
49+
50+
<Story
51+
name="Accordion With Snippet"
52+
args={{
53+
...Accordion.props,
54+
items: [
55+
{ value: '1', title: 'What is the meaning of life?', content: Content1 },
56+
{ value: '2', title: 'How do I become a better person?', content: Content2 },
57+
{ value: '3', title: 'What is the best way to help others?', content: Content3 },
58+
],
59+
}}
60+
>
1361
{#snippet children(args)}
1462
<Accordion {...args} />
1563
{/snippet}

src/lib/features/Accordion.svelte

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
<script lang="ts">
22
import type { Snippet } from 'svelte';
3-
import { Root, Item, Trigger, Content } from '../shadcnComponents/ui/accordion';
43
import type { Intent } from '../utils/types';
4+
import * as Accordion from '../shadcnComponents/ui/accordion';
55
66
interface Props {
7-
trigger: string;
8-
content: string | Snippet;
97
intent?: Intent;
8+
items: { value: string; title: string; content: string | Snippet }[];
109
}
1110
12-
let { trigger, content, intent = 'dark' }: Props = $props();
11+
let { intent = 'dark', items }: Props = $props();
1312
</script>
1413

15-
<Root>
16-
<Item value="item-1" class={intent === 'light' ? 'text-white' : 'text-black'}>
17-
<Trigger {intent}>{trigger}</Trigger>
18-
<Content
19-
>{#if typeof content === 'function'}
20-
{@render content()}
21-
{:else}
22-
{content}
23-
{/if}</Content
24-
>
25-
</Item>
26-
</Root>
14+
<Accordion.Root type="multiple">
15+
{#each items as item (item.value)}
16+
<Accordion.Item value={item.value} class={intent === 'light' ? 'text-white' : 'text-black'}>
17+
<Accordion.Trigger {intent}>{item.title}</Accordion.Trigger>
18+
<Accordion.Content
19+
>{#if typeof item.content === 'function'}
20+
{@render item.content()}
21+
{:else}
22+
{item.content}
23+
{/if}</Accordion.Content
24+
>
25+
</Accordion.Item>
26+
{/each}
27+
</Accordion.Root>

src/lib/features/AccordionList.stories.svelte

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)