@rokkit/core 1.0.0-next.22 → 1.0.0-next.23

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": "@rokkit/core",
3
- "version": "1.0.0-next.22",
3
+ "version": "1.0.0-next.23",
4
4
  "description": "Core components, actions and stores for svelte apps.",
5
5
  "author": "Jerry Thomas <me@jerrythomas.name>",
6
6
  "license": "MIT",
@@ -63,7 +63,7 @@
63
63
  class:is-selected={item === value}
64
64
  data-path={index}
65
65
  >
66
- <Summary {fields} {using} bind:content={item} />
66
+ <Summary {fields} {using} bind:value={item} />
67
67
  {#if hasItems && item[fields.isOpen]}
68
68
  <List
69
69
  bind:items={item[fields.children]}
@@ -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} content={item} {fields} />
30
+ <svelte:component this={component} value={item} {fields} />
31
31
  </crumb>
32
32
  {/if}
33
33
  {/each}
@@ -16,8 +16,8 @@
16
16
  export let fields = defaultFields
17
17
  export let using = { default: Text }
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
23
  $: using = { default: Text, ...using }
@@ -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/Icon.svelte CHANGED
@@ -1,17 +1,31 @@
1
1
  <script>
2
2
  let className = ''
3
3
  export { className as class }
4
-
5
4
  export let name = ''
6
- let h
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
10
+
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-click-events-have-key-events -->
10
- <square-icon
11
- class="flex flex-col flex-shrink-0 h-full items-center justify-center {className}"
12
- bind:clientHeight={h}
13
- style:width="{h}px"
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
- <icon class={name} aria-hidden="true" />
17
- </square-icon>
30
+ <i class={name} aria-hidden="true" />
31
+ </icon>
package/src/List.svelte CHANGED
@@ -3,6 +3,7 @@
3
3
  import { createEventDispatcher } from 'svelte'
4
4
  import { defaultFields } from './constants'
5
5
  import { Text } from './items'
6
+ import { props } from 'ramda'
6
7
 
7
8
  const dispatch = createEventDispatcher()
8
9
 
@@ -47,6 +48,7 @@
47
48
  ? using[item[fields.component]] || using.default
48
49
  : using.default}
49
50
  {@const path = [...hierarchy, index].join(',')}
51
+ {@const props = item[fields.props] || { fields }}
50
52
  <item
51
53
  class="flex flex-shrink-0 flex-grow-0 items-center cursor-pointer w-full gap-2 select-none item"
52
54
  role="option"
@@ -56,8 +58,8 @@
56
58
  >
57
59
  <svelte:component
58
60
  this={component}
59
- bind:content={item}
60
- {fields}
61
+ bind:value={item}
62
+ {...props}
61
63
  on:change
62
64
  />
63
65
  </item>
@@ -28,35 +28,25 @@
28
28
  class:rtl
29
29
  tabindex="-1"
30
30
  >
31
- <!-- tabindex={hierarchy.length == 0 ? 0 : -1}
32
- use:navigator={{ items, fields, indices, enabled: hierarchy.length == 0 }}
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:content
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 === content}
44
+ selected={value === item}
55
45
  />
56
46
  <!-- types={[...connectors, type, nodeTypes[index]]} -->
