@axel669/zephyr 0.4.7 → 0.5.0-alpha.0

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 (54) hide show
  1. package/package.json +41 -40
  2. package/src/async/button.svelte +17 -13
  3. package/src/async/suspend.svelte +38 -0
  4. package/src/changed.js +10 -0
  5. package/src/composed/data-table/th.svelte +2 -2
  6. package/src/composed/data-table.svelte +7 -7
  7. package/src/composed/entry-button.svelte +13 -16
  8. package/src/control/button.svelte +26 -22
  9. package/src/control/input.svelte +52 -50
  10. package/src/control/label.svelte +28 -24
  11. package/src/control/link.svelte +36 -30
  12. package/src/control/radio-group.svelte +13 -10
  13. package/src/control/select.svelte +21 -16
  14. package/src/control/tabs.svelte +18 -14
  15. package/src/control/toggle.svelte +33 -22
  16. package/src/data-display/avatar.svelte +12 -11
  17. package/src/data-display/badge.svelte +9 -7
  18. package/src/data-display/chip.svelte +27 -17
  19. package/src/data-display/details.svelte +22 -14
  20. package/src/data-display/popover.svelte +12 -9
  21. package/src/data-display/progress.svelte +17 -13
  22. package/src/data-display/table.svelte +24 -16
  23. package/src/data-display/tooltip.svelte +11 -9
  24. package/src/dialogs/alert.svelte +19 -12
  25. package/src/dialogs/confirm.svelte +22 -16
  26. package/src/{hash.js → hash.svelte.js} +9 -0
  27. package/src/{index.mjs → index.js} +12 -11
  28. package/src/{composed/element-toast.svelte → info/element-toaster.svelte} +41 -27
  29. package/src/info/icon.svelte +4 -4
  30. package/src/info/titlebar.svelte +20 -14
  31. package/src/info/toast.svelte +35 -0
  32. package/src/info/toaster/message.svelte +42 -0
  33. package/src/info/toaster.svelte +64 -6
  34. package/src/layout/dialog.svelte +10 -12
  35. package/src/layout/drawer.svelte +47 -18
  36. package/src/layout/flex.svelte +13 -11
  37. package/src/layout/grid.svelte +17 -15
  38. package/src/layout/modal.svelte +36 -26
  39. package/src/layout/paper.svelte +42 -33
  40. package/src/layout/screen.svelte +13 -9
  41. package/src/props.js +24 -0
  42. package/src/routing/route.svelte +31 -15
  43. package/src/routing/{routing.js → routing.svelte.js} +10 -1
  44. package/src/routing/title.svelte +8 -6
  45. package/src/spinner/circle-spinner.svelte +10 -8
  46. package/src/spinner/hexagon-spinner.svelte +10 -8
  47. package/src/text.svelte +6 -10
  48. package/src/composed/toast/message.svelte +0 -33
  49. package/src/composed/toast.svelte +0 -70
  50. package/src/info/notification.svelte +0 -28
  51. package/src/inline-dialog.svelte +0 -23
  52. /package/src/{handler$.mjs → handler$.js} +0 -0
  53. /package/src/{variant.mjs → variant.js} +0 -0
  54. /package/src/{wsx.mjs → wsx.js} +0 -0
@@ -1,5 +1,3 @@
1
- <svelte:options immutable />
2
-
3
1
  <script>
4
2
  import Button from "../control/button.svelte"
5
3
  import Dialog from "../layout/dialog.svelte"
@@ -8,38 +6,46 @@
8
6
  import Text from "../text.svelte"
9
7
  import Titlebar from "../info/titlebar.svelte"
10
8
 
11
- import { handler$ } from "../handler$.mjs"
9
+ import { handler$ } from "../handler$.js"
12
10
 
13
- export let close
14
- export let title = "Confirm"
15
- export let icon
16
- export let message
17
- export let okText = "OK"
18
- export let cancelText = "Cancel"
19
- export let color = "@primary"
11
+ const {
12
+ close,
13
+ titleText = "Confirm",
14
+ icon,
15
+ message,
16
+ okText = "OK",
17
+ cancelText = "Cancel",
18
+ color = "@primary",
19
+ } = $props()
20
20
 
