Skip to content

Commit ebcf057

Browse files
authored
Add animation transitions and combobox option styling support (#2893)
* feat(combobox): add class prop support for custom option styling - Add class prop to combobox-option component - Add optionClass prop to combobox component to pass through custom classes - Use tailwind-merge to properly combine classes with defaults * feat(menu): add smooth animation transitions for menu open/close - Replace fly transition with CSS transitions for better performance - Use visibility and transform/opacity for smooth animations - Add transition-all with 100ms duration for opening - Scale from 95% to 100% with opacity fade * feat(modal): add smooth animation transitions for modal open - Add transition classes for smooth scale and opacity animations - Use duration-200 for modal (slightly slower than menu for better UX) - Add backdrop fade animation with bg-black/50 * fix(modal): remove backdrop background color override
1 parent 8ad24da commit ebcf057

4 files changed

Lines changed: 27 additions & 7 deletions

File tree

src/lib/holocene/combobox/combobox-option.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
<script lang="ts">
2+
import { twMerge as merge } from 'tailwind-merge';
3+
24
import MenuItem from '$lib/holocene/menu/menu-item.svelte';
35
46
interface Props {
57
selected?: boolean;
68
disabled?: boolean;
79
label: string;
10+
class?: string;
811
}
912
1013
interface DisabledProps {
1114
label: string;
1215
disabled: true;
1316
selected?: never;
17+
class?: string;
1418
}
1519
1620
type $$Props = Props | DisabledProps;
1721
1822
export let selected = false;
1923
export let disabled = false;
2024
export let label: string;
25+
let className = '';
26+
export { className as class };
2127
</script>
2228

2329
<MenuItem
2430
on:click
2531
role="option"
26-
class="break-all"
32+
class={merge('break-all', className)}
2733
aria-selected={selected}
2834
aria-disabled={disabled}
2935
{selected}

src/lib/holocene/combobox/combobox.svelte

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
maxMenuHeight?: string;
9494
variant?: ComboboxStyles['variant'];
9595
class?: string;
96+
optionClass?: string;
9697
}
9798
9899
type MultiSelectProps = {
@@ -163,6 +164,7 @@
163164
export let loading = false;
164165
export let loadingText = 'Loading more results';
165166
export let variant: ComboboxStyles['variant'] = 'default';
167+
export let optionClass = '';
166168
167169
export let numberOfItemsSelectedLabel = (count: number) =>
168170
`${count} option${count > 1 ? 's' : ''} selected`;
@@ -577,6 +579,7 @@
577579
on:click={() => handleSelectOption(option)}
578580
selected={isSelected(option, value)}
579581
label={getDisplayValue(option)}
582+
class={optionClass}
580583
/>
581584
{:else}
582585
{#if loading === false}

src/lib/holocene/menu/menu.svelte

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import type { HTMLAttributes } from 'svelte/elements';
3-
import { fly } from 'svelte/transition';
43
54
import { getContext } from 'svelte';
65
import { twMerge as merge } from 'tailwind-merge';
@@ -45,10 +44,16 @@
4544
</script>
4645

4746
<ul
48-
in:fly={{ duration: 100 }}
4947
role="menu"
50-
class={merge('menu', maxHeight, position, className)}
51-
class:hidden={!$open}
48+
class={merge(
49+
'menu',
50+
'transition-all duration-100 ease-out',
51+
!$open && 'invisible scale-95 opacity-0',
52+
$open && 'visible scale-100 opacity-100',
53+
maxHeight,
54+
position,
55+
className,
56+
)}
5257
aria-labelledby={id}
5358
tabindex={-1}
5459
style={position === 'top-right' || position === 'top-left'

src/lib/holocene/modal.svelte

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@
8888
{id}
8989
on:close={handleCancel}
9090
bind:this={modalElement}
91-
class={merge('body', className)}
91+
class={merge(
92+
'body',
93+
'transition-all duration-200 ease-out',
94+
open && 'scale-100 opacity-100',
95+
!open && 'scale-95 opacity-0',
96+
className,
97+
)}
9298
class:large
9399
class:hightlightNav
94100
aria-modal="true"
@@ -142,7 +148,7 @@
142148
}
143149
144150
.body::backdrop {
145-
@apply cursor-pointer;
151+
@apply cursor-pointer transition-opacity duration-200;
146152
}
147153
148154
.body.hightlightNav::backdrop {

0 commit comments

Comments
 (0)