@axel669/zephyr 0.1.17 → 0.2.0-beta.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 (115) hide show
  1. package/LICENSE +21 -21
  2. package/package.json +10 -7
  3. package/readme.md +55 -44
  4. package/src/async/button.svelte +31 -0
  5. package/src/async/load-zone.svelte +17 -0
  6. package/src/composed/data-table/th.svelte +60 -0
  7. package/src/composed/data-table.md +83 -0
  8. package/src/composed/data-table.svelte +136 -150
  9. package/src/composed/entry-button.md +34 -0
  10. package/src/composed/entry-button.svelte +29 -68
  11. package/src/composed/table-functions.js +13 -0
  12. package/src/composed/toast/message.svelte +56 -44
  13. package/src/composed/toast.md +36 -0
  14. package/src/composed/toast.svelte +68 -108
  15. package/src/control/button.md +37 -0
  16. package/src/control/button.svelte +25 -0
  17. package/src/control/input.svelte +107 -0
  18. package/src/control/label.md +45 -0
  19. package/src/control/label.svelte +36 -0
  20. package/src/control/link.md +46 -0
  21. package/src/control/link.svelte +28 -0
  22. package/src/control/radio.md +56 -0
  23. package/src/control/radio.svelte +26 -0
  24. package/src/control/select.md +68 -0
  25. package/src/control/select.svelte +62 -0
  26. package/src/control/tabs.md +45 -0
  27. package/src/control/tabs.svelte +39 -0
  28. package/src/control/toggle.md +55 -0
  29. package/src/control/toggle.svelte +47 -0
  30. package/src/data-display/avatar.md +32 -0
  31. package/src/data-display/avatar.svelte +23 -0
  32. package/src/data-display/badge.md +24 -0
  33. package/src/data-display/badge.svelte +12 -0
  34. package/src/data-display/chip.md +32 -0
  35. package/src/data-display/chip.svelte +26 -0
  36. package/src/data-display/details.md +3 -0
  37. package/src/{details.svelte → data-display/details.svelte} +3 -3
  38. package/src/data-display/popover.md +28 -0
  39. package/src/data-display/popover.svelte +23 -0
  40. package/src/data-display/progress.md +42 -0
  41. package/src/data-display/progress.svelte +25 -0
  42. package/src/data-display/table.md +7 -0
  43. package/src/data-display/table.svelte +36 -0
  44. package/src/data-display/tooltip.md +25 -0
  45. package/src/data-display/tooltip.svelte +15 -0
  46. package/src/dialogs/alert.md +3 -0
  47. package/src/dialogs/alert.svelte +4 -4
  48. package/src/dialogs/confirm.md +3 -0
  49. package/src/dialogs/confirm.svelte +5 -5
  50. package/src/functions.md +77 -0
  51. package/src/handler$.mjs +20 -68
  52. package/src/index.mjs +58 -92
  53. package/src/info/icon.md +17 -0
  54. package/src/info/icon.svelte +9 -0
  55. package/src/info/notification.md +32 -0
  56. package/src/info/notification.svelte +16 -0
  57. package/src/info/titlebar.md +49 -0
  58. package/src/info/titlebar.svelte +18 -0
  59. package/src/info/toaster.md +22 -0
  60. package/src/info/toaster.svelte +14 -0
  61. package/src/inline-dialog.svelte +23 -23
  62. package/src/layout/dialog.md +34 -0
  63. package/src/layout/dialog.svelte +24 -0
  64. package/src/layout/drawer.md +61 -0
  65. package/src/layout/drawer.svelte +47 -0
  66. package/src/layout/flex.md +39 -0
  67. package/src/layout/flex.svelte +22 -0
  68. package/src/layout/grid.md +57 -0
  69. package/src/layout/grid.svelte +26 -0
  70. package/src/layout/modal.md +47 -0
  71. package/src/layout/modal.svelte +58 -0
  72. package/src/layout/paper.md +90 -0
  73. package/src/layout/paper.svelte +45 -0
  74. package/src/layout/screen.md +28 -0
  75. package/src/layout/screen.svelte +32 -0
  76. package/src/{circle-spinner.svelte → spinner/circle-spinner.svelte} +2 -2
  77. package/src/{hexagon-spinner.svelte → spinner/hexagon-spinner.svelte} +2 -2
  78. package/src/spinner/spinners.md +3 -0
  79. package/src/text.md +34 -0
  80. package/src/text.svelte +20 -49
  81. package/src/variant.mjs +12 -12
  82. package/src/wsx.mjs +24 -45
  83. package/src/avatar.svelte +0 -54
  84. package/src/badge.svelte +0 -40
  85. package/src/button.svelte +0 -86
  86. package/src/chip.svelte +0 -56
  87. package/src/dialog.svelte +0 -54
  88. package/src/drawer.svelte +0 -121
  89. package/src/flex.svelte +0 -57
  90. package/src/grid.svelte +0 -66
  91. package/src/icon.svelte +0 -34
  92. package/src/input/area.svelte +0 -98
  93. package/src/input/elems.mjs +0 -7
  94. package/src/input/email.svelte +0 -104
  95. package/src/input/file.svelte +0 -82
  96. package/src/input/number.svelte +0 -104
  97. package/src/input/password.svelte +0 -101
  98. package/src/input/search.svelte +0 -104
  99. package/src/input/text.svelte +0 -104
  100. package/src/link.svelte +0 -67
  101. package/src/modal.svelte +0 -73
  102. package/src/notification.svelte +0 -57
  103. package/src/paper.svelte +0 -127
  104. package/src/popover.svelte +0 -60
  105. package/src/progress.svelte +0 -60
  106. package/src/radio.svelte +0 -82
  107. package/src/screen.svelte +0 -69
  108. package/src/select.svelte +0 -122
  109. package/src/table.svelte +0 -69
  110. package/src/tabs.svelte +0 -78
  111. package/src/titlebar.svelte +0 -69
  112. package/src/toaster.svelte +0 -42
  113. package/src/toggle.svelte +0 -94
  114. package/src/tooltip.svelte +0 -45
  115. package/src/vars.mjs +0 -61
