Skip to content

Commit e7d18c7

Browse files
committed
feat(tooltip): support disabling unmounted content
1 parent a4df4ad commit e7d18c7

File tree

4 files changed

+115
-52
lines changed

4 files changed

+115
-52
lines changed

src/lib/floating/dialog/NeoDialog.svelte

Lines changed: 3 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@
142142
</dialog>
143143

144144
<style lang="scss">
145+
@use 'src/lib/styles/mixin' as mixin;
146+
145147
.neo-dialog {
146148
margin: auto;
147149
padding: 0;
@@ -156,60 +158,12 @@
156158
}
157159
158160
&.neo-fade {
159-
opacity: 0;
160-
transition: opacity, scale, display, overlay;
161-
transition-timing-function: ease;
162-
transition-duration: 0.2s;
163-
transition-behavior: allow-discrete;
164-
scale: 0.95;
161+
@include mixin.fade-in($backdrop-color-end: --neo-dialog-backdrop-color, $backdrop-filter-end: --neo-dialog-backdrop-filter);
165162
166163
&[data-modal='true'] {
167164
position: fixed;
168165
inset: 0;
169166
}
170-
171-
&::backdrop {
172-
background: transparent;
173-
backdrop-filter: blur(0);
174-
transition:
175-
background 0.4s,
176-
backdrop-filter 0.4s,
177-
display 0.2s,
178-
overlay 0.2s;
179-
transition-timing-function: ease;
180-
transition-behavior: allow-discrete;
181-
}
182-
183-
&[open] {
184-
display: block;
185-
opacity: 1;
186-
transition-timing-function: ease-out;
187-
transition-duration: 0.3s;
188-
scale: 1;
189-
190-
&::backdrop {
191-
background: var(--neo-dialog-backdrop-color, var(--neo-background-color-backdrop));
192-
backdrop-filter: var(--neo-dialog-backdrop-filter, blur(2px));
193-
transition:
194-
background 0.4s,
195-
backdrop-filter 0.4s,
196-
display 0.3s,
197-
overlay 0.3s;
198-
transition-timing-function: ease-out;
199-
}
200-
}
201-
202-
@starting-style {
203-
&[open] {
204-
opacity: 0;
205-
scale: 0.95;
206-
207-
&::backdrop {
208-
background: transparent;
209-
backdrop-filter: blur(0);
210-
}
211-
}
212-
}
213167
}
214168
}
215169

src/lib/floating/tooltips/NeoTooltip.svelte

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
useInteractions,
1414
useRole,
1515
} from '@skeletonlabs/floating-ui-svelte';
16-
1716
import { innerHeight, innerWidth } from 'svelte/reactivity/window';
1817
import { scale } from 'svelte/transition';
1918
@@ -75,6 +74,10 @@
7574
closeOnDismiss = true,
7675
dismissOptions,
7776
77+
// Mounting
78+
unmountOnClose = true,
79+
fade = !unmountOnClose,
80+
7881
// Events
7982
onChange,
8083
onOpen,
@@ -258,7 +261,6 @@
258261
$effect(() => addMethods(triggerRef));
259262
260263
const computeSize = <T extends 'width' | 'height'>(value: NeoTooltipProps[T], dimension: T): SizeOption<T> | undefined => {
261-
if (!open) return;
262264
const tSize = dimension === 'width' ? triggerRef?.offsetWidth : triggerRef?.offsetHeight;
263265
if (value === NeoTooltipSizeStrategy.Match) return { absolute: toPixel(tSize) };
264266
if (value === NeoTooltipSizeStrategy.Min) return { min: toPixel(tSize) };
@@ -283,6 +285,7 @@
283285
onChange?.(open);
284286
if (open) onOpen?.();
285287
else onClose?.();
288+
if (!unmountOnClose && open) floating.update();
286289
},
287290
() => open,
288291
{ skip: 1 },
@@ -303,11 +306,13 @@
303306
</svelte:element>
304307
{/if}
305308