57
- {#if hasChildren && content[fields.isOpen]}
47
+ {#if hasChildren && item[fields.isOpen]}
58
48
  <svelte:self
59
- items={content[fields.children]}
49
+ items={item[fields.children]}
60
50
  bind:value
61
51
  {fields}
62
52
  {using}
@@ -41,7 +41,7 @@
41
41
  on:next={moveNext}
42
42
  on:previous={moveBack}
43
43
  />
44
- <!-- <svelte:component this={component} bind:content={value} {fields} on:change /> -->
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,23 +1,26 @@
1
1
  <script>
2
+ import { createEventDispatcher } from 'svelte'
2
3
  import { defaultFields } from './constants'
3
4
  import { Text } 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 = { default: Text }
14
+ export let using = {}
10
15
  export let compact = true
11
16
  export let value
17
+ let cursor = []
12
18
 
13
- const getComponent = (item, fields) => {
14
- return fields.component
15
- ? item[fields.component] ?? using.default
16
- : using.default
17
- }
19
+ function handleNav(event) {
20
+ value = event.detail.node
21
+ cursor = event.detail.path
18
22
 
19
- const onItemClick = (item) => {
20
- value = item
23
+ dispatch('change', { item: value, indices: cursor })
21
24
  }
22
25
 
23
26
  $: useComponent = !items.every((item) => [false, true].includes(item))
@@ -28,25 +31,37 @@
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 ? getComponent(item, fields) : null}
39
- <!-- svelte-ignore a11y-click-events-have-key-events -->
51
+ {@const component = useComponent
52
+ ? getComponent(item, fields, using)
53
+ : null}
40
54
  <item
41
55
  class="flex relative"
42
- class:is-selected={item === value}
43
- on:click={() => onItemClick(item)}
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} content={item} {fields} />
64
+ <svelte:component this={component} value={item} {fields} />
50
65
  {/if}
51
66
  </item>
52
67
  {/each}
@@ -3,25 +3,28 @@
3
3
 
4
4
  const dispatch = createEventDispatcher()
5
5
 
6
- export let icon = null
7
- export let label
8
- export let active = false
9
- export let allowClose = false
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 class="flex flex-row items-center" class:active on:click>
14
- {#if icon}
15
- <icon class={icon} aria-label={icon} />
16
- {/if}
17
- {#if label}
18
- <p class="flex flex-shrink-0 flex-grow justify-center">{label}</p>
19
- {/if}
20
- {#if allowClose}
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,8 +1,10 @@
1
1
  <script>
2
- import { defaultFields } from './constants'
2
+ import { TableIndex } from './../../../shared/config/dist/tableIndex.d.ts'
3
+ import { defaultFields, defaultStateIcons } from './constants'
3
4
  import { Text } from './items'
4
5
  import { navigator } from './actions'
5
6
  import { createEventDispatcher } from 'svelte'
7
+ import TabItem from './TabItem.svelte'
6
8
 
7
9
  const dispatch = createEventDispatcher()
8
10
 
@@ -12,20 +14,39 @@
12
14
  export let fields = {}
13
15
  export let using = {}
14
16
  export let value = null
17
+ export let below = false
18
+ export let align = 'left'
19
+ export let editable = false
20
+ export let icons = defaultStateIcons.action
21
+
15
22
  let cursor = []
16
23
 
24
+ function handleRemove(item) {
25
+ if (typeof item === Object) {
26
+ item[fields.isDeleted] = true
27
+ } else {
28
+ items = items.filter((i) => i !== item)
29
+ }
30
+
31
+ dispatch('remove', { item })
32
+ }
17
33
  function handleNav(event) {
18
34
  value = event.detail.node
19
35
  cursor = event.detail.path
20
36
 
21
37
  dispatch('select', { item: value, indices: cursor })
22
38
  }
39
+ $: icons = { ...defaultStateIcons.action, ...icons }
40
+ $: filtered = items.filter((item) => !item[fields.isDeleted])
23
41
  $: fields = { ...defaultFields, ...fields }
24
42
  $: using = { default: Text, ...using }
25
43
  </script>
26
44
 
27
45
  <tabs
28
46
  class="flex w-full {className}"
47
+ class:is-below={below}
48
+ class:justify-center={align == 'center'}
49
+ class:justify-end={align == 'right'}
29
50
  tabindex="0"
30
51
  role="listbox"
31
52
  use:navigator={{
@@ -37,13 +58,42 @@
37
58
  on:move={handleNav}
38
59
  on:select={handleNav}
39
60
  >
40
- {#each items as item, index}
41
- {@const component = item[fields.component]
61
+ {#each filtered as item, index}
62
+ <TabItem
63
+ value={item}
64
+ {index}
65
+ {fields}
66
+ {using}
67
+ removable={editable}
68
+ selected={item === value}
69
+ {icons}
70
+ />
71
+ <!-- {@const component = item[fields.component]
42
72
  ? using[item[fields.component]] || using.default
43
73
  : using.default}
44
74
 
45
- <item class="flex" class:is-selected={item === value} data-path={index}>
46
- <svelte:component this={component} content={item} {fields} />
47
- </item>
75
+ <item
76
+ class="flex"
77
+ role="option"
78
+ aria-selected={item === value}
79
+ class:is-selected={item === value}
80
+ data-path={index}
81
+ >
82
+ <svelte:component this={component} value={item} {fields} />
83
+ {#if editable}
84
+ <icon class={icons.close} on:click={() => handleRemove(item)} />
85
+ {/if}
86
+ </item> -->
48
87
  {/each}
88
+ {#if editable}
89
+ <add-tab
90
+ class="flex items-center"
91
+ role="button"
92
+ on:click={() => dispatch('add')}
93
+ on:keydown={(e) => e.key === 'Enter' && e.currentTarget.click()}
94
+ tabindex="0"
95
+ >
96
+ <icon class={icons.add} />
97
+ </add-tab>
98
+ {/if}
49
99
  </tabs>
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
- // }
@@ -4,45 +4,45 @@
4
4
 
5
5
  const dispatch = createEventDispatcher()
6
6
 
7
- export let content
7
+ export let value
8
8
  export let fields = {}
9
9
 
10
10
  $: fields = { ...defaultFields, ...fields }
11
- $: hasItems = content[fields.children] && content[fields.children].length > 0
11
+ $: hasItems = value[fields.children] && value[fields.children].length > 0
12
12
 
13
13
  function toggle() {
14
14
  if (hasItems) {
15
- content.isOpen = !content.isOpen
15
+ value.isOpen = !value.isOpen
16
16
  }
17
- dispatch('toggle', content)
17
+ dispatch('toggle', value)
18
18
  }
19
19
  </script>
20
20
 
21
21
  <!-- svelte-ignore a11y-click-events-have-key-events -->
22
22
  <collapsible
23
23
  class="flex flex-row flex-shrink-0 items-center w-full leading-loose cursor-pointer"
24
- class:expanded={content.isOpen}
24
+ class:expanded={value.isOpen}
25
25
  on:click={toggle}
26
26
  >
27
- {#if content[fields.image]}
27
+ {#if value[fields.image]}
28
28
  <img
29
29
  class="h-8 w-8 rounded-full"
30
- alt={content[fields.text]}
31
- src={content[fields.image]}
30
+ alt={value[fields.text]}
31
+ src={value[fields.image]}
32
32
  />
33
33
  {/if}
34
- {#if content[fields.icon]}
35
- <icon class={content[fields.icon]} />
34
+ {#if value[fields.icon]}
35
+ <icon class={value[fields.icon]} />
36
36
  {/if}
37
- {#if content[fields.url]}
38
- <a href={content[fields.url]} class="flex flex-grow">
39
- {content[fields.text]}
37
+ {#if value[fields.url]}
38
+ <a href={value[fields.url]} class="flex flex-grow">
39
+ {value[fields.text]}
40
40
  </a>
41
41
  {:else}
42
- <p class="flex flex-grow">{content[fields.text]}</p>
42
+ <p class="flex flex-grow">{value[fields.text]}</p>
43
43
  {/if}
44
44
  {#if hasItems}
45
- {#if content.isOpen}
45
+ {#if value.isOpen}
46
46
  <icon class="sm accordion-opened" aria-label="expand" />
47
47
  {:else}
48
48
  <icon class="sm accordion-closed" aria-label="collapse" />
@@ -2,17 +2,17 @@
2
2
  import Text from './Text.svelte'
3
3
  import { defaultFields } from '../constants'
4
4
 
5
- export let content
5
+ export let value
6
6
  export let fields = defaultFields
7
7
 
8
- $: target = fields.target ? content[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={content[fields.url]}
13
+ href={value[fields.url]}
14
14
  {target}
15
15
  tabindex="-1"
16
16
  >
17
- <Text {content} {fields} />
17
+ <Text {value} {fields} />
18
18
  </a>
@@ -1,8 +1,8 @@
1
1
  <script>
2
2
  import Connector from './Connector.svelte'
3
3
  import { defaultFields, defaultStateIcons } from '../constants'
4
-
5
- export let content
4
+ import Icon from '../Icon.svelte'
5
+ export let value
6
6
  export let fields = defaultFields
7
7
  export let types = []
8
8
  export let stateIcons = defaultStateIcons.node
@@ -13,13 +13,13 @@
13
13
  export let path = []
14
14
 
15
15
  $: stateIcons = { ...defaultStateIcons.node, ...(stateIcons ?? {}) }
16
- $: hasChildren = fields.children in content
16
+ $: hasChildren = fields.children in value
17
17
  $: state =
18
- hasChildren && content[fields.isOpen]
18
+ hasChildren && value[fields.isOpen]
19
19
  ? { icon: stateIcons.opened, label: 'collapse' }
20
20
  : { icon: stateIcons.closed, label: 'expand' }
21
- $: component = content[fields.component]
22
- ? using[content[fields.component]] || using.default
21
+ $: component = value[fields.component]
22
+ ? using[value[fields.component]] || using.default
23
23
  : using.default
24
24
  </script>
25
25
 
@@ -35,14 +35,12 @@
35
35
  >
36
36
  {#each types as type}
37
37
  {#if type === 'icon'}
38
- <span class="flex flex-col w-4 h-full items-center justify-center">
39
- <icon class={state.icon} aria-label={state.label} tabindex="-1" />
40
- </span>
38
+ <Icon name={state.icon} label={state.label} class="w-4 small" />
41
39
  {:else}
42
40
  <Connector {type} />
43
41
  {/if}
44
42
  {/each}
45
43
  <item>
46
- <svelte:component this={component} bind:content {fields} />
44
+ <svelte:component this={component} bind:value {fields} />
47
45
  </item>
48
46
  </node>
@@ -20,7 +20,7 @@
20
20
 
21
21
  <pill class="flex flex-row items-center">
22
22
  <item class="flex flex-row items-center">
23
- <svelte:component this={component} content={value} {fields} />
23
+ <svelte:component this={component} {value} {fields} />
24
24
  </item>
25
25
  <!-- svelte-ignore a11y-click-events-have-key-events -->
26
26
  {#if removable}
@@ -2,23 +2,23 @@
2
2
  import { defaultFields } from '../constants'
3
3
  import Text from './Text.svelte'
4
4
 
5
- export let content
5
+ export let value
6
6
  export let fields = {}
7
7
  export let using = {}
8
8
 
9
9
  $: fields = { ...defaultFields, ...fields }
10
10
  $: using = { default: Text, ...using }
11
- $: hasItems = content[fields.children] && content[fields.children].length > 0
12
- $: component = using[content[fields.component] ?? 'default']
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:content {fields} />
19
+ <svelte:component this={component} bind:value {fields} />
20
20
  {#if hasItems}
21
- {#if content[fields.isOpen]}
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" />
@@ -1,25 +1,26 @@
1
1
  <script>
2
2
  import { defaultFields } from '../constants'
3
+ import Icon from '../Icon.svelte'
3
4
 
4
- export let content
5
+ export let value
5
6
  export let fields = defaultFields
6
7
 
7
- $: isObject = typeof content == 'object'
8
- $: text = isObject ? content[fields.text] : content
8
+ $: isObject = typeof value == 'object'
9
+ $: text = isObject ? value[fields.text] : value
9
10
  </script>
10
11
 
11
12
  {#if isObject}
12
- {#if content[fields.icon]}
13
+ {#if value[fields.icon]}
13
14
  {@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]}
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]}
19
20
  <img
20
21
  class="h-4 w-4 object-cover"
21
- alt={content[fields.text]}
22
- src={content[fields.image]}
22
+ alt={value[fields.text]}
23
+ src={value[fields.image]}
23
24
  />
24
25
  {/if}
25
26
  {/if}
package/src/lib/index.js CHANGED
@@ -1 +1,7 @@
1
1
  export * from './nested'
2
+
3
+ export function getComponent(item, fields, using) {
4
+ return fields.component
5
+ ? item[fields.component] ?? using.default
6
+ : using.default
7
+ }
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import { defaultFields } from '../../src/constants'
3
- export let content
3
+ export let value
4
4
  export let fields = defaultFields
5
5
  </script>
6
6
 
7
- <span>{content[fields.text]}</span>
7
+ <span>{value[fields.text]}</span>
@@ -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>