@axel669/zephyr 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +32 -0
  3. package/readme.md +44 -0
  4. package/src/avatar.svelte +54 -0
  5. package/src/badge.svelte +40 -0
  6. package/src/button.svelte +80 -0
  7. package/src/chip.svelte +53 -0
  8. package/src/composed/data-table.svelte +150 -0
  9. package/src/composed/entry-button.svelte +66 -0
  10. package/src/composed/toast/message.svelte +44 -0
  11. package/src/composed/toast.svelte +108 -0
  12. package/src/dialog.svelte +53 -0
  13. package/src/drawer.svelte +121 -0
  14. package/src/flex.svelte +57 -0
  15. package/src/grid.svelte +66 -0
  16. package/src/handler$.mjs +68 -0
  17. package/src/icon.svelte +34 -0
  18. package/src/index.mjs +85 -0
  19. package/src/inline-dialog.svelte +23 -0
  20. package/src/input/area.svelte +97 -0
  21. package/src/input/elems.mjs +7 -0
  22. package/src/input/email.svelte +102 -0
  23. package/src/input/file.svelte +81 -0
  24. package/src/input/number.svelte +102 -0
  25. package/src/input/password.svelte +99 -0
  26. package/src/input/search.svelte +102 -0
  27. package/src/input/text.svelte +102 -0
  28. package/src/link.svelte +62 -0
  29. package/src/modal.svelte +68 -0
  30. package/src/notification.svelte +57 -0
  31. package/src/paper.svelte +114 -0
  32. package/src/popover.svelte +60 -0
  33. package/src/progress.svelte +60 -0
  34. package/src/radio.svelte +82 -0
  35. package/src/screen.svelte +69 -0
  36. package/src/select.svelte +121 -0
  37. package/src/table.svelte +69 -0
  38. package/src/tabs.svelte +77 -0
  39. package/src/text.svelte +49 -0
  40. package/src/titlebar.svelte +69 -0
  41. package/src/toaster.svelte +42 -0
  42. package/src/toggle.svelte +90 -0
  43. package/src/tooltip.svelte +45 -0
  44. package/src/vars.mjs +61 -0
  45. package/src/wsx.mjs +45 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Chris Morgan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@axel669/zephyr",
