From 62dbabdbe66a97c15423a9508688867ddc73a86f Mon Sep 17 00:00:00 2001 From: Hunter Johnston Date: Fri, 19 Apr 2024 18:18:40 -0400 Subject: [PATCH 1/4] broken --- package.json | 2 +- packages/bits-ui/package.json | 2 +- packages/bits-ui/src/lib/bits/index.ts | 4 +- .../popover/components/popover-content.svelte | 45 ++--- .../src/lib/bits/popover/popover.svelte.ts | 6 + .../dismissable-layer.svelte.ts | 16 +- pnpm-lock.yaml | 164 +++++++++--------- sites/docs/package.json | 2 +- .../components/demos/date-picker-demo.svelte | 4 +- .../demos/date-range-picker-demo.svelte | 4 +- 10 files changed, 132 insertions(+), 117 deletions(-) diff --git a/package.json b/package.json index 34d4abc43..f2da07854 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "prettier": "^3.2.5", "prettier-plugin-svelte": "^3.2.2", "prettier-plugin-tailwindcss": "0.5.13", - "svelte": "5.0.0-next.108", + "svelte": "5.0.0-next.109", "svelte-eslint-parser": "^0.34.1", "wrangler": "^3.44.0" }, diff --git a/packages/bits-ui/package.json b/packages/bits-ui/package.json index 7b84b4f80..f7d69e0eb 100644 --- a/packages/bits-ui/package.json +++ b/packages/bits-ui/package.json @@ -44,7 +44,7 @@ "jsdom": "^24.0.0", "publint": "^0.2.7", "resize-observer-polyfill": "^1.5.1", - "svelte": "5.0.0-next.108", + "svelte": "5.0.0-next.109", "svelte-check": "^3.6.9", "tslib": "^2.6.2", "typescript": "^5.3.3", diff --git a/packages/bits-ui/src/lib/bits/index.ts b/packages/bits-ui/src/lib/bits/index.ts index 9122e0fdd..aef73a2ea 100644 --- a/packages/bits-ui/src/lib/bits/index.ts +++ b/packages/bits-ui/src/lib/bits/index.ts @@ -9,9 +9,9 @@ export * as Collapsible from "./collapsible/index.js"; export * as Combobox from "./combobox/index.js"; export * as ContextMenu from "./context-menu/index.js"; export * as DateField from "./date-field/index.js"; -export * as DatePicker from "./date-picker/index.js"; +// export * as DatePicker from "./date-picker/index.js"; export * as DateRangeField from "./date-range-field/index.js"; -export * as DateRangePicker from "./date-range-picker/index.js"; +// export * as DateRangePicker from "./date-range-picker/index.js"; export * as Dialog from "./dialog/index.js"; export * as DropdownMenu from "./dropdown-menu/index.js"; export * as Label from "./label/index.js"; diff --git a/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte b/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte index 2adb2ed97..86bd67109 100644 --- a/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte +++ b/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte @@ -1,7 +1,7 @@ - - {#snippet presence({ present })} - - {#snippet content({ props })} - {@const mergedProps = { - ...state.props, - ...props, - hidden: present.value ? undefined : true, - ...restProps, - }} - {#if asChild} - {@render child?.({ props: mergedProps })} - {:else} -
- {@render children?.()} -
- {/if} - {/snippet} -
+ + {#snippet popper({ props })} + {@const mergedProps = { + ...props, + ...state.props, + ...restProps, + }} + {#if asChild} + {@render child?.({ props: mergedProps })} + {:else} +
+ {@render children?.()} +
+ {/if} {/snippet} -
+ diff --git a/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts b/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts index 170000038..dbd5c1025 100644 --- a/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts +++ b/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts @@ -29,6 +29,12 @@ class PopoverRootState { this.open.value = !this.open.value; } + close = () => { + console.log("closing!"); + if (!this.open.value) return; + this.open.value = false; + }; + createTrigger(props: PopoverTriggerStateProps) { return new PopoverTriggerState(props, this); } diff --git a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts index 8d151553b..d828975bd 100644 --- a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts +++ b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts @@ -1,4 +1,3 @@ -import { onDestroy } from "svelte"; import type { DismissableLayerProps, InteractOutsideBehaviorType, @@ -141,10 +140,16 @@ export class DismissableLayerState { }, 10); #onInteractOutside = debounce((e: InteractOutsideEvent) => { - const node = this.node.value!; + if (!this.node.value) return; + const behaviorType = this.#behaviorType.value; - if (!this.#isResponsibleLayer || this.#isAnyEventIntercepted() || !isValidEvent(e, node)) + if ( + !this.#isResponsibleLayer || + this.#isAnyEventIntercepted() || + !isValidEvent(e, this.node.value) + ) { return; + } if (behaviorType !== "close" && behaviorType !== "defer-otherwise-close") return; if (!this.#isPointerDownOutside) return; this.#interactOutsideProp.value(e); @@ -159,8 +164,8 @@ export class DismissableLayerState { }; #markResponsibleLayer = () => { - const node = this.node.value!; - this.#isResponsibleLayer = isResponsibleLayer(node); + if (!this.node.value) return; + this.#isResponsibleLayer = isResponsibleLayer(this.node.value); }; #resetState = debounce(() => { @@ -181,6 +186,7 @@ export function useDismissableLayer(props: DismissableLayerStateProps) { } function isResponsibleLayer(node: HTMLElement): boolean { + console.log(layers); const layersArr = [...layers]; /** * We first check if we can find a top layer with `close` or `ignore`. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a97f884a4..748daef23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 2.27.1 '@huntabyte/eslint-config': specifier: ^0.3.1 - version: 0.3.1(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.108)(typescript@5.4.3) + version: 0.3.1(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.109)(typescript@5.4.3) '@huntabyte/eslint-plugin': specifier: ^0.1.0 version: 0.1.0(eslint@9.0.0) @@ -25,22 +25,22 @@ importers: version: 9.0.0 eslint-plugin-svelte: specifier: ^2.37.0 - version: 2.37.0(eslint@9.0.0)(svelte@5.0.0-next.108) + version: 2.37.0(eslint@9.0.0)(svelte@5.0.0-next.109) prettier: specifier: ^3.2.5 version: 3.2.5 prettier-plugin-svelte: specifier: ^3.2.2 - version: 3.2.2(prettier@3.2.5)(svelte@5.0.0-next.108) + version: 3.2.2(prettier@3.2.5)(svelte@5.0.0-next.109) prettier-plugin-tailwindcss: specifier: 0.5.13 version: 0.5.13(prettier-plugin-svelte@3.2.2)(prettier@3.2.5) svelte: - specifier: 5.0.0-next.108 - version: 5.0.0-next.108 + specifier: 5.0.0-next.109 + version: 5.0.0-next.109 svelte-eslint-parser: specifier: ^0.34.1 - version: 0.34.1(svelte@5.0.0-next.108) + version: 0.34.1(svelte@5.0.0-next.109) wrangler: specifier: ^3.44.0 version: 3.44.0 @@ -58,7 +58,7 @@ importers: version: 3.5.2 '@melt-ui/svelte': specifier: 0.76.2 - version: 0.76.2(svelte@5.0.0-next.108) + version: 0.76.2(svelte@5.0.0-next.109) esm-env: specifier: ^1.0.0 version: 1.0.0 @@ -71,16 +71,16 @@ importers: devDependencies: '@melt-ui/pp': specifier: ^0.3.0 - version: 0.3.0(@melt-ui/svelte@0.76.2)(svelte@5.0.0-next.108) + version: 0.3.0(@melt-ui/svelte@0.76.2)(svelte@5.0.0-next.109) '@sveltejs/kit': specifier: ^2.5.0 - version: 2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.108)(vite@5.2.8) + version: 2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.109)(vite@5.2.8) '@sveltejs/package': specifier: ^2.2.7 - version: 2.3.0(svelte@5.0.0-next.108)(typescript@5.4.3) + version: 2.3.0(svelte@5.0.0-next.109)(typescript@5.4.3) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.0 - version: 3.1.0(svelte@5.0.0-next.108)(vite@5.2.8) + version: 3.1.0(svelte@5.0.0-next.109)(vite@5.2.8) '@testing-library/dom': specifier: ^10.0.0 version: 10.0.0 @@ -89,7 +89,7 @@ importers: version: 6.4.2(vitest@1.5.0) '@testing-library/svelte': specifier: ^4.2.2 - version: 4.2.2(svelte@5.0.0-next.108) + version: 4.2.2(svelte@5.0.0-next.109) '@testing-library/user-event': specifier: ^14.5.2 version: 14.5.2(@testing-library/dom@10.0.0) @@ -121,11 +121,11 @@ importers: specifier: ^1.5.1 version: 1.5.1 svelte: - specifier: 5.0.0-next.108 - version: 5.0.0-next.108 + specifier: 5.0.0-next.109 + version: 5.0.0-next.109 svelte-check: specifier: ^3.6.9 - version: 3.6.9(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.108) + version: 3.6.9(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.109) tslib: specifier: ^2.6.2 version: 2.6.2 @@ -146,14 +146,14 @@ importers: version: 3.5.2 '@melt-ui/svelte': specifier: 0.76.2 - version: 0.76.2(svelte@5.0.0-next.108) + version: 0.76.2(svelte@5.0.0-next.109) bits-ui: specifier: workspace:* version: link:../../packages/bits-ui devDependencies: '@melt-ui/pp': specifier: ^0.3.0 - version: 0.3.0(@melt-ui/svelte@0.76.2)(svelte@5.0.0-next.108) + version: 0.3.0(@melt-ui/svelte@0.76.2)(svelte@5.0.0-next.109) '@prettier/sync': specifier: 0.3.0 version: 0.3.0(prettier@3.2.5) @@ -162,10 +162,10 @@ importers: version: 4.2.0(@sveltejs/kit@2.5.5)(wrangler@3.44.0) '@sveltejs/kit': specifier: ^2.5.0 - version: 2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.108)(vite@5.2.8) + version: 2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.109)(vite@5.2.8) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.0 - version: 3.1.0(svelte@5.0.0-next.108)(vite@5.2.8) + version: 3.1.0(svelte@5.0.0-next.109)(vite@5.2.8) '@tailwindcss/typography': specifier: ^0.5.10 version: 0.5.12(tailwindcss@3.4.3) @@ -195,13 +195,13 @@ importers: version: 0.3.4(esbuild@0.20.2) mdsx: specifier: ^0.0.5 - version: 0.0.5(svelte@5.0.0-next.108) + version: 0.0.5(svelte@5.0.0-next.109) mode-watcher: specifier: ^0.2.0 - version: 0.2.2(svelte@5.0.0-next.108) + version: 0.2.2(svelte@5.0.0-next.109) phosphor-svelte: specifier: ^1.4.2 - version: 1.4.2(svelte@5.0.0-next.108) + version: 1.4.2(svelte@5.0.0-next.109) postcss: specifier: ^8.4.33 version: 8.4.38 @@ -221,11 +221,11 @@ importers: specifier: ^1.1.1 version: 1.2.2 svelte: - specifier: 5.0.0-next.108 - version: 5.0.0-next.108 + specifier: 5.0.0-next.109 + version: 5.0.0-next.109 svelte-check: specifier: ^3.6.9 - version: 3.6.9(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.108) + version: 3.6.9(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.109) tailwind-merge: specifier: ^2.2.1 version: 2.2.2 @@ -280,7 +280,7 @@ packages: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - /@antfu/eslint-config@2.13.3(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.108)(typescript@5.4.3): + /@antfu/eslint-config@2.13.3(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.109)(typescript@5.4.3): resolution: {integrity: sha512-DCyrnFgWtIc0mUTn8HeVB15Z/t9oEQZk8ce6S14Kq6z42LbMfZxPu6hs4SmPFYWLJoEzYq87dxsRv3glOX+aGw==} hasBin: true peerDependencies: @@ -340,8 +340,8 @@ packages: eslint-plugin-markdown: 4.0.1(eslint@9.0.0) eslint-plugin-n: 17.2.0(eslint@9.0.0) eslint-plugin-no-only-tests: 3.1.0 - eslint-plugin-perfectionist: 2.8.0(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.108)(typescript@5.4.3)(vue-eslint-parser@9.4.2) - eslint-plugin-svelte: 2.37.0(eslint@9.0.0)(svelte@5.0.0-next.108) + eslint-plugin-perfectionist: 2.8.0(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.109)(typescript@5.4.3)(vue-eslint-parser@9.4.2) + eslint-plugin-svelte: 2.37.0(eslint@9.0.0)(svelte@5.0.0-next.109) eslint-plugin-toml: 0.11.0(eslint@9.0.0) eslint-plugin-unicorn: 52.0.0(eslint@9.0.0) eslint-plugin-unused-imports: 3.1.0(@typescript-eslint/eslint-plugin@7.6.0)(eslint@9.0.0) @@ -354,7 +354,7 @@ packages: local-pkg: 0.5.0 parse-gitignore: 2.0.0 picocolors: 1.0.0 - svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.108) + svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.109) toml-eslint-parser: 0.9.3 vue-eslint-parser: 9.4.2(eslint@9.0.0) yaml-eslint-parser: 1.2.2 @@ -1640,7 +1640,7 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} dev: true - /@huntabyte/eslint-config@0.3.1(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.108)(typescript@5.4.3): + /@huntabyte/eslint-config@0.3.1(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.109)(typescript@5.4.3): resolution: {integrity: sha512-aLnVtA+n556gtv+NfCfIi1OoM0j0tsHP9ERlVaaJ3p+AHoZyT6FYefEInX6Snxwt4U5WzmL/gJ8w0QbyZdyH4w==} hasBin: true peerDependencies: @@ -1648,7 +1648,7 @@ packages: eslint-plugin-svelte: ^2.37.0 svelte-eslint-parser: ^0.34.1 dependencies: - '@antfu/eslint-config': 2.13.3(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.108)(typescript@5.4.3) + '@antfu/eslint-config': 2.13.3(@vue/compiler-sfc@3.4.21)(eslint-plugin-svelte@2.37.0)(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.109)(typescript@5.4.3) '@antfu/install-pkg': 0.3.2 '@clack/prompts': 0.7.0 '@huntabyte/eslint-plugin': 0.1.0(eslint@9.0.0) @@ -1657,10 +1657,10 @@ packages: chalk: 5.3.0 eslint: 9.0.0 eslint-flat-config-utils: 0.2.2 - eslint-plugin-svelte: 2.37.0(eslint@9.0.0)(svelte@5.0.0-next.108) + eslint-plugin-svelte: 2.37.0(eslint@9.0.0)(svelte@5.0.0-next.109) local-pkg: 0.5.0 parse-gitignore: 2.0.0 - svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.108) + svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.109) yargs: 17.7.2 transitivePeerDependencies: - '@unocss/eslint-plugin' @@ -1832,20 +1832,20 @@ packages: - supports-color dev: true - /@melt-ui/pp@0.3.0(@melt-ui/svelte@0.76.2)(svelte@5.0.0-next.108): + /@melt-ui/pp@0.3.0(@melt-ui/svelte@0.76.2)(svelte@5.0.0-next.109): resolution: {integrity: sha512-b07Bdh8l2KcwKVCXOY+SoBw1dk9eWvQfMSi6SoacpRVyVmmfpi0kV4oGt3HYF0tUCB3sEmVicxse50ZzZxEzEA==} engines: {pnpm: '>=8.6.3'} peerDependencies: '@melt-ui/svelte': '>= 0.29.0' svelte: ^3.55.0 || ^4.0.0 || ^5.0.0-next.1 dependencies: - '@melt-ui/svelte': 0.76.2(svelte@5.0.0-next.108) + '@melt-ui/svelte': 0.76.2(svelte@5.0.0-next.109) estree-walker: 3.0.3 magic-string: 0.30.9 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 dev: true - /@melt-ui/svelte@0.76.2(svelte@5.0.0-next.108): + /@melt-ui/svelte@0.76.2(svelte@5.0.0-next.109): resolution: {integrity: sha512-7SbOa11tXUS95T3fReL+dwDs5FyJtCEqrqG3inRziDws346SYLsxOQ6HmX+4BkIsQh1R8U3XNa+EMmdMt38lMA==} peerDependencies: svelte: '>=3 <5' @@ -1856,7 +1856,7 @@ packages: dequal: 2.0.3 focus-trap: 7.5.4 nanoid: 5.0.6 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -2358,13 +2358,13 @@ packages: wrangler: ^3.28.4 dependencies: '@cloudflare/workers-types': 4.20240329.0 - '@sveltejs/kit': 2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.108)(vite@5.2.8) + '@sveltejs/kit': 2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.109)(vite@5.2.8) esbuild: 0.19.12 worktop: 0.8.0-next.18 wrangler: 3.44.0 dev: true - /@sveltejs/kit@2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.108)(vite@5.2.8): + /@sveltejs/kit@2.5.5(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.109)(vite@5.2.8): resolution: {integrity: sha512-ULe3PB00q4+wYRL+IS5FDPsCEVnhEITofm7b9Yz8malcH3r1SAnW/JJ6T13hIMeu8QNRIuVQWo+P4+2VklbnLQ==} engines: {node: '>=18.13'} hasBin: true @@ -2374,7 +2374,7 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.3 dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.0(svelte@5.0.0-next.108)(vite@5.2.8) + '@sveltejs/vite-plugin-svelte': 3.1.0(svelte@5.0.0-next.109)(vite@5.2.8) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 4.3.2 @@ -2386,12 +2386,12 @@ packages: sade: 1.8.1 set-cookie-parser: 2.6.0 sirv: 2.0.4 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 tiny-glob: 0.2.9 vite: 5.2.8(@types/node@20.12.2) dev: true - /@sveltejs/package@2.3.0(svelte@5.0.0-next.108)(typescript@5.4.3): + /@sveltejs/package@2.3.0(svelte@5.0.0-next.109)(typescript@5.4.3): resolution: {integrity: sha512-wmtwEfi3gQnmtotAjygRHR6cmLfpblQl1dU764f3N2I5DPe34llFs44bHOYcuk91Bp2sSq6bWUmNwxGlYCchOA==} engines: {node: ^16.14 || >=18} hasBin: true @@ -2402,13 +2402,13 @@ packages: kleur: 4.1.5 sade: 1.8.1 semver: 7.6.0 - svelte: 5.0.0-next.108 - svelte2tsx: 0.7.5(svelte@5.0.0-next.108)(typescript@5.4.3) + svelte: 5.0.0-next.109 + svelte2tsx: 0.7.5(svelte@5.0.0-next.109)(typescript@5.4.3) transitivePeerDependencies: - typescript dev: true - /@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.108)(vite@5.2.8): + /@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.109)(vite@5.2.8): resolution: {integrity: sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==} engines: {node: ^18.0.0 || >=20} peerDependencies: @@ -2416,28 +2416,28 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.0 dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.0(svelte@5.0.0-next.108)(vite@5.2.8) + '@sveltejs/vite-plugin-svelte': 3.1.0(svelte@5.0.0-next.109)(vite@5.2.8) debug: 4.3.4 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 vite: 5.2.8(@types/node@20.12.2) transitivePeerDependencies: - supports-color dev: true - /@sveltejs/vite-plugin-svelte@3.1.0(svelte@5.0.0-next.108)(vite@5.2.8): + /@sveltejs/vite-plugin-svelte@3.1.0(svelte@5.0.0-next.109)(vite@5.2.8): resolution: {integrity: sha512-sY6ncCvg+O3njnzbZexcVtUqOBE3iYmQPJ9y+yXSkOwG576QI/xJrBnQSRXFLGwJNBa0T78JEKg5cIR0WOAuUw==} engines: {node: ^18.0.0 || >=20} peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.0 dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.108)(vite@5.2.8) + '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@5.0.0-next.109)(vite@5.2.8) debug: 4.3.4 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.9 - svelte: 5.0.0-next.108 - svelte-hmr: 0.16.0(svelte@5.0.0-next.108) + svelte: 5.0.0-next.109 + svelte-hmr: 0.16.0(svelte@5.0.0-next.109) vite: 5.2.8(@types/node@20.12.2) vitefu: 0.2.5(vite@5.2.8) transitivePeerDependencies: @@ -2531,14 +2531,14 @@ packages: vitest: 1.5.0(@types/node@20.12.2)(jsdom@24.0.0) dev: true - /@testing-library/svelte@4.2.2(svelte@5.0.0-next.108): + /@testing-library/svelte@4.2.2(svelte@5.0.0-next.109): resolution: {integrity: sha512-zl2V/39V/uIRe+FjXfeB7Nvg/2DBqAFlKbpqtbAogtyoYtdQ0Z/d8Was8ZdtXl3QCa8NBNd3J0QUKSTDaEQYCA==} engines: {node: '>= 10'} peerDependencies: svelte: ^3 || ^4 || ^5 dependencies: '@testing-library/dom': 9.3.4 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 dev: true /@testing-library/user-event@14.5.2(@testing-library/dom@10.0.0): @@ -4366,7 +4366,7 @@ packages: engines: {node: '>=5.0.0'} dev: true - /eslint-plugin-perfectionist@2.8.0(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.108)(typescript@5.4.3)(vue-eslint-parser@9.4.2): + /eslint-plugin-perfectionist@2.8.0(eslint@9.0.0)(svelte-eslint-parser@0.34.1)(svelte@5.0.0-next.109)(typescript@5.4.3)(vue-eslint-parser@9.4.2): resolution: {integrity: sha512-XBjQ4ctU1rOzQ4bFJoUowe8XdsIIz42JqNrouFlae1TO78HjoyYBaRP8+gAHDDQCSdHY10pbChyzlJeBA6D51w==} peerDependencies: astro-eslint-parser: ^0.16.0 @@ -4388,15 +4388,15 @@ packages: eslint: 9.0.0 minimatch: 9.0.4 natural-compare-lite: 1.4.0 - svelte: 5.0.0-next.108 - svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.108) + svelte: 5.0.0-next.109 + svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.109) vue-eslint-parser: 9.4.2(eslint@9.0.0) transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-svelte@2.37.0(eslint@9.0.0)(svelte@5.0.0-next.108): + /eslint-plugin-svelte@2.37.0(eslint@9.0.0)(svelte@5.0.0-next.109): resolution: {integrity: sha512-H/2Gz7agYHEMEEzRuLYuCmAIdjuBnbhFG9hOK0yCdSBvvJGJMkjo+lR6j67OIvLOavgp4L7zA5LnDKi8WqdPhQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: @@ -4418,8 +4418,8 @@ packages: postcss-safe-parser: 6.0.0(postcss@8.4.38) postcss-selector-parser: 6.0.16 semver: 7.6.0 - svelte: 5.0.0-next.108 - svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.108) + svelte: 5.0.0-next.109 + svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.109) transitivePeerDependencies: - supports-color - ts-node @@ -6494,7 +6494,7 @@ packages: '@types/mdast': 4.0.3 dev: true - /mdsx@0.0.5(svelte@5.0.0-next.108): + /mdsx@0.0.5(svelte@5.0.0-next.109): resolution: {integrity: sha512-crYbZC0L5kQjaRABvHIXj9H2O1qikIw9KKqS3bo2En4XVgvHH7TO5bJ2X86PxJK7H6QEBAubjUma9+qpbsPC5A==} peerDependencies: svelte: ^4.0.0 @@ -6506,7 +6506,7 @@ packages: rehype-stringify: 10.0.0 remark-parse: 11.0.0 remark-rehype: 11.1.0 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 unified: 11.0.4 unist-util-visit: 5.0.0 vfile: 6.0.1 @@ -7221,12 +7221,12 @@ packages: ufo: 1.5.3 dev: true - /mode-watcher@0.2.2(svelte@5.0.0-next.108): + /mode-watcher@0.2.2(svelte@5.0.0-next.109): resolution: {integrity: sha512-QjkHQL9pXrr7Vb0P3WbOWAF8mv1Q6jEwUZ5GUyCnI9eEoXH234zuaOGChUF7ZQtjxwtmXDzKFSW/36TvLDg1/A==} peerDependencies: svelte: ^4.0.0 dependencies: - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 dev: true /mri@1.2.0: @@ -7647,12 +7647,12 @@ packages: is-reference: 3.0.2 dev: true - /phosphor-svelte@1.4.2(svelte@5.0.0-next.108): + /phosphor-svelte@1.4.2(svelte@5.0.0-next.109): resolution: {integrity: sha512-wdHKlZbE5D3ad1dd4K9bqWxpOb6gIwe+/ZeXGI9YpdKqECxqd+g3/NsLYE1+/hjlXixTWhQ7VMVIxTtBRXegCg==} peerDependencies: svelte: '>=3' dependencies: - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 dev: true /picocolors@1.0.0: @@ -7854,14 +7854,14 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /prettier-plugin-svelte@3.2.2(prettier@3.2.5)(svelte@5.0.0-next.108): + /prettier-plugin-svelte@3.2.2(prettier@3.2.5)(svelte@5.0.0-next.109): resolution: {integrity: sha512-ZzzE/wMuf48/1+Lf2Ffko0uDa6pyCfgHV6+uAhtg2U0AAXGrhCSW88vEJNAkAxW5qyrFY1y1zZ4J8TgHrjW++Q==} peerDependencies: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 dependencies: prettier: 3.2.5 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 dev: true /prettier-plugin-tailwindcss@0.5.13(prettier-plugin-svelte@3.2.2)(prettier@3.2.5): @@ -7917,7 +7917,7 @@ packages: optional: true dependencies: prettier: 3.2.5 - prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@5.0.0-next.108) + prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@5.0.0-next.109) dev: true /prettier@2.8.8: @@ -8831,7 +8831,7 @@ packages: engines: {node: '>= 0.4'} dev: true - /svelte-check@3.6.9(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.108): + /svelte-check@3.6.9(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.109): resolution: {integrity: sha512-hDQrk3L0osX07djQyMiXocKysTLfusqi8AriNcCiQxhQR49/LonYolcUGMtZ0fbUR8HTR198Prrgf52WWU9wEg==} hasBin: true peerDependencies: @@ -8843,8 +8843,8 @@ packages: import-fresh: 3.3.0 picocolors: 1.0.0 sade: 1.8.1 - svelte: 5.0.0-next.108 - svelte-preprocess: 5.1.3(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.108)(typescript@5.4.3) + svelte: 5.0.0-next.109 + svelte-preprocess: 5.1.3(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.109)(typescript@5.4.3) typescript: 5.4.3 transitivePeerDependencies: - '@babel/core' @@ -8858,7 +8858,7 @@ packages: - sugarss dev: true - /svelte-eslint-parser@0.34.1(svelte@5.0.0-next.108): + /svelte-eslint-parser@0.34.1(svelte@5.0.0-next.109): resolution: {integrity: sha512-9+uLA1pqI9AZioKVGJzYYmlOZWxfoCXSbAM9iaNm7H01XlYlzRTtJfZgl9o3StQGN41PfGJIbkKkfk3e/pHFfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -8872,19 +8872,19 @@ packages: espree: 9.6.1 postcss: 8.4.38 postcss-scss: 4.0.9(postcss@8.4.38) - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 dev: true - /svelte-hmr@0.16.0(svelte@5.0.0-next.108): + /svelte-hmr@0.16.0(svelte@5.0.0-next.109): resolution: {integrity: sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==} engines: {node: ^12.20 || ^14.13.1 || >= 16} peerDependencies: svelte: ^3.19.0 || ^4.0.0 dependencies: - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 dev: true - /svelte-preprocess@5.1.3(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.108)(typescript@5.4.3): + /svelte-preprocess@5.1.3(postcss-load-config@5.0.3)(postcss@8.4.38)(svelte@5.0.0-next.109)(typescript@5.4.3): resolution: {integrity: sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==} engines: {node: '>= 16.0.0', pnpm: ^8.0.0} requiresBuild: true @@ -8929,11 +8929,11 @@ packages: postcss-load-config: 5.0.3(postcss@8.4.38) sorcery: 0.11.0 strip-indent: 3.0.0 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 typescript: 5.4.3 dev: true - /svelte2tsx@0.7.5(svelte@5.0.0-next.108)(typescript@5.4.3): + /svelte2tsx@0.7.5(svelte@5.0.0-next.109)(typescript@5.4.3): resolution: {integrity: sha512-+y8z4YLGsCYN8yjkqPXrqg6yKa73IZfU2WC3MVxiM0YU2/HbGZ1Tiq1ceKCOhMQVBFWjOgC/C465wN/ux6FsDQ==} peerDependencies: svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 @@ -8941,12 +8941,12 @@ packages: dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 5.0.0-next.108 + svelte: 5.0.0-next.109 typescript: 5.4.3 dev: true - /svelte@5.0.0-next.108: - resolution: {integrity: sha512-4COuyOm+U2Iflb2VqxDev2iFeh214YHE6yOkKOKoDCGrd6IuEOaoopf+BpWgsF5v2PLqcF4HNkLYSbdwNc8AAA==} + /svelte@5.0.0-next.109: + resolution: {integrity: sha512-KiUxHKORb3zP0s6V3aoehLJtwBptolhQEvhvoALJUfuASa3Lq+pEqsoff1ShpN42nPGKcq9kH4a2MGEefUsRGg==} engines: {node: '>=18'} dependencies: '@ampproject/remapping': 2.3.0 diff --git a/sites/docs/package.json b/sites/docs/package.json index 263f55efb..7a2bbfb43 100644 --- a/sites/docs/package.json +++ b/sites/docs/package.json @@ -38,7 +38,7 @@ "rehype-slug": "^6.0.0", "remark-gfm": "^4.0.0", "shiki": "^1.1.1", - "svelte": "5.0.0-next.108", + "svelte": "5.0.0-next.109", "svelte-check": "^3.6.9", "tailwind-merge": "^2.2.1", "tailwind-variants": "^0.1.20", diff --git a/sites/docs/src/lib/components/demos/date-picker-demo.svelte b/sites/docs/src/lib/components/demos/date-picker-demo.svelte index e09f1434a..ed820f90a 100644 --- a/sites/docs/src/lib/components/demos/date-picker-demo.svelte +++ b/sites/docs/src/lib/components/demos/date-picker-demo.svelte @@ -1,4 +1,4 @@ - diff --git a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts index d828975bd..b75cc8946 100644 --- a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts +++ b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts @@ -1,3 +1,4 @@ +import { onDestroy, onMount, untrack } from "svelte"; import type { DismissableLayerProps, InteractOutsideBehaviorType, @@ -16,6 +17,7 @@ import { getOwnerDocument, isElement, isOrContainsTarget, + noop, useNodeById, } from "$lib/internal/index.js"; @@ -54,31 +56,58 @@ export class DismissableLayerState { #isResponsibleLayer = false; node: Box; #documentObj = undefined as unknown as Document; + #present: ReadonlyBox; constructor(props: DismissableLayerStateProps) { this.node = useNodeById(props.id); this.#behaviorType = props.behaviorType; this.#interactOutsideStartProp = props.onInteractOutsideStart; this.#interactOutsideProp = props.onInteractOutside; + this.#present = props.present; - layers.set(this, this.#behaviorType); + $effect(() => { + console.log("present", this.#present.value); + }); $effect(() => { this.#documentObj = getOwnerDocument(this.node.value); + }); - const unsubEvents = this.#addEventListeners(); + let unsubEvents = noop; + $effect(() => { + if (this.#present.value) { + layers.set( + this, + untrack(() => this.#behaviorType) + ); + unsubEvents = this.#addEventListeners(); + } return () => { - unsubEvents(); - this.#resetState.destroy(); + this.#resetState(); + layers.delete(this); this.#onInteractOutsideStart.destroy(); this.#onInteractOutside.destroy(); - layers.delete(this); + unsubEvents(); + }; + }); + + $effect(() => { + return () => { + // onDestroy, cleanup anything leftover + untrack(() => { + this.#resetState.destroy(); + layers.delete(this); + this.#onInteractOutsideStart.destroy(); + this.#onInteractOutside.destroy(); + unsubEvents(); + }); }; }); } #addEventListeners() { + console.log("adding event listeners"); return executeCallbacks( /** * CAPTURE INTERACTION START @@ -131,8 +160,13 @@ export class DismissableLayerState { } #onInteractOutsideStart = debounce((e: InteractOutsideEvent) => { - const node = this.node.value!; - if (!this.#isResponsibleLayer || this.#isAnyEventIntercepted() || !isValidEvent(e, node)) + console.log("onInteractOutsideStart"); + if (!this.node.value) return; + if ( + !this.#isResponsibleLayer || + this.#isAnyEventIntercepted() || + !isValidEvent(e, this.node.value) + ) return; this.#interactOutsideStartProp.value(e); if (e.defaultPrevented) return; @@ -140,6 +174,7 @@ export class DismissableLayerState { }, 10); #onInteractOutside = debounce((e: InteractOutsideEvent) => { + console.log("onInteractOutside"); if (!this.node.value) return; const behaviorType = this.#behaviorType.value; @@ -156,19 +191,23 @@ export class DismissableLayerState { }, 10); #markInterceptedEvent = (e: HTMLElementEventMap[InteractOutsideInterceptEventType]) => { + console.log("markInterceptedEvent", e.type); this.#interceptedEvents[e.type as InteractOutsideInterceptEventType] = true; }; #markNonInterceptedEvent = (e: HTMLElementEventMap[InteractOutsideInterceptEventType]) => { + console.log("markNonInterceptedEvent", e.type); this.#interceptedEvents[e.type as InteractOutsideInterceptEventType] = false; }; #markResponsibleLayer = () => { + console.log("markResponsibleLayer"); if (!this.node.value) return; this.#isResponsibleLayer = isResponsibleLayer(this.node.value); }; #resetState = debounce(() => { + console.log("resetState"); for (const eventType in this.#interceptedEvents) { this.#interceptedEvents[eventType as InteractOutsideInterceptEventType] = false; } @@ -177,6 +216,7 @@ export class DismissableLayerState { }, 20); #isAnyEventIntercepted() { + console.log("isAnyEventIntercepted"); return Object.values(this.#interceptedEvents).some(Boolean); } } @@ -186,7 +226,7 @@ export function useDismissableLayer(props: DismissableLayerStateProps) { } function isResponsibleLayer(node: HTMLElement): boolean { - console.log(layers); + console.log("isResponsibleLayer"); const layersArr = [...layers]; /** * We first check if we can find a top layer with `close` or `ignore`. @@ -203,6 +243,7 @@ function isResponsibleLayer(node: HTMLElement): boolean { } function isValidEvent(e: InteractOutsideEvent, node: HTMLElement): boolean { + console.log("isValidEvent"); if ("button" in e && e.button > 0) return false; const target = e.target; if (!isElement(target)) return false; diff --git a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/types.ts b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/types.ts index f245451a8..044e3fca4 100644 --- a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/types.ts +++ b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/types.ts @@ -45,6 +45,12 @@ export type DismissableLayerProps = { * @defaultValue `close` */ behaviorType?: InteractOutsideBehaviorType; + + /** + * Whether the layer is active. Currently, we determine this with the + * `presence` returned from the `presence` layer. + */ + present: boolean; }; export type InteractOutsideInterceptEventType = diff --git a/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte b/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte index 2d8e25c99..dbb13614c 100644 --- a/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte +++ b/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte @@ -3,11 +3,12 @@ import { useEscapeLayer } from "./escape-layer.svelte.js"; import { noop, readonlyBox } from "$lib/internal/index.js"; - let { behaviorType = "close", onEscape = noop, children }: EscapeLayerProps = $props(); + let { behaviorType = "close", onEscape = noop, children, present }: EscapeLayerProps = $props(); useEscapeLayer({ behaviorType: readonlyBox(() => behaviorType), onEscape: readonlyBox(() => onEscape), + present: readonlyBox(() => present), }); diff --git a/packages/bits-ui/src/lib/bits/utilities/escape-layer/types.ts b/packages/bits-ui/src/lib/bits/utilities/escape-layer/types.ts index 59f21dc40..f0dd2e5b4 100644 --- a/packages/bits-ui/src/lib/bits/utilities/escape-layer/types.ts +++ b/packages/bits-ui/src/lib/bits/utilities/escape-layer/types.ts @@ -24,4 +24,10 @@ export type EscapeLayerProps = { * @defaultValue `close` */ behaviorType?: EscapeBehaviorType; + + /** + * Whether the layer is enabled. Currently, we determine this with the + * `presence` returned from the `presence` layer. + */ + present: boolean; }; diff --git a/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte b/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte index 52249a3f3..89569bf4f 100644 --- a/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte +++ b/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte @@ -15,9 +15,12 @@ {#snippet presence({ present })} {#snippet content({ props })} - - - + + + {@render popper?.({ props: { ...props, hidden: present.value ? undefined : true }, })} diff --git a/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte b/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte index 824fc4852..e48686f99 100644 --- a/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte +++ b/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte @@ -9,6 +9,7 @@ onPointerUp = noop, id, children, + present, }: PreventTextSelectionOverflowLayerProps = $props(); usePreventTextSelectionOverflowLayer({ @@ -16,6 +17,7 @@ enabled: readonlyBox(() => enabled), onPointerDown: readonlyBox(() => onPointerDown), onPointerUp: readonlyBox(() => onPointerUp), + present: readonlyBox(() => present), }); diff --git a/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/types.ts b/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/types.ts index 0fbac8849..fd78c7051 100644 --- a/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/types.ts +++ b/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/types.ts @@ -27,4 +27,10 @@ export type PreventTextSelectionOverflowLayerProps = { * @defaultValue `true` */ enabled?: boolean; + + /** + * Whether the layer is enabled. Currently, we determine this with the + * `presence` returned from the `presence` layer. + */ + present: boolean; }; diff --git a/packages/bits-ui/src/lib/internal/debounce.ts b/packages/bits-ui/src/lib/internal/debounce.ts index 5d837cce6..718f703c0 100644 --- a/packages/bits-ui/src/lib/internal/debounce.ts +++ b/packages/bits-ui/src/lib/internal/debounce.ts @@ -8,6 +8,8 @@ export function debounce any>(fn: T, wait = 500) { timeout = setTimeout(later, wait); }; - debounced.destroy = () => clearTimeout(timeout); + debounced.destroy = () => { + clearTimeout(timeout); + }; return debounced; } diff --git a/packages/bits-ui/src/lib/internal/events.ts b/packages/bits-ui/src/lib/internal/events.ts index 37939412c..8de5a309d 100644 --- a/packages/bits-ui/src/lib/internal/events.ts +++ b/packages/bits-ui/src/lib/internal/events.ts @@ -97,6 +97,7 @@ export function addEventListener( // Return a function that removes the event listener from the target element(s). return () => { + console.log("removing event listeners"); events.forEach((_event) => target.removeEventListener(_event, handler, options)); }; } diff --git a/sites/docs/src/lib/components/api-ref/data-attr-value-content.svelte b/sites/docs/src/lib/components/api-ref/data-attr-value-content.svelte index 9cd4308ab..4a5bcded2 100644 --- a/sites/docs/src/lib/components/api-ref/data-attr-value-content.svelte +++ b/sites/docs/src/lib/components/api-ref/data-attr-value-content.svelte @@ -3,7 +3,6 @@ import { Info } from "$icons/index.js"; import { Code } from "$lib/components/index.js"; import type { DataAttrSchema } from "$lib/types/index.js"; - import { flyAndScale } from "$lib/utils/index.js"; export let attr: DataAttrSchema; @@ -23,8 +22,6 @@ diff --git a/sites/docs/src/lib/components/api-ref/prop-copy.svelte b/sites/docs/src/lib/components/api-ref/prop-copy.svelte index 6507c771b..2cffa29fc 100644 --- a/sites/docs/src/lib/components/api-ref/prop-copy.svelte +++ b/sites/docs/src/lib/components/api-ref/prop-copy.svelte @@ -1,7 +1,6 @@ @@ -16,8 +15,6 @@ diff --git a/sites/docs/src/lib/components/api-ref/prop-type-content.svelte b/sites/docs/src/lib/components/api-ref/prop-type-content.svelte index 112264292..c25792df2 100644 --- a/sites/docs/src/lib/components/api-ref/prop-type-content.svelte +++ b/sites/docs/src/lib/components/api-ref/prop-type-content.svelte @@ -3,7 +3,7 @@ import { Info } from "$icons/index.js"; import { Code } from "$lib/components/index.js"; import type { PropType } from "$lib/types/index.js"; - import { flyAndScale, parseTypeDef } from "$lib/utils/index.js"; + import { parseTypeDef } from "$lib/utils/index.js"; export let type: PropType | string; @@ -23,8 +23,6 @@ diff --git a/sites/docs/src/routes/sink/+page.svelte b/sites/docs/src/routes/sink/+page.svelte new file mode 100644 index 000000000..b570287b9 --- /dev/null +++ b/sites/docs/src/routes/sink/+page.svelte @@ -0,0 +1,7 @@ + + +
+ +
From 649edb8af8639389acb019f20cf7e4c6e524ac24 Mon Sep 17 00:00:00 2001 From: Hunter Johnston Date: Fri, 19 Apr 2024 20:16:11 -0400 Subject: [PATCH 3/4] cleanup memory leakes --- .../dismissable-layer.svelte.ts | 16 +------------ .../escape-layer/escape-layer.svelte.ts | 18 ++++++++++---- .../floating-layer/floating-layer.svelte.ts | 1 - ...nt-text-selection-overflow-layer.svelte.ts | 24 +++++++++++++------ 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts index b75cc8946..60ebcfd08 100644 --- a/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts +++ b/packages/bits-ui/src/lib/bits/utilities/dismissable-layer/dismissable-layer.svelte.ts @@ -1,4 +1,4 @@ -import { onDestroy, onMount, untrack } from "svelte"; +import { untrack } from "svelte"; import type { DismissableLayerProps, InteractOutsideBehaviorType, @@ -65,10 +65,6 @@ export class DismissableLayerState { this.#interactOutsideProp = props.onInteractOutside; this.#present = props.present; - $effect(() => { - console.log("present", this.#present.value); - }); - $effect(() => { this.#documentObj = getOwnerDocument(this.node.value); }); @@ -107,7 +103,6 @@ export class DismissableLayerState { } #addEventListeners() { - console.log("adding event listeners"); return executeCallbacks( /** * CAPTURE INTERACTION START @@ -160,7 +155,6 @@ export class DismissableLayerState { } #onInteractOutsideStart = debounce((e: InteractOutsideEvent) => { - console.log("onInteractOutsideStart"); if (!this.node.value) return; if ( !this.#isResponsibleLayer || @@ -174,7 +168,6 @@ export class DismissableLayerState { }, 10); #onInteractOutside = debounce((e: InteractOutsideEvent) => { - console.log("onInteractOutside"); if (!this.node.value) return; const behaviorType = this.#behaviorType.value; @@ -191,23 +184,19 @@ export class DismissableLayerState { }, 10); #markInterceptedEvent = (e: HTMLElementEventMap[InteractOutsideInterceptEventType]) => { - console.log("markInterceptedEvent", e.type); this.#interceptedEvents[e.type as InteractOutsideInterceptEventType] = true; }; #markNonInterceptedEvent = (e: HTMLElementEventMap[InteractOutsideInterceptEventType]) => { - console.log("markNonInterceptedEvent", e.type); this.#interceptedEvents[e.type as InteractOutsideInterceptEventType] = false; }; #markResponsibleLayer = () => { - console.log("markResponsibleLayer"); if (!this.node.value) return; this.#isResponsibleLayer = isResponsibleLayer(this.node.value); }; #resetState = debounce(() => { - console.log("resetState"); for (const eventType in this.#interceptedEvents) { this.#interceptedEvents[eventType as InteractOutsideInterceptEventType] = false; } @@ -216,7 +205,6 @@ export class DismissableLayerState { }, 20); #isAnyEventIntercepted() { - console.log("isAnyEventIntercepted"); return Object.values(this.#interceptedEvents).some(Boolean); } } @@ -226,7 +214,6 @@ export function useDismissableLayer(props: DismissableLayerStateProps) { } function isResponsibleLayer(node: HTMLElement): boolean { - console.log("isResponsibleLayer"); const layersArr = [...layers]; /** * We first check if we can find a top layer with `close` or `ignore`. @@ -243,7 +230,6 @@ function isResponsibleLayer(node: HTMLElement): boolean { } function isValidEvent(e: InteractOutsideEvent, node: HTMLElement): boolean { - console.log("isValidEvent"); if ("button" in e && e.button > 0) return false; const target = e.target; if (!isElement(target)) return false; diff --git a/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte.ts b/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte.ts index 6de829913..4c2414d8b 100644 --- a/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte.ts +++ b/packages/bits-ui/src/lib/bits/utilities/escape-layer/escape-layer.svelte.ts @@ -1,8 +1,9 @@ -import { onDestroy } from "svelte"; +import { untrack } from "svelte"; import type { EscapeBehaviorType, EscapeLayerProps } from "./types.js"; import type { ReadonlyBox, ReadonlyBoxedValues } from "$lib/internal/box.svelte.js"; import { type EventCallback, addEventListener } from "$lib/internal/events.js"; import { kbd } from "$lib/internal/kbd.js"; +import { noop } from "$lib/internal/callbacks.js"; const layers = new Map>(); @@ -11,14 +12,23 @@ type EscapeLayerStateProps = ReadonlyBoxedValues>; #behaviorType: ReadonlyBox; + #present: ReadonlyBox; constructor(props: EscapeLayerStateProps) { this.#behaviorType = props.behaviorType; this.#onEscapeProp = props.onEscape; - layers.set(this, this.#behaviorType); + this.#present = props.present; - $effect.root(() => { - const unsubEvents = this.#addEventListener(); + let unsubEvents = noop; + + $effect(() => { + if (this.#present.value) { + layers.set( + this, + untrack(() => this.#behaviorType) + ); + unsubEvents = this.#addEventListener(); + } return () => { unsubEvents(); diff --git a/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts b/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts index c30867e24..08672a9fd 100644 --- a/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts +++ b/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts @@ -1,4 +1,3 @@ -import type { VirtualElement } from "@floating-ui/core"; import { getContext, setContext, untrack } from "svelte"; import { type Middleware, diff --git a/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte.ts b/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte.ts index 66f416853..11525dc19 100644 --- a/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte.ts +++ b/packages/bits-ui/src/lib/bits/utilities/prevent-text-selection-overflow-layer/prevent-text-selection-overflow-layer.svelte.ts @@ -1,4 +1,4 @@ -import { onDestroy } from "svelte"; +import { untrack } from "svelte"; import type { PreventTextSelectionOverflowLayerProps } from "./types.js"; import { type Box, @@ -26,18 +26,25 @@ export class PreventTextSelectionOverflowLayerState { #enabled: ReadonlyBox; #unsubSelectionLock = noop; #node: Box; + #present: ReadonlyBox; constructor(props: StateProps) { this.#node = useNodeById(props.id); this.#enabled = props.enabled; this.#onPointerDownProp = props.onPointerDown; this.#onPointerUpProp = props.onPointerUp; + this.#present = props.present; - layers.set(this, this.#enabled); - - $effect.root(() => { - const unsubEvents = this.#addEventListeners(); + let unsubEvents = noop; + $effect(() => { + if (this.#present.value) { + layers.set( + this, + untrack(() => this.#enabled) + ); + unsubEvents = this.#addEventListeners(); + } return () => { unsubEvents(); this.#resetSelectionLock(); @@ -102,6 +109,9 @@ function setUserSelect(node: HTMLElement, value: string) { } function isHighestLayer(instance: PreventTextSelectionOverflowLayerState) { - const [topLayer] = [...layers].at(-1)!; - return topLayer === instance; + const layersArr = [...layers]; + if (!layersArr.length) return false; + const highestLayer = layersArr.at(-1); + if (!highestLayer) return false; + return highestLayer[0] === instance; } From d8c98faa505e53415f0d1374fc42d8ac80d8ff05 Mon Sep 17 00:00:00 2001 From: Hunter Johnston Date: Fri, 19 Apr 2024 22:28:16 -0400 Subject: [PATCH 4/4] we're in there --- .../popover/components/popover-content.svelte | 6 +-- .../src/lib/bits/popover/popover.svelte.ts | 1 + .../components/floating-layer-content.svelte | 2 + .../floating-layer/floating-layer.svelte.ts | 13 ++++--- .../bits/utilities/floating-layer/types.ts | 5 +++ .../popper-layer/popper-layer.svelte | 2 +- packages/bits-ui/src/lib/internal/events.ts | 1 - .../floating-svelte/use-floating.svelte.ts | 2 +- .../src/lib/internal/use-presence.svelte.ts | 39 +++++++++---------- 9 files changed, 39 insertions(+), 32 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte b/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte index 86bd67109..c1f822292 100644 --- a/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte +++ b/packages/bits-ui/src/lib/bits/popover/components/popover-content.svelte @@ -22,19 +22,19 @@ {#snippet popper({ props })} {@const mergedProps = { - ...props, - ...state.props, ...restProps, + ...state.props, + ...props, }} {#if asChild} {@render child?.({ props: mergedProps })} diff --git a/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts b/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts index 7e2b383cd..eac37c7cb 100644 --- a/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts +++ b/packages/bits-ui/src/lib/bits/popover/popover.svelte.ts @@ -87,6 +87,7 @@ class PopoverTriggerState { #onkeydown = (e: KeyboardEvent) => { if (!(e.key === kbd.ENTER || e.key === kbd.SPACE)) return; + e.preventDefault(); this.root.toggleOpen(); }; } diff --git a/packages/bits-ui/src/lib/bits/utilities/floating-layer/components/floating-layer-content.svelte b/packages/bits-ui/src/lib/bits/utilities/floating-layer/components/floating-layer-content.svelte index a1b6abec4..1597dc258 100644 --- a/packages/bits-ui/src/lib/bits/utilities/floating-layer/components/floating-layer-content.svelte +++ b/packages/bits-ui/src/lib/bits/utilities/floating-layer/components/floating-layer-content.svelte @@ -21,6 +21,7 @@ strategy = "fixed", dir = "ltr", style = {}, + present, }: ContentProps = $props(); const state = setFloatingContentState({ @@ -40,6 +41,7 @@ strategy: readonlyBox(() => strategy), dir: readonlyBox(() => dir), style: readonlyBox(() => style), + present: readonlyBox(() => present), }); diff --git a/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts b/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts index 08672a9fd..9c0b555d5 100644 --- a/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts +++ b/packages/bits-ui/src/lib/bits/utilities/floating-layer/floating-layer.svelte.ts @@ -16,6 +16,7 @@ import { type Box, type ReadonlyBox, type ReadonlyBoxedValues, + afterTick, boxedState, generateId, styleToString, @@ -82,6 +83,7 @@ export type FloatingContentStateProps = ReadonlyBoxedValues<{ onPlaced: () => void; dir: TextDirection; style: StyleProperties; + present: boolean; }>; class FloatingContentState { @@ -103,6 +105,7 @@ class FloatingContentState { updatePositionStrategy = undefined as unknown as FloatingContentStateProps["updatePositionStrategy"]; onPlaced = undefined as unknown as FloatingContentStateProps["onPlaced"]; + present = undefined as unknown as FloatingContentStateProps["present"]; arrowSize: { readonly value: | { @@ -200,7 +203,7 @@ class FloatingContentState { ...this.style.value, // if the FloatingContent hasn't been placed yet (not all measurements done) // we prevent animations so that users's animation don't kick in too early referring wrong sides - animation: !this.floating.isPositioned ? "none" : undefined, + // animation: !this.floating.isPositioned ? "none" : undefined, }), }); @@ -222,6 +225,9 @@ class FloatingContentState { this.dir = props.dir; this.style = props.style; this.root = root; + this.present = props.present; + this.arrowSize = useSize(this.root.arrowNode); + this.root.contentNode = useNodeById(this.id); this.floating = useFloating({ strategy: () => this.strategy.value, placement: () => this.desiredPlacement, @@ -233,12 +239,9 @@ class FloatingContentState { }); return cleanup; }, + open: () => this.present.value, }); - this.arrowSize = useSize(this.root.arrowNode); - - this.root.contentNode = useNodeById(this.id); - $effect(() => { if (this.floating.isPositioned) { this.onPlaced?.value(); diff --git a/packages/bits-ui/src/lib/bits/utilities/floating-layer/types.ts b/packages/bits-ui/src/lib/bits/utilities/floating-layer/types.ts index 749d418a3..ec964d05f 100644 --- a/packages/bits-ui/src/lib/bits/utilities/floating-layer/types.ts +++ b/packages/bits-ui/src/lib/bits/utilities/floating-layer/types.ts @@ -98,6 +98,11 @@ export type FloatingLayerContentProps = { * The style properties to apply to the content. */ style?: StyleProperties; + + /** + * Whether the floating layer is present. + */ + present: boolean; }; export type FloatingLayerArrowProps = { diff --git a/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte b/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte index 89569bf4f..741a3cc3c 100644 --- a/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte +++ b/packages/bits-ui/src/lib/bits/utilities/popper-layer/popper-layer.svelte @@ -13,7 +13,7 @@ {#snippet presence({ present })} - + {#snippet content({ props })} diff --git a/packages/bits-ui/src/lib/internal/events.ts b/packages/bits-ui/src/lib/internal/events.ts index 8de5a309d..37939412c 100644 --- a/packages/bits-ui/src/lib/internal/events.ts +++ b/packages/bits-ui/src/lib/internal/events.ts @@ -97,7 +97,6 @@ export function addEventListener( // Return a function that removes the event listener from the target element(s). return () => { - console.log("removing event listeners"); events.forEach((_event) => target.removeEventListener(_event, handler, options)); }; } diff --git a/packages/bits-ui/src/lib/internal/floating-svelte/use-floating.svelte.ts b/packages/bits-ui/src/lib/internal/floating-svelte/use-floating.svelte.ts index ef727f5ac..b8a56c932 100644 --- a/packages/bits-ui/src/lib/internal/floating-svelte/use-floating.svelte.ts +++ b/packages/bits-ui/src/lib/internal/floating-svelte/use-floating.svelte.ts @@ -1,5 +1,6 @@ import { computePosition } from "@floating-ui/dom"; import { box, boxedState } from "../box.svelte.js"; +import { afterTick } from "../after-tick.js"; import type { UseFloatingOptions, UseFloatingReturn } from "./types.js"; import { get, getDPR, roundByDPR } from "./utils.js"; @@ -59,7 +60,6 @@ export function useFloating(options: UseFloatingOptions): UseFloatingReturn { function update() { if (reference.value === null || floating.value === null) return; - computePosition(reference.value, floating.value, { middleware: middlewareOption, placement: placementOption, diff --git a/packages/bits-ui/src/lib/internal/use-presence.svelte.ts b/packages/bits-ui/src/lib/internal/use-presence.svelte.ts index 89bee80c6..fa39c07c0 100644 --- a/packages/bits-ui/src/lib/internal/use-presence.svelte.ts +++ b/packages/bits-ui/src/lib/internal/use-presence.svelte.ts @@ -1,6 +1,6 @@ -import { onDestroy } from "svelte"; +import { onDestroy, untrack } from "svelte"; import { type Box, type ReadonlyBox, boxedState, watch } from "./box.svelte.js"; -import { useNodeById, useStateMachine } from "$lib/internal/index.js"; +import { afterTick, useNodeById, useStateMachine } from "$lib/internal/index.js"; export function usePresence(present: ReadonlyBox, id: ReadonlyBox) { const styles = boxedState({}) as unknown as Box; @@ -34,7 +34,7 @@ export function usePresence(present: ReadonlyBox, id: ReadonlyBox, id: ReadonlyBox, id: ReadonlyBox, id: ReadonlyBox { - if (currNode) { - styles.value = getComputedStyle(currNode); - currNode.addEventListener("animationstart", handleAnimationStart); - currNode.addEventListener("animationcancel", handleAnimationEnd); - currNode.addEventListener("animationend", handleAnimationEnd); - } else { - dispatch("ANIMATION_END"); - prevNode?.removeEventListener("animationstart", handleAnimationStart); - prevNode?.removeEventListener("animationcancel", handleAnimationEnd); - prevNode?.removeEventListener("animationend", handleAnimationEnd); - } - }, - { immediate: true } - ); + const watcher = watch(node, (currNode, prevNode) => { + if (currNode) { + styles.value = getComputedStyle(currNode); + currNode.addEventListener("animationstart", handleAnimationStart); + currNode.addEventListener("animationcancel", handleAnimationEnd); + currNode.addEventListener("animationend", handleAnimationEnd); + } else { + dispatch("ANIMATION_END"); + prevNode?.removeEventListener("animationstart", handleAnimationStart); + prevNode?.removeEventListener("animationcancel", handleAnimationEnd); + prevNode?.removeEventListener("animationend", handleAnimationEnd); + } + }); onDestroy(() => { watcher();