@rokkit/ui 1.0.0-next.121 → 1.0.0-next.123
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/README.md +1 -1
- package/dist/index.d.ts +1 -5
- package/dist/tree/List.spec.svelte.d.ts +1 -0
- package/dist/tree/Node.spec.svelte.d.ts +1 -0
- package/dist/tree/Root.spec.svelte.d.ts +1 -0
- package/package.json +4 -4
- package/src/BreadCrumbs.svelte +14 -19
- package/src/Button.svelte +3 -7
- package/src/Card.svelte +6 -2
- package/src/GraphPaper.svelte +43 -0
- package/src/Icon.svelte +21 -16
- package/src/Item.svelte +6 -6
- package/src/List.svelte +8 -7
- package/src/ListBody.svelte +3 -2
- package/src/PickOne.svelte +60 -0
- package/src/Pill.svelte +2 -2
- package/src/ProgressDots.svelte +1 -1
- package/src/Select.svelte +0 -3
- package/src/Stepper.svelte +2 -2
- package/src/Summary.svelte +1 -1
- package/src/Switch.svelte +45 -32
- package/src/Tabs.svelte +155 -75
- package/src/Toggle.svelte +2 -1
- package/src/ToggleThemeMode.svelte +7 -3
- package/src/index.js +1 -5
- package/src/tree/List.spec.svelte.js +84 -0
- package/src/tree/List.svelte +78 -0
- package/src/tree/Node.spec.svelte.js +104 -0
- package/src/tree/Node.svelte +80 -0
- package/src/tree/Root.spec.svelte.js +63 -0
- package/src/tree/Root.svelte +81 -0
- package/dist/input/types.d.ts +0 -9
- package/src/DataEditor.svelte +0 -31
- package/src/FieldLayout.svelte +0 -48
- package/src/Form.svelte +0 -17
- package/src/ListEditor.svelte +0 -44
- package/src/NestedEditor.svelte +0 -88
- package/src/input/Input.svelte +0 -17
- package/src/input/InputField.svelte +0 -69
- package/src/input/InputSelect.svelte +0 -23
- package/src/input/InputSwitch.svelte +0 -19
- package/src/input/types.js +0 -29
package/README.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -33,13 +33,9 @@ export { default as ToggleThemeMode } from "./ToggleThemeMode.svelte";
|
|
|
33
33
|
export { default as Overlay } from "./Overlay.svelte";
|
|
34
34
|
export { default as Message } from "./Message.svelte";
|
|
35
35
|
export { default as SlidingColumns } from "./SlidingColumns.svelte";
|
|
36
|
-
export { default as InputField } from "./input/InputField.svelte";
|
|
37
|
-
export { default as Form } from "./Form.svelte";
|
|
38
|
-
export { default as FieldLayout } from "./FieldLayout.svelte";
|
|
39
|
-
export { default as DataEditor } from "./DataEditor.svelte";
|
|
40
|
-
export { default as NestedEditor } from "./NestedEditor.svelte";
|
|
41
36
|
export { default as Stepper } from "./Stepper.svelte";
|
|
42
37
|
export { default as ProgressDots } from "./ProgressDots.svelte";
|
|
43
38
|
export { default as Card } from "./Card.svelte";
|
|
44
39
|
export { default as Shine } from "./Shine.svelte";
|
|
45
40
|
export { default as Tilt } from "./Tilt.svelte";
|
|
41
|
+
export { default as GraphPaper } from "./GraphPaper.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rokkit/ui",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.123",
|
|
4
4
|
"description": "Data driven UI components, improving DX",
|
|
5
5
|
"author": "Jerry Thomas <me@jerrythomas.name>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"@rokkit/actions": "latest",
|
|
35
35
|
"@rokkit/core": "latest",
|
|
36
36
|
"@rokkit/data": "latest",
|
|
37
|
-
"@rokkit/
|
|
37
|
+
"@rokkit/forms": "latest",
|
|
38
38
|
"@rokkit/states": "latest",
|
|
39
39
|
"d3-scale": "^4.0.2",
|
|
40
40
|
"date-fns": "^4.1.0",
|
|
41
|
-
"ramda": "^0.
|
|
42
|
-
"typescript": "^5.
|
|
41
|
+
"ramda": "^0.31.3",
|
|
42
|
+
"typescript": "^5.9.2"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/src/BreadCrumbs.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { getSnippet } from '@rokkit/core'
|
|
3
2
|
import Item from './Item.svelte'
|
|
4
|
-
|
|
3
|
+
import Icon from './Icon.svelte'
|
|
4
|
+
import { Proxy } from '@rokkit/states'
|
|
5
5
|
/**
|
|
6
6
|
* @typedef {Object} Props
|
|
7
7
|
* @property {string} [class]
|
|
@@ -12,26 +12,21 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/** @type {Props} */
|
|
15
|
-
let { class: classes = '', items = [], separator = '/', fields,
|
|
15
|
+
let { class: classes = '', items = [], separator = '/', fields, child } = $props()
|
|
16
|
+
let childSnippet = $derived(child ? child : defaultChild)
|
|
16
17
|
</script>
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
{#snippet defaultChild(proxy)}
|
|
20
|
+
<Item {proxy} />
|
|
21
|
+
{/snippet}
|
|
22
|
+
<div data-crumb-root class={classes}>
|
|
19
23
|
{#each items as item, index (index)}
|
|
24
|
+
{@const proxy = new Proxy(item, fields)}
|
|
20
25
|
{#if index > 0}
|
|
21
|
-
<
|
|
22
|
-
{#if separator.length === 1}
|
|
23
|
-
{separator}
|
|
24
|
-
{:else}
|
|
25
|
-
<icon class={separator}></icon>
|
|
26
|
-
{/if}
|
|
27
|
-
</span>
|
|
26
|
+
<Icon name={separator} data-crumb-separator></Icon>
|
|
28
27
|
{/if}
|
|
29
|
-
<
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
{:else}
|
|
33
|
-
<Item value={item} {fields} />
|
|
34
|
-
{/if}
|
|
35
|
-
</rk-crumb>
|
|
28
|
+
<div data-crumb-item class:is-selected={index === items.length - 1}>
|
|
29
|
+
{@render childSnippet?.(proxy)}
|
|
30
|
+
</div>
|
|
36
31
|
{/each}
|
|
37
|
-
</
|
|
32
|
+
</div>
|
package/src/Button.svelte
CHANGED
|
@@ -25,16 +25,12 @@
|
|
|
25
25
|
disabled = false,
|
|
26
26
|
onclick
|
|
27
27
|
} = $props()
|
|
28
|
-
|
|
29
|
-
const primary = $derived(variant === 'primary')
|
|
30
|
-
const secondary = $derived(variant === 'secondary')
|
|
31
|
-
const tertiary = $derived(variant === 'tertiary')
|
|
32
28
|
</script>
|
|
33
29
|
|
|
34
30
|
<button
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
data-button-root
|
|
32
|
+
data-variant={variant}
|
|
33
|
+
data-disabled={disabled}
|
|
38
34
|
class={classes}
|
|
39
35
|
{disabled}
|
|
40
36
|
{type}
|
package/src/Card.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { Proxy } from '@rokkit/states'
|
|
3
|
-
let { class: classNames = '', value = $bindable(), fields, child, onClick } = $props()
|
|
3
|
+
let { class: classNames = '', value = $bindable(), fields, child, children, onClick } = $props()
|
|
4
4
|
|
|
5
5
|
const proxy = $state(new Proxy(value, fields))
|
|
6
6
|
const childSnippet = $derived(child ?? defaultChild)
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
tabindex="-1"
|
|
37
37
|
class={classNames}
|
|
38
38
|
>
|
|
39
|
-
{
|
|
39
|
+
{#if children}
|
|
40
|
+
{@render children()}
|
|
41
|
+
{:else}
|
|
42
|
+
{@render childSnippet(proxy)}
|
|
43
|
+
{/if}
|
|
40
44
|
</div>
|
|
41
45
|
{/if}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let {
|
|
3
|
+
class: className = '',
|
|
4
|
+
unit = '.5rem',
|
|
5
|
+
majorGridSize = 5,
|
|
6
|
+
minorGridThickness = 0.5,
|
|
7
|
+
majorGridThickness = 0.5,
|
|
8
|
+
children
|
|
9
|
+
} = $props()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<div
|
|
13
|
+
data-graph-paper
|
|
14
|
+
class="flex flex-col {className}"
|
|
15
|
+
style:--unit={unit}
|
|
16
|
+
style:--size="calc( {majorGridSize} * {unit})"
|
|
17
|
+
style:--minor-grid="{minorGridThickness}px"
|
|
18
|
+
style:--major-grid="{majorGridThickness}px"
|
|
19
|
+
>
|
|
20
|
+
<content class="flex flex-col">
|
|
21
|
+
{@render children?.()}
|
|
22
|
+
</content>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<style>
|
|
26
|
+
[data-graph-paper] {
|
|
27
|
+
background-image:
|
|
28
|
+
linear-gradient(currentColor var(--major-grid), transparent var(--major-grid)),
|
|
29
|
+
linear-gradient(90deg, currentColor var(--major-grid), transparent var(--major-grid)),
|
|
30
|
+
linear-gradient(currentColor var(--minor-grid), transparent var(--minor-grid)),
|
|
31
|
+
linear-gradient(90deg, currentColor var(--minor-grid), transparent var(--minor-grid));
|
|
32
|
+
background-size:
|
|
33
|
+
var(--size) var(--size),
|
|
34
|
+
var(--size) var(--size),
|
|
35
|
+
var(--unit) var(--unit),
|
|
36
|
+
var(--unit) var(--unit);
|
|
37
|
+
background-position:
|
|
38
|
+
calc(-1 * var(--minor-grid)) calc(-1 * var(--minor-grid)),
|
|
39
|
+
calc(-1 * var(--minor-grid)) calc(-1 * var(--minor-grid)),
|
|
40
|
+
calc(-1 * var(--minor-grid)) calc(-1 * var(--minor-grid)),
|
|
41
|
+
calc(-1 * var(--minor-grid)) calc(-1 * var(--minor-grid));
|
|
42
|
+
}
|
|
43
|
+
</style>
|
package/src/Icon.svelte
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { createEmitter } from '@rokkit/core'
|
|
3
2
|
/**
|
|
4
3
|
* @typedef {Object} Props
|
|
5
4
|
* @property {string} [class]
|
|
@@ -21,40 +20,41 @@
|
|
|
21
20
|
let {
|
|
22
21
|
ref = $bindable(),
|
|
23
22
|
class: classes = '',
|
|
24
|
-
name,
|
|
23
|
+
name = '?',
|
|
25
24
|
state = null,
|
|
26
25
|
size = 'base',
|
|
27
26
|
role = 'img',
|
|
28
27
|
label = null,
|
|
29
28
|
disabled = false,
|
|
30
29
|
tabindex = $bindable(0),
|
|
31
|
-
checked = $bindable(
|
|
32
|
-
|
|
30
|
+
checked = $bindable(),
|
|
31
|
+
onclick,
|
|
32
|
+
onchange,
|
|
33
|
+
onmouseenter,
|
|
34
|
+
onmouseleave,
|
|
35
|
+
...restProps
|
|
33
36
|
} = $props()
|
|
34
37
|
|
|
35
|
-
let emitter = $derived(createEmitter(events, ['click', 'change', 'mouseenter', 'mouseleave']))
|
|
36
38
|
function handleClick(e) {
|
|
37
39
|
if (role === 'img') return
|
|
38
40
|
e.preventDefault()
|
|
39
41
|
|
|
40
42
|
if (!disabled) {
|
|
41
43
|
if (isCheckbox) {
|
|
42
|
-
checked = !checked
|
|
43
|
-
|
|
44
|
+
checked = !Boolean(checked)
|
|
45
|
+
onchange?.(checked)
|
|
44
46
|
}
|
|
45
|
-
|
|
47
|
+
onclick?.()
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
let isCheckbox = $derived(role === 'checkbox' || role === 'option')
|
|
50
52
|
let validatedTabindex = $derived(role === 'img' || disabled ? -1 : tabindex)
|
|
51
|
-
let ariaChecked = $derived(
|
|
52
|
-
['checkbox', 'option'].includes(role) ? (checked !== null ? checked : false) : null
|
|
53
|
-
)
|
|
53
|
+
let ariaChecked = $derived(['checkbox', 'option'].includes(role) && checked)
|
|
54
54
|
</script>
|
|
55
55
|
|
|
56
56
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
57
|
-
<
|
|
57
|
+
<icon
|
|
58
58
|
bind:this={ref}
|
|
59
59
|
data-tag-icon
|
|
60
60
|
data-state={state}
|
|
@@ -69,8 +69,13 @@
|
|
|
69
69
|
onclick={handleClick}
|
|
70
70
|
onkeydown={(e) => e.key === 'Enter' && e.currentTarget.click()}
|
|
71
71
|
tabindex={validatedTabindex}
|
|
72
|
-
onmouseenter
|
|
73
|
-
|
|
72
|
+
{onmouseenter}
|
|
73
|
+
{onmouseleave}
|
|
74
|
+
{...restProps}
|
|
74
75
|
>
|
|
75
|
-
|
|
76
|
-
</
|
|
76
|
+
{#if name.length <= 2}
|
|
77
|
+
<span>{name}</span>
|
|
78
|
+
{:else}
|
|
79
|
+
<i class={name} aria-hidden="true"></i>
|
|
80
|
+
{/if}
|
|
81
|
+
</icon>
|
package/src/Item.svelte
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/** @type {Props} */
|
|
10
|
-
let { value, fields } = $props()
|
|
11
|
-
let
|
|
12
|
-
let content = $derived(
|
|
13
|
-
let ariaLabel = $derived(
|
|
14
|
-
let icon = $derived(
|
|
15
|
-
let image = $derived(
|
|
10
|
+
let { value, fields, proxy = null } = $props()
|
|
11
|
+
let proxyItem = $derived(proxy ?? new Proxy(value, fields))
|
|
12
|
+
let content = $derived(proxyItem.get('text'))
|
|
13
|
+
let ariaLabel = $derived(proxyItem.get('label') ?? content)
|
|
14
|
+
let icon = $derived(proxyItem.get('icon'))
|
|
15
|
+
let image = $derived(proxyItem.get('image'))
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
{#if icon}
|
package/src/List.svelte
CHANGED
|
@@ -52,7 +52,8 @@
|
|
|
52
52
|
let wrapper = new ListController(items, value, fields, { multiSelect })
|
|
53
53
|
</script>
|
|
54
54
|
|
|
55
|
-
<
|
|
55
|
+
<div
|
|
56
|
+
data-list
|
|
56
57
|
class={classes}
|
|
57
58
|
role="listbox"
|
|
58
59
|
aria-label={name}
|
|
@@ -61,14 +62,14 @@
|
|
|
61
62
|
onaction={handleAction}
|
|
62
63
|
>
|
|
63
64
|
{#if header}
|
|
64
|
-
<
|
|
65
|
+
<div data-list-header>{@render header()}</div>
|
|
65
66
|
{/if}
|
|
66
|
-
<
|
|
67
|
+
<div data-list-body>
|
|
67
68
|
{#if items.length === 0}
|
|
68
69
|
{#if empty}
|
|
69
70
|
{@render empty()}
|
|
70
71
|
{:else}
|
|
71
|
-
<
|
|
72
|
+
<p>No items found.</p>
|
|
72
73
|
{/if}
|
|
73
74
|
{:else}
|
|
74
75
|
<ListBody
|
|
@@ -81,8 +82,8 @@
|
|
|
81
82
|
{snippets}
|
|
82
83
|
/>
|
|
83
84
|
{/if}
|
|
84
|
-
</
|
|
85
|
+
</div>
|
|
85
86
|
{#if footer}
|
|
86
|
-
<
|
|
87
|
+
<div data-list-footer>{@render footer()}</div>
|
|
87
88
|
{/if}
|
|
88
|
-
</
|
|
89
|
+
</div>
|
package/src/ListBody.svelte
CHANGED
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
{@const template = getSnippet(snippets, fm.get('snippet', item, 'stub'))}
|
|
23
23
|
{@const pathKey = getKeyFromPath([...path, index])}
|
|
24
24
|
{@const props = fm.get('props', item) || {}}
|
|
25
|
-
<
|
|
25
|
+
<div
|
|
26
|
+
data-list-item
|
|
26
27
|
role="option"
|
|
27
28
|
data-path={pathKey}
|
|
28
29
|
aria-selected={selectedKeys.has(pathKey)}
|
|
@@ -38,5 +39,5 @@
|
|
|
38
39
|
<Item value={item} {fields} />
|
|
39
40
|
{/if}
|
|
40
41
|
</svelte:boundary>
|
|
41
|
-
</
|
|
42
|
+
</div>
|
|
42
43
|
{/each}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
// import { onMount } from 'svelte'
|
|
3
|
+
// import { $state, $derived } from 'svelte'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {Object} Props
|
|
7
|
+
* @property {any[]} options
|
|
8
|
+
* @property {any} value
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** @type Props */
|
|
12
|
+
let { options, value = $bindable() } = $props()
|
|
13
|
+
|
|
14
|
+
// const optionRefs = new Map<number, HTMLLabelElement>()
|
|
15
|
+
|
|
16
|
+
// const $indicatorStyle = $derived(() => {
|
|
17
|
+
// const el = optionRefs.get(value)
|
|
18
|
+
// if (!el) return ''
|
|
19
|
+
// const { offsetLeft, offsetWidth } = el
|
|
20
|
+
// return `transform: translateX(${offsetLeft}px); width: ${offsetWidth}px;`
|
|
21
|
+
// })
|
|
22
|
+
|
|
23
|
+
// onMount(() => {
|
|
24
|
+
// setTimeout(() => {
|
|
25
|
+
// optionRefs.get(value)?.offsetLeft
|
|
26
|
+
// })
|
|
27
|
+
// })
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div class="relative inline-flex rounded-md bg-gray-200 p-1" data-pickone-root role="radiogroup">
|
|
31
|
+
<!-- Indicator -->
|
|
32
|
+
<div
|
|
33
|
+
class="absolute h-full rounded-md bg-white shadow transition-all duration-300"
|
|
34
|
+
data-pickone-current
|
|
35
|
+
aria-hidden="true"
|
|
36
|
+
></div>
|
|
37
|
+
|
|
38
|
+
{#each options as option, index (index)}
|
|
39
|
+
<div
|
|
40
|
+
class="relative z-10 cursor-pointer text-sm font-medium text-gray-700"
|
|
41
|
+
data-pickone-option
|
|
42
|
+
aria-checked={option === value}
|
|
43
|
+
role="radio"
|
|
44
|
+
>
|
|
45
|
+
<label class="bg-red flex size-full px-4 py-2">
|
|
46
|
+
<input
|
|
47
|
+
type="radio"
|
|
48
|
+
name="pickone"
|
|
49
|
+
value={option}
|
|
50
|
+
class="peer hidden"
|
|
51
|
+
checked={option === value}
|
|
52
|
+
onchange={() => (value = option)}
|
|
53
|
+
/>
|
|
54
|
+
<span class="transition peer-checked:font-semibold peer-checked:text-black">
|
|
55
|
+
{option}
|
|
56
|
+
</span>
|
|
57
|
+
</label>
|
|
58
|
+
</div>
|
|
59
|
+
{/each}
|
|
60
|
+
</div>
|
package/src/Pill.svelte
CHANGED
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
</script>
|
|
33
33
|
|
|
34
34
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
35
|
-
<
|
|
35
|
+
<div data-pill-root use:keyboard={keyMappings} onremove={handle} tabindex="0" class={classes}>
|
|
36
36
|
<Item {value} {mapping}></Item>
|
|
37
37
|
{#if removable}
|
|
38
38
|
<Icon name="action-close" role="button" aria-label="Remove" {disabled} onclick={handle} small
|
|
39
39
|
></Icon>
|
|
40
40
|
{/if}
|
|
41
|
-
</
|
|
41
|
+
</div>
|
package/src/ProgressDots.svelte
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
{#each steps as step, index (index)}
|
|
25
25
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
26
26
|
<dot
|
|
27
|
-
class="step flex h-3 w-3 rounded-full border-2
|
|
27
|
+
class="step border-surface-100 bg-surface-300 flex h-3 w-3 rounded-full border-2"
|
|
28
28
|
on:click={handleClick}
|
|
29
29
|
data-step={step}
|
|
30
30
|
data-active={step === current}
|
package/src/Select.svelte
CHANGED
|
@@ -52,9 +52,6 @@
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// $: fields = { ...defaultFields, ...fields }
|
|
56
|
-
// $: using = { default: Item, ...using }
|
|
57
|
-
// $: activeIndex = options.findIndex((item) => item === value)
|
|
58
55
|
let offsetTop = $derived(activeItem?.offsetTop + activeItem?.clientHeight ?? 0)
|
|
59
56
|
</script>
|
|
60
57
|
|
package/src/Stepper.svelte
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
{#each data as { label }, stage (stage)}
|
|
46
46
|
{#if label}
|
|
47
47
|
<p
|
|
48
|
-
class="col-span-3 flex w-full justify-center text-center font-medium leading-loose
|
|
48
|
+
class="text-surface-800 col-span-3 flex w-full justify-center text-center font-medium leading-loose"
|
|
49
49
|
class:pending={stage > currentStage}
|
|
50
50
|
>
|
|
51
51
|
{label}
|
|
@@ -61,6 +61,6 @@
|
|
|
61
61
|
grid-template-columns: repeat(var(--count), 2fr 6fr 2fr);
|
|
62
62
|
}
|
|
63
63
|
.pending {
|
|
64
|
-
@apply
|
|
64
|
+
@apply text-surface-500 font-light;
|
|
65
65
|
}
|
|
66
66
|
</style>
|
package/src/Summary.svelte
CHANGED
package/src/Switch.svelte
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { equals } from 'ramda'
|
|
3
|
-
import { noop, FieldMapper } from '@rokkit/core'
|
|
4
3
|
import { keyboard } from '@rokkit/actions'
|
|
4
|
+
import { Proxy } from '@rokkit/states'
|
|
5
5
|
import Item from './Item.svelte'
|
|
6
|
-
// import { defaultMapping } from './constants'
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* @typedef {Object} Props
|
|
10
|
-
* @property {string}
|
|
11
|
-
* @property {any}
|
|
12
|
-
* @property {
|
|
13
|
-
* @property {
|
|
14
|
-
* @property {boolean}
|
|
15
|
-
* @property {boolean}
|
|
9
|
+
* @property {string} [class]
|
|
10
|
+
* @property {any} value
|
|
11
|
+
* @property {import('@rokkit/core').FieldMapping} fields
|
|
12
|
+
* @property {Array<any>} [options]
|
|
13
|
+
* @property {boolean} [compact]
|
|
14
|
+
* @property {boolean} [disabled]
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
17
|
/** @type {Props} */
|
|
19
18
|
let {
|
|
20
19
|
class: classes = '',
|
|
21
20
|
value = $bindable(),
|
|
21
|
+
description = 'Toggle Switch',
|
|
22
22
|
options = [false, true],
|
|
23
23
|
fields,
|
|
24
24
|
compact = false,
|
|
25
25
|
disabled = false,
|
|
26
|
-
onchange
|
|
27
|
-
|
|
26
|
+
onchange,
|
|
27
|
+
child,
|
|
28
28
|
...extra
|
|
29
29
|
} = $props()
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Toggles the value of the switch
|
|
33
|
+
* @param {number} direction - The direction to toggle the switch
|
|
34
|
+
*/
|
|
33
35
|
function toggle(direction = 1) {
|
|
34
36
|
let nextIndex
|
|
35
37
|
const index = options.indexOf(value)
|
|
@@ -43,6 +45,10 @@
|
|
|
43
45
|
onchange(value)
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param event
|
|
51
|
+
*/
|
|
46
52
|
function handleClick(event) {
|
|
47
53
|
const index = event.target.closest('[data-path]').dataset.path
|
|
48
54
|
value = options[index]
|
|
@@ -52,20 +58,25 @@
|
|
|
52
58
|
next: ['ArrowRight', 'ArrowDown', ' ', 'Enter'],
|
|
53
59
|
prev: ['ArrowLeft', 'ArrowUp']
|
|
54
60
|
}
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
|
|
62
|
+
let childSnippet = $derived(child ? child : defaultChild)
|
|
57
63
|
</script>
|
|
58
64
|
|
|
65
|
+
{#snippet defaultChild(proxy)}
|
|
66
|
+
<Item {proxy} />
|
|
67
|
+
{/snippet}
|
|
68
|
+
|
|
59
69
|
{#if !Array.isArray(options) || options.length < 2}
|
|
60
|
-
<
|
|
70
|
+
<div data-error>Items should be an array with at least two items.</div>
|
|
61
71
|
{:else}
|
|
62
72
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
63
|
-
<
|
|
73
|
+
<div
|
|
64
74
|
class={classes}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
data-switch-root
|
|
76
|
+
data-switch-off={options.length === 2 && equals(value, options[0])}
|
|
77
|
+
data-switch-on={options.length === 2 && equals(value, options[1])}
|
|
78
|
+
data-switch-compact={compact}
|
|
79
|
+
aria-label={description}
|
|
69
80
|
aria-orientation="horizontal"
|
|
70
81
|
aria-disabled={disabled}
|
|
71
82
|
tabindex="0"
|
|
@@ -75,19 +86,21 @@
|
|
|
75
86
|
onprev={() => toggle(-1)}
|
|
76
87
|
onclick={handleClick}
|
|
77
88
|
>
|
|
78
|
-
{#each options as item, index (
|
|
79
|
-
|
|
80
|
-
<
|
|
89
|
+
{#each options as item, index (index)}
|
|
90
|
+
{@const proxy = new Proxy(item, fields)}
|
|
91
|
+
<div
|
|
92
|
+
data-switch-item
|
|
93
|
+
class="relative"
|
|
94
|
+
role="option"
|
|
95
|
+
aria-selected={equals(item, value)}
|
|
96
|
+
data-path={index}
|
|
97
|
+
>
|
|
81
98
|
{#if equals(item, value)}
|
|
82
|
-
<
|
|
99
|
+
<div data-switch-mark class="absolute bottom-0 left-0 right-0 top-0"></div>
|
|
83
100
|
{/if}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
{:else}
|
|
88
|
-
<Item value={item} {fields} />
|
|
89
|
-
{/if}
|
|
90
|
-
</rk-item>
|
|
101
|
+
|
|
102
|
+
{@render childSnippet?.(proxy)}
|
|
103
|
+
</div>
|
|
91
104
|
{/each}
|
|
92
|
-
</
|
|
105
|
+
</div>
|
|
93
106
|
{/if}
|