3
+ "version": "0.1.1",
4
+ "description": "",
5
+ "main": "src/index.mjs",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1",
9
+ "demo": "rollup -c test/rollup.config.mjs"
10
+ },
11
+ "keywords": [],
12
+ "author": "",
13
+ "license": "MIT",
14
+ "dependencies": {
15
+ "@axel669/windstorm": "^0.1.10",
16
+ "@labyrinthos/asuid": "^0.2.0"
17
+ },
18
+ "peerDependencies": {
19
+ "svelte": "^3.58.0"
20
+ },
21
+ "devDependencies": {
22
+ "@axel669/ipsen": "^0.3.1",
23
+ "@axel669/rollup-html-input": "^0.1.2",
24
+ "@rollup/plugin-node-resolve": "^15.0.2",
25
+ "@rollup/plugin-terser": "^0.4.0",
26
+ "rollup": "^3.20.2",
27
+ "rollup-plugin-svelte": "^7.1.4"
28
+ },
29
+ "files": [
30
+ "src/"
31
+ ]
32
+ }
package/readme.md ADDED
@@ -0,0 +1,44 @@
1
+
2
+
3
+ # Zephyr
4
+ Zephyr is a svelte binding for the
5
+ [Windstorm](https://www.npmjs.com/package/@axel669/windstorm)
6
+ library.
7
+
8
+ [Docs Here](https://svelte-wind.axel669.net)
9
+
10
+ ## Installation
11
+ Zephyr can be installed through npm (or the variants like yarn, pnpm, etc).
12
+
13
+ ```bash
14
+ npm install @axel669/svelte-wind
15
+ ```
16
+
17
+ ## Usage
18
+ Components can be imported individually from the library for tree-shaking, or
19
+ the entire lib can imported at once, but I dunno how big that bundle will be.
20
+
21
+ ```svelte
22
+ <script>
23
+ // individual import for tree shaking
24
+ import { Button } from "@axel69/svelte-wind"
25
+
26
+ // bring the whole thing to keep it simple
27
+ import * as Wind from "@axel69/svelte-wind"
28
+ </script>
29
+
30
+ <!-- the wsx action can be used to setup the ws-x needed for the body -->
31
+ <svelte:body use:wsx={{theme, "@app": true}} />
32
+
33
+ <Button on:click={stuff}>
34
+ I'm a button!
35
+ </Button>
36
+
37
+ <Wind.Button on:click={stuff}>
38
+ I'm also button!
39
+ </Wind.Button>
40
+ ```
41
+
42
+ ### Svelte Config
43
+ No special configuration of svelte is required, nor is there a separate plugin
44
+ that needs to be added. Just have svelte and you're good to go.
@@ -0,0 +1,54 @@
1
+ <script>
2
+ /*md
3
+ [@] Components/Data Display/Avatar
4
+
5
+ # Avatar
6
+
7
+ Displays an image or text in a circular container.
8
+
9
+ ## Base
10
+ [Windstorm Avatar](https://axel669.github.io/lib.windstorm/#components-avatar)
11
+
12
+ ## Props
13
+ All [windstorm functions](https://axel669.github.io/lib.windstorm/#css-shorthands)
14
+ are supported.
15
+
16
+ - ### alt `string`
17
+ Alt text for the image. Has no effect if image prop is not used.
18
+ - ### color `string`
19
+ Sets `$color`
20
+ - ### image `string`
21
+ An image url. If no url is provided the text property is displayed.
22
+ - ### text `string`
23
+ Text to show in the avatar area if image is not used.
24
+
25
+ ## Example
26
+ ```svelte
27
+ <Avatar image="url" />
28
+ <Avatar image="url" alt="text" />
29
+ <Avatar text="Hi" color="primary" />
30
+ ```
31
+ */
32
+
33
+ import wsx from "./wsx.mjs"
34
+
35
+ export let alt = ""
36
+ export let image = null
37
+
38
+ export let text = ""
39
+
40
+ export let color = false
41
+
42
+ $: wind = {
43
+ $color: color,
44
+ ...$$restProps
45
+ }
46
+ </script>
47
+
48
+ <ws-avatar use:wsx={wind}>
49
+ {#if image !== null}
50
+ <img src={image} {alt} />
51
+ {:else}
52
+ {text}
53
+ {/if}
54
+ </ws-avatar>
@@ -0,0 +1,40 @@
1
+ <script>
2
+ /*md
3
+ [@] Components/Data Display/Badge
4
+
5
+ # Badge
6
+ Adds a small badge over the upper-right corner of some content.
7
+
8
+ ## Base
9
+ [Windstorm Badge](https://axel669.github.io/lib.windstorm/#components-badge)
10
+
11
+ ## Props
12
+ All [windstorm functions](https://axel669.github.io/lib.windstorm/#css-shorthands)
13
+ are supported.
14
+
15
+ - ### color `string`
16
+ Sets `$color`
17
+ - ### text `string`
18
+ The badge text.
19
+
20
+ ## Example
21
+ ```svelte
22
+ <Badge text="100">
23
+ Unread Messages
24
+ </Badge>
25
+ <Badge text="1k+" color="warning">
26
+ <button>Clickable Content</button>
27
+ </Badge>
28
+ ```
29
+ */
30
+ import wsx from "./wsx.mjs"
31
+
32
+ export let color = "default"
33
+ export let text = ""
34
+
35
+ $: wind = { $color: color, ...$$restProps }
36
+ </script>
37
+
38
+ <ws-badge ws-text={text} use:wsx={wind}>
39
+ <slot />
40
+ </ws-badge>
@@ -0,0 +1,80 @@
1
+ <script>
2
+ /*md
3
+ [@] Components/Button
4
+
5
+ # Button
6
+
7
+ Basic clickable component for handling user interaction.
8
+
9
+ ## Base
10
+ [Windstorm Button](https://axel669.github.io/lib.windstorm/#components-button)
11
+
12
+ ## Props
13
+ All [windstorm functions](https://axel669.github.io/lib.windstorm/#css-shorthands)
14
+ are supported.
15
+
16
+ - ### color `string`
17
+ Sets `$color`
18
+ - ### compact `bool`
19
+ Sets `$compact`
20
+ - ### for `string`
21
+ The ID of a dom element that the button is tied to. Only works with
22
+ label buttons.
23
+ - ### label `string`
24
+ If true, the button will be displayed in the DOM using a `<label>`
25
+ element instead of a `<button>`.
26
+ - ### variant `string`
27
+ Sets the button type to `@<variant>` (ex: "flat" -> `@flat`). Default
28
+ variant is "flat". Currently supports "flat", "fill", "outline".
29
+
30
+ ## Events
31
+ - click
32
+
33
+ ## Example
34
+ ```svelte
35
+ <Button on:click={action}>
36
+ Flat Button
37
+ </Button>
38
+ <Button on:click={action} variant="outline">
39
+ Outlined Button
40
+ </Button>
41
+ <Button on:click={action} variant="fill" color="danger">
42
+ Filled Button
43
+ </Button>
44
+
45
+ <Button label for="thing">
46
+ Toggle
47
+ </Button>
48
+ <input type="checkbox" id="toggle" />
49
+ ```
50
+ */
51
+
52
+ import wsx from "./wsx.mjs"
53
+
54
+ export let color = "default"
55
+ export let compact = false
56
+ export let variant = "flat"
57
+
58
+ let _for = ""
59
+ export { _for as for }
60
+ export let label = false
61
+
62
+ $: wind = {
63
+ [`@${variant}`]: true,
64
+ $color: color,
65
+ $compact: compact,
66
+ "@button": label,
67
+ ...$$restProps
68
+ }
69
+ </script>
70
+
71
+ {#if label === true}
72
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
73
+ <label use:wsx={wind} for={_for} on:click|stopPropagation>
74
+ <slot />
75
+ </label>
76
+ {:else}
77
+ <button use:wsx={wind} on:click|stopPropagation>
78
+ <slot />
79
+ </button>
80
+ {/if}
@@ -0,0 +1,53 @@
1
+ <script>
2
+ /*md
3
+ [@] Components/Data Display/Chip
4
+
5
+ # Chip
6
+ Shows a small piece of information that is separate from the surrounding
7
+ info and optionally allows interaction.
8
+
9
+ ## Base
10
+ [Windstorm Chip](https://axel669.github.io/lib.windstorm/#components-chip)
11
+
12
+ ## Props
13
+ All [windstorm functions](https://axel669.github.io/lib.windstorm/#css-shorthands)
14
+ are supported.
15
+
16
+ - ### color `string`
17
+ Sets `$color`
18
+ - ### clickable `bool`
19
+ If true, the chip will have the button ripple effect when clicked.
20
+ - ### variant `string`
21
+ Sets the chip type to `@<variant>` (ex: "fill" -> `@fill`). Default
22
+ variant is "outline". Currently supports "fill", "outline".
23
+
24
+ ## Events
25
+ - click
26
+
27
+ ## Example
28
+ ```svelte
29
+ Emails:
30
+ <Chip clickable>admin@site.com</Chip>
31
+ <Chip clickable color="warning">weirdge@site.com</Chip>
32
+ <Chip color="primary">required@site.io</Chip>
33
+ ```
34
+ */
35
+
36
+ import wsx from "./wsx.mjs"
37
+
38
+ export let color = "default"
39
+ export let clickable = false
40
+ export let variant = "outline"
41
+
42
+ $: wind = {
43
+ [`@${variant}`]: true,
44
+ $color: color,
45
+ $click: clickable,
46
+ ...$$restProps
47
+ }
48
+ </script>
49
+
50
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
51
+ <ws-chip use:wsx={wind} on:click>
52
+ <slot />
53
+ </ws-chip>
@@ -0,0 +1,150 @@
1
+ <script>
2
+ /*md
3
+ [@] Components/Data Display/DataTable
4
+
5
+ # DataTable
6
+
7
+ The DataTable is a more advanced way to show data on screen. Underneath is
8
+ a table element like the Table component, but the DataTable supports
9
+ more fine-grained control over how data is passed, how rows are displayed,
10
+ and pagination.
11
+
12
+ > If pagination is not needed, the DataTable may not be necessary as it will
13
+ > only be shortcutting data formatting at that point.
14
+
15
+ ## Props
16
+ All [windstorm functions](https://axel669.github.io/lib.windstorm/#css-shorthands)
17
+ are supported.
18
+
19
+ - ### color
20
+ Sets `$color`
21
+ - ### cols `Array`
22
+ The columns that should be displayed. Should be in the format of
23
+ `{ label, width?, format?, prop? }`. If a format function is provided,
24
+ it is called on each cell to determine a cells value as
25
+ `format(rowItem)`, otherwise the property defined in prop will be used
26
+ as the cell value.
27
+ - ### data `Array`
28
+ The data to display. Each item in the array can be in either the same
29
+ format as the Table, or any kind of object if column format functions
30
+ are used.
31
+ - ### cellWSX `function`
32
+ If given, this function will be called for each cell, and should return
33
+ an object that will be passed to the `wsx` action for each <td>
34
+ generated. The function is passed `(rowvalue, rowNum, col)`.
35
+ - ### rowWSX `function`
36
+ If given, this function will be called for each row, and should return
37
+ an object that will be passed to the `wsx` action for each <tr>
38
+ generated. The function is passed `(rowValue, rowNum)`.
39
+ - ### page
40
+ The current page of data being viewed. Can be bound, or set to control
41
+ which page is displayed
42
+ - ### pageSize
43
+ The number of items to show on each page. Default is 10
44
+ - ### rowHeight
45
+ The height of each row. Can be set individually through rowWSX, but
46
+ that may lead to a degraded user experience if the rows change size
47
+ while paging through the data
48
+
49
+ ## Usage
50
+ ```js
51
+ let page
52
+ const cols = [
53
+ { label: "N", prop: "a" },
54
+ { label: "Squared", prop: "b" },
55
+ { label: "Cubed", format: row => `^3 = ${row.c}` },
56
+ ]
57
+ const data = [
58
+ { a: 1, b: 1 ** 2, c: 1 ** 3 },
59
+ { a: 2, b: 2 ** 2, c: 2 ** 3 },
60
+ { a: 3, b: 3 ** 2, c: 3 ** 3 },
61
+ { a: 4, b: 4 ** 2, c: 4 ** 3 },
62
+ { a: 5, b: 5 ** 2, c: 5 ** 3 },
63
+ { a: 6, b: 6 ** 2, c: 6 ** 3 },
64
+ { a: 7, b: 7 ** 2, c: 7 ** 3 },
65
+ { a: 8, b: 8 ** 2, c: 8 ** 3 },
66
+ { a: 9, b: 9 ** 2, c: 9 ** 3 },
67
+ { a: 10, b: 10 ** 2, c: 10 ** 3 },
68
+ { a: 11, b: 11 ** 2, c: 11 ** 3 },
69
+ { a: 12, b: 12 ** 2, c: 12 ** 3 },
70
+ { a: 13, b: 13 ** 2, c: 13 ** 3 },
71
+ ]
72
+ ```
73
+ ```svelte
74
+ <DataTable {cols} {data} color="warning" pageSize={3} bind:page />
75
+ ```
76
+ */
77
+
78
+ import Button from "../button.svelte"
79
+ import Icon from "../icon.svelte"
80
+ import Paper from "../paper.svelte"
81
+ import Text from "../text.svelte"
82
+
83
+ import Grid from "../grid.svelte"
84
+
85
+ import wsx from "../wsx.mjs"
86
+
87
+ export let color = false
88
+ export let data = []
89
+ export let cols = []
90
+ export let rowWSX = null
91
+ export let cellWSX = null
92
+ export let pageSize = 10
93
+ export let page = 0
94
+ export let rowHeight = "40px"
95
+
96
+ $: wind = {
97
+ $color: color,
98
+ ...$$restProps,
99
+ }
100
+
101
+ $: rows = Array.from(
102
+ { length: pageSize },
103
+ (_, i) => data[page * pageSize + i]
104
+ )
105
+ $: pageCount = Math.ceil(data.length / pageSize)
106
+
107
+ const prev = () => page = Math.max(0, page - 1)
108
+ const next = () => page = Math.min(pageCount - 1, page + 1)
109
+ </script>
110
+
111
+ <Paper card {color} lprops={{ "fl-cr-a": "stretch", p: "0px" }}>
112
+ <table use:wsx={wind}>
113
+ <thead>
114
+ <tr>
115
+ {#each cols as col}
116
+ <th use:wsx={{ w: col.width, h: rowHeight }}>{col.label}</th>
117
+ {/each}
118
+ </tr>
119
+ </thead>
120
+ <tbody>
121
+ {#each rows as row, rowNum}
122
+ {#if row === undefined}
123
+ <tr use:wsx={{ h: rowHeight }}></tr>
124
+ {:else}
125
+ <tr use:wsx={{ h: rowHeight, ...rowWSX?.(row, rowNum) }}>
126
+ {#each cols as col, colNum}
127
+ <td use:wsx={cellWSX?.(row, rowNum, col)}>
128
+ {(col.format !== undefined)
129
+ ? col.format?.(row)
130
+ : row[col.prop]
131
+ }
132
+ </td>
133
+ {/each}
134
+ </tr>
135
+ {/if}
136
+ {/each}
137
+ </tbody>
138
+ </table>
139
+ <Grid slot="footer" gr-col="min-content min-content min-content 1fr">
140
+ <Button on:click={prev}>
141
+ <Icon name="arrow-big-left" />
142
+ </Button>
143
+ <Button on:click={next}>
144
+ <Icon name="arrow-big-right" />
145
+ </Button>
146
+ <Text adorn t-ws="nowrap">
147
+ Page {page + 1} / {pageCount}
148
+ </Text>
149
+ </Grid>
150
+ </Paper>
@@ -0,0 +1,66 @@
1
+ <script>
2
+ /*md
3
+ [@] Components/EntryButton
4
+
5
+ # EntryButton
6
+
7
+ The EntryButton is a convenient way to display modals and screens over
8
+ content without needing to bind variables have lots of Modal elements in
9
+ addition to the buttons that show them.
10
+
11
+ ## Props
12
+
13
+ - ### component
14
+ The component to show when clicked
15
+ - ### props
16
+ The props to pass to the component when it is shown
17
+ - ### this
18
+ The wrapper for the component. Default is Modal but any component that
19
+ has the same interface as Modal will work
20
+
21
+ ## Events
22
+ - ### entry
23
+ When the component is close the entry event is fired. The detail
24
+ property of the event will have the value from closing it
25
+
26
+ ## Usage
27
+ ```svelte
28
+ <EntryButton component={Subscreen} on:entry={console.log}>
29
+ Open Subscreen
30
+ </EntryButton>
31
+ <EntryButton component={CoolDialog} on:entry={console.log}>
32
+ Open Subscreen
33
+ </EntryButton>
34
+ <EntryButton this={CoolModal} component={CustomThing} on:entry={console.log}>
35
+ Open Subscreen
36
+ </EntryButton>
37
+ ```
38
+ */
39
+
40
+ import { createEventDispatcher } from "svelte"
41
+
42
+ import Button from "../button.svelte"
43
+ import Modal from "../modal.svelte"
44
+ import { handler$ } from "../handler$.mjs"
45
+
46
+ export let component
47
+ export let props
48
+ let wrapper = Modal
49
+ export { wrapper as this }
50
+
51
+ const send = createEventDispatcher()
52
+
53
+ let element = null
54
+ const open = handler$(
55
+ async (props) => {
56
+ const result = await element.show(props)
57
+ send("entry", result)
58
+ }
59
+ )
60
+ </script>
61
+
62
+ <Button {...$$restProps} on:click={open(props)}>
63
+ <slot />
64
+ </Button>
65
+
66
+ <svelte:component this={wrapper} {component} bind:this={element} />
@@ -0,0 +1,44 @@
1
+ <script>
2
+ /*md
3
+ [@] Components/ToastMessage
4
+
5
+ # ToastMessage
6
+
7
+ The default component for Toast to show messages with
8
+
9
+ ## Props
10
+ - ### actionText `string`
11
+ If given, the message will have a button that can be clicked and will
12
+ use this text for the button text
13
+ - ### color `string`
14
+ Sets `$color`
15
+ - ### icon `string`
16
+ An icon to show with the message
17
+ - ### message `string`
18
+ The message to show
19
+ */
20
+
21
+ import { createEventDispatcher } from "svelte"
22
+
23
+ import Button from "../../button.svelte"
24
+ import Icon from "../../icon.svelte"
25
+ import Notification from "../../notification.svelte"
26
+
27
+ export let message = ""
28
+ export let icon = ""
29
+ export let color = false
30
+ export let actionText = null
31
+
32
+ const dispatch = createEventDispatcher()
33
+ const dismiss = () => dispatch("action", null)
34
+ const respond = () => dispatch("action", true)
35
+ </script>
36
+
37
+ <Notification {color} on:click={dismiss}>
38
+ <Icon name={icon}>{message}</Icon>
39
+ {#if actionText}
40
+ <Button {color} variant="fill" on:click={respond}>
41
+ {actionText}
42
+ </Button>
43
+ {/if}
44
+ </Notification>
@@ -0,0 +1,108 @@
1
+ <script context="module">
2
+ const genID = () => `${Date.now()}:${Math.random().toString(16)}`
3
+
4
+ const delays = {}
5
+ const delay = ({time, action, id}) => {
6
+ const trigger = () => {
7
+ const info = delays[id]
8
+ clearTimeout(info.id)
9
+ action()
10
+ delete delays[id]
11
+ }
12
+ const timeoutID = setTimeout(trigger, time)
13
+ delays[id] = { trigger, id: timeoutID }
14
+ }
15
+ delay.trigger = (id) => delays[id].trigger()
16
+ </script>
17
+
18
+ <script>
19
+ /*md
20
+ [@] Components/Toast
21
+
22
+ # Toast
23
+
24
+ Displays toast notifications along the edge of the screen.
25
+
26
+ ## Props
27
+ See the Toaster component. The Toast component is wrapper around it that
28
+ also controls the children being shown for convenience.
29
+
30
+ - ### component
31
+ The component to use as a wrapper for the messages. Defaults to the
32
+ ToastMessage component.
33
+
34
+ ## Functions
35
+ - ### show(duration, props)
36
+ Shows a toast notification that will disappear after the specified
37
+ duration (time in milliseconds). The props provided are passed to an
38
+ instance of the component specified in the props.
39
+
40
+ ## Events
41
+ - ### action(info)
42
+ Fired when a toast message is clicked. The info argument contains a
43
+ value property that is provided by the message component, and a copy
44
+ of the props passed to that instace.\\
45
+ For the default messages, the value will be `null` if no button was
46
+ clicked, and `true` if the action button was clicked. This allows
47
+ actions to be taken against interactions in the message without having
48
+ to bind all kinds of events or callbacks.
49
+
50
+ ## Usage
51
+ ```js
52
+ let toast = null
53
+ const notify = () => toast.show(5000, { message: "hi" })
54
+ ```
55
+ ```svelte
56
+ <Toast bind:this={toast} position="bc" />
57
+ ```
58
+ */
59
+ import { createEventDispatcher } from "svelte"
60
+ import { fade } from "svelte/transition"
61
+
62
+ import { eventHandler$ } from "../handler$.mjs"
63
+
64
+ import Toaster from "../toaster.svelte"
65
+
66
+ import ToastMessage from "./toast/message.svelte"
67
+
68
+ export let component = ToastMessage
69
+ export let position = "tc"
70
+
71
+ let items = []
72
+
73
+ const dispatch = createEventDispatcher()
74
+ const act = eventHandler$(
75
+ (evt, id, props) => {
76
+ delay.trigger(id)
77
+ dispatch(
78
+ "action",
79
+ { value: evt.detail, props }
80
+ )
81
+ }
82
+ )
83
+
84
+ export const show = (duration, props) => {
85
+ const id = genID()
86
+ items = [...items, { id, props }]
87
+ delay({
88
+ action: () => items = items.filter(
89
+ item => item.id !== id
90
+ ),
91
+ time: duration,
92
+ id,
93
+ })
94
+ }
95
+ export const clear = () => items = []
96
+ </script>
97
+
98
+ <Toaster {position} {...$$restProps}>
99
+ {#each items as {props, id} (id)}
100
+ <wsv-toast-wrapper ws-x="grid" transition:fade={{duration: 200}}>
101
+ <svelte:component
102
+ this={component}
103
+ {...props}
104
+ on:action={act(id, props)}
105
+ />
106
+ </wsv-toast-wrapper>
107
+ {/each}
108
+ </Toaster>