feat(breakpoint): add Breakpoint

This commit is contained in:
Eric Y Liu 2021-07-07 11:59:37 -07:00
commit cf384dec0a
10 changed files with 264 additions and 2 deletions

View file

@ -1,6 +1,6 @@
# Component Index
> 170 components exported from carbon-components-svelte@0.39.0.
> 171 components exported from carbon-components-svelte@0.39.0.
## Components
@ -11,6 +11,7 @@
- [`Breadcrumb`](#breadcrumb)
- [`BreadcrumbItem`](#breadcrumbitem)
- [`BreadcrumbSkeleton`](#breadcrumbskeleton)
- [`Breakpoint`](#breakpoint)
- [`Button`](#button)
- [`ButtonSet`](#buttonset)
- [`ButtonSkeleton`](#buttonskeleton)
@ -344,6 +345,36 @@ None.
| mouseenter | forwarded | -- |
| mouseleave | forwarded | -- |
## `Breakpoint`
### Types
```ts
export type BreakpointSize = "sm" | "md" | "lg" | "xlg" | "max";
export type BreakpointValue = 320 | 672 | 1056 | 1312 | 1584;
```
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :---------- | :----------------- | :------- | :--------------------------------------------------- | ------------------------------------------------------------------------- | ----------- |
| sizes | <code>let</code> | Yes | <code>Record<BreakpointSize, boolean></code> | <code>{ sm: false, md: false, lg: false, xlg: false, max: false, }</code> | -- |
| size | <code>let</code> | Yes | <code>BreakpointSize</code> | -- | -- |
| breakpoints | <code>const</code> | No | <code>Record<BreakpointSize, BreakpointValue></code> | <code>{ sm: 320, md: 672, lg: 1056, xlg: 1312, max: 1584, }</code> | -- |
### Slots
| Slot name | Default | Props | Fallback |
| :-------- | :------ | :----------------------------------------------------------------------------- | :------- |
| -- | Yes | <code>{ sizes: Record<BreakpointSize, boolean>, size: BreakpointSize } </code> | -- |
### Events
| Event name | Type | Detail |
| :--------- | :--------- | :----------------------------------------------------------------------- |
| match | dispatched | <code>{ size: BreakpointSize; breakpointValue: BreakpointValue; }</code> |
## `Button`
### Props

View file

@ -1,5 +1,5 @@
{
"total": 170,
"total": 171,
"components": [
{
"moduleName": "Accordion",
@ -344,6 +344,64 @@
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
},
{
"moduleName": "Breakpoint",
"filePath": "src/Breakpoint/Breakpoint.svelte",
"props": [
{
"name": "size",
"kind": "let",
"type": "BreakpointSize",
"isFunction": false,
"constant": false,
"reactive": true
},
{
"name": "sizes",
"kind": "let",
"type": "Record<BreakpointSize, boolean>",
"value": "{ sm: false, md: false, lg: false, xlg: false, max: false, }",
"isFunction": false,
"constant": false,
"reactive": true
},
{
"name": "breakpoints",
"kind": "const",
"type": "Record<BreakpointSize, BreakpointValue>",
"value": "{ sm: 320, md: 672, lg: 1056, xlg: 1312, max: 1584, }",
"isFunction": false,
"constant": true,
"reactive": false
}
],
"slots": [
{
"name": "__default__",
"default": true,
"slot_props": "{ sizes: Record<BreakpointSize, boolean>, size: BreakpointSize }"
}
],
"events": [
{
"type": "dispatched",
"name": "match",
"detail": "{ size: BreakpointSize; breakpointValue: BreakpointValue; }"
}
],
"typedefs": [
{
"type": "\"sm\" | \"md\" | \"lg\" | \"xlg\" | \"max\"",
"name": "BreakpointSize",
"ts": "type BreakpointSize = \"sm\" | \"md\" | \"lg\" | \"xlg\" | \"max\""
},
{
"type": "320 | 672 | 1056 | 1312 | 1584",
"name": "BreakpointValue",
"ts": "type BreakpointValue = 320 | 672 | 1056 | 1312 | 1584"
}
]
},
{
"moduleName": "Button",
"filePath": "src/Button/Button.svelte",

View file

@ -0,0 +1,21 @@
<script>
import {
Breakpoint
} from "carbon-components-svelte";
import Preview from "../../components/Preview.svelte";
</script>
The [Carbon Design System grid implementation](https://carbondesignsystem.com/guidelines/2x-grid/implementation#responsive-options) defines five responsive breakpoints:
- Small (`sm`): less than 672px
- Medium (`md`): 672 - 1056px
- Large (`lg`): 1056 - 1312px
- X-Large (`xlg`): 1312 - 1584px
- Max (`max`): greater than 1584px
This utility component uses the [Window.matchMedia API](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) to declaratively determine the current Carbon breakpoint size.
### Default
<FileSource src="/framed/Breakpoint/Breakpoint" />

View file

@ -0,0 +1,14 @@
<script>
import { Breakpoint } from "carbon-components-svelte";
let size;
let events = [];
</script>
<Breakpoint bind:size on:match="{(e) => (events = [...events, e.detail])}" />
<h1>{size}</h1>
<pre>
{JSON.stringify(events,null, 2)}
</pre>

View file

@ -0,0 +1,88 @@
<script>
/**
* @typedef {"sm" | "md" | "lg" | "xlg" | "max"} BreakpointSize
* @typedef {320 | 672 | 1056 | 1312 | 1584} BreakpointValue
* @event {{ size: BreakpointSize; breakpointValue: BreakpointValue; }} match
*/
/** @type {BreakpointSize} */
export let size = undefined;
/** @type {Record<BreakpointSize, boolean>} */
export let sizes = {
sm: false,
md: false,
lg: false,
xlg: false,
max: false,
};
/** @type {Record<BreakpointSize, BreakpointValue>} */
export const breakpoints = {
sm: 320,
md: 672,
lg: 1056,
xlg: 1312,
max: 1584,
};
import { createEventDispatcher, onMount } from "svelte";
const dispatch = createEventDispatcher();
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;
}
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";
if (size) dispatch("match", { size, breakpointValue: breakpoints[size] });
}
</script>
<slot sizes="{sizes}" size="{size}" />

1
src/Breakpoint/index.js Normal file
View file

@ -0,0 +1 @@
export { default as Breakpoint } from "./Breakpoint.svelte";

View file

@ -1,6 +1,7 @@
export { Accordion, AccordionItem, AccordionSkeleton } from "./Accordion";
export { AspectRatio } from "./AspectRatio";
export { Breadcrumb, BreadcrumbItem, BreadcrumbSkeleton } from "./Breadcrumb";
export { Breakpoint } from "./Breakpoint";
export { Button, ButtonSkeleton, ButtonSet } from "./Button";
export { Checkbox, CheckboxSkeleton } from "./Checkbox";
export { ContentSwitcher, Switch } from "./ContentSwitcher";

View file

@ -0,0 +1,15 @@
<script lang="ts">
import { Breakpoint } from "../types";
let size;
</script>
<Breakpoint
bind:size
let:size="{currentSize}"
on:match="{(e) => {
console.log(e.detail);
}}"
>
{currentSize}
</Breakpoint>

32
types/Breakpoint/Breakpoint.d.ts vendored Normal file
View file

@ -0,0 +1,32 @@
/// <reference types="svelte" />
import { SvelteComponentTyped } from "svelte";
export type BreakpointSize = "sm" | "md" | "lg" | "xlg" | "max";
export type BreakpointValue = 320 | 672 | 1056 | 1312 | 1584;
export interface BreakpointProps {
size?: BreakpointSize;
/**
* @default { sm: false, md: false, lg: false, xlg: false, max: false, }
*/
sizes?: Record<BreakpointSize, boolean>;
/**
* @constant
* @default { sm: 320, md: 672, lg: 1056, xlg: 1312, max: 1584, }
*/
breakpoints?: { sm: 320; md: 672; lg: 1056; xlg: 1312; max: 1584 };
}
export default class Breakpoint extends SvelteComponentTyped<
BreakpointProps,
{
match: CustomEvent<{
size: BreakpointSize;
breakpointValue: BreakpointValue;
}>;
},
{ default: { sizes: Record<BreakpointSize, boolean>; size: BreakpointSize } }
> {}

1
types/index.d.ts vendored
View file

@ -5,6 +5,7 @@ export { default as AspectRatio } from "./AspectRatio/AspectRatio";
export { default as Breadcrumb } from "./Breadcrumb/Breadcrumb";
export { default as BreadcrumbItem } from "./Breadcrumb/BreadcrumbItem";
export { default as BreadcrumbSkeleton } from "./Breadcrumb/BreadcrumbSkeleton";
export { default as Breakpoint } from "./Breakpoint/Breakpoint";
export { default as Button } from "./Button/Button";
export { default as ButtonSkeleton } from "./Button/ButtonSkeleton";
export { default as ButtonSet } from "./Button/ButtonSet";