",
- "value": "{ sm: 320, md: 672, lg: 1056, xlg: 1312, max: 1584, }",
- "isFunction": false,
- "isFunctionDeclaration": false,
- "constant": true,
- "reactive": false
}
],
"slots": [
@@ -410,7 +399,7 @@
"events": [
{
"type": "dispatched",
- "name": "match",
+ "name": "change",
"detail": "{ size: BreakpointSize; breakpointValue: BreakpointValue; }"
}
],
diff --git a/docs/src/pages/components/Breakpoint.svx b/docs/src/pages/components/Breakpoint.svx
index 082f57bc..22bf672f 100644
--- a/docs/src/pages/components/Breakpoint.svx
+++ b/docs/src/pages/components/Breakpoint.svx
@@ -22,6 +22,14 @@ This utility component uses the [Window.matchMedia API](https://developer.mozill
Bind to the `size` prop to determine the current breakpoint size. Possible values include: `"sm" | "md" | "lg" | "xlg" | "max"`.
-The `"on:match"` event will fire only when a breakpoint change event occurs (e.g., the browser width is resized).
+The `"on:change"` event will fire when the size is initially determined and when a breakpoint change event occurs (e.g., the browser width is resized).
-
\ No newline at end of file
+
+
+### Store and Breakpoint Values
+
+As an alternative to the component, `breakpointObserver` can be used to get the current size as a Svelte store. The store has two additional functions which create derived stores that return a `boolean` indicating whether the size is smaller/larger than a certain breakpoint.
+
+There also exists a `breakpoints` dictionary mapping from `BreakpointSize` to `BreakpointValue`.
+
+
diff --git a/docs/src/pages/framed/Breakpoint/Breakpoint.svelte b/docs/src/pages/framed/Breakpoint/Breakpoint.svelte
index 83116706..b1b7e0a1 100644
--- a/docs/src/pages/framed/Breakpoint/Breakpoint.svelte
+++ b/docs/src/pages/framed/Breakpoint/Breakpoint.svelte
@@ -5,13 +5,13 @@
let events = [];
-
+
Resize the width of your browser.
Breakpoint size
{size}
-on:match
+on:change
{JSON.stringify(events, null, 2)}
diff --git a/docs/src/pages/framed/Breakpoint/BreakpointObserver.svelte b/docs/src/pages/framed/Breakpoint/BreakpointObserver.svelte
new file mode 100644
index 00000000..a37e4683
--- /dev/null
+++ b/docs/src/pages/framed/Breakpoint/BreakpointObserver.svelte
@@ -0,0 +1,15 @@
+
+
+Current breakpoint size: {$size}
+Current breakpoint value: {breakpoints[$size]}px
+Smaller than medium: {$smaller}
+Larger than medium: {$larger}
diff --git a/src/Breakpoint/Breakpoint.svelte b/src/Breakpoint/Breakpoint.svelte
index 19ef305f..c040e903 100644
--- a/src/Breakpoint/Breakpoint.svelte
+++ b/src/Breakpoint/Breakpoint.svelte
@@ -2,7 +2,7 @@
/**
* @typedef {"sm" | "md" | "lg" | "xlg" | "max"} BreakpointSize
* @typedef {320 | 672 | 1056 | 1312 | 1584} BreakpointValue
- * @event {{ size: BreakpointSize; breakpointValue: BreakpointValue; }} match
+ * @event {{ size: BreakpointSize; breakpointValue: BreakpointValue; }} change
* @slot {{ size: BreakpointSize; sizes: Record; }}
*/
@@ -24,77 +24,23 @@
max: false,
};
- /**
- * Reference the Carbon grid breakpoints
- * @type {Record}
- */
- export const breakpoints = {
- sm: 320,
- md: 672,
- lg: 1056,
- xlg: 1312,
- max: 1584,
- };
-
- import { createEventDispatcher, onMount } from "svelte";
+ import { createEventDispatcher } from "svelte";
+ import { breakpointObserver } from "./breakpointObserver";
+ import { breakpoints } from "./breakpoints";
const dispatch = createEventDispatcher();
+ const observer = breakpointObserver();
- onMount(() => {
- const width = window.innerWidth;
-
- if (width > breakpoints.max) size = "max";
- else if (width < breakpoints.md) size = "sm";
- else if (width >= breakpoints.md && width <= breakpoints.lg) size = "md";
- else if (width >= breakpoints.lg && width <= breakpoints.xlg) size = "lg";
- else if (width >= breakpoints.xlg && width <= breakpoints.max) size = "xlg";
-
- const match = {
- sm: window.matchMedia(`(max-width: ${breakpoints.md}px)`),
- md: window.matchMedia(
- `(min-width: ${breakpoints.md}px) and (max-width: ${breakpoints.lg}px)`
- ),
- lg: window.matchMedia(
- `(min-width: ${breakpoints.lg}px) and (max-width: ${breakpoints.xlg}px)`
- ),
- xlg: window.matchMedia(
- `(min-width: ${breakpoints.xlg}px) and (max-width: ${breakpoints.max}px)`
- ),
- max: window.matchMedia(`(min-width: ${breakpoints.max}px)`),
- };
- const matchers = Object.entries(match);
- const matchersBySize = Object.fromEntries(
- matchers.map(([size, queryList]) => [queryList.media, size])
- );
-
- function handleChange({ matches, media }) {
- const size = matchersBySize[media];
-
- sizes = { ...sizes };
- sizes[size] = matches;
-
- if (matches)
- dispatch("match", { size, breakpointValue: breakpoints[size] });
- }
-
- matchers.forEach(([size, queryList]) =>
- queryList.addEventListener("change", handleChange)
- );
-
- return () => {
- matchers.forEach(([size, queryList]) =>
- queryList.removeEventListener("change", handleChange)
- );
- };
- });
-
- $: {
- if (sizes.sm) size = "sm";
- if (sizes.md) size = "md";
- if (sizes.lg) size = "lg";
- if (sizes.xlg) size = "xlg";
- if (sizes.max) size = "max";
- }
+ $: size = $observer;
+ $: sizes = {
+ sm: size == "sm",
+ md: size == "md",
+ lg: size == "lg",
+ xlg: size == "xlg",
+ max: size == "max",
+ };
+ $: if (size != undefined)
+ dispatch("change", { size, breakpointValue: breakpoints[size] });
diff --git a/src/Breakpoint/breakpointObserver.d.ts b/src/Breakpoint/breakpointObserver.d.ts
new file mode 100644
index 00000000..6c8cbdf1
--- /dev/null
+++ b/src/Breakpoint/breakpointObserver.d.ts
@@ -0,0 +1,22 @@
+import type { Readable, Subscriber, Unsubscriber } from "svelte/store";
+import type { BreakpointSize, BreakpointValue } from "./breakpoints";
+
+/**
+ * Creates a readable store that returns the current breakpoint size.
+ * It also provides functions for creating derived stores used to do comparisons.
+ */
+export function breakpointObserver(): {
+ subscribe: (this: void, run: Subscriber, invalidate?: (value?: any) => void) => Unsubscriber;
+ /**
+ * Returns a store readable store that returns whether the current
+ * breakpoint is smaller than {@link size}.
+ * @param {BreakpointSize} size Size to compare against.
+ */
+ smallerThan: (size: BreakpointSize) => Readable;
+ /**
+ * Returns a store readable store that returns whether the current
+ * breakpoint is larger than {@link size}.
+ * @param {BreakpointSize} size Size to compare against.
+ */
+ largerThan: (size: BreakpointSize) => Readable;
+};
diff --git a/src/Breakpoint/breakpointObserver.js b/src/Breakpoint/breakpointObserver.js
new file mode 100644
index 00000000..a5836bd6
--- /dev/null
+++ b/src/Breakpoint/breakpointObserver.js
@@ -0,0 +1,80 @@
+import { onMount } from "svelte";
+import { derived, writable } from "svelte/store";
+import { breakpoints } from "./breakpoints";
+
+/**
+ * Creates a readable store that returns the current breakpoint size.
+ * It also provides functions for creating derived stores used to do comparisons.
+ */
+export function breakpointObserver() {
+ const store = writable(undefined);
+
+ onMount(() => {
+ /** @type {Record} */
+ const match = {
+ sm: window.matchMedia(`(max-width: ${breakpoints.md}px)`),
+ md: window.matchMedia(
+ `(min-width: ${breakpoints.md}px) and (max-width: ${breakpoints.lg}px)`
+ ),
+ lg: window.matchMedia(
+ `(min-width: ${breakpoints.lg}px) and (max-width: ${breakpoints.xlg}px)`
+ ),
+ xlg: window.matchMedia(
+ `(min-width: ${breakpoints.xlg}px) and (max-width: ${breakpoints.max}px)`
+ ),
+ max: window.matchMedia(`(min-width: ${breakpoints.max}px)`),
+ };
+ const matchers = Object.entries(match);
+ const sizeByMedia = Object.fromEntries(
+ matchers.map(([size, queryList]) => [queryList.media, size])
+ );
+
+ const size = matchers.find(([size, queryList]) => queryList.matches)[0];
+ store.set(size);
+
+ /** @type {(e: MediaQueryListEvent) => void} */
+ function handleChange({ matches, media }) {
+ const size = sizeByMedia[media];
+ if (matches) store.set(size);
+ }
+
+ matchers.forEach(([size, queryList]) =>
+ queryList.addEventListener("change", handleChange)
+ );
+
+ return () => {
+ matchers.forEach(([size, queryList]) =>
+ queryList.removeEventListener("change", handleChange)
+ );
+ };
+ });
+
+ return {
+ subscribe: store.subscribe,
+
+ /**
+ * Returns a store readable store that returns whether the current
+ * breakpoint is smaller than {@link size}.
+ * @param {import("./breakpoints").BreakpointSize} size Size to compare against.
+ */
+ smallerThan: (size) => {
+ checkSizeValid(size);
+ return derived(store, ($size) => breakpoints[$size] < breakpoints[size]);
+ },
+
+ /**
+ * Returns a store readable store that returns whether the current
+ * breakpoint is larger than {@link size}.
+ * @param {import("./breakpoints").BreakpointSize} size Size to compare against.
+ */
+ largerThan: (size) => {
+ checkSizeValid(size);
+ return derived(store, ($size) => breakpoints[$size] > breakpoints[size]);
+ },
+ };
+}
+
+function checkSizeValid(size) {
+ if (size in breakpoints == false)
+ throw new Error(`"${size}" is not a valid breakpoint size.`);
+}
diff --git a/src/Breakpoint/breakpoints.d.ts b/src/Breakpoint/breakpoints.d.ts
new file mode 100644
index 00000000..86da62ef
--- /dev/null
+++ b/src/Breakpoint/breakpoints.d.ts
@@ -0,0 +1,9 @@
+/**
+ * Pixel sizes of Carbon grid breakpoints.
+ * @type {Record}
+ */
+export const breakpoints: Record;
+
+export type BreakpointSize = "sm" | "md" | "lg" | "xlg" | "max";
+
+export type BreakpointValue = 320 | 672 | 1056 | 1312 | 1584;
diff --git a/src/Breakpoint/breakpoints.js b/src/Breakpoint/breakpoints.js
new file mode 100644
index 00000000..5773f066
--- /dev/null
+++ b/src/Breakpoint/breakpoints.js
@@ -0,0 +1,11 @@
+/**
+ * Pixel sizes of Carbon grid breakpoints.
+ * @type {Record}
+ */
+export const breakpoints = Object.freeze({
+ sm: 320,
+ md: 672,
+ lg: 1056,
+ xlg: 1312,
+ max: 1584,
+});
diff --git a/src/Breakpoint/index.d.ts b/src/Breakpoint/index.d.ts
new file mode 100644
index 00000000..e9046700
--- /dev/null
+++ b/src/Breakpoint/index.d.ts
@@ -0,0 +1,3 @@
+export { default as Breakpoint } from "./Breakpoint.svelte";
+export { breakpointObserver } from "./breakpointObserver";
+export { breakpoints } from "./breakpoints";
diff --git a/src/Breakpoint/index.js b/src/Breakpoint/index.js
index a84d174b..749b78c5 100644
--- a/src/Breakpoint/index.js
+++ b/src/Breakpoint/index.js
@@ -1 +1,3 @@
export { default as Breakpoint } from "./Breakpoint.svelte";
+export { breakpointObserver } from "./breakpointObserver";
+export { breakpoints } from "./breakpoints";
diff --git a/tests/Breakpoint.test.svelte b/tests/Breakpoint.test.svelte
index 2b5bef5b..cbad6dc0 100644
--- a/tests/Breakpoint.test.svelte
+++ b/tests/Breakpoint.test.svelte
@@ -1,14 +1,14 @@
{
console.log(e.detail);
}}"
>
diff --git a/types/Breakpoint/Breakpoint.svelte.d.ts b/types/Breakpoint/Breakpoint.svelte.d.ts
index b46f0c3e..3fd72642 100644
--- a/types/Breakpoint/Breakpoint.svelte.d.ts
+++ b/types/Breakpoint/Breakpoint.svelte.d.ts
@@ -22,15 +22,10 @@ export interface BreakpointProps {
export default class Breakpoint extends SvelteComponentTyped<
BreakpointProps,
{
- match: CustomEvent<{
+ change: CustomEvent<{
size: BreakpointSize;
breakpointValue: BreakpointValue;
}>;
},
{ default: { size: BreakpointSize; sizes: Record } }
-> {
- /**
- * Reference the Carbon grid breakpoints
- */
- breakpoints: Record;
-}
+> {}