@rokkit/ui 1.0.0-next.120 → 1.0.0-next.122
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 +0 -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 +2 -2
- package/src/BreadCrumbs.svelte +14 -19
- package/src/Button.svelte +3 -7
- 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/Pill.svelte +3 -3
- package/src/Select.svelte +0 -3
- package/src/Switch.svelte +45 -32
- package/src/Tabs.svelte +147 -77
- package/src/TabsOld.svelte +96 -0
- package/src/Toggle.svelte +2 -1
- package/src/ToggleThemeMode.svelte +7 -3
- package/src/index.js +0 -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,11 +33,6 @@ 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";
|
|
@@ -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.122",
|
|
4
4
|
"description": "Data driven UI components, improving DX",
|
|
5
5
|
"author": "Jerry Thomas <me@jerrythomas.name>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
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",
|
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/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}
|
package/src/Pill.svelte
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* @property {boolean} [disabled]
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
/** @type {
|
|
15
|
+
/** @type {ListProps} */
|
|
16
16
|
let {
|
|
17
17
|
value,
|
|
18
18
|
class: classes = '',
|
|
@@ -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/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/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}
|