feat: add has function to createContext (#18472)

closes #18471.

---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
pull/18733/head
Adnane Taghi 2 days ago committed by GitHub
parent 5034b59e9e
commit 4ae5eb3f23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': minor
---
feat: add `has` function to `createContext`

@ -4,7 +4,7 @@ title: Context
Context allows components to access values owned by parent components without passing them down as props (potentially through many layers of intermediate components, known as 'prop-drilling'). Context allows components to access values owned by parent components without passing them down as props (potentially through many layers of intermediate components, known as 'prop-drilling').
By creating a `[get, set]` pair of functions with `createContext`, you can set the context in a parent component and get it in a child component: By creating a `[get, set, has]` triplet of functions with `createContext`, you can set the context in a parent component and get it in a child component:
<!-- codeblock:start {"title":"Context","selected":"context.ts"} --> <!-- codeblock:start {"title":"Context","selected":"context.ts"} -->
```svelte ```svelte

@ -78,7 +78,7 @@ Certain lifecycle methods can only be used during component initialisation. To f
Context was not set in the current component or any of its ancestors Context was not set in the current component or any of its ancestors
``` ```
The [`createContext()`](svelte#createContext) utility returns a `[get, set]` pair of functions. `get` will throw an error if `set` was not used to set the context in the current component or any of its ancestors. The [`createContext()`](svelte#createContext) utility returns a `[get, set, has]` triplet of functions. `get` will throw an error if `set` was not used to set the context in the current component or any of its ancestors.
### snippet_without_render_tag ### snippet_without_render_tag

@ -64,7 +64,7 @@ Certain lifecycle methods can only be used during component initialisation. To f
> Context was not set in the current component or any of its ancestors > Context was not set in the current component or any of its ancestors
The [`createContext()`](svelte#createContext) utility returns a `[get, set]` pair of functions. `get` will throw an error if `set` was not used to set the context in the current component or any of its ancestors. The [`createContext()`](svelte#createContext) utility returns a `[get, set, has]` triplet of functions. `get` will throw an error if `set` was not used to set the context in the current component or any of its ancestors.
## snippet_without_render_tag ## snippet_without_render_tag

@ -72,17 +72,17 @@ export function set_dev_current_component_function(fn) {
} }
/** /**
* Returns a `[get, set]` pair of functions for working with context in a type-safe way. * Returns a `[get, set, has]` triplet of functions for working with context in a type-safe way.
* *
* `get` will throw an error if `set` has not yet been called in the current component or any of * `get` will throw an error if `set` has not yet been called in the current component or any of
* its ancestors. * its ancestors.
* *
* @template T * @template T
* @returns {[() => T, (context: T) => T]} * @returns {[() => T, (context: T) => T, () => boolean]}
* @since 5.40.0 * @since 5.40.0
*/ */
export function createContext() { export function createContext() {
return /** @type {[() => T, (context: T) => T]} */ ( return /** @type {[() => T, (context: T) => T, () => boolean]} */ (
create_context(getContext, setContext, hasContext) create_context(getContext, setContext, hasContext)
); );
} }

@ -12,11 +12,11 @@ export function set_ssr_context(v) {
/** /**
* @template T * @template T
* @returns {[() => T, (context: T) => T]} * @returns {[() => T, (context: T) => T, () => boolean]}
* @since 5.40.0 * @since 5.40.0
*/ */
export function createContext() { export function createContext() {
return /** @type {[() => T, (context: T) => T]} */ ( return /** @type {[() => T, (context: T) => T, () => boolean]} */ (
create_context(getContext, setContext, hasContext) create_context(getContext, setContext, hasContext)
); );
} }

@ -5,7 +5,7 @@ import { lifecycle_outside_component, missing_context } from './errors.js';
* @param {(key: object) => T} get_context * @param {(key: object) => T} get_context
* @param {(key: object, context: T) => T} set_context * @param {(key: object, context: T) => T} set_context
* @param {(key: object) => boolean} has_context * @param {(key: object) => boolean} has_context
* @returns {[() => T, (context: T) => T]} * @returns {[() => T, (context: T) => T, () => boolean]}
*/ */
export function create_context(get_context, set_context, has_context) { export function create_context(get_context, set_context, has_context) {
const key = {}; const key = {};
@ -18,7 +18,8 @@ export function create_context(get_context, set_context, has_context) {
return get_context(key); return get_context(key);
}, },
(context) => set_context(key, context) (context) => set_context(key, context),
() => has_context(key)
]; ];
} }