@@ -1,150 +1,136 @@
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>
1
+ <svelte:options immutable />
2
+
3
+ <script context="module">
4
+ // find the first filter in the list that returns false
5
+ const applyFilters = (data, filters) => data.filter(
6
+ (row) => {
7
+ for (const [filter, value] of filters) {
8
+ if (filter(row, value) === false) {
9
+ return false
10
+ }
11
+ }
12
+ return true
13
+ }
14
+ )
15
+ const noSort = {
16
+ direction: null,
17
+ func: (a, b) => 0,
18
+ base: null,
19
+ }
20
+
21
+ export const dtContext = Symbol("table key")
22
+ </script>
23
+
24
+ <script>
25
+ import { createEventDispatcher, setContext } from "svelte"
26
+ import { writable } from "svelte/store"
27
+
28
+ import Button from "../control/button.svelte"
29
+ import Icon from "../info/icon.svelte"
30
+ import Paper from "../layout/paper.svelte"
31
+ import Table from "../data-display/table.svelte"
32
+ import Text from "../text.svelte"
33
+
34
+ import Grid from "../layout/grid.svelte"
35
+
36
+ import wsx from "../wsx.mjs"
37
+ import { handler$, eventHandler$ } from "../handler$.mjs"
38
+
39
+ export let color = false
40
+ export let fillHeader = true
41
+ export let data = []
42
+ export let pageSize = 10
43
+ export let page = 0
44
+ export let rowHeight = "40px"
45
+
46
+ $: rows = Array.from(
47
+ { length: pageSize },
48
+ (_, i) => filteredData[page * pageSize + i]
49
+ )
50
+ $: rowCount = filteredData.length
51
+ $: pageCount = Math.ceil(rowCount / pageSize)
52
+ $: maxPage = Math.max(pageCount - 1, 0)
53
+
54
+ let sorting = noSort
55
+ let filters = new Map()
56
+ let filterFunctions = []
57
+
58
+ $: filteredData =
59
+ applyFilters(data, filterFunctions)
60
+ .sort(sorting.func)
61
+
62
+ const prev = () => page = Math.max(0, page - 1)
63
+ const next = () => page = Math.min(maxPage, page + 1)
64
+
65
+ const updateSort = (func) => {
66
+ if (sorting.base === func) {
67
+ if (sorting.direction === "desc") {
68
+ sorting = noSort
69
+ return
70
+ }
71
+ sorting = {
72
+ func: (a, b) => -func(a, b),
73
+ base: func,
74
+ direction: "desc"
75
+ }
76
+ return
77
+ }
78
+ sorting = {
79
+ func,
80
+ base: func,
81
+ direction: "asc",
82
+ }
83
+ }
84
+ const updateFilter = (func, value) => {
85
+ if (func === null) {
86
+ return
87
+ }
88
+ filters.set(func, value)
89
+ filterFunctions = [
90
+ ...filters.entries()
91
+ ]
92
+ }
93
+
94
+ const context = writable({})
95
+ $: $context = {
96
+ updateSort,
97
+ fillHeader,
98
+ sorting,
99
+ updateFilter,
100
+ }
101
+ setContext(dtContext, context)
102
+
103
+ const fire = createEventDispatcher()
104
+ const pass = handler$(
105
+ (row) => fire("row-click", row)
106
+ )
107
+ </script>
108
+
109
+ <Paper card {color} l-fl.cross="stretch" l-p="0px">
110
+ <Table data={rows} {color} {fillHeader} {...$$restProps}>
111
+ <tr ws-x="h.min[{rowHeight}]" slot="header">
112
+ <slot name="header">
113
+ <th>No Header Defined</th>
114
+ </slot>
115
+ </tr>
116
+ <tr ws-x="h[{rowHeight}]" slot="row" let:row>
117
+ <slot name="row" {row}>
118
+ <th>No Row Defined</th>
119
+ </slot>
120
+ </tr>
121
+ <tr ws-x="h[{rowHeight}]" slot="empty-row" />
122
+ </Table>
123
+ <Grid slot="footer" gr.cols="min-content min-content min-content 1fr">
124
+ {#if pageCount > 0}
125
+ <Button on:click={prev} disabled={page === 0}>
126
+ <Icon name="arrow-big-left" />
127
+ </Button>
128
+ <Button on:click={next} disabled={page === maxPage}>
129
+ <Icon name="arrow-big-right" />
130
+ </Button>
131
+ <Text adorn t.ws="nowrap">
132
+ Page {page + 1} / {pageCount}
133
+ </Text>
134
+ {/if}
135
+ </Grid>
136
+ </Paper>
@@ -0,0 +1,34 @@
1
+ # EntryButton
2
+
3
+ The EntryButton is a convenient way to display modals and screens over
4
+ content without needing to bind variables have lots of Modal elements in
5
+ addition to the buttons that show them.
6
+
7
+ ## Props
8
+
9
+ - ### component
10
+ The component to show when clicked
11
+ - ### props
12
+ The props to pass to the component when it is shown, or a function that
13
+ generates the props when called
14
+ - ### this
15
+ The wrapper for the component. Default is Modal but any component that
16
+ has the same interface as Modal will work
17
+
18
+ ## Events
19
+ - ### entry
20
+ When the component is close the entry event is fired. The detail
21
+ property of the event will have the value from closing it
22
+
23
+ ## Example
24
+ ```svelte
25
+ <EntryButton component={Subscreen} on:entry={console.log}>
26
+ Open Subscreen
27
+ </EntryButton>
28
+ <EntryButton component={CoolDialog} on:entry={console.log}>
29
+ Open Subscreen
30
+ </EntryButton>
31
+ <EntryButton this={CoolModal} component={CustomThing} on:entry={console.log}>
32
+ Open Subscreen
33
+ </EntryButton>
34
+ ```
@@ -1,68 +1,29 @@
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, or a function that
17
- generates the props when called
18
- - ### this
19
- The wrapper for the component. Default is Modal but any component that
20
- has the same interface as Modal will work
21
-
22
- ## Events
23
- - ### entry
24
- When the component is close the entry event is fired. The detail
25
- property of the event will have the value from closing it
26
-
27
- ## Usage
28
- ```svelte
29
- <EntryButton component={Subscreen} on:entry={console.log}>
30
- Open Subscreen
31
- </EntryButton>
32
- <EntryButton component={CoolDialog} on:entry={console.log}>
33
- Open Subscreen
34
- </EntryButton>
35
- <EntryButton this={CoolModal} component={CustomThing} on:entry={console.log}>
36
- Open Subscreen
37
- </EntryButton>
38
- ```
39
- */
40
-
41
- import { createEventDispatcher } from "svelte"
42
-
43
- import Button from "../button.svelte"
44
- import Modal from "../modal.svelte"
45
- import { handler$ } from "../handler$.mjs"
46
-
47
- export let component
48
- export let props
49
- let wrapper = Modal
50
- export { wrapper as this }
51
-
52
- const send = createEventDispatcher()
53
-
54
- let element = null
55
- const open = handler$(
56
- async (props) => {
57
- const elemProps = (typeof props === "function") ? props() : props
58
- const result = await element.show(elemProps)
59
- send("entry", result)
60
- }
61
- )
62
- </script>
63
-
64
- <Button {...$$restProps} on:click={open(props)}>
65
- <slot />
66
- </Button>
67
-
68
- <svelte:component this={wrapper} {component} bind:this={element} />
1
+ <script>
2
+ import { createEventDispatcher } from "svelte"
3
+
4
+ import Button from "../control/button.svelte"
5
+ import Modal from "../layout/modal.svelte"
6
+ import { handler$ } from "../handler$.mjs"
7
+
8
+ export let component
9
+ export let props
10
+ let wrapper = Modal
11
+ export { wrapper as this }
12
+
13
+ const send = createEventDispatcher()
14
+
15
+ let element = null
16
+ const open = handler$(
17
+ async (props) => {
18
+ const elemProps = (typeof props === "function") ? props() : props
19
+ const result = await element.show(elemProps)
20
+ send("entry", result)
21
+ }
22
+ )
23
+ </script>
24
+
25
+ <Button {...$$restProps} on:click={open(props)}>
26
+ <slot />
27
+ </Button>
28
+
29
+ <svelte:component this={wrapper} {component} bind:this={element} />
@@ -0,0 +1,13 @@
1
+ export const filters = {
2
+ text: (propName) =>
3
+ (row, text) =>
4
+ row[propName]
5
+ .toLowerCase()
6
+ .includes(text.toLowerCase())
7
+ }
8
+ export const sorts = {
9
+ natural: (propName) => {
10
+ const comparitor = new Intl.Collator(undefined, { numeric: true })
11
+ return (a, b) => comparitor.compare(a[propName], b[propName])
12
+ }
13
+ }
@@ -1,44 +1,56 @@
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>
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
+
11
+ ### actionText
12
+ `string`
13
+
14
+ If given, the message will have a button that can be clicked and will
15
+ use this text for the button text
16
+
17
+ ### color
18
+ `string`
19
+
20
+ Sets `$color`
21
+
22
+ ### icon
23
+ `string`
24
+
25
+ An icon to show with the message
26
+
27
+ ### message
28
+ `string`
29
+
30
+ The message to show
31
+ */
32
+
33
+ import { createEventDispatcher } from "svelte"
34
+
35
+ import Button from "../../control/button.svelte"
36
+ import Icon from "../../info/icon.svelte"
37
+ import Notification from "../../info/notification.svelte"
38
+
39
+ export let message = ""
40
+ export let icon = ""
41
+ export let color = false
42
+ export let actionText = null
43
+
44
+ const dispatch = createEventDispatcher()
45
+ const dismiss = () => dispatch("action", null)
46
+ const respond = () => dispatch("action", true)
47
+ </script>
48
+
49
+ <Notification {color} on:click={dismiss}>
50
+ <Icon name={icon}>{message}</Icon>
51
+ {#if actionText}
52
+ <Button {color} variant="fill" on:click={respond}>
53
+ {actionText}
54
+ </Button>
55
+ {/if}
56
+ </Notification>
@@ -0,0 +1,36 @@
1
+ # Toast
2
+
3
+ Displays toast notifications along the edge of the screen.
4
+
5
+ ## Props
6
+ See the Toaster component. The Toast component is wrapper around it that
7
+ also controls the children being shown for convenience.
8
+
9
+ - ### component
10
+ The component to use as a wrapper for the messages. Defaults to the
11
+ ToastMessage component.
12
+
13
+ ## Functions
14
+ - ### show(duration, props)
15
+ Shows a toast notification that will disappear after the specified
16
+ duration (time in milliseconds). The props provided are passed to an
17
+ instance of the component specified in the props.
18
+
19
+ ## Events
20
+ - ### action(info)
21
+ Fired when a toast message is clicked. The info argument contains a
22
+ value property that is provided by the message component, and a copy
23
+ of the props passed to that instace.\\
24
+ For the default messages, the value will be `null` if no button was
25
+ clicked, and `true` if the action button was clicked. This allows
26
+ actions to be taken against interactions in the message without having
27
+ to bind all kinds of events or callbacks.
28
+
29
+ ## Example
30
+ ```js
31
+ let toast = null
32
+ const notify = () => toast.show(5000, { message: "hi" })
33
+ ```
34
+ ```svelte
35
+ <Toast bind:this={toast} position="bc" />
36
+ ```