Skip to content

Commit

Permalink
Merge pull request #56 from significa/SIGN-621
Browse files Browse the repository at this point in the history
Feat: MultiSelect
  • Loading branch information
kaaps authored Jan 18, 2024
2 parents d74ba10 + 132d027 commit f98aea9
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
},
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
"source.fixAll": "explicit"
},
"eslint.validate": ["svelte"],
"tailwindCSS.experimental.classRegex": [["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]]
Expand Down
146 changes: 124 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
"tailwindcss": "^3.3.3"
},
"devDependencies": {
"@melt-ui/pp": "^0.3.0",
"@melt-ui/svelte": "^0.70.0",
"@storybook/addon-a11y": "^7.4.2",
"@storybook/addon-essentials": "^7.4.2",
"@storybook/addon-interactions": "^7.4.2",
Expand Down
57 changes: 57 additions & 0 deletions src/lib/components/forms/multi-select.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script lang="ts">
import { createSelect } from '@melt-ui/svelte';
import Checkbox from './checkbox.svelte';
import Icon, { type IconOptions } from '../icon.svelte';
import type { ListboxOption } from '@melt-ui/svelte/dist/builders/listbox/types';
import { fly } from 'svelte/transition';
const {
elements: { trigger, menu, option },
states: { open, selected: meltSelected },
helpers: { isSelected }
} = createSelect<string, true>({
forceVisible: true,
positioning: {
placement: 'bottom',
fitViewport: true,
sameWidth: true
},
multiple: true
});
export let icon: undefined | IconOptions = undefined;
export let options: string[] = [];
export let selected: ListboxOption<string>[] | undefined = [];
export let selectedLabel: undefined | string = '';
$: selected = $meltSelected;
</script>

<div class="flex flex-col gap-1">
<button
class="flex h-12 min-w-[220px] items-center justify-between rounded-sm border border-background-offset bg-background-panel px-5 py-2 text-sm font-semibold hover:opacity-90 hover:transition-all focus:border-border-active focus:outline-none focus:ring-4 focus:ring-outline focus:transition-all"
{...$trigger}
use:trigger
>
{selectedLabel || 'Select'}
<Icon icon={icon || 'chevron-down'} />
</button>
{#if $open}
<div
class="z-10 mt-1 flex max-h-[300px] flex-col overflow-y-auto rounded-sm border border-background-offset bg-background-panel p-2"
{...$menu}
use:menu
transition:fly={{ y: -12, duration: 150 }}
>
{#each options as value}
<div
class="relative flex cursor-pointer items-center justify-between rounded-xs px-3 py-2.5 text-sm font-semibold hover:cursor-pointer hover:bg-background-offset hover:ring-1 hover:ring-border hover:transition-all focus:z-10 data-[highlighted]:bg-background-offset data-[highlighted]:ring-1 data-[highlighted]:ring-border data-[highlighted]:transition-all"
{...$option({ value, label: value })}
use:option
>
{value}
<Checkbox class="cursor-pointer" checked={$isSelected(value)} />
</div>
{/each}
</div>
{/if}
</div>
1 change: 1 addition & 0 deletions src/lib/components/icon.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
| 'pause'
| 'pdf'
| 'play'
| 'plus'
| 'sun'
| 'theme'
| 'trash';
Expand Down
4 changes: 4 additions & 0 deletions src/lib/components/icons/plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/stories/multi-select-story.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script lang="ts">
import MultiSelect from '$lib/components/forms/multi-select.svelte';
import type { ListboxOption } from '@melt-ui/svelte/dist/builders/listbox/types';
const options = ['Caramel', 'Chocolate', 'Strawberry', 'Cookies & Cream'];
let selected: ListboxOption<string>[] | undefined;
</script>

<MultiSelect {options} bind:selected selectedLabel="Select a label" />
14 changes: 14 additions & 0 deletions src/stories/multi-select.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Meta, StoryObj } from '@storybook/svelte';

import MultiSelect from './multi-select-story.svelte';

const meta = {
title: 'Forms/MultiSelect',
component: MultiSelect,
argTypes: {}
} satisfies Meta<MultiSelect>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {};

0 comments on commit f98aea9

Please sign in to comment.