@ -1,7 +1,13 @@
<script> <script>
import { get } from './main.svelte'; import { get, has, has_unset } from './main.svelte';
const message = get(); const message = get();
</script> </script>
<h1>{message}</h1> <h1>{message}</h1>
{#if has()}
<h2>it's me</h2>
{/if}
{#if !has_unset()}
<h2>or not</h2>
{/if}

@ -2,7 +2,7 @@ import { test } from '../../test';
export default test({ export default test({
ssrHtml: `<div></div>`, ssrHtml: `<div></div>`,
html: `<div><h1>hello</h1></div>`, html: `<div><h1>hello</h1><h2>it's me</h2><h2>or not</h2></div>`,
test() {} test() {}
}); });

@ -3,9 +3,11 @@
import Child from './Child.svelte'; import Child from './Child.svelte';
/** @type {ReturnType<typeof createContext<string>>} */ /** @type {ReturnType<typeof createContext<string>>} */
const [get, set] = createContext(); const [get, set, has] = createContext();
/** @type {ReturnType<typeof createContext<string>>} */
const [, , has_unset] = createContext();
export { get }; export { get, has, has_unset };
function Wrapper(Component) { function Wrapper(Component) {
return (...args) => { return (...args) => {
@ -15,6 +17,8 @@
} }
</script> </script>
<div {@attach (target) => { <div
mount(Wrapper(Child), { target }); {@attach (target) => {
}}></div> mount(Wrapper(Child), { target });
}}
></div>

@ -1,7 +1,13 @@
<script> <script>
import { get } from './main.svelte'; import { get, has, has_unset } from './main.svelte';
const message = get(); const message = get();
</script> </script>
<h1>{message}</h1> <h1>{message}</h1>
{#if has()}
<h2>it's me</h2>
{/if}
{#if !has_unset()}
<h2>or not</h2>
{/if}

@ -1,5 +1,5 @@
import { test } from '../../test'; import { test } from '../../test';
export default test({ export default test({
html: `<h1>hello</h1>` html: `<h1>hello</h1><h2>it's me</h2><h2>or not</h2>`
}); });

@ -2,9 +2,11 @@
import { createContext } from 'svelte'; import { createContext } from 'svelte';
/** @type {ReturnType<typeof createContext<string>>} */ /** @type {ReturnType<typeof createContext<string>>} */
const [get, set] = createContext(); const [get, set, has] = createContext();
/** @type {ReturnType<typeof createContext<string>>} */
const [, , has_unset] = createContext();
export { get }; export { get, has, has_unset };
</script> </script>
<script> <script>

@ -492,14 +492,14 @@ declare module 'svelte' {
*/ */
export function fork(fn: () => void): Fork; export function fork(fn: () => void): Fork;
/** /**
* Returns a `[get, set]` pair of functions for working with context in a type-safe way. * Returns a `[get, set, has]` triplet of functions for working with context in a type-safe way.
* *
* `get` will throw an error if `set` has not yet been called in the current component or any of * `get` will throw an error if `set` has not yet been called in the current component or any of
* its ancestors. * its ancestors.
* *
* @since 5.40.0 * @since 5.40.0
*/ */
export function createContext<T>(): [() => T, (context: T) => T]; export function createContext<T>(): [() => T, (context: T) => T, () => boolean];
/** /**
* Retrieves the context set with the specified `key` in the current component or any of its * Retrieves the context set with the specified `key` in the current component or any of its
* ancestors. If multiple components set the same key, the value from the closest one is returned. * ancestors. If multiple components set the same key, the value from the closest one is returned.

Loading…
Cancel
Save