306-
{#if floating.open}
309+
{#if !unmountOnClose || floating.open}
307310
<svelte:element
308311
this={tag}
309312
bind:this={ref}
313+
hidden={!floating.open}
310314
class:neo-tooltip={true}
315+
class:neo-fade={fade}
311316
class:neo-rounded={rounded}
312317
class:neo-tinted={tinted}
313318
class:neo-filled={filled}
@@ -363,6 +368,27 @@
363368
max-height: inherit;
364369
}
365370
371+
&[hidden] {
372+
display: none;
373+
}
374+
375+
&.neo-fade {
376+
@include mixin.fade-in(
377+
$toggle: ':not([hidden])',
378+
379+
$enter-duration: 0.2s,
380+
$exit-duration: 0.15s,
381+
382+
$enter-timing: ease-out,
383+
$exit-timing: ease-out
384+
);
385+
386+
&[data-modal='true'] {
387+
position: fixed;
388+
inset: 0;
389+
}
390+
}
391+
366392
&.neo-borderless {
367393
--neo-tooltip-border-color: transparent;
368394
}

src/lib/floating/tooltips/neo-tooltip.model.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,21 @@ export type NeoTooltipProps = {
207207
*/
208208
dismissOptions?: UseDismissOptions;
209209

210+
// Mounting
211+
212+
/**
213+
* Whether to unmount the dialog content when closed.
214+
*
215+
* @default true
216+
*/
217+
unmountOnClose?: boolean;
218+
/**
219+
* Whether to apply in/out transition with a fade effect.
220+
*
221+
* @default true
222+
*/
223+
fade?: boolean;
224+
210225
// Events
211226
/**
212227
* Event Handlers that fires on state change.

src/lib/styles/mixin.scss

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,71 @@
410410
grid-area: $area;
411411
}
412412
}
413+
414+
@mixin fade-in(
415+
$toggle: [open],
416+
$opacity-start: 0,
417+
$opacity-end: 1,
418+
419+
$scale-start: 0.95,
420+
$scale-end: 1,
421+
422+
$enter-duration: 0.3s,
423+
$exit-duration: 0.2s,
424+
425+
$enter-timing: ease,
426+
$exit-timing: ease-out,
427+
428+
$backdrop-color-start: transparent,
429+
$backdrop-color-end: --neo-fade-in-backdrop-color,
430+
$backdrop-filter-start: blur(0),
431+
$backdrop-filter-end: --neo-fade-in-backdrop-filter
432+
) {
433+
opacity: $opacity-start;
434+
transition: opacity, scale, display, overlay;
435+
transition-timing-function: $exit-timing;
436+
transition-duration: $exit-duration;
437+
transition-behavior: allow-discrete;
438+
scale: $scale-start;
439+
440+
&::backdrop {
441+
background: $backdrop-color-start;
442+
backdrop-filter: $backdrop-filter-start;
443+
transition:
444+
backdrop-filter $exit-duration,
445+
display $exit-duration,
446+
overlay $exit-duration;
447+
transition-timing-function: $exit-timing;
448+
transition-behavior: allow-discrete;
449+
}
450+
451+
&#{$toggle} {
452+
display: block;
453+
opacity: $opacity-end;
454+
transition-timing-function: $enter-timing;
455+
transition-duration: $enter-duration;
456+
scale: $scale-end;
457+
458+
&::backdrop {
459+
background: var($backdrop-color-end, var(--neo-background-color-backdrop));
460+
backdrop-filter: var($backdrop-filter-end, blur(2px));
461+
transition:
462+
backdrop-filter $enter-duration,
463+
display $enter-duration,
464+
overlay $enter-duration;
465+
transition-timing-function: $enter-timing;
466+
}
467+
}
468+
469+
@starting-style {
470+
&#{$toggle} {
471+
opacity: $opacity-start;
472+
scale: $scale-start;
473+
474+
&::backdrop {
475+
background: $backdrop-color-start;
476+
backdrop-filter: $backdrop-filter-start;
477+
}
478+
}
479+
}
480+
}

0 commit comments

Comments
 (0)