@rokkit/core 1.0.0-next.22 → 1.0.0-next.24
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 +13 -12
- package/src/Accordion.svelte +3 -3
- package/src/BreadCrumbs.svelte +3 -3
- package/src/DropDown.svelte +7 -7
- package/src/DropSearch.svelte +3 -3
- package/src/Icon.svelte +23 -9
- package/src/List.svelte +5 -4
- package/src/NestedList.svelte +8 -18
- package/src/NestedPaginator.svelte +2 -2
- package/src/SpinList.svelte +3 -3
- package/src/Switch.svelte +31 -16
- package/src/TabItem.svelte +20 -17
- package/src/Tabs.svelte +43 -11
- package/src/Tree.svelte +2 -2
- package/src/actions/navigable.js +0 -1
- package/src/actions/swipeable.js +0 -1
- package/src/constants.js +0 -29
- package/src/items/Item.svelte +29 -0
- package/src/items/{Pill.svelte → ItemWrapper.svelte} +23 -8
- package/src/items/Link.svelte +5 -5
- package/src/items/Node.svelte +9 -10
- package/src/items/Summary.svelte +7 -7
- package/src/items/index.js +2 -3
- package/src/lib/index.js +6 -0
- package/src/mocks/Custom.svelte +3 -4
- package/src/List-Discard.svelte +0 -48
- package/src/items/Collapsible.svelte +0 -51
- package/src/items/Text.svelte +0 -28
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rokkit/core",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.24",
|
|
4
4
|
"description": "Core components, actions and stores for svelte apps.",
|
|
5
5
|
"author": "Jerry Thomas <me@jerrythomas.name>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,18 +16,19 @@
|
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"@jerrythomas/eslint-config-svelte": "^1.0.2",
|
|
18
18
|
"@jerrythomas/prettier-config": "^1.0.0",
|
|
19
|
-
"@sveltejs/vite-plugin-svelte": "^2.
|
|
19
|
+
"@sveltejs/vite-plugin-svelte": "^2.2.0",
|
|
20
20
|
"@testing-library/svelte": "^3.2.2",
|
|
21
|
-
"@vitest/coverage-
|
|
22
|
-
"@vitest/
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
21
|
+
"@vitest/coverage-c8": "^0.31.0",
|
|
22
|
+
"@vitest/coverage-istanbul": "^0.31.0",
|
|
23
|
+
"@vitest/ui": "~0.31.0",
|
|
24
|
+
"eslint": "^8.40.0",
|
|
25
|
+
"jsdom": "^22.0.0",
|
|
26
|
+
"svelte": "^3.59.1",
|
|
27
|
+
"typescript": "^5.0.4",
|
|
27
28
|
"validators": "latest",
|
|
28
|
-
"vite": "^4.3.
|
|
29
|
-
"vitest": "~0.
|
|
30
|
-
"shared-config": "1.0.0"
|
|
29
|
+
"vite": "^4.3.5",
|
|
30
|
+
"vitest": "~0.31.0",
|
|
31
|
+
"shared-config": "1.0.0-next.23"
|
|
31
32
|
},
|
|
32
33
|
"files": [
|
|
33
34
|
"src/**/*.js",
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
}
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
|
-
"ramda": "^0.
|
|
51
|
+
"ramda": "^0.29.0"
|
|
51
52
|
},
|
|
52
53
|
"scripts": {
|
|
53
54
|
"lint": "prettier --check --plugin-search-dir=. . && eslint .",
|
package/src/Accordion.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { createEventDispatcher } from 'svelte'
|
|
3
3
|
import { defaultFields } from './constants'
|
|
4
|
-
import {
|
|
4
|
+
import { Item, Summary } from './items'
|
|
5
5
|
import List from './List.svelte'
|
|
6
6
|
import { navigator } from './actions/navigator'
|
|
7
7
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
let cursor = []
|
|
17
17
|
|
|
18
18
|
$: fields = { ...defaultFields, ...fields }
|
|
19
|
-
$: using = { default:
|
|
19
|
+
$: using = { default: Item, ...using }
|
|
20
20
|
|
|
21
21
|
function handle(event) {
|
|
22
22
|
// console.log(event.type, event.detail)
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
class:is-selected={item === value}
|
|
64
64
|
data-path={index}
|
|
65
65
|
>
|
|
66
|
-
<Summary {fields} {using} bind:
|
|
66
|
+
<Summary {fields} {using} bind:value={item} />
|
|
67
67
|
{#if hasItems && item[fields.isOpen]}
|
|
68
68
|
<List
|
|
69
69
|
bind:items={item[fields.children]}
|
package/src/BreadCrumbs.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { defaultFields } from './constants'
|
|
3
|
-
import {
|
|
3
|
+
import { Item } from './items'
|
|
4
4
|
|
|
5
5
|
export let items = []
|
|
6
6
|
export let separator = '/'
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
export let using
|
|
9
9
|
|
|
10
10
|
$: fields = { ...defaultFields, ...(fields ?? {}) }
|
|
11
|
-
$: using = { default:
|
|
11
|
+
$: using = { default: Item, ...(using ?? {}) }
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<crumbs class="flex">
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
</span>
|
|
28
28
|
{/if}
|
|
29
29
|
<crumb class:is-selected={index == items.length - 1}>
|
|
30
|
-
<svelte:component this={component}
|
|
30
|
+
<svelte:component this={component} value={item} {fields} />
|
|
31
31
|
</crumb>
|
|
32
32
|
{/if}
|
|
33
33
|
{/each}
|
package/src/DropDown.svelte
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { defaultFields, defaultStateIcons } from './constants.js'
|
|
5
5
|
|
|
6
6
|
import Icon from './Icon.svelte'
|
|
7
|
-
import
|
|
7
|
+
import Item from './items/Item.svelte'
|
|
8
8
|
import List from './List.svelte'
|
|
9
9
|
import Slider from './Slider.svelte'
|
|
10
10
|
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
export { className as class }
|
|
15
15
|
export let items = []
|
|
16
16
|
export let fields = defaultFields
|
|
17
|
-
export let using = { default:
|
|
17
|
+
export let using = { default: Item }
|
|
18
18
|
export let value = null
|
|
19
|
-
export let title
|
|
20
|
-
export let icon
|
|
19
|
+
export let title = null
|
|
20
|
+
export let icon = null
|
|
21
21
|
export let small = false
|
|
22
22
|
|
|
23
|
-
$: using = { default:
|
|
23
|
+
$: using = { default: Item, ...using }
|
|
24
24
|
$: fields = { ...defaultFields, ...fields }
|
|
25
25
|
|
|
26
26
|
let offsetTop = 0
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
>
|
|
47
47
|
<button
|
|
48
48
|
on:click|stopPropagation={() => (open = !open)}
|
|
49
|
-
class="flex"
|
|
49
|
+
class="flex items-center"
|
|
50
50
|
bind:clientHeight={offsetTop}
|
|
51
51
|
tabindex="-1"
|
|
52
52
|
>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
<Icon name={icon} />
|
|
55
55
|
{/if}
|
|
56
56
|
{#if !small && title}
|
|
57
|
-
<p>{title}</p>
|
|
57
|
+
<p class="flex w-full">{title}</p>
|
|
58
58
|
{/if}
|
|
59
59
|
{#if open}
|
|
60
60
|
<icon class={icons.opened} />
|
package/src/DropSearch.svelte
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import { defaultFields } from './constants.js'
|
|
3
3
|
import List from './List.svelte'
|
|
4
4
|
import Slider from './Slider.svelte'
|
|
5
|
-
import {
|
|
5
|
+
import { Item } from './items'
|
|
6
6
|
|
|
7
7
|
export let data
|
|
8
8
|
export let value = null
|
|
9
9
|
export let fields = defaultFields
|
|
10
|
-
export let using = { default:
|
|
10
|
+
export let using = { default: Item }
|
|
11
11
|
|
|
12
|
-
$: using = { default:
|
|
12
|
+
$: using = { default: Item, ...using }
|
|
13
13
|
$: fields = { ...defaultFields, ...fields }
|
|
14
14
|
|
|
15
15
|
let opened = false
|
package/src/Icon.svelte
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
let className = ''
|
|
3
3
|
export { className as class }
|
|
4
|
+
export let name
|
|
5
|
+
export let size = 'base'
|
|
6
|
+
export let role = 'img'
|
|
7
|
+
export let label = name
|
|
8
|
+
export let disabled = false
|
|
9
|
+
export let tabindex = 0
|
|
4
10
|
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
$: tabindex = role !== 'button' || disabled ? -1 : tabindex
|
|
12
|
+
$: small = size === 'small' || className.includes('small')
|
|
13
|
+
$: medium = size === 'medium' || className.includes('medium')
|
|
14
|
+
$: large = size === 'large' || className.includes('large')
|
|
7
15
|
</script>
|
|
8
16
|
|
|
9
|
-
<!-- svelte-ignore a11y-
|
|
10
|
-
<
|
|
11
|
-
class="flex flex-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
18
|
+
<icon
|
|
19
|
+
class="flex flex-shrink-0 items-center justify-center {className}"
|
|
20
|
+
class:small
|
|
21
|
+
class:medium
|
|
22
|
+
class:large
|
|
23
|
+
class:disabled
|
|
24
|
+
{role}
|
|
25
|
+
aria-label={label}
|
|
14
26
|
on:click
|
|
27
|
+
on:keydown={(e) => e.key === 'Enter' && e.currentTarget.click()}
|
|
28
|
+
{tabindex}
|
|
15
29
|
>
|
|
16
|
-
<
|
|
17
|
-
</
|
|
30
|
+
<i class={name} aria-hidden="true" />
|
|
31
|
+
</icon>
|
package/src/List.svelte
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { navigator } from './actions'
|
|
3
3
|
import { createEventDispatcher } from 'svelte'
|
|
4
4
|
import { defaultFields } from './constants'
|
|
5
|
-
import {
|
|
5
|
+
import { Item } from './items'
|
|
6
6
|
|
|
7
7
|
const dispatch = createEventDispatcher()
|
|
8
8
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
$: fields = { ...defaultFields, ...fields }
|
|
27
|
-
$: using = { default:
|
|
27
|
+
$: using = { default: Item, ...using }
|
|
28
28
|
$: filtered = items.filter((item) => !item[fields.isDeleted])
|
|
29
29
|
</script>
|
|
30
30
|
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
? using[item[fields.component]] || using.default
|
|
48
48
|
: using.default}
|
|
49
49
|
{@const path = [...hierarchy, index].join(',')}
|
|
50
|
+
{@const props = item[fields.props] || { fields }}
|
|
50
51
|
<item
|
|
51
52
|
class="flex flex-shrink-0 flex-grow-0 items-center cursor-pointer w-full gap-2 select-none item"
|
|
52
53
|
role="option"
|
|
@@ -56,8 +57,8 @@
|
|
|
56
57
|
>
|
|
57
58
|
<svelte:component
|
|
58
59
|
this={component}
|
|
59
|
-
bind:
|
|
60
|
-
{
|
|
60
|
+
bind:value={item}
|
|
61
|
+
{...props}
|
|
61
62
|
on:change
|
|
62
63
|
/>
|
|
63
64
|
</item>
|
package/src/NestedList.svelte
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { Node,
|
|
2
|
+
import { Node, Item } from './items'
|
|
3
3
|
import { defaultFields, defaultStateIcons } from './constants'
|
|
4
4
|
import { getLineTypes } from './lib/connector'
|
|
5
5
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
export let hierarchy = []
|
|
15
15
|
export let icons
|
|
16
16
|
|
|
17
|
-
$: using = { default:
|
|
17
|
+
$: using = { default: Item, ...using }
|
|
18
18
|
$: fields = { ...defaultFields, ...fields }
|
|
19
19
|
$: nodeTypes = items.map((_, index) =>
|
|
20
20
|
index === items.length - 1 ? 'last' : 'child'
|
|
@@ -28,35 +28,25 @@
|
|
|
28
28
|
class:rtl
|
|
29
29
|
tabindex="-1"
|
|
30
30
|
>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
on:select={handle}
|
|
34
|
-
on:move={handle}
|
|
35
|
-
on:expand={handle}
|
|
36
|
-
on:collapse={handle}
|
|
37
|
-
> -->
|
|
38
|
-
{#each items as content, index}
|
|
39
|
-
<!-- {@const type = nodeTypes[index] === 'middle' ? 'line' : 'empty'} -->
|
|
40
|
-
{@const hasChildren = fields.children in content}
|
|
41
|
-
<!-- {@const connectors = types.slice(0, -1)} -->
|
|
31
|
+
{#each items as item, index}
|
|
32
|
+
{@const hasChildren = fields.children in item}
|
|
42
33
|
{@const path = [...hierarchy, index]}
|
|
43
34
|
{@const connectors = getLineTypes(hasChildren, types, nodeTypes[index])}
|
|
44
35
|
|
|
45
|
-
<!-- types={[...connectors, nodeTypes[index]]} -->
|
|
46
36
|
<Node
|
|
47
|
-
bind:
|
|
37
|
+
bind:value={item}
|
|
48
38
|
{fields}
|
|
49
39
|
{using}
|
|
50
40
|
types={connectors}
|
|
51
41
|
{rtl}
|
|
52
42
|
{path}
|
|
53
43
|
stateIcons={icons}
|
|
54
|
-
selected={value ===
|
|
44
|
+
selected={value === item}
|
|
55
45
|
/>
|
|
56
46
|
<!-- types={[...connectors, type, nodeTypes[index]]} -->
|
|
57
|
-
{#if hasChildren &&
|
|
47
|
+
{#if hasChildren && item[fields.isOpen]}
|
|
58
48
|
<svelte:self
|
|
59
|
-
items={
|
|
49
|
+
items={item[fields.children]}
|
|
60
50
|
bind:value
|
|
61
51
|
{fields}
|
|
62
52
|
{using}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import BreadCrumbs from './BreadCrumbs.svelte'
|
|
3
3
|
import { defaultFields } from './constants'
|
|
4
|
-
import {
|
|
4
|
+
import { Item } from './items'
|
|
5
5
|
import { flattenNestedList } from './lib/nested'
|
|
6
6
|
import { createEventDispatcher } from 'svelte'
|
|
7
7
|
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
$: flatList = flattenNestedList(items, fields)
|
|
52
52
|
$: fields = { ...defaultFields, ...(fields ?? {}) }
|
|
53
|
-
$: using = { default:
|
|
53
|
+
$: using = { default: Item, ...(using ?? {}) }
|
|
54
54
|
</script>
|
|
55
55
|
|
|
56
56
|
<pages>
|
package/src/SpinList.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { createEventDispatcher } from 'svelte'
|
|
3
3
|
import { defaultFields } from './constants'
|
|
4
|
-
import {
|
|
4
|
+
import { Item } from './items'
|
|
5
5
|
import { navigable } from './actions'
|
|
6
6
|
import { getComponent } from './list'
|
|
7
7
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
dispatch('select', items[index])
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
$: using = { default:
|
|
27
|
+
$: using = { default: Item, ...using }
|
|
28
28
|
$: fields = { ...defaultFields, ...fields }
|
|
29
29
|
$: value = index >= 0 ? items[index] : null
|
|
30
30
|
$: component = getComponent(value, fields)
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
on:next={moveNext}
|
|
42
42
|
on:previous={moveBack}
|
|
43
43
|
/>
|
|
44
|
-
<!-- <svelte:component this={component} bind:
|
|
44
|
+
<!-- <svelte:component this={component} bind:value={value} {fields} on:change /> -->
|
|
45
45
|
<square class="h-full position-absolute right-0">
|
|
46
46
|
<icon class="i-carbon-chevron-sort" />
|
|
47
47
|
</square>
|
package/src/Switch.svelte
CHANGED
|
@@ -1,52 +1,67 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { createEventDispatcher } from 'svelte'
|
|
2
3
|
import { defaultFields } from './constants'
|
|
3
|
-
import {
|
|
4
|
+
import { Item } from './items'
|
|
5
|
+
import { navigator } from './actions'
|
|
6
|
+
import { getComponent } from './lib'
|
|
7
|
+
|
|
8
|
+
const dispatch = createEventDispatcher()
|
|
4
9
|
|
|
5
10
|
let className = ''
|
|
6
11
|
export { className as class }
|
|
7
12
|
export let items = [false, true]
|
|
8
13
|
export let fields = defaultFields
|
|
9
|
-
export let using = {
|
|
14
|
+
export let using = {}
|
|
10
15
|
export let compact = true
|
|
11
16
|
export let value
|
|
17
|
+
let cursor = []
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
: using.default
|
|
17
|
-
}
|
|
19
|
+
function handleNav(event) {
|
|
20
|
+
value = event.detail.node
|
|
21
|
+
cursor = event.detail.path
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
value = item
|
|
23
|
+
dispatch('change', { item: value, indices: cursor })
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
$: useComponent = !items.every((item) => [false, true].includes(item))
|
|
24
27
|
$: fields = { ...defaultFields, ...fields }
|
|
25
|
-
$: using = { default:
|
|
28
|
+
$: using = { default: Item, ...using }
|
|
26
29
|
</script>
|
|
27
30
|
|
|
28
31
|
{#if !Array.isArray(items) || items.length < 2}
|
|
29
32
|
<error>Items should be an array with at least two items.</error>
|
|
30
33
|
{:else}
|
|
31
|
-
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
32
34
|
<toggle-switch
|
|
33
35
|
class="flex items-center {className}"
|
|
36
|
+
class:is-off={items.length == 2 && value === items[0]}
|
|
37
|
+
class:is-on={items.length == 2 && value === items[1]}
|
|
34
38
|
class:compact
|
|
35
39
|
tabindex="0"
|
|
40
|
+
role="listbox"
|
|
41
|
+
use:navigator={{
|
|
42
|
+
items,
|
|
43
|
+
fields,
|
|
44
|
+
vertical: false,
|
|
45
|
+
indices: cursor
|
|
46
|
+
}}
|
|
47
|
+
on:move={handleNav}
|
|
48
|
+
on:select={handleNav}
|
|
36
49
|
>
|
|
37
50
|
{#each items as item, index (item)}
|
|
38
|
-
{@const component = useComponent
|
|
39
|
-
|
|
51
|
+
{@const component = useComponent
|
|
52
|
+
? getComponent(item, fields, using)
|
|
53
|
+
: null}
|
|
40
54
|
<item
|
|
41
55
|
class="flex relative"
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
role="option"
|
|
57
|
+
aria-selected={item === value}
|
|
58
|
+
data-path={index}
|
|
44
59
|
>
|
|
45
60
|
{#if item == value}
|
|
46
61
|
<indicator class="absolute top-0 left-0 right-0 bottom-0" />
|
|
47
62
|
{/if}
|
|
48
63
|
{#if component}
|
|
49
|
-
<svelte:component this={component}
|
|
64
|
+
<svelte:component this={component} value={item} {fields} />
|
|
50
65
|
{/if}
|
|
51
66
|
</item>
|
|
52
67
|
{/each}
|
package/src/TabItem.svelte
CHANGED
|
@@ -3,25 +3,28 @@
|
|
|
3
3
|
|
|
4
4
|
const dispatch = createEventDispatcher()
|
|
5
5
|
|
|
6
|
-
export let
|
|
7
|
-
export let
|
|
8
|
-
export let
|
|
9
|
-
export let
|
|
6
|
+
export let fields = {}
|
|
7
|
+
export let using = {}
|
|
8
|
+
export let value = null
|
|
9
|
+
export let index = 0
|
|
10
|
+
export let icons
|
|
11
|
+
export let selected = false
|
|
12
|
+
export let removable = false
|
|
13
|
+
|
|
14
|
+
$: component = value[fields.component]
|
|
15
|
+
? using[value[fields.component]] || using.default
|
|
16
|
+
: using.default
|
|
10
17
|
</script>
|
|
11
18
|
|
|
12
19
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
13
|
-
<tab
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
{
|
|
17
|
-
{
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
{#if
|
|
21
|
-
<icon
|
|
22
|
-
class="remove small"
|
|
23
|
-
aria-label="remove"
|
|
24
|
-
on:click={() => dispatch('remove')}
|
|
25
|
-
/>
|
|
20
|
+
<tab
|
|
21
|
+
class="flex flex-row items-center"
|
|
22
|
+
role="option"
|
|
23
|
+
aria-selected={selected}
|
|
24
|
+
data-path={index}
|
|
25
|
+
>
|
|
26
|
+
<svelte:component this={component} {value} {fields} />
|
|
27
|
+
{#if removable}
|
|
28
|
+
<icon class={icons.close} on:click={() => dispatch('remove')} />
|
|
26
29
|
{/if}
|
|
27
30
|
</tab>
|
package/src/Tabs.svelte
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { defaultFields } from './constants'
|
|
3
|
-
import
|
|
2
|
+
import { defaultFields, defaultStateIcons } from './constants'
|
|
3
|
+
import Icon from './Icon.svelte'
|
|
4
|
+
import { ItemWrapper } from './items'
|
|
4
5
|
import { navigator } from './actions'
|
|
5
6
|
import { createEventDispatcher } from 'svelte'
|
|
6
7
|
|
|
@@ -12,20 +13,38 @@
|
|
|
12
13
|
export let fields = {}
|
|
13
14
|
export let using = {}
|
|
14
15
|
export let value = null
|
|
16
|
+
export let below = false
|
|
17
|
+
export let align = 'left'
|
|
18
|
+
export let editable = false
|
|
19
|
+
export let icons = defaultStateIcons.action
|
|
20
|
+
|
|
15
21
|
let cursor = []
|
|
16
22
|
|
|
23
|
+
function handleRemove(item) {
|
|
24
|
+
if (typeof item === Object) {
|
|
25
|
+
item[fields.isDeleted] = true
|
|
26
|
+
} else {
|
|
27
|
+
items = items.filter((i) => i !== item)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
dispatch('remove', { item })
|
|
31
|
+
}
|
|
17
32
|
function handleNav(event) {
|
|
18
33
|
value = event.detail.node
|
|
19
34
|
cursor = event.detail.path
|
|
20
35
|
|
|
21
36
|
dispatch('select', { item: value, indices: cursor })
|
|
22
37
|
}
|
|
38
|
+
$: icons = { ...defaultStateIcons.action, ...icons }
|
|
39
|
+
$: filtered = items.filter((item) => !item[fields.isDeleted])
|
|
23
40
|
$: fields = { ...defaultFields, ...fields }
|
|
24
|
-
$: using = { default: Text, ...using }
|
|
25
41
|
</script>
|
|
26
42
|
|
|
27
43
|
<tabs
|
|
28
44
|
class="flex w-full {className}"
|
|
45
|
+
class:is-below={below}
|
|
46
|
+
class:justify-center={align == 'center'}
|
|
47
|
+
class:justify-end={align == 'right'}
|
|
29
48
|
tabindex="0"
|
|
30
49
|
role="listbox"
|
|
31
50
|
use:navigator={{
|
|
@@ -37,13 +56,26 @@
|
|
|
37
56
|
on:move={handleNav}
|
|
38
57
|
on:select={handleNav}
|
|
39
58
|
>
|
|
40
|
-
{#each
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
{#each filtered as item, index}
|
|
60
|
+
<ItemWrapper
|
|
61
|
+
value={item}
|
|
62
|
+
{index}
|
|
63
|
+
{fields}
|
|
64
|
+
{using}
|
|
65
|
+
removable={editable}
|
|
66
|
+
selected={item === value}
|
|
67
|
+
{icons}
|
|
68
|
+
class="tab"
|
|
69
|
+
on:remove={handleRemove}
|
|
70
|
+
/>
|
|
48
71
|
{/each}
|
|
72
|
+
{#if editable}
|
|
73
|
+
<Icon
|
|
74
|
+
name="add"
|
|
75
|
+
role="button"
|
|
76
|
+
label="Add Tab"
|
|
77
|
+
size="small"
|
|
78
|
+
on:click={() => dispatch('add')}
|
|
79
|
+
/>
|
|
80
|
+
{/if}
|
|
49
81
|
</tabs>
|
package/src/Tree.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { createEventDispatcher } from 'svelte'
|
|
3
3
|
import NestedList from './NestedList.svelte'
|
|
4
|
-
import {
|
|
4
|
+
import { Item } from './items'
|
|
5
5
|
import { defaultFields } from './constants'
|
|
6
6
|
import { navigator } from './actions/navigator'
|
|
7
7
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
export { className as class }
|
|
11
11
|
export let items = []
|
|
12
12
|
export let fields = {}
|
|
13
|
-
export let using = { default:
|
|
13
|
+
export let using = { default: Item }
|
|
14
14
|
export let root = null
|
|
15
15
|
export let value = null
|
|
16
16
|
|
package/src/actions/navigable.js
CHANGED
|
@@ -2,7 +2,6 @@ export function navigable(
|
|
|
2
2
|
node,
|
|
3
3
|
{ horizontal = true, nested = false, enabled = true } = {}
|
|
4
4
|
) {
|
|
5
|
-
// console.log(node, enabled)
|
|
6
5
|
if (!enabled) return { destroy() {} }
|
|
7
6
|
const previous = () => node.dispatchEvent(new CustomEvent('previous'))
|
|
8
7
|
const next = () => node.dispatchEvent(new CustomEvent('next'))
|
package/src/actions/swipeable.js
CHANGED
package/src/constants.js
CHANGED
|
@@ -93,32 +93,3 @@ export function stateIconsFromNames(icons) {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
export const defaultStateIcons = stateIconsFromNames(defaultIcons)
|
|
96
|
-
// export const defaultStateIcons = {
|
|
97
|
-
// accordion: {
|
|
98
|
-
// opened: 'accordion-opened',
|
|
99
|
-
// closed: 'accordion-closed'
|
|
100
|
-
// },
|
|
101
|
-
// item: {
|
|
102
|
-
// remove: 'item-remove',
|
|
103
|
-
// add: 'item-add',
|
|
104
|
-
// clear: 'item-clear',
|
|
105
|
-
// search: 'item-search'
|
|
106
|
-
// },
|
|
107
|
-
// node: {
|
|
108
|
-
// opened: 'node-opened',
|
|
109
|
-
// closed: 'node-closed'
|
|
110
|
-
// },
|
|
111
|
-
// list: {
|
|
112
|
-
// selector: 'list-selector'
|
|
113
|
-
// },
|
|
114
|
-
// checkbox: {
|
|
115
|
-
// checked: 'checkbox-checked',
|
|
116
|
-
// unchecked: 'checkbox-unchecked',
|
|
117
|
-
// unknown: 'checkbox-unknown'
|
|
118
|
-
// },
|
|
119
|
-
// rating: { filled: 'rating-filled', empty: 'rating-empty' },
|
|
120
|
-
// radio: {
|
|
121
|
-
// off: 'radio-off',
|
|
122
|
-
// on: 'radio-on'
|
|
123
|
-
// }
|
|
124
|
-
// }
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { defaultFields } from '../constants'
|
|
3
|
+
import Icon from '../Icon.svelte'
|
|
4
|
+
|
|
5
|
+
export let value
|
|
6
|
+
export let fields = defaultFields
|
|
7
|
+
|
|
8
|
+
$: isObject = typeof value == 'object'
|
|
9
|
+
$: text = isObject ? value[fields.text] : value
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
{#if isObject}
|
|
13
|
+
{#if value[fields.icon]}
|
|
14
|
+
{@const iconName =
|
|
15
|
+
typeof value[fields.icon] == 'object'
|
|
16
|
+
? value[fields.icon][value[fields.state]]
|
|
17
|
+
: value[fields.icon]}
|
|
18
|
+
<Icon name={iconName} />
|
|
19
|
+
{:else if value[fields.image]}
|
|
20
|
+
<img
|
|
21
|
+
class="h-4 w-4 object-cover"
|
|
22
|
+
alt={value[fields.text]}
|
|
23
|
+
src={value[fields.image]}
|
|
24
|
+
/>
|
|
25
|
+
{/if}
|
|
26
|
+
{/if}
|
|
27
|
+
{#if text}
|
|
28
|
+
<p class="flex w-full">{text}</p>
|
|
29
|
+
{/if}
|
|
@@ -1,32 +1,47 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { createEventDispatcher } from 'svelte'
|
|
3
3
|
import { defaultFields, defaultStateIcons } from '../constants'
|
|
4
|
-
import
|
|
4
|
+
import Item from './Item.svelte'
|
|
5
|
+
import Icon from '../Icon.svelte'
|
|
6
|
+
|
|
5
7
|
const dispatch = createEventDispatcher()
|
|
6
8
|
|
|
9
|
+
let className = ''
|
|
10
|
+
export { className as class }
|
|
7
11
|
export let value
|
|
8
12
|
export let fields = defaultFields
|
|
9
|
-
export let using = { default:
|
|
13
|
+
export let using = { default: Item }
|
|
10
14
|
export let removable = false
|
|
15
|
+
export let selected = false
|
|
16
|
+
export let index = null
|
|
17
|
+
export let icons = defaultStateIcons.action
|
|
11
18
|
|
|
12
19
|
function handleClick() {
|
|
13
20
|
dispatch('remove', value)
|
|
14
21
|
}
|
|
22
|
+
|
|
15
23
|
$: component =
|
|
16
24
|
typeof value == 'object'
|
|
17
25
|
? using[value[fields.component] ?? 'default']
|
|
18
26
|
: using.default
|
|
19
27
|
</script>
|
|
20
28
|
|
|
21
|
-
<
|
|
29
|
+
<wrap-item
|
|
30
|
+
class="flex flex-row items-center {className}"
|
|
31
|
+
role="option"
|
|
32
|
+
aria-selected={selected}
|
|
33
|
+
data-path={index}
|
|
34
|
+
>
|
|
22
35
|
<item class="flex flex-row items-center">
|
|
23
|
-
<svelte:component this={component}
|
|
36
|
+
<svelte:component this={component} bind:value {fields} />
|
|
24
37
|
</item>
|
|
25
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
26
38
|
{#if removable}
|
|
27
|
-
<
|
|
28
|
-
|
|
39
|
+
<Icon
|
|
40
|
+
name={icons.remove}
|
|
41
|
+
role="button"
|
|
42
|
+
label="Remove"
|
|
43
|
+
size="small"
|
|
29
44
|
on:click={handleClick}
|
|
30
45
|
/>
|
|
31
46
|
{/if}
|
|
32
|
-
</
|
|
47
|
+
</wrap-item>
|
package/src/items/Link.svelte
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import
|
|
2
|
+
import Item from './Item.svelte'
|
|
3
3
|
import { defaultFields } from '../constants'
|
|
4
4
|
|
|
5
|
-
export let
|
|
5
|
+
export let value
|
|
6
6
|
export let fields = defaultFields
|
|
7
7
|
|
|
8
|
-
$: target = fields.target ?
|
|
8
|
+
$: target = fields.target ? value[fields.target] : ''
|
|
9
9
|
</script>
|
|
10
10
|
|
|
11
11
|
<a
|
|
12
12
|
class="flex flex-row flex-grow items-center"
|
|
13
|
-
href={
|
|
13
|
+
href={value[fields.url]}
|
|
14
14
|
{target}
|
|
15
15
|
tabindex="-1"
|
|
16
16
|
>
|
|
17
|
-
<
|
|
17
|
+
<Item {value} {fields} />
|
|
18
18
|
</a>
|
package/src/items/Node.svelte
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import Connector from './Connector.svelte'
|
|
3
2
|
import { defaultFields, defaultStateIcons } from '../constants'
|
|
3
|
+
import Icon from '../Icon.svelte'
|
|
4
|
+
import Connector from './Connector.svelte'
|
|
4
5
|
|
|
5
|
-
export let
|
|
6
|
+
export let value
|
|
6
7
|
export let fields = defaultFields
|
|
7
8
|
export let types = []
|
|
8
9
|
export let stateIcons = defaultStateIcons.node
|
|
@@ -13,13 +14,13 @@
|
|
|
13
14
|
export let path = []
|
|
14
15
|
|
|
15
16
|
$: stateIcons = { ...defaultStateIcons.node, ...(stateIcons ?? {}) }
|
|
16
|
-
$: hasChildren = fields.children in
|
|
17
|
+
$: hasChildren = fields.children in value
|
|
17
18
|
$: state =
|
|
18
|
-
hasChildren &&
|
|
19
|
+
hasChildren && value[fields.isOpen]
|
|
19
20
|
? { icon: stateIcons.opened, label: 'collapse' }
|
|
20
21
|
: { icon: stateIcons.closed, label: 'expand' }
|
|
21
|
-
$: component =
|
|
22
|
-
? using[
|
|
22
|
+
$: component = value[fields.component]
|
|
23
|
+
? using[value[fields.component]] || using.default
|
|
23
24
|
: using.default
|
|
24
25
|
</script>
|
|
25
26
|
|
|
@@ -35,14 +36,12 @@
|
|
|
35
36
|
>
|
|
36
37
|
{#each types as type}
|
|
37
38
|
{#if type === 'icon'}
|
|
38
|
-
<
|
|
39
|
-
<icon class={state.icon} aria-label={state.label} tabindex="-1" />
|
|
40
|
-
</span>
|
|
39
|
+
<Icon name={state.icon} label={state.label} class="w-4 small" />
|
|
41
40
|
{:else}
|
|
42
41
|
<Connector {type} />
|
|
43
42
|
{/if}
|
|
44
43
|
{/each}
|
|
45
44
|
<item>
|
|
46
|
-
<svelte:component this={component} bind:
|
|
45
|
+
<svelte:component this={component} bind:value {fields} />
|
|
47
46
|
</item>
|
|
48
47
|
</node>
|
package/src/items/Summary.svelte
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { defaultFields } from '../constants'
|
|
3
|
-
import
|
|
3
|
+
import Item from './Item.svelte'
|
|
4
4
|
|
|
5
|
-
export let
|
|
5
|
+
export let value
|
|
6
6
|
export let fields = {}
|
|
7
7
|
export let using = {}
|
|
8
8
|
|
|
9
9
|
$: fields = { ...defaultFields, ...fields }
|
|
10
|
-
$: using = { default:
|
|
11
|
-
$: hasItems =
|
|
12
|
-
$: component = using[
|
|
10
|
+
$: using = { default: Item, ...using }
|
|
11
|
+
$: hasItems = value[fields.children] && value[fields.children].length > 0
|
|
12
|
+
$: component = using[value[fields.component] ?? 'default']
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
15
|
<summary
|
|
16
16
|
class="flex flex-row flex-shrink-0 items-center w-full cursor-pointer"
|
|
17
17
|
tabindex="-1"
|
|
18
18
|
>
|
|
19
|
-
<svelte:component this={component} bind:
|
|
19
|
+
<svelte:component this={component} bind:value {fields} />
|
|
20
20
|
{#if hasItems}
|
|
21
|
-
{#if
|
|
21
|
+
{#if value[fields.isOpen]}
|
|
22
22
|
<icon class="sm accordion-opened" aria-label="expand" />
|
|
23
23
|
{:else}
|
|
24
24
|
<icon class="sm accordion-closed" aria-label="collapse" />
|
package/src/items/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
export { default as
|
|
1
|
+
export { default as Item } from './Item.svelte'
|
|
2
2
|
export { default as Link } from './Link.svelte'
|
|
3
3
|
export { default as Node } from './Node.svelte'
|
|
4
|
-
export { default as
|
|
5
|
-
export { default as Collapsible } from './Collapsible.svelte'
|
|
4
|
+
export { default as ItemWrapper } from './ItemWrapper.svelte'
|
|
6
5
|
export { default as Connector } from './Connector.svelte'
|
|
7
6
|
export { default as Separator } from './Separator.svelte'
|
|
8
7
|
export { default as Summary } from './Summary.svelte'
|
package/src/lib/index.js
CHANGED
package/src/mocks/Custom.svelte
CHANGED
package/src/List-Discard.svelte
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import ListActions from './ListActions.svelte'
|
|
3
|
-
import ListItems from './List.svelte'
|
|
4
|
-
|
|
5
|
-
let className = 'list'
|
|
6
|
-
export { className as class }
|
|
7
|
-
export let items = []
|
|
8
|
-
export let fields = {}
|
|
9
|
-
export let using = {}
|
|
10
|
-
export let value = null
|
|
11
|
-
export let searchable = false
|
|
12
|
-
export let editable = false
|
|
13
|
-
|
|
14
|
-
let search
|
|
15
|
-
let filtered
|
|
16
|
-
|
|
17
|
-
function addItem() {
|
|
18
|
-
items = [...items, {}]
|
|
19
|
-
value = items[items.length - 1]
|
|
20
|
-
}
|
|
21
|
-
function deleteSelection() {
|
|
22
|
-
if (value) value.isDeleted = true
|
|
23
|
-
}
|
|
24
|
-
function clearSelection() {
|
|
25
|
-
value = null
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
$: filtered =
|
|
29
|
-
searchable && search && search.length
|
|
30
|
-
? items.filter((item) => item[fields.text].includes(search))
|
|
31
|
-
: items
|
|
32
|
-
</script>
|
|
33
|
-
|
|
34
|
-
<list class="flex flex-col w-full {className}">
|
|
35
|
-
{#if searchable || editable}
|
|
36
|
-
<ListActions
|
|
37
|
-
bind:search
|
|
38
|
-
{searchable}
|
|
39
|
-
{editable}
|
|
40
|
-
on:delete={deleteSelection}
|
|
41
|
-
on:clear={clearSelection}
|
|
42
|
-
on:add={addItem}
|
|
43
|
-
/>
|
|
44
|
-
{/if}
|
|
45
|
-
<scroll class="flex flex-col h-full overflow-scroll">
|
|
46
|
-
<ListItems bind:items={filtered} {fields} {using} bind:value on:select />
|
|
47
|
-
</scroll>
|
|
48
|
-
</list>
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEventDispatcher } from 'svelte'
|
|
3
|
-
import { defaultFields } from '../constants'
|
|
4
|
-
|
|
5
|
-
const dispatch = createEventDispatcher()
|
|
6
|
-
|
|
7
|
-
export let content
|
|
8
|
-
export let fields = {}
|
|
9
|
-
|
|
10
|
-
$: fields = { ...defaultFields, ...fields }
|
|
11
|
-
$: hasItems = content[fields.children] && content[fields.children].length > 0
|
|
12
|
-
|
|
13
|
-
function toggle() {
|
|
14
|
-
if (hasItems) {
|
|
15
|
-
content.isOpen = !content.isOpen
|
|
16
|
-
}
|
|
17
|
-
dispatch('toggle', content)
|
|
18
|
-
}
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
22
|
-
<collapsible
|
|
23
|
-
class="flex flex-row flex-shrink-0 items-center w-full leading-loose cursor-pointer"
|
|
24
|
-
class:expanded={content.isOpen}
|
|
25
|
-
on:click={toggle}
|
|
26
|
-
>
|
|
27
|
-
{#if content[fields.image]}
|
|
28
|
-
<img
|
|
29
|
-
class="h-8 w-8 rounded-full"
|
|
30
|
-
alt={content[fields.text]}
|
|
31
|
-
src={content[fields.image]}
|
|
32
|
-
/>
|
|
33
|
-
{/if}
|
|
34
|
-
{#if content[fields.icon]}
|
|
35
|
-
<icon class={content[fields.icon]} />
|
|
36
|
-
{/if}
|
|
37
|
-
{#if content[fields.url]}
|
|
38
|
-
<a href={content[fields.url]} class="flex flex-grow">
|
|
39
|
-
{content[fields.text]}
|
|
40
|
-
</a>
|
|
41
|
-
{:else}
|
|
42
|
-
<p class="flex flex-grow">{content[fields.text]}</p>
|
|
43
|
-
{/if}
|
|
44
|
-
{#if hasItems}
|
|
45
|
-
{#if content.isOpen}
|
|
46
|
-
<icon class="sm accordion-opened" aria-label="expand" />
|
|
47
|
-
{:else}
|
|
48
|
-
<icon class="sm accordion-closed" aria-label="collapse" />
|
|
49
|
-
{/if}
|
|
50
|
-
{/if}
|
|
51
|
-
</collapsible>
|
package/src/items/Text.svelte
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { defaultFields } from '../constants'
|
|
3
|
-
|
|
4
|
-
export let content
|
|
5
|
-
export let fields = defaultFields
|
|
6
|
-
|
|
7
|
-
$: isObject = typeof content == 'object'
|
|
8
|
-
$: text = isObject ? content[fields.text] : content
|
|
9
|
-
</script>
|
|
10
|
-
|
|
11
|
-
{#if isObject}
|
|
12
|
-
{#if content[fields.icon]}
|
|
13
|
-
{@const iconName =
|
|
14
|
-
typeof content[fields.icon] == 'object'
|
|
15
|
-
? content[fields.icon][content[fields.state]]
|
|
16
|
-
: content[fields.icon]}
|
|
17
|
-
<icon class={iconName} />
|
|
18
|
-
{:else if content[fields.image]}
|
|
19
|
-
<img
|
|
20
|
-
class="h-4 w-4 object-cover"
|
|
21
|
-
alt={content[fields.text]}
|
|
22
|
-
src={content[fields.image]}
|
|
23
|
-
/>
|
|
24
|
-
{/if}
|
|
25
|
-
{/if}
|
|
26
|
-
{#if text}
|
|
27
|
-
<p class="flex w-full">{text}</p>
|
|
28
|
-
{/if}
|