@rokkit/ui 1.0.0-next.108 → 1.0.0-next.109

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/ui",
3
- "version": "1.0.0-next.108",
3
+ "version": "1.0.0-next.109",
4
4
  "description": "Organisms are larger, more complex building blocks that are composed of multiple molecules",
5
5
  "author": "Jerry Thomas <me@jerrythomas.name>",
6
6
  "license": "MIT",
@@ -32,6 +32,8 @@
32
32
  "@rokkit/actions": "latest",
33
33
  "@rokkit/core": "latest",
34
34
  "@rokkit/states": "latest",
35
+ "@rokkit/data": "latest",
36
+ "@rokkit/input": "latest",
35
37
  "d3-scale": "^4.0.2",
36
38
  "date-fns": "^4.1.0",
37
39
  "ramda": "^0.30.1"
@@ -14,6 +14,7 @@
14
14
  import Item from './Item.svelte'
15
15
  import ListBody from './ListBody.svelte'
16
16
 
17
+ const eventNames = ['collapse', 'change', 'expand', 'click', 'select', 'move']
17
18
  /**
18
19
  * @typedef {Object} Props
19
20
  * @property {string} [class]
@@ -35,16 +36,28 @@
35
36
  header = null,
36
37
  footer = null,
37
38
  empty = null,
38
- stub = null,
39
- extra,
40
- ...events
39
+ oncollapse,
40
+ onexpand,
41
+ onchange,
42
+ onselect,
43
+ onmove,
44
+ ...snippets
41
45
  } = $props()
42
46
 
43
47
  let emitter = $derived(
44
- createEmitter(events, ['collapse', 'change', 'expand', 'click', 'select', 'move'])
48
+ createEmitter({ oncollapse, onexpand, onchange, onselect, onmove }, eventNames)
45
49
  )
50
+ function handleAction(event) {
51
+ const { name, data } = event.detail
52
+
53
+ if (has(name, emitter)) {
54
+ value = data.value
55
+ selected = data.selected
56
+ emitter[name](data)
57
+ }
58
+ }
59
+
46
60
  let wrapper = new NestedController(items, value, fields, {
47
- events,
48
61
  multiselect,
49
62
  autoCloseSiblings
50
63
  })
@@ -70,7 +83,7 @@
70
83
  {/if}
71
84
  </rk-list-item>
72
85
  {/if}
73
- {#each items as item, index}
86
+ {#each items as item, index (index)}
74
87
  {@const key = `${index}`}
75
88
  {@const expanded = item[derivedFields.expanded]}
76
89
  <div
@@ -92,9 +105,8 @@
92
105
  bind:value
93
106
  fields={fields.fields ?? fields}
94
107
  {selected}
95
- {stub}
96
108
  onchange={emitter.change}
97
- {extra}
109
+ {snippets}
98
110
  />
99
111
  </rk-list>
100
112
  {/if}
@@ -16,7 +16,7 @@
16
16
  </script>
17
17
 
18
18
  <rk-crumbs class={classes}>
19
- {#each items as item, index}
19
+ {#each items as item, index (index)}
20
20
  {#if index > 0}
21
21
  <span>
22
22
  {#if separator.length === 1}
@@ -60,14 +60,14 @@
60
60
  </month-year>
61
61
  <cal-body class="flex w-full cursor-pointer flex-col p-1">
62
62
  <days-of-week class="grid grid-cols-7">
63
- {#each weekdays as day, index}
63
+ {#each weekdays as day, index (index)}
64
64
  <p class:weekend={index % 6 === 0}>
65
65
  {day.slice(0, 1)}
66
66
  </p>
67
67
  {/each}
68
68
  </days-of-week>
69
69
  <days-of-month class="grid grid-cols-7 grid-rows-5">
70
- {#each days as { day, offset, date, weekend }}
70
+ {#each days as { day, offset, date, weekend } (date)}
71
71
  {@const start = offset > 0 ? offset : 'auto'}
72
72
  <!-- svelte-ignore a11y_click_events_have_key_events -->
73
73
  <day-of-month
@@ -33,7 +33,7 @@
33
33
  <p>{value.text}</p>
34
34
  </slide>
35
35
  <dot-nav role="radiogroup">
36
- {#each items as item, index}
36
+ {#each items as item, index (index)}
37
37
  <dot
38
38
  role="radio"
39
39
  aria-checked={currentIndex === index}
@@ -23,7 +23,7 @@
23
23
  <error> Invalid schema. Expected schema to include an 'elements' array. </error>
24
24
  {:else}
25
25
  <Wrapper {...wrapperProps}>
26
- {#each schema.elements as item}
26
+ {#each schema.elements as item, index (index)}
27
27
  {@const elementPath = item.key ? [...path, item.key] : path}
28
28
  {@const props = { ...item.props, path: elementPath }}
29
29
  {@const nested = Array.isArray(item.elements) && item.elements.length > 0}
package/src/List.svelte CHANGED
@@ -30,8 +30,10 @@
30
30
  header,
31
31
  footer,
32
32
  empty,
33
- stub,
34
- ...events
33
+ onselect,
34
+ onchange,
35
+ onmove,
36
+ ...snippets
35
37
  } = $props()
36
38
 
37
39
  let selected = $state([])
@@ -46,8 +48,7 @@
46
48
  }
47
49
  }
48
50
 
49
- let emitter = createEmitter(events, ['select', 'change', 'move'])
50
- let extra = omit(['onselect', 'onchange', 'onmove'], events)
51
+ let emitter = createEmitter({ onchange, onmove, onselect }, ['select', 'change', 'move'])
51
52
  let wrapper = new ListController(items, value, fields, { multiSelect })
52
53
  </script>
53
54
 
@@ -76,9 +77,8 @@
76
77
  {fields}
77
78
  selectedKeys={wrapper.selectedKeys}
78
79
  focusedKey={wrapper.focusedKey}
79
- {stub}
80
80
  onchange={emitter.change}
81
- {extra}
81
+ {snippets}
82
82
  />
83
83
  {/if}
84
84
  </rk-body>
@@ -11,16 +11,15 @@
11
11
  onchange = () => {},
12
12
  selectedKeys = new SvelteSet(),
13
13
  focusedKey = null,
14
- stub = null,
15
- extra
14
+ snippets = {}
16
15
  } = $props()
17
16
  let fm = $derived.by(() => {
18
17
  return new FieldMapper(fields)
19
18
  })
20
19
  </script>
21
20
 
22
- {#each items as item, index}
23
- {@const template = getSnippet(extra, fm.get('snippet', item, stub))}
21
+ {#each items as item, index (index)}
22
+ {@const template = getSnippet(snippets, fm.get('snippet', item, 'stub'))}
24
23
  {@const pathKey = getKeyFromPath([...path, index])}
25
24
  {@const props = fm.get('props', item) || {}}
26
25
  <rk-list-item
@@ -36,7 +36,7 @@
36
36
  >
37
37
  {#if value.length > 0}
38
38
  <items class="flex flex-wrap">
39
- {#each value as item}
39
+ {#each value as item, index (index)}
40
40
  <Item value={item} {fields} {using} removable on:remove={handleRemove} class="pill" />
41
41
  {/each}
42
42
  </items>
@@ -42,7 +42,7 @@
42
42
  </script>
43
43
 
44
44
  <rk-nested-list role="tree">
45
- {#each items as item, index}
45
+ {#each items as item, index (index)}
46
46
  {@const nodePath = [...path, index]}
47
47
  {@const key = getKeyFromPath(nodePath)}
48
48
  {@const expanded = item[fields.expanded]}
@@ -1,6 +1,8 @@
1
1
  <script>
2
2
  import { defaultFields, flattenNestedList } from '@rokkit/core'
3
- import { Item, BreadCrumbs } from '@rokkit/molecules'
3
+ import Item from './Item.svelte'
4
+ import BreadCrumbs from './BreadCrumbs.svelte'
5
+ import Icon from './Icon.svelte'
4
6
  // import { flattenNestedList } from './lib/nested'
5
7
  import { createEventDispatcher } from 'svelte'
6
8
 
@@ -47,13 +49,15 @@
47
49
 
48
50
  $: flatList = flattenNestedList(items, fields)
49
51
  $: fields = { ...defaultFields, ...(fields ?? {}) }
50
- $: using = { default: Item, ...(using ?? {}) }
51
52
  </script>
52
53
 
53
54
  <pages>
54
- <!-- svelte-ignore a11y-click-events-have-key-events -->
55
- <icon class="arrow-left cursor-pointer" on:click={() => handleNav('previous')} />
55
+ <Icon
56
+ name="arrow-left"
57
+ class="cursor-pointer"
58
+ label="Previous"
59
+ onclick={() => handleNav('previous')}
60
+ />
56
61
  <BreadCrumbs items={trail} {fields} {using} />
57
- <!-- svelte-ignore a11y-click-events-have-key-events -->
58
- <icon class="arrow-right cursor-pointer" on:click={() => handleNav('next')} />
62
+ <Icon name="arrow-right" class="cursor-pointer" onclick={() => handleNav('next')} label="Next" />
59
63
  </pages>
package/src/Node.svelte CHANGED
@@ -41,7 +41,6 @@
41
41
  )
42
42
 
43
43
  const template = getSnippet(value[fields.snippet], snippets, stub)
44
- $inspect(template)
45
44
  </script>
46
45
 
47
46
  <rk-node
@@ -53,7 +52,7 @@
53
52
  data-depth={path.length}
54
53
  >
55
54
  <div class="flex flex-row items-center">
56
- {#each types as type}
55
+ {#each types as type, index (index)}
57
56
  {#if type === 'icon'}
58
57
  <Icon name={state.icon} label={state.label} state={stateName} class="w-4" size="small" />
59
58
  {:else}
@@ -41,7 +41,7 @@
41
41
  </script>
42
42
 
43
43
  <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
44
- <nav-pages class="grid grid-cols-3 select-none {className}" tabindex="0">
44
+ <nav-pages class="grid select-none grid-cols-3 {className}" tabindex="0">
45
45
  <!-- svelte-ignore a11y-click-events-have-key-events -->
46
46
  <span
47
47
  class="flex cursor-pointer items-center"
@@ -59,7 +59,7 @@
59
59
  </span>
60
60
  <span class="flex items-center justify-center">
61
61
  <block class="flex items-center">
62
- {#each items as item, index}
62
+ {#each items as item, index (index)}
63
63
  <!-- svelte-ignore a11y-click-events-have-key-events -->
64
64
  <pg
65
65
  class:numbers
@@ -21,7 +21,7 @@
21
21
  </script>
22
22
 
23
23
  <span class="progress flex items-center gap-2" class:empty={count === 0}>
24
- {#each steps as step}
24
+ {#each steps as step, index (index)}
25
25
  <!-- svelte-ignore a11y-click-events-have-key-events -->
26
26
  <dot
27
27
  class="step flex h-3 w-3 rounded-full border-2 border-neutral-100 bg-neutral-300"
@@ -37,7 +37,7 @@
37
37
  class="flex cursor-pointer select-none flex-col {className}"
38
38
  class:disabled={readOnly}
39
39
  >
40
- {#each options as item}
40
+ {#each options as item, index (index)}
41
41
  {@const label = mapping.get('text', item)}
42
42
  {@const itemValue = mapping.get('value', item, label)}
43
43
 
@@ -104,7 +104,7 @@
104
104
  </rk-range-track>
105
105
 
106
106
  <rk-ticks style:--count={tickItems.length - 1}>
107
- {#each tickItems as { value, label }}
107
+ {#each tickItems as { value, label }, index (index)}
108
108
  <RangeTick {label} {value} on:click={handleClick} />
109
109
  {/each}
110
110
  </rk-ticks>
package/src/Rating.svelte CHANGED
@@ -76,7 +76,7 @@
76
76
  {#if name}
77
77
  <input {name} hidden type="number" bind:value min={0} {max} readOnly={disabled} />
78
78
  {/if}
79
- {#each stars as selected, index}
79
+ {#each stars as selected, index (index)}
80
80
  {@const stateIcon = selected ? stateIcons.filled : stateIcons.empty}
81
81
  {@const label = [placeholder, index + 1, 'out of', max].join(' ')}
82
82
  <Icon
@@ -63,7 +63,7 @@
63
63
  class="overflow-hidden {className}"
64
64
  bind:clientWidth={width}
65
65
  >
66
- {#each items as item, index}
66
+ {#each items as item, index (index)}
67
67
  {@const segmentClass = 'col-' + (index + 1)}
68
68
  {@const props = mapping.get('props', item, {})}
69
69
  {@const Template = item[mapping.fields.component]}
@@ -34,7 +34,7 @@
34
34
  class="relative grid h-full w-full overflow-hidden"
35
35
  bind:clientWidth={width}
36
36
  >
37
- {#each columns as column, index}
37
+ {#each columns as column, index (index)}
38
38
  {#if index === activeIndex}
39
39
  <rk-segment
40
40
  class="slide absolute h-full w-full {column}"
@@ -21,11 +21,11 @@
21
21
  </script>
22
22
 
23
23
  <div
24
- class="stepper w-full flex flex-col items-center gap-3 border rounded p-8 shadow"
24
+ class="stepper flex w-full flex-col items-center gap-3 rounded border p-8 shadow"
25
25
  style:--count={data.length}
26
26
  >
27
27
  <row>
28
- {#each data as { text, completed, active, steps }, stage}
28
+ {#each data as { text, completed, active, steps }, stage (stage)}
29
29
  <div class="flex flex-col items-center justify-center first:col-start-2">
30
30
  <Stage {text} {completed} {active} on:click={() => handleClick({ stage })} />
31
31
  </div>
@@ -42,10 +42,10 @@
42
42
  {/each}
43
43
  </row>
44
44
  <row>
45
- {#each data as { label }, stage}
45
+ {#each data as { label }, stage (stage)}
46
46
  {#if label}
47
47
  <p
48
- class="col-span-3 w-full flex justify-center font-medium leading-loose text-center text-neutral-800"
48
+ class="col-span-3 flex w-full justify-center text-center font-medium leading-loose text-neutral-800"
49
49
  class:pending={stage > currentStage}
50
50
  >
51
51
  {label}
@@ -57,10 +57,10 @@
57
57
 
58
58
  <style lang="postcss">
59
59
  .stepper row {
60
- @apply w-full grid;
60
+ @apply grid w-full;
61
61
  grid-template-columns: repeat(var(--count), 2fr 6fr 2fr);
62
62
  }
63
63
  .pending {
64
- @apply text-neutral-500 font-light;
64
+ @apply font-light text-neutral-500;
65
65
  }
66
66
  </style>
@@ -1,5 +1,4 @@
1
1
  <script>
2
- import { defaultMapping } from './constants'
3
2
  import Item from './Item.svelte'
4
3
  /**
5
4
  * @typedef {Object} Props
@@ -37,7 +37,7 @@
37
37
  <td class={classes}>
38
38
  <rk-cell>
39
39
  {#if path}
40
- {#each levels.slice(0, -1) as _}
40
+ {#each levels.slice(0, -1) as level (level)}
41
41
  <Connector type="empty" />
42
42
  {/each}
43
43
  {#if isParent}
package/src/Tabs.svelte CHANGED
@@ -71,7 +71,7 @@
71
71
  onremove={handleRemove}
72
72
  onadd={handleAdd}
73
73
  >
74
- {#each filtered as item, index}
74
+ {#each filtered as item, index (index)}
75
75
  {@const Template = getSnippet(extra, mapper.get('snippet', item), stub)}
76
76
  <rk-tab>
77
77
  {#if Template}
@@ -120,19 +120,19 @@
120
120
  <table class:striped>
121
121
  <thead>
122
122
  <tr>
123
- {#each columns as col}
123
+ {#each columns as col (col.key)}
124
124
  <th>{col.label ?? col.key}</th>
125
125
  {/each}
126
126
  </tr>
127
127
  </thead>
128
128
  <tbody>
129
- {#each visible as item, index}
129
+ {#each visible as item, index (index)}
130
130
  <tr
131
131
  class:cursor-pointer={!item._isParent}
132
132
  aria-current={currentItem === item}
133
133
  onclick={stopPropagation((e) => handleItemClick(e, item))}
134
134
  >
135
- {#each columns as col, index}
135
+ {#each columns as col, index (index)}
136
136
  {@const value = { ...pick(['icon'], col), ...item }}
137
137
  {@const SvelteComponent = mapping.get('component', item)}
138
138
  <td>
@@ -147,7 +147,7 @@
147
147
  <!-- {/if} -->
148
148
  {:else}
149
149
  {#if col.path}
150
- {#each item._levels.slice(0, -1) as _}
150
+ {#each item._levels.slice(0, -1) as _, index (index)}
151
151
  <Connector type="empty" />
152
152
  {/each}
153
153
  {#if item._isParent}
@@ -14,7 +14,7 @@
14
14
  </script>
15
15
 
16
16
  <rk-status-report class={classes}>
17
- {#each items as { text, status }}
17
+ {#each items as { text, status }, index (index)}
18
18
  <rk-message class={status}>
19
19
  <Icon name={icons[status]} />
20
20
  <p>{text}</p>