@axel669/zephyr 0.4.4-beta.0 → 0.4.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axel669/zephyr",
3
- "version": "0.4.4-beta.0",
3
+ "version": "0.4.6",
4
4
  "description": "",
5
5
  "main": "src/index.mjs",
6
6
  "type": "module",
@@ -13,12 +13,12 @@
13
13
  "author": "",
14
14
  "license": "MIT",
15
15
  "dependencies": {
16
- "@axel669/windstorm": "0.4.4"
16
+ "@axel669/rollup-copy-static": "^0.2.0",
17
+ "@axel669/windstorm": "0.4.6"
17
18
  },
18
19
  "devDependencies": {
19
20
  "@axel669/asuid": "^0.2.1",
20
21
  "@axel669/ipsen": "0.4.0-beta.7",
21
- "@axel669/rollup-copy-static": "^0.1.2",
22
22
  "@axel669/rollup-html-input": "^0.1.2",
23
23
  "@rollup/plugin-node-resolve": "^15.0.2",
24
24
  "@rollup/plugin-terser": "^0.4.0",
@@ -0,0 +1,96 @@
1
+ <svelte:options immutable />
2
+
3
+ <script context="module">
4
+ const genID = () => `${Date.now()}:${Math.random().toString(16)}`
5
+
6
+ const delays = {}
7
+ const delay = ({time, action, id}) => {
8
+ const trigger = () => {
9
+ const info = delays[id]
10
+ clearTimeout(info.id)
11
+ action()
12
+ delete delays[id]
13
+ }
14
+ const timeoutID = setTimeout(trigger, time)
15
+ delays[id] = { trigger, id: timeoutID }
16
+ }
17
+ delay.trigger = (id) => delays[id].trigger()
18
+
19
+ const macros = {
20
+ top: {
21
+ "-y": "100%",
22
+ flex: "column-reverse",
23
+ },
24
+ bottom: {
25
+ "y": "100%",
26
+ flex: "column"
27
+ },
28
+ }
29
+ </script>
30
+
31
+ <script>
32
+ import { createEventDispatcher } from "svelte"
33
+ import { fade } from "svelte/transition"
34
+
35
+ import { eventHandler$ } from "../handler$.mjs"
36
+ import wsx from "../wsx.mjs"
37
+
38
+ import Toaster from "../info/toaster.svelte"
39
+
40
+ import ToastMessage from "./toast/message.svelte"
41
+
42
+ export let component = ToastMessage
43
+ export let position = "top"
44
+
45
+ let items = []
46
+
47
+ const dispatch = createEventDispatcher()
48
+ const act = eventHandler$(
49
+ (evt, id, props) => {
50
+ delay.trigger(id)
51
+ dispatch(
52
+ "action",
53
+ { value: evt.detail, props }
54
+ )
55
+ }
56
+ )
57
+
58
+ export const show = (duration, props) => {
59
+ const id = genID()
60
+ items = [...items, { id, props }]
61
+ delay({
62
+ action: () => items = items.filter(
63
+ item => item.id !== id
64
+ ),
65
+ time: duration,
66
+ id,
67
+ })
68
+ }
69
+ export const clear = () => items = []
70
+
71
+
72
+ $: wind = {
73
+ gap: "8px",
74
+ pos: "absolute",
75
+ x: "50%",
76
+ z: "50",
77
+ tf: "translateX(-50%)",
78
+ ...macros[position],
79
+ ...$$restProps,
80
+ }
81
+ </script>
82
+
83
+ <zephyr-element-toaster ws-x="[disp inline-grid] [pos relative]">
84
+ <slot {show} />
85
+ <zephyr-element-toast-messages use:wsx={wind}>
86
+ {#each items as {props, id} (id)}
87
+ <zephyr-toast-wrapper ws-x="[grid]" transition:fade={{duration: 200}}>
88
+ <svelte:component
89
+ this={component}
90
+ {...props}
91
+ on:action={act(id, props)}
92
+ />
93
+ </zephyr-toast-wrapper>
94
+ {/each}
95
+ </zephyr-element-toast-messages>
96
+ </zephyr-element-toaster>
@@ -4,20 +4,28 @@
4
4
  import wsx from "../wsx.mjs"
5
5
  import variant from "../variant.mjs"
6
6
 
7
- export let color = "@default"
7
+ export let color = false
8
8
  export let compact = false
9
+ export let ground = false
9
10
  export let disabled
10
11
 
11
12
  export let fill = false
12
13
  export let outline = false
13
14
  export let flat = false
14
15
 
15
- $: type = variant({ fill, outline, flat })
16
+ // $: type = variant({ fill, outline, flat })
17
+ $: type = variant(
18
+ "$flat",
19
+ { fill },
20
+ { outline },
21
+ { flat }
22
+ )
16
23
 
17
24
  $: wind = {
18
25
  [type]: true,
19
26
  "$color": color,
20
27
  $compact: compact,
28
+ $ground: ground,
21
29
  ...$$restProps
22
30
  }
23
31
  </script>
@@ -1,89 +1,101 @@
1
- <svelte:options immutable />
2
-
3
- <script>
4
- import wsx from "../wsx.mjs"
5
-
6
- export let type = "text"
7
-
8
- export let flat = false
9
- export let label
10
- export let color = "@default"
11
- export let disabled
12
-
13
- export let value = ""
14
- export let autocompleteOptions = null
15
-
16
- let input = null
17
- export const focus = () => input.focus()
18
-
19
- const id =
20
- (autocompleteOptions === null)
21
- ? null
22
- : `${Math.random().toString(16)}_${Date.now()}`
23
-
24
- const update = (evt) => value = evt.target.value
25
-
26
- $: restKeys = Object.keys($$restProps)
27
- $: props = restKeys.reduce(
28
- (props, key) => {
29
- const [target, name] =
30
- (key.startsWith("i-") === true)
31
- ? [props.input, key.slice(2)]
32
- : [props.wind, key]
33
- target[name] = $$restProps[key]
34
- return props
35
- },
36
- {wind: {}, input: {}}
37
- )
38
-
39
- $: wind = {
40
- "$flat": flat,
41
- "@@control": true,
42
- "$color": color,
43
- ...props.wind,
44
- }
45
-
46
- $: tag = (type === "area") ? "textarea" : "input"
47
- </script>
48
-
49
- <label use:wsx={wind}>
50
- {#if label}
51
- <span use:wsx={{ "$label": true }}>{label}</span>
52
- {/if}
53
- <svelte:element
54
- this={tag}
55
- {...props.input}
56
- {disabled}
57
- {type}
58
- {value}
59
- list={id}
60
- on:focus
61
- on:blur
62
- on:input={update}
63
- bind:this={input}
64
- />
65
-
66
- {#if $$slots.start}
67
- <span use:wsx={{ "$start": true }}>
68
- <slot name="start" />
69
- </span>
70
- {/if}
71
- {#if $$slots.end}
72
- <span use:wsx={{ "$end": true }}>
73
- <slot name="end" />
74
- </span>
75
- {/if}
76
- {#if $$slots.extra}
77
- <span use:wsx={{ "$extra": true }}>
78
- <slot name="extra" />
79
- </span>
80
- {/if}
81
-
82
- {#if autocompleteOptions !== null}
83
- <datalist {id}>
84
- {#each autocompleteOptions as value}
85
- <option {value} />
86
- {/each}
87
- </datalist>
88
- {/if}
89
- </label>
1
+ <svelte:options immutable />
2
+
3
+ <script>
4
+ import wsx, { none } from "../wsx.mjs"
5
+ import variant from "../variant.mjs"
6
+
7
+ export let type = "text"
8
+
9
+ export let flat = false
10
+ export let lined = false
11
+ export let linedFill = false
12
+ export let outline = false
13
+ export let label
14
+ export let color = "@default"
15
+ export let disabled
16
+
17
+ export let value = ""
18
+ export let autocompleteOptions = null
19
+
20
+ let input = null
21
+ export const focus = () => input.focus()
22
+
23
+ const id =
24
+ (autocompleteOptions === null)
25
+ ? null
26
+ : `${Math.random().toString(16)}_${Date.now()}`
27
+
28
+ const update = (evt) => value = evt.target.value
29
+
30
+ $: restKeys = Object.keys($$restProps)
31
+ $: props = restKeys.reduce(
32
+ (props, key) => {
33
+ const [target, name] =
34
+ (key.startsWith("i-") === true)
35
+ ? [props.input, key.slice(2)]
36
+ : [props.wind, key]
37
+ target[name] = $$restProps[key]
38
+ return props
39
+ },
40
+ {wind: {}, input: {}}
41
+ )
42
+
43
+ $: variantStyle = variant(
44
+ none,
45
+ { outline },
46
+ { linedFill },
47
+ { lined },
48
+ { flat }
49
+ )
50
+
51
+ $: wind = {
52
+ [variantStyle]: true,
53
+ "@@control": true,
54
+ "$color": color,
55
+ ...props.wind,
56
+ }
57
+
58
+ $: tag = (type === "area") ? "textarea" : "input"
59
+ </script>
60
+
61
+ <label use:wsx={wind}>
62
+ {#if label}
63
+ <span use:wsx={{ "$label": true }}>{label}</span>
64
+ {/if}
65
+ <svelte:element
66
+ this={tag}
67
+ {...props.input}
68
+ {disabled}
69
+ {type}
70
+ {value}
71
+ list={id}
72
+ on:focus
73
+ on:blur
74
+ on:input={update}
75
+ bind:this={input}
76
+ />
77
+
78
+ {#if $$slots.start}
79
+ <span use:wsx={{ "$start": true }}>
80
+ <slot name="start" />
81
+ </span>
82
+ {/if}
83
+ {#if $$slots.end}
84
+ <span use:wsx={{ "$end": true }}>
85
+ <slot name="end" />
86
+ </span>
87
+ {/if}
88
+ {#if $$slots.extra}
89
+ <span use:wsx={{ "$extra": true }}>
90
+ <slot name="extra" />
91
+ </span>
92
+ {/if}
93
+
94
+ {#if autocompleteOptions !== null}
95
+ <datalist {id}>
96
+ {#each autocompleteOptions as value}
97
+ <option {value} />
98
+ {/each}
99
+ </datalist>
100
+ {/if}
101
+ </label>
@@ -6,6 +6,7 @@
6
6
 
7
7
  export let color = false
8
8
  export let compact = false
9
+ export let ground = false
9
10
  export let disabled
10
11
 
11
12
  export let fill = false
@@ -16,7 +17,12 @@
16
17
  export { _for as for }
17
18
  export let button = false
18
19
 
19
- $: type = variant({ fill, outline, flat })
20
+ $: type = variant(
21
+ "$flat",
22
+ { fill },
23
+ { outline },
24
+ { flat }
25
+ )
20
26
  $: baseStyles =
21
27
  (button === true)
22
28
  ? {
@@ -24,6 +30,7 @@
24
30
  [type]: true,
25
31
  "$color": color,
26
32
  $compact: compact,
33
+ $ground: ground,
27
34
  }
28
35
  : {}
29
36
 
@@ -1,32 +1,41 @@
1
- <svelte:options immutable />
2
-
3
- <script>
4
- import wsx from "../wsx.mjs"
5
- import variant from "../variant.mjs"
6
-
7
- export let button = false
8
- export let color = false
9
-
10
- export let href = ""
11
- export let rel = "noreferrer"
12
- export let target = null
13
-
14
- export let fill = false
15
- export let outline = false
16
- export let flat = false
17
-
18
- export let disabled = null
19
-
20
- $: type = variant({ fill, outline, flat })
21
-
22
- $: wind = {
23
- "@@button": button,
24
- [type]: true,
25
- "$color": color,
26
- ...$$restProps
27
- }
28
- </script>
29
-
30
- <a {href} {target} {rel} disabled={disabled || null} use:wsx={wind} on:click>
31
- <slot />
32
- </a>
1
+ <svelte:options immutable />
2
+
3
+ <script>
4
+ import wsx from "../wsx.mjs"
5
+ import variant from "../variant.mjs"
6
+
7
+ export let button = false
8
+ export let color = false
9
+ export let compact = false
10
+ export let ground = false
11
+
12
+ export let href = ""
13
+ export let rel = "noreferrer"
14
+ export let target = null
15
+
16
+ export let fill = false
17
+ export let outline = false
18
+ export let flat = false
19
+
20
+ export let disabled = null
21
+
22
+ $: type = variant(
23
+ "$flat",
24
+ { fill },
25
+ { outline },
26
+ { flat }
27
+ )
28
+
29
+ $: wind = {
30
+ "@@button": button,
31
+ [type]: true,
32
+ "$color": color,
33
+ $compact: compact,
34
+ $ground: ground,
35
+ ...$$restProps
36
+ }
37
+ </script>
38
+
39
+ <a {href} {target} {rel} disabled={disabled || null} use:wsx={wind} on:click>
40
+ <slot />
41
+ </a>
@@ -1,25 +1,25 @@
1
- <svelte:options immutable />
2
-
3
- <script>
4
- import { fade } from "svelte/transition"
5
- import wsx from "../wsx.mjs"
6
-
7
- let visible = false
8
- const show = () => visible = true
9
- const hide = () => visible = false
10
- const anim = { duration: 250 }
11
-
12
- $: wind = {
13
- $show: true,
14
- ...$$restProps,
15
- }
16
- </script>
17
-
18
- <ws-popover use:wsx={wind}>
19
- <slot {show} />
20
- {#if visible}
21
- <wind-content ws-x="[$content] [inset 0px]" transition:fade={anim}>
22
- <slot name="content" {hide} />
23
- </wind-content>
24
- {/if}
25
- </ws-popover>
1
+ <svelte:options immutable />
2
+
3
+ <script>
4
+ import { fade } from "svelte/transition"
5
+ import wsx from "../wsx.mjs"
6
+
7
+ let visible = false
8
+ const show = () => visible = true
9
+ const hide = () => visible = false
10
+ const anim = { duration: 250 }
11
+
12
+ $: wind = {
13
+ $show: true,
14
+ ...$$restProps,
15
+ }
16
+ </script>
17
+
18
+ <ws-popover use:wsx={wind}>
19
+ <slot {show} />
20
+ {#if visible}
21
+ <wind-content ws-x="[$content] [inset 0px]" transition:fade={anim}>
22
+ <slot name="content" {hide} />
23
+ </wind-content>
24
+ {/if}
25
+ </ws-popover>
@@ -1,27 +1,21 @@
1
- <svelte:options immutable />
2
-
3
- <script>
4
- import wsx from "../wsx.mjs"
5
-
6
- export let value = 0
7
- export let max = 1
8
- export let color = "default"
9
- export let outline = false
10
- export let row = false
11
- export let label = null
12
-
13
- $: wind = {
14
- "@@progress": true,
15
- "$outline": outline,
16
- "$color": color,
17
- $row: row,
18
- ...$$restProps,
19
- }
20
- </script>
21
-
22
- <label use:wsx={wind}>
23
- {#if label}
24
- <span ws-x="[$progress-label] [t.ws nowrap]">{label}</span>
25
- {/if}
26
- <progress {value} {max} />
27
- </label>
1
+ <svelte:options immutable />
2
+
3
+ <script>
4
+ import wsx from "../wsx.mjs"
5
+
6
+ export let value = 0
7
+ export let min = 0
8
+ export let max = 1
9
+ export let buffer = 0
10
+ export let busy = false
11
+ export let color = "@default"
12
+
13
+ $: wind = {
14
+ "$color": color,
15
+ ...$$restProps,
16
+ }
17
+
18
+ $: busyStatus = (busy === true) ? { busy: true } : {}
19
+ </script>
20
+
21
+ <ws-progress use:wsx={wind} {...busyStatus} {min} {max} {value} {buffer} />
package/src/hash.js CHANGED
@@ -1,14 +1,14 @@
1
- import { readable } from "svelte/store"
2
-
3
- export const hash = readable(
4
- location.hash.slice(1),
5
- (set) => {
6
- window.addEventListener(
7
- "popstate",
8
- () => set(location.hash.slice(1))
9
- )
10
- }
11
- )
12
- hash.set = (value) => {
13
- location.hash = value
14
- }
1
+ import { readable } from "svelte/store"
2
+
3
+ export const hash = readable(
4
+ location.hash.slice(1),
5
+ (set) => {
6
+ window.addEventListener(
7
+ "popstate",
8
+ () => set(location.hash.slice(1))
9
+ )
10
+ }
11
+ )
12
+ hash.set = (value) => {
13
+ location.hash = value
14
+ }
package/src/index.mjs CHANGED
@@ -40,6 +40,7 @@ export { default as Confirm } from "./dialogs/confirm.svelte"
40
40
 
41
41
  export { default as DataTable } from "./composed/data-table.svelte"
42
42
  export { default as TH } from "./composed/data-table/th.svelte"
43
+ export { default as ElementToast } from "./composed/element-toast.svelte"
43
44
  export { default as EntryButton } from "./composed/entry-button.svelte"
44
45
  export { default as Form } from "./composed/form.svelte"
45
46
  export { default as Toast } from "./composed/toast.svelte"
@@ -1,28 +1,28 @@
1
- <script>
2
- import wsx from "../wsx.mjs"
3
-
4
- export let color = false
5
-
6
- $: wind = {
7
- "$color": color,
8
- ...$$restProps,
9
- }
10
- </script>
11
-
12
- <!-- svelte-ignore a11y-click-events-have-key-events -->
13
- <!-- svelte-ignore a11y-interactive-supports-focus -->
14
- <ws-notification use:wsx={wind} on:click role="button">
15
- {#if $$slots.start}
16
- <div ws-x="[$start] [grid]">
17
- <slot name="start" />
18
- </div>
19
- {/if}
20
- <div ws-x="[$notif-text]">
21
- <slot />
22
- </div>
23
- {#if $$slots.end}
24
- <div ws-x="[$end] [grid]">
25
- <slot name="end" />
26
- </div>
27
- {/if}
28
- </ws-notification>
1
+ <script>
2
+ import wsx from "../wsx.mjs"
3
+
4
+ export let color = false
5
+
6
+ $: wind = {
7
+ "$color": color,
8
+ ...$$restProps,
9
+ }
10
+ </script>
11
+
12
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
13
+ <!-- svelte-ignore a11y-interactive-supports-focus -->
14
+ <ws-notification use:wsx={wind} on:click role="button">
15
+ {#if $$slots.start}
16
+ <div ws-x="[$start] [grid]">
17
+ <slot name="start" />
18
+ </div>
19
+ {/if}
20
+ <div ws-x="[$notif-text]">
21
+ <slot />
22
+ </div>
23
+ {#if $$slots.end}
24
+ <div ws-x="[$end] [grid]">
25
+ <slot name="end" />
26
+ </div>
27
+ {/if}
28
+ </ws-notification>
@@ -11,7 +11,6 @@
11
11
  }
12
12
  $: wind = {
13
13
  ...$$restProps,
14
- "gr.cols": "auto 1fr auto"
15
14
  }
16
15
  </script>
17
16
 
@@ -1,49 +1,49 @@
1
- <svelte:options immutable />
2
-
3
- <script context="module">
4
- const defs = {
5
- select: {
6
- "@@select": true,
7
- "w.min": "35vw",
8
- grid: true,
9
- over: "hidden"
10
- },
11
- menu: {
12
- "@@menu": true,
13
- },
14
- action: {
15
- "@@action": true,
16
- }
17
- }
18
- </script>
19
-
20
- <script>
21
- import wsx from "../wsx.mjs"
22
-
23
- import Paper from "./paper.svelte"
24
-
25
- export let height
26
- export let type = "menu"
27
-
28
- const trick = (node, options) => ({
29
- delay: 0,
30
- duration: 250,
31
- css: () => "",
32
- })
33
-
34
- $: container = {
35
- ...defs[type],
36
- h: (type === "select") ? height : "100%",
37
- grid: true,
38
- }
39
- </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>
49
- </wind-drawer-container>
1
+ <svelte:options immutable />
2
+
3
+ <script context="module">
4
+ const defs = {
5
+ select: {
6
+ "@@select": true,
7
+ "w.min": "35vw",
8
+ grid: true,
9
+ over: "hidden"
10
+ },
11
+ menu: {
12
+ "@@menu": true,
13
+ },
14
+ action: {
15
+ "@@action": true,
16
+ }
17
+ }
18
+ </script>
19
+
20
+ <script>
21
+ import wsx from "../wsx.mjs"
22
+
23
+ import Paper from "./paper.svelte"
24
+
25
+ export let height
26
+ export let type = "menu"
27
+
28
+ const trick = (node, options) => ({
29
+ delay: 0,
30
+ duration: 250,
31
+ css: () => "",
32
+ })
33
+
34
+ $: container = {
35
+ ...defs[type],
36
+ h: (type === "select") ? height : "100%",
37
+ grid: true,
38
+ }
39
+ </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>
49
+ </wind-drawer-container>
@@ -1,56 +1,56 @@
1
- <svelte:options immutable />
2
-
3
- <script>
4
- import Flex from "./flex.svelte"
5
- import wsx from "../wsx.mjs"
6
-
7
- export let color
8
- export let card = false
9
- export let square = false
10
- export let layout = Flex
11
- export let scrollable = true
12
-
13
- $: props = Object.entries($$restProps).reduce(
14
- (p, [key, value]) => {
15
- const [target, name] =
16
- (key.startsWith("l-") === true)
17
- ? [ p.layout, key.slice(2) ]
18
- : [ p.paper, key ]
19
- target[name] = value
20
- return p
21
- },
22
- { layout: {}, paper: {} }
23
- )
24
-
25
- $: layoutProps = {
26
- over: scrollable ? "auto" : false,
27
- $content: true,
28
- ...props.layout,
29
- }
30
- $: wind = {
31
- "$color": color,
32
- "$outline": card,
33
- r: square && "0px",
34
- ...props.paper,
35
- }
36
- </script>
37
-
38
- <ws-paper use:wsx={wind}>
39
- {#if $$slots.header}
40
- <div ws-x="[$header] [grid] [p 0px]">
41
- <slot name="header" />
42
- </div>
43
- {/if}
44
- {#if $$slots.content}
45
- <slot name="content" />
46
- {:else}
47
- <svelte:component this={layout} {...layoutProps}>
48
- <slot />
49
- </svelte:component>
50
- {/if}
51
- {#if $$slots.footer}
52
- <div ws-x="[$footer] [grid] [p 0px]">
53
- <slot name="footer" />
54
- </div>
55
- {/if}
56
- </ws-paper>
1
+ <svelte:options immutable />
2
+
3
+ <script>
4
+ import Flex from "./flex.svelte"
5
+ import wsx from "../wsx.mjs"
6
+
7
+ export let color
8
+ export let card = false
9
+ export let square = false
10
+ export let layout = Flex
11
+ export let scrollable = true
12
+
13
+ $: props = Object.entries($$restProps).reduce(
14
+ (p, [key, value]) => {
15
+ const [target, name] =
16
+ (key.startsWith("l-") === true)
17
+ ? [ p.layout, key.slice(2) ]
18
+ : [ p.paper, key ]
19
+ target[name] = value
20
+ return p
21
+ },
22
+ { layout: {}, paper: {} }
23
+ )
24
+
25
+ $: layoutProps = {
26
+ over: scrollable ? "auto" : false,
27
+ $content: true,
28
+ ...props.layout,
29
+ }
30
+ $: wind = {
31
+ "$color": color,
32
+ "$outline": card,
33
+ r: square && "0px",
34
+ ...props.paper,
35
+ }
36
+ </script>
37
+
38
+ <ws-paper use:wsx={wind}>
39
+ {#if $$slots.header}
40
+ <div ws-x="[$header] [grid] [p 0px]">
41
+ <slot name="header" />
42
+ </div>
43
+ {/if}
44
+ {#if $$slots.content}
45
+ <slot name="content" />
46
+ {:else}
47
+ <svelte:component this={layout} {...layoutProps}>
48
+ <slot />
49
+ </svelte:component>
50
+ {/if}
51
+ {#if $$slots.footer}
52
+ <div ws-x="[$footer] [grid] [p 0px]">
53
+ <slot name="footer" />
54
+ </div>
55
+ {/if}
56
+ </ws-paper>
@@ -1,48 +1,48 @@
1
- <script context="module">
2
- const urlPattern = (path, exact) => {
3
- const regexSource = path.replace(
4
- /:([\w\-]+)/g,
5
- (_, name) => `\(?<${name}>[\\w\\-\\%]+\)`
6
- )
7
- if (exact === true) {
8
- return new RegExp(`(?<_path>^${regexSource})$`)
9
- }
10
- return new RegExp(`(?<_path>^${regexSource})(((?<=\\/)[\\w\\-\\%])|\\/|$)`)
11
- }
12
- </script>
13
-
14
- <script>
15
- import { getContext, setContext } from "svelte"
16
-
17
- import { ctx, resolve, route } from "./routing.js"
18
-
19
- export let path = ""
20
- export let component = null
21
- export let props = {}
22
- export let exact = false
23
-
24
- const parent = getContext(ctx.parent) ?? "/"
25
- const fullPath = resolve(parent, path)
26
-
27
- setContext(ctx.parent, fullPath)
28
- $: pattern = urlPattern(fullPath, exact)
29
- $: match = $route.match(pattern)
30
- $: routeParams = Object.fromEntries(
31
- Object.entries({ ...match?.groups }).map(
32
- ([key, value]) => [key, decodeURIComponent(value)]
33
- )
34
- )
35
- $: routeInfo = {
36
- params: routeParams,
37
- match: routeParams._path,
38
- route: $route,
39
- }
40
- </script>
41
-
42
- {#if match !== null}
43
- {#key routeParams._path}
44
- <slot {routeInfo}>
45
- <svelte:component this={component} {...props} {routeInfo} />
46
- </slot>
47
- {/key}
48
- {/if}
1
+ <script context="module">
2
+ const urlPattern = (path, exact) => {
3
+ const regexSource = path.replace(
4
+ /:([\w\-]+)/g,
5
+ (_, name) => `\(?<${name}>[\\w\\-\\%]+\)`
6
+ )
7
+ if (exact === true) {
8
+ return new RegExp(`(?<_path>^${regexSource})$`)
9
+ }
10
+ return new RegExp(`(?<_path>^${regexSource})(((?<=\\/)[\\w\\-\\%])|\\/|$)`)
11
+ }
12
+ </script>
13
+
14
+ <script>
15
+ import { getContext, setContext } from "svelte"
16
+
17
+ import { ctx, resolve, route } from "./routing.js"
18
+
19
+ export let path = ""
20
+ export let component = null
21
+ export let props = {}
22
+ export let exact = false
23
+
24
+ const parent = getContext(ctx.parent) ?? "/"
25
+ const fullPath = resolve(parent, path)
26
+
27
+ setContext(ctx.parent, fullPath)
28
+ $: pattern = urlPattern(fullPath, exact)
29
+ $: match = $route.match(pattern)
30
+ $: routeParams = Object.fromEntries(
31
+ Object.entries({ ...match?.groups }).map(
32
+ ([key, value]) => [key, decodeURIComponent(value)]
33
+ )
34
+ )
35
+ $: routeInfo = {
36
+ params: routeParams,
37
+ match: routeParams._path,
38
+ route: $route,
39
+ }
40
+ </script>
41
+
42
+ {#if match !== null}
43
+ {#key routeParams._path}
44
+ <slot {routeInfo}>
45
+ <svelte:component this={component} {...props} {routeInfo} />
46
+ </slot>
47
+ {/key}
48
+ {/if}
@@ -1,62 +1,62 @@
1
- import { onMount, getContext } from "svelte"
2
- import { writable, derived } from "svelte/store"
3
-
4
- import { hash } from "../hash.js"
5
-
6
- export const route = derived(
7
- hash,
8
- hash => {
9
- if (hash.startsWith("/") === false) {
10
- return `/${hash}`
11
- }
12
- return hash
13
- }
14
- )
15
-
16
- export const ctx = {
17
- router: Symbol("Router Context"),
18
- parent: Symbol("Route Parent"),
19
- layout: Symbol("Layout Context"),
20
- }
21
- export const resolve = (base, part) => {
22
- if (part === "" || part === "/") {
23
- return base
24
- }
25
- if (base === "/" || base === undefined) {
26
- return `/${part}`
27
- }
28
- if (part.startsWith("/") === true) {
29
- return `${base}${part}`
30
- }
31
- return `${base}/${part}`
32
- }
33
- export const relpath = (path) => {
34
- const base = getContext(ctx.parent)
35
- return `#${resolve(base, path)}`
36
- }
37
-
38
- const emptyStack = Symbol("empty stack")
39
- export const stackStore = (initial = stackStore.empty) => {
40
- const stack = [writable(initial)]
41
- const current = writable(initial)
42
- let attachment = stack[0].subscribe(current.set)
43
-
44
- return {
45
- subscribe: current.subscribe,
46
- push: (initial) => {
47
- const item = writable(initial)
48
- onMount(() => {
49
- stack.push(item)
50
- attachment()
51
- attachment = item.subscribe(current.set)
52
- return () => {
53
- stack.pop()
54
- attachment()
55
- attachment = stack[stack.length - 1].subscribe(current.set)
56
- }
57
- })
58
- return item
59
- }
60
- }
61
- }
62
- stackStore.empty = emptyStack
1
+ import { onMount, getContext } from "svelte"
2
+ import { writable, derived } from "svelte/store"
3
+
4
+ import { hash } from "../hash.js"
5
+
6
+ export const route = derived(
7
+ hash,
8
+ hash => {
9
+ if (hash.startsWith("/") === false) {
10
+ return `/${hash}`
11
+ }
12
+ return hash
13
+ }
14
+ )
15
+
16
+ export const ctx = {
17
+ router: Symbol("Router Context"),
18
+ parent: Symbol("Route Parent"),
19
+ layout: Symbol("Layout Context"),
20
+ }
21
+ export const resolve = (base, part) => {
22
+ if (part === "" || part === "/") {
23
+ return base
24
+ }
25
+ if (base === "/" || base === undefined) {
26
+ return `/${part}`
27
+ }
28
+ if (part.startsWith("/") === true) {
29
+ return `${base}${part}`
30
+ }
31
+ return `${base}/${part}`
32
+ }
33
+ export const relpath = (path) => {
34
+ const base = getContext(ctx.parent)
35
+ return `#${resolve(base, path)}`
36
+ }
37
+
38
+ const emptyStack = Symbol("empty stack")
39
+ export const stackStore = (initial = stackStore.empty) => {
40
+ const stack = [writable(initial)]
41
+ const current = writable(initial)
42
+ let attachment = stack[0].subscribe(current.set)
43
+
44
+ return {
45
+ subscribe: current.subscribe,
46
+ push: (initial) => {
47
+ const item = writable(initial)
48
+ onMount(() => {
49
+ stack.push(item)
50
+ attachment()
51
+ attachment = item.subscribe(current.set)
52
+ return () => {
53
+ stack.pop()
54
+ attachment()
55
+ attachment = stack[stack.length - 1].subscribe(current.set)
56
+ }
57
+ })
58
+ return item
59
+ }
60
+ }
61
+ }
62
+ stackStore.empty = emptyStack
@@ -1,26 +1,26 @@
1
- <script context="module">
2
- import { writable } from "svelte/store"
3
-
4
- import { stackStore } from "./routing.js"
5
-
6
- // const stack = writable([])
7
- const stack = stackStore()
8
-
9
- const updateTitle = (format, data) => {
10
- if (format === null || data === stackStore.empty) {
11
- return
12
- }
13
-
14
- document.title = format(data)
15
- }
16
- </script>
17
-
18
- <script>
19
- import { onMount } from "svelte"
20
- export let data = ""
21
- export let format = null
22
-
23
- stack.push(data)
24
-
25
- $: updateTitle(format, $stack)
26
- </script>
1
+ <script context="module">
2
+ import { writable } from "svelte/store"
3
+
4
+ import { stackStore } from "./routing.js"
5
+
6
+ // const stack = writable([])
7
+ const stack = stackStore()
8
+
9
+ const updateTitle = (format, data) => {
10
+ if (format === null || data === stackStore.empty) {
11
+ return
12
+ }
13
+
14
+ document.title = format(data)
15
+ }
16
+ </script>
17
+
18
+ <script>
19
+ import { onMount } from "svelte"
20
+ export let data = ""
21
+ export let format = null
22
+
23
+ stack.push(data)
24
+
25
+ $: updateTitle(format, $stack)
26
+ </script>
package/src/variant.mjs CHANGED
@@ -1,12 +1,10 @@
1
- export default ({ flat, fill, outline }, def = "$flat") => {
2
- if (outline === true) {
3
- return "$outline"
4
- }
5
- if (fill === true) {
6
- return "$fill"
7
- }
8
- if (flat === true) {
9
- return "$flat"
1
+ export default (def, ...variants) => {
2
+ for (const variant of variants) {
3
+ const [entry] = Object.entries(variant)
4
+ const [key, value] = entry
5
+ if (value === true) {
6
+ return `$${key.replace(/[A-Z]/g, (s) => `-${s.toLocaleLowerCase()}`)}`
7
+ }
10
8
  }
11
9
  return def
12
10
  }
package/src/wsx.mjs CHANGED
@@ -1,25 +1,29 @@
1
- import ws from "@axel669/windstorm"
2
-
3
- export default (node, props) => {
4
- const update = (props) => {
5
- const { slot = null, ...goodProps } = props ?? {}
6
- if (goodProps === null || goodProps === undefined) {
7
- node.setAttribute("ws-x", null)
8
- return
9
- }
10
- const formatted = Object.entries(goodProps).reduce(
11
- (props, [key, value]) => {
12
- const realKey = key.replaceAll("--", ":").replace(/^\-/, "$")
13
- props[realKey] = value
14
- return props
15
- },
16
- {}
17
- )
18
- node.setAttribute(
19
- "ws-x",
20
- ws.x(formatted)
21
- )
22
- }
23
- update(props)
24
- return { update }
25
- }
1
+ import ws from "@axel669/windstorm"
2
+
3
+ export const none = Symbol("none")
4
+ export default (node, props) => {
5
+ const update = (props) => {
6
+ const { slot = null, ...goodProps } = props ?? {}
7
+ if (goodProps === null || goodProps === undefined) {
8
+ node.setAttribute("ws-x", null)
9
+ return
10
+ }
11
+ const formatted = Object.entries(goodProps).reduce(
12
+ (props, [key, value]) => {
13
+ if (key === none) {
14
+ return props
15
+ }
16
+ const realKey = key.replace(/^!/, "").replaceAll("_", ":")
17
+ props[realKey] = value
18
+ return props
19
+ },
20
+ {}
21
+ )
22
+ node.setAttribute(
23
+ "ws-x",
24
+ ws.x(formatted)
25
+ )
26
+ }
27
+ update(props)
28
+ return { update }
29
+ }