21
21
  const cls = handler$(close)
22
22
  </script>
23
23
 
24
24
  <Dialog card {color}>
25
- <Titlebar slot="header" {color}>
26
- <Text title slot="title">
25
+ {#snippet header()}
26
+ <Titlebar {color}>
27
+ {#snippet title()}
28
+ <Text title>
27
29
  <Icon name={icon}>
28
- {title}
30
+ {titleText}
29
31
  </Icon>
30
32
  </Text>
33
+ {/snippet}
31
34
  </Titlebar>
35
+ {/snippet}
32
36
 
33
37
  <Text>
34
38
  {message}
35
39
  </Text>
36
40
 
37
- <Grid cols="1fr 1fr" slot="footer" p="0px">
38
- <Button on:click={cls(false)} color="@danger">
41
+ {#snippet footer()}
42
+ <Grid cols="1fr 1fr" p="0px">
43
+ <Button onclick={cls(false)} color="@danger" ground>
39
44
  {cancelText}
40
45
  </Button>
41
- <Button on:click={cls(true)} color="@secondary">
46
+ <Button onclick={cls(true)} color="@secondary" ground>
42
47
  {okText}
43
48
  </Button>
44
49
  </Grid>
50
+ {/snippet}
45
51
  </Dialog>
@@ -1,5 +1,14 @@
1
1
  import { readable } from "svelte/store"
2
2
 
3
+ // export const hash = $state(location.hash.slice(1))
4
+ // window.addEventListener(
5
+ // "popstate",
6
+ // () => hashValue = location.hash.slice(1)
7
+ // )
8
+ // $effect(
9
+ // () => location.hash = hash
10
+ // )
11
+
3
12
  export const hash = readable(
4
13
  location.hash.slice(1),
5
14
  (set) => {
@@ -17,9 +17,10 @@ export { default as Progress } from "./data-display/progress.svelte"
17
17
  export { default as Table } from "./data-display/table.svelte"
18
18
  export { default as Tooltip } from "./data-display/tooltip.svelte"
19
19
 
20
+ export { default as ElementToaster } from "./info/element-toaster.svelte"
20
21
  export { default as Icon } from "./info/icon.svelte"
21
- export { default as Notification } from "./info/notification.svelte"
22
22
  export { default as Titlebar } from "./info/titlebar.svelte"
23
+ export { default as Toast } from "./info/toast.svelte"
23
24
  export { default as Toaster } from "./info/toaster.svelte"
24
25
 
25
26
  export { default as Dialog } from "./layout/dialog.svelte"
@@ -38,27 +39,27 @@ export { default as HexagonSpinner } from "./spinner/hexagon-spinner.svelte"
38
39
  export { default as Alert } from "./dialogs/alert.svelte"
39
40
  export { default as Confirm } from "./dialogs/confirm.svelte"
40
41
 
41
- export { default as DataTable } from "./composed/data-table.svelte"
42
- export { default as TH } from "./composed/data-table/th.svelte"
43
- export { default as ElementToast } from "./composed/element-toast.svelte"
42
+ // export { default as DataTable } from "./composed/data-table.svelte"
43
+ // export { default as TH } from "./composed/data-table/th.svelte"
44
44
  export { default as EntryButton } from "./composed/entry-button.svelte"
45
- export { default as Form } from "./composed/form.svelte"
46
- export { default as Toast } from "./composed/toast.svelte"
45
+ // export { default as Form } from "./composed/form.svelte"
47
46
 
48
47
  export { default as AsyncButton } from "./async/button.svelte"
49
- export { default as LoadZone } from "./async/load-zone.svelte"
48
+ // export { default as LoadZone } from "./async/load-zone.svelte"
49
+ export { default as Suspend } from "./async/suspend.svelte"
50
50
 
51
51
  export { default as Route } from "./routing/route.svelte"
52
52
  export { default as Title } from "./routing/title.svelte"
53
53
 
54
- export { default as wsx } from "./wsx.mjs"
54
+ export { default as wsx } from "./wsx.js"
55
55
 
56
- export { hash } from "./hash.js"
56
+ export { hash } from "./hash.svelte.js"
57
57
 
58
58
  export {
59
59
  route,
60
60
  stackStore,
61
61
  relpath,
62
- } from "./routing/routing.js"
63
- export * from "./handler$.mjs"
62
+ } from "./routing/routing.svelte.js"
63
+ export * from "./handler$.js"
64
64
  export * from "./composed/table-functions.js"
65
+ export * from "./changed.js"
@@ -1,6 +1,4 @@
1
- <svelte:options immutable />
2
-
3
- <script context="module">
1
+ <script module>
4
2
  const genID = () => `${Date.now()}:${Math.random().toString(16)}`
5
3
 
6
4
  const delays = {}
@@ -18,40 +16,59 @@
18
16
 
19
17
  const macros = {
20
18
  top: {
19
+ x: "50%",
20
+ tf: "translateX(-50%)",
21
21
  "-y": "100%",
22
22
  flex: "column-reverse",
23
23
  },
24
24
  bottom: {
25
+ x: "50%",
26
+ tf: "translateX(-50%)",
25
27
  "y": "100%",
26
28
  flex: "column"
27
29
  },
30
+ left: {
31
+ y: "50%",
32
+ tf: "translateY(-50%)",
33
+ "-x": "100%",
34
+ flex: "row-reverse"
35
+ },
36
+ right: {
37
+ y: "50%",
38
+ tf: "translateY(-50%)",
39
+ "x": "100%",
40
+ flex: "row"
41
+ },
28
42
  }
29
43
  </script>
30
44
 
31
45
  <script>
32
- import { createEventDispatcher } from "svelte"
33
46
  import { fade } from "svelte/transition"
34
47
 
35
- import { eventHandler$ } from "../handler$.mjs"
36
- import wsx from "../wsx.mjs"
48
+ import { eventHandler$ } from "../handler$.js"
49
+ import wsx from "../wsx.js"
37
50
 
38
- import Toaster from "../info/toaster.svelte"
51
+ import ToastMessage from "./toaster/message.svelte"
39
52
 
40
- import ToastMessage from "./toast/message.svelte"
53
+ const {
54
+ component = ToastMessage,
55
+ position = "top",
56
+ content,
57
+ onaction,
58
+ ...rest
59
+ } = $props()
41
60
 
42
- export let component = ToastMessage
43
- export let position = "top"
61
+ let items = $state([])
44
62
 
45
- let items = []
46
-
47
- const dispatch = createEventDispatcher()
48
63
  const act = eventHandler$(
49
64
  (evt, id, props) => {
50
65
  delay.trigger(id)
51
- dispatch(
52
- "action",
53
- { value: evt.detail, props }
54
- )
66
+ evt.props = props
67
+ onaction?.(evt)
68
+ // dispatch(
69
+ // "action",
70
+ // { value: evt.detail, props }
71
+ // )
55
72
  }
56
73
  )
57
74
 
@@ -68,27 +85,24 @@
68
85
  }
69
86
  export const clear = () => items = []
70
87
 
71
-
72
- $: wind = {
88
+ const wind = $derived({
73
89
  gap: "8px",
74
90
  pos: "absolute",
75
- x: "50%",
76
91
  z: "50",
77
- tf: "translateX(-50%)",
78
92
  ...macros[position],
79
- ...$$restProps,
80
- }
93
+ ...rest,
94
+ })
95
+ const Message = $derived(component)
81
96
  </script>
82
97
 
83
98
  <zephyr-element-toaster ws-x="[disp inline-grid] [pos relative]">
84
- <slot {show} />
99
+ {@render content?.(show)}
85
100
  <zephyr-element-toast-messages use:wsx={wind}>
86
101
  {#each items as {props, id} (id)}
87
102
  <zephyr-toast-wrapper ws-x="[grid]" transition:fade={{duration: 200}}>
88
- <svelte:component
89
- this={component}
103
+ <Message
90
104
  {...props}
91
- on:action={act(id, props)}
105
+ onaction={act(id, props)}
92
106
  />
93
107
  </zephyr-toast-wrapper>
94
108
  {/each}
@@ -1,9 +1,9 @@
1
1
  <script>
2
- import wsx from "../wsx.mjs"
2
+ import wsx from "../wsx.js"
3
3
 
4
- export let name
4
+ const { name, children, ...rest } = $props()
5
5
  </script>
6
6
 
7
- <ws-icon class="bi-{name}" use:wsx={$$restProps}>
8
- <slot />
7
+ <ws-icon data-icon={name} use:wsx={rest}>
8
+ {@render children?.()}
9
9
  </ws-icon>
@@ -1,34 +1,40 @@
1
1
  <script>
2
- import wsx from "../wsx.mjs"
2
+ import wsx from "../wsx.js"
3
3
 
4
- export let color
5
- export let fill = false
4
+ const {
5
+ color,
6
+ fill = false,
7
+ title,
8
+ menu,
9
+ action,
10
+ ...rest
11
+ } = $props()
6
12
 
7
- $: titleProps = {
13
+ const titleProps = $derived({
8
14
  "$color": color,
9
15
  "$fill": fill,
10
16
  $title: true,
11
- }
12
- $: wind = {
13
- ...$$restProps,
14
- }
17
+ })
18
+ const wind = $derived({
19
+ ...rest,
20
+ })
15
21
  </script>
16
22
 
17
23
  <ws-titlebar use:wsx={wind}>
18
- {#if $$slots.title}
24
+ {#if title}
19
25
  <div use:wsx={titleProps}>
20
- <slot name="title" />
26
+ {@render title()}
21
27
  </div>
22
28
  {/if}
23
29
 
24
- {#if $$slots.menu}
30
+ {#if menu}
25
31
  <div ws-x="[$menu] [grid] [p 0px]">
26
- <slot name="menu" />
32
+ {@render menu()}
27
33
  </div>
28
34
  {/if}
29
- {#if $$slots.action}
35
+ {#if action}
30
36
  <div ws-x="[$action] [grid] [p 0px]">
31
- <slot name="action" />
37
+ {@render action()}
32
38
  </div>
33
39
  {/if}
34
40
  </ws-titlebar>
@@ -0,0 +1,35 @@
1
+ <script>
2
+ import wsx from "../wsx.js"
3
+
4
+ const {
5
+ color,
6
+ children,
7
+ start,
8
+ end,
9
+ onclick,
10
+ ...rest
11
+ } = $props()
12
+
13
+ const wind = $derived({
14
+ "$color": color,
15
+ ...rest,
16
+ })
17
+ </script>
18
+
19
+ <!-- svelte-ignore a11y_interactive_supports_focus -->
20
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
21
+ <ws-toast use:wsx={wind} {onclick} role="button">
22
+ {#if start}
23
+ <div ws-x="[$start] [grid]">
24
+ {@render start()}
25
+ </div>
26
+ {/if}
27
+ <div ws-x="[$notif-text]">
28
+ {@render children?.()}
29
+ </div>
30
+ {#if end}
31
+ <div ws-x="[$end] [grid]">
32
+ {@render end()}
33
+ </div>
34
+ {/if}
35
+ </ws-toast>
@@ -0,0 +1,42 @@
1
+ <script>
2
+ import Button from "../../control/button.svelte"
3
+ import Icon from "../icon.svelte"
4
+ import Toast from "../toast.svelte"
5
+ import Text from "../../text.svelte"
6
+
7
+ const {
8
+ message = "",
9
+ icon = false,
10
+ color = false,
11
+ actionText = null,
12
+ onaction,
13
+ } = $props()
14
+
15
+ const dismiss = () => onaction({ value: null })
16
+ const respond = (evt) => {
17
+ evt.stopPropagation()
18
+ onaction({ value: true })
19
+ }
20
+ </script>
21
+
22
+ <Toast {color} onclick={dismiss}>
23
+ {#snippet start()}
24
+ <Text adorn>
25
+ {#if icon !== false}
26
+ <Icon name={icon} />
27
+ {/if}
28
+ </Text>
29
+ {/snippet}
30
+
31
+ <span>{message}</span>
32
+
33
+ {#snippet end()}
34
+ <div ws-x="[grid]">
35
+ {#if actionText}
36
+ <Button onclick={respond} r.l="0px" ground>
37
+ {actionText}
38
+ </Button>
39
+ {/if}
40
+ </div>
41
+ {/snippet}
42
+ </Toast>
@@ -1,14 +1,72 @@
1
+ <script 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
+
1
18
  <script>
2
- import wsx from "../wsx.mjs"
19
+ import { fade } from "svelte/transition"
3
20
 
4
- export let position = "tc"
21
+ import { eventHandler$ } from "../handler$.js"
22
+ import wsx from "../wsx.js"
5
23
 
6
- $: wind = {
7
- [`$${position}`]: true,
8
- ...$$restProps,
24
+ import ToastMessage from "./toaster/message.svelte"
25
+
26
+ const {
27
+ message = ToastMessage,
28
+ position = "tc",
29
+ onaction,
30
+ ...rest
31
+ } = $props()
32
+
33
+ let items = $state([])
34
+
35
+ const act = eventHandler$(
36
+ (evt, id, props) => {
37
+ delay.trigger(id)
38
+ evt.props = props
39
+ onaction?.(evt)
40
+ }
41
+ )
42
+
43
+ export const show = (duration, props) => {
44
+ const id = genID()
45
+ items = [...items, { id, props }]
46
+ delay({
47
+ action: () => items = items.filter(
48
+ item => item.id !== id
49
+ ),
50
+ time: duration,
51
+ id,
52
+ })
9
53
  }
54
+ export const clear = () => items = []
55
+
56
+ const wind = $derived({
57
+ [`$${position}`]: true,
58
+ ...rest,
59
+ })
60
+ const Message = $derived(message)
10
61
  </script>
11
62
 
12
63
  <ws-toaster use:wsx={wind}>
13
- <slot />
64
+ {#each items as {props, id} (id)}
65
+ <zephyr-toast-wrapper ws-x="[grid]" transition:fade={{duration: 200}}>
66
+ <Message
67
+ {...props}
68
+ onaction={act(id, {...props})}
69
+ />
70
+ </zephyr-toast-wrapper>
71
+ {/each}
14
72
  </ws-toaster>
@@ -1,26 +1,24 @@
1
- <svelte:options immutable />
2
-
3
1
  <script>
4
2
  import { fade } from "svelte/transition"
5
3
 
6
- import wsx from "../wsx.mjs"
4
+ import wsx from "../wsx.js"
7
5
 
8
6
  import Paper from "./paper.svelte"
9
7
 
8
+ const props = $props()
9
+
10
10
  const trick = (node, options) => ({
11
11
  delay: 0,
12
12
  duration: 250,
13
13
  css: () => "",
14
14
  })
15
+ const onclick = (evt) => {
16
+ evt.stopPropagation()
17
+ }
15
18
  </script>
16
19
 
17
- <!-- svelte-ignore a11y-click-events-have-key-events -->
18
- <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
19
- <wind-wrapper transition:trick ws-x="@@dialog [grid]" on:click|stopPropagation
20
- role="dialog">
21
- <Paper {...$$props}>
22
- <slot name="header" slot="header" />
23
- <slot />
24
- <slot name="footer" slot="footer" />
25
- </Paper>
20
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
21
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
22
+ <wind-wrapper transition:trick ws-x="@@dialog [grid]" {onclick} role="dialog">
23
+ <Paper {...props} />
26
24
  </wind-wrapper>
@@ -1,6 +1,4 @@
1
- <svelte:options immutable />
2
-
3
- <script context="module">
1
+ <script module>
4
2
  const defs = {
5
3
  select: {
6
4
  "@@select": true,
@@ -15,35 +13,66 @@
15
13
  "@@action": true,
16
14
  }
17
15
  }
16
+ const parseTime = (timestring) => {
17
+ if (!timestring) {
18
+ return 200
19
+ }
20
+ const { base, scale } =
21
+ timestring.match(/(?<base>\d+)(?<scale>s|ms)/)?.groups ?? {}
22
+ if (base === undefined) {
23
+ return 200
24
+ }
25
+ const numeric = parseInt(base)
26
+ if (scale === "ms") {
27
+ return numeric
28
+ }
29
+ return numeric * 1000
30
+ }
18
31
  </script>
19
32
 
20
33
  <script>
21
- import wsx from "../wsx.mjs"
34
+ import { getContext } from "svelte"
35
+
36
+ import wsx from "../wsx.js"
22
37
 
23
38
  import Paper from "./paper.svelte"
39
+ import { modalContext } from "./modal.svelte"
40
+
41
+ const {
42
+ height,
43
+ type = "menu",
44
+ children,
45
+ header,
46
+ footer,
47
+ content,
48
+ ...rest
49
+ } = $props()
50
+ // export let height
51
+ // export let type = "menu"
24
52
 
25
- export let height
26
- export let type = "menu"
53
+ const animTime = getContext(modalContext)
27
54
 
55
+ // When Svelte removes things from the DOM they are removed immediately
56
+ // unless Svelte has a transition running. Adding this prevents the drawer
57
+ // from disappearing without first letting the built in animations run.
28
58
  const trick = (node, options) => ({
29
59
  delay: 0,
30
- duration: 250,
60
+ duration: parseTime($animTime),
31
61
  css: () => "",
32
62
  })
33
63
 
34
- $: container = {
64
+ const container = $derived({
35
65
  ...defs[type],
66
+ $show: true,
36
67
  h: (type === "select") ? height : "100%",
37
68
  grid: true,
38
- }
69
+ })
70
+ const onclick = (evt) => evt.stopPropagation()
39
71
  </script>
40
- <!-- svelte-ignore a11y-click-events-have-key-events -->
41
- <!-- svelte-ignore a11y-interactive-supports-focus -->
42
- <wind-drawer-container use:wsx={container} on:click|stopPropagation
43
- role="menubar" transition:trick>
44
- <Paper r="0px" {...$$restProps}>
45
- <slot name="header" slot="header" />
46
- <slot />
47
- <slot name="footer" slot="footer" />
48
- </Paper>
72
+
73
+ <!-- svelte-ignore a11y_interactive_supports_focus -->
74
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
75
+ <wind-drawer-container use:wsx={container} {onclick} role="menubar"
76
+ transition:trick>
77
+ <Paper r="0px" {...rest} {header} {footer} {content} {children} />
49
78
  </wind-drawer-container>
@@ -1,22 +1,24 @@
1
- <svelte:options immutable />
2
-
3
1
  <script>
4
- import wsx from "../wsx.mjs"
2
+ import wsx from "../wsx.js"
5
3
 
6
- export let direction = false
7
- export let cross = "stretch"
8
- export let main = "start"
9
- export let scrollable = false
4
+ const {
5
+ direction = false,
6
+ cross = "stretch",
7
+ main = "start",
8
+ scrollable = false,
9
+ children,
10
+ ...rest
11
+ } = $props()
10
12
 
11
- $: wind = {
13
+ const wind = $derived({
12
14
  "fl.dir": direction,
13
15
  "fl.cross": cross,
14
16
  "fl.main": main,
15
17
  over: (scrollable === true) ? "auto" : null,
16
- ...$$restProps
17
- }
18
+ ...rest
19
+ })
18
20
  </script>
19
21
 
20
22
  <ws-flex use:wsx={wind}>
21
- <slot />
23
+ {@render children?.()}
22
24
  </ws-flex>