Skip to content

Commit cdd583e

Browse files
committed
fix: svelte portal warning
1 parent f5bc5e4 commit cdd583e

2 files changed

Lines changed: 39 additions & 9 deletions

File tree

packages/svelte/CHANGELOG.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,17 @@ description: All notable changes will be documented in this file.
2020
- Fix issue where the browser might not be able to infer the mime type of a file due to limitations, drag source or
2121
security restrictions. As a fallback in the file validation logic, we now infer the mime type from the file
2222
extension.
23+
- **Portal**: Fix issue where `lifecycle_double_unmount` warning could be triggered.
2324

2425
## [5.1.1] - 2025-07-05
2526

2627
### Fixed
2728

2829
- **Combobox**
29-
3030
- Expose `reason` to `onOpenChange` and `onInputValueChange` callbacks
3131
- Expose `api.clearHighlightedValue` function to clear highlighted value
3232

3333
- **Date Picker**
34-
3534
- Fix issue where datepicker errors when setting `selectionMode=range` and `minView=year`
3635
- Fix issue where `focusedValue` could not be fully controlled
3736

@@ -40,7 +39,6 @@ description: All notable changes will be documented in this file.
4039
- **Progress**: Improve `valueAsString` formatting
4140

4241
- **Select**
43-
4442
- Select highlighted item only if it exists in the collection
4543
- Expose `api.clearHighlightedValue` function to clear highlighted value
4644

@@ -110,15 +108,13 @@ description: All notable changes will be documented in this file.
110108
is now required. A warning will be logged if it is not provided
111109

112110
- **Tree View**
113-
114111
- Fix issue where clicking a branch with indeterminate state doesn't check its child nodes
115112
- Remove `aria-busy` attribute from branch trigger when not loading children
116113
- Expose node details in `onExpandChange`, `onSelectionChange` and `onFocusChange`
117114

118115
- **Angle Slider**: Fix issue where scrubbing doesn't feel smooth on touch devices
119116

120117
- **Timer**
121-
122118
- Fix issue where timer could continue beyond `targetMs` when window is not visible
123119
- Add validation to ensure `startMs` and `targetMs` are configured correctly
124120
- Fix `progressPercent` calculation for countdown timers
@@ -135,7 +131,6 @@ description: All notable changes will be documented in this file.
135131
### Added
136132

137133
- **Tree View**
138-
139134
- Add support for checkbox state for checkbox trees via `defaultCheckedValue`, `checkedValue`, `onCheckedChange` props
140135
- Add callback for when `loadChildren` fails via `onLoadChildrenError` prop
141136

packages/svelte/src/lib/components/portal/portal.svelte

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
<script module lang="ts">
22
import type { Snippet } from 'svelte'
3+
34
export interface PortalProps {
5+
/**
6+
* If true, the portal will not be rendered.
7+
*/
8+
disabled?: boolean
9+
/**
10+
* The container to render the portal into.
11+
*/
412
container?: HTMLElement
13+
/**
14+
* The children to render in the portal.
15+
*/
516
children: Snippet
617
}
718
</script>
@@ -13,13 +24,37 @@
1324
import { getAllContexts, mount, unmount } from 'svelte'
1425
import PortalConsumer from './portal-consumer.svelte'
1526
16-
const { container = globalThis?.document?.body, children }: PortalProps = $props()
27+
const { container = globalThis?.document?.body, children, disabled = false }: PortalProps = $props()
1728
1829
const context = getAllContexts()
1930
31+
let instance: ReturnType<typeof mount> | null = null
32+
33+
const unmountInstance = () => {
34+
if (instance) {
35+
unmount(instance)
36+
instance = null
37+
}
38+
}
39+
2040
$effect(() => {
21-
mount(PortalConsumer, { target: container, props: { children }, context })
41+
if (disabled || !container) {
42+
unmountInstance()
43+
return
44+
}
45+
46+
instance = mount(PortalConsumer, {
47+
target: container,
48+
props: { children },
49+
context,
50+
})
2251
23-
return () => unmount(PortalConsumer)
52+
return () => {
53+
unmountInstance()
54+
}
2455
})
2556
</script>
57+
58+
{#if disabled}
59+
{@render children?.()}
60+
{/if}

0 commit comments

Comments
 (0)