feat: add LocalStorage component

This commit is contained in:
Eric Y Liu 2021-03-13 14:38:08 -08:00
commit 1f7fe60695
11 changed files with 199 additions and 3 deletions

View file

@ -1,6 +1,6 @@
# Component Index
> 159 components exported from carbon-components-svelte@0.29.2.
> 160 components exported from carbon-components-svelte@0.29.2.
## Components
@ -73,6 +73,7 @@
- [`ListBoxSelection`](#listboxselection)
- [`ListItem`](#listitem)
- [`Loading`](#loading)
- [`LocalStorage`](#localstorage)
- [`Modal`](#modal)
- [`ModalBody`](#modalbody)
- [`ModalFooter`](#modalfooter)
@ -2044,6 +2045,26 @@ None.
None.
## `LocalStorage`
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------- | :--------------- | :------- | :------------------ | -------------------------------- | ----------------------------- |
| value | <code>let</code> | Yes | <code>any</code> | <code>""</code> | Provide a value to persist |
| key | <code>let</code> | No | <code>string</code> | <code>"local-storage-key"</code> | Specify the local storage key |
### Slots
None.
### Events
| Event name | Type | Detail |
| :--------- | :--------- | :------------------------------------------- |
| save | dispatched | <code>any</code> |
| update | dispatched | <code>{ prevValue: any; value: any; }</code> |
## `Modal`
### Props

View file

@ -1,5 +1,5 @@
{
"total": 159,
"total": 160,
"components": [
{
"moduleName": "Accordion",
@ -4821,6 +4821,42 @@
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
},
{
"moduleName": "LocalStorage",
"filePath": "src/LocalStorage/LocalStorage.svelte",
"props": [
{
"name": "key",
"kind": "let",
"description": "Specify the local storage key",
"type": "string",
"value": "\"local-storage-key\"",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "value",
"kind": "let",
"description": "Provide a value to persist",
"type": "any",
"value": "\"\"",
"isFunction": false,
"constant": false,
"reactive": true
}
],
"slots": [],
"events": [
{ "type": "dispatched", "name": "save", "detail": "any" },
{
"type": "dispatched",
"name": "update",
"detail": "{ prevValue: any; value: any; }"
}
],
"typedefs": []
},
{
"moduleName": "Modal",
"filePath": "src/Modal/Modal.svelte",

View file

@ -20,7 +20,7 @@
import Footer from "../components/Footer.svelte";
const deprecated = ["ToggleSmall", "Icon"];
const new_components = ["ImageLoader"];
const new_components = ["ImageLoader", "LocalStorage"];
let isOpen = false;
let isSideNavOpen = true;

View file

@ -0,0 +1,9 @@
<script>
import Preview from "../../components/Preview.svelte";
</script>
This utility component wraps the [Window.localStorage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to persist values by key. This is useful for non-persistent data (e.g., dark mode toggle).
### Reactive example
<FileSource src="/framed/LocalStorage/LocalStorage" />

View file

@ -0,0 +1,29 @@
<script>
import { LocalStorage, Toggle, Button } from "carbon-components-svelte";
let storage;
let toggled = false;
let events = [];
$: document.documentElement.setAttribute("theme", toggled ? "g100" : "white");
</script>
<LocalStorage
bind:this="{storage}"
key="dark-mode"
bind:value="{toggled}"
on:save="{() => {
events = [...events, { event: 'on:save' }];
}}"
on:update="{({ detail }) => {
events = [...events, { event: 'on:update', detail }];
}}"
/>
<Toggle size="sm" labelText="Dark mode" bind:toggled />
<br />
<pre>
{JSON.stringify(events, null, 2)}
</pre>

View file

@ -0,0 +1,55 @@
<script>
/**
* @event {any} save
* @event {{ prevValue: any; value: any; }} update
*/
/**
* Specify the local storage key
*/
export let key = "local-storage-key";
/**
* Provide a value to persist
* @type {any}
*/
export let value = "";
import { onMount, afterUpdate, createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
let prevValue = value;
function setItem() {
if (typeof value === "object") {
localStorage.setItem(key, JSON.stringify(value));
} else {
localStorage.setItem(key, value);
}
}
onMount(() => {
const item = localStorage.getItem(key);
if (item != null) {
try {
value = JSON.parse(item);
} catch (e) {
value = item;
}
} else {
setItem(value);
dispatch("save");
}
});
afterUpdate(() => {
if (prevValue !== value) {
setItem(value);
dispatch("update", { prevValue, value });
}
prevValue = value;
});
</script>

View file

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

View file

@ -61,6 +61,7 @@ export {
} from "./ListBox";
export { ListItem } from "./ListItem";
export { Loading } from "./Loading";
export { LocalStorage } from "./LocalStorage";
export { MultiSelect } from "./MultiSelect";
export { Modal } from "./Modal";
export {

View file

@ -0,0 +1,18 @@
<script lang="ts">
import { LocalStorage } from "../types";
let storage;
let toggled = false;
</script>
<LocalStorage
bind:this="{storage}"
key="dark-mode"
bind:value="{toggled}"
on:save="{() => {
events = [...events, { event: 'on:save' }];
}}"
on:update="{({ detail }) => {
events = [...events, { event: 'on:update', detail }];
}}"
/>

25
types/LocalStorage/LocalStorage.d.ts vendored Normal file
View file

@ -0,0 +1,25 @@
/// <reference types="svelte" />
import { SvelteComponentTyped } from "svelte";
export interface LocalStorageProps {
/**
* Specify the local storage key
* @default "local-storage-key"
*/
key?: string;
/**
* Provide a value to persist
* @default ""
*/
value?: any;
}
export default class LocalStorage extends SvelteComponentTyped<
LocalStorageProps,
{
save: CustomEvent<any>;
update: CustomEvent<{ prevValue: any; value: any }>;
},
{}
> {}

1
types/index.d.ts vendored
View file

@ -69,6 +69,7 @@ export { default as ListBoxMenuItem } from "./ListBox/ListBoxMenuItem";
export { default as ListBoxSelection } from "./ListBox/ListBoxSelection";
export { default as ListItem } from "./ListItem/ListItem";
export { default as Loading } from "./Loading/Loading";
export { default as LocalStorage } from "./LocalStorage/LocalStorage";
export { default as MultiSelect } from "./MultiSelect/MultiSelect";
export { default as Modal } from "./Modal/Modal";
export { default as ToastNotification } from "./Notification/ToastNotification";