@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
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
+
import { cleanup, render, fireEvent } from '@testing-library/svelte'
|
|
3
|
+
import Root from './Root.svelte'
|
|
4
|
+
|
|
5
|
+
describe('Tree Root Component', () => {
|
|
6
|
+
const items = [
|
|
7
|
+
{ id: 1, label: 'Node 1', children: [{ id: 2, label: 'Node 1.1' }] },
|
|
8
|
+
{ id: 3, label: 'Node 2' }
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
beforeEach(() => cleanup())
|
|
12
|
+
|
|
13
|
+
it('renders tree root with items', () => {
|
|
14
|
+
const { container } = render(Root, {
|
|
15
|
+
props: { items, fields: { text: 'label', children: 'children' } }
|
|
16
|
+
})
|
|
17
|
+
const rootEl = container.querySelector('[data-tree-root]')
|
|
18
|
+
expect(rootEl).not.toBeNull()
|
|
19
|
+
// const contentEls = container.querySelectorAll('[data-tree-content]')
|
|
20
|
+
// expect(Array.from(contentEls).some((el) => el.textContent.includes('Node 1'))).toBe(true)
|
|
21
|
+
// expect(Array.from(contentEls).some((el) => el.textContent.includes('Node 2'))).toBe(true)
|
|
22
|
+
expect(rootEl).toMatchSnapshot()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// it('renders header and footer if provided', () => {
|
|
26
|
+
// const header = () => 'Header'
|
|
27
|
+
// const footer = () => 'Footer'
|
|
28
|
+
// const { container } = render(Root, {
|
|
29
|
+
// props: { items, fields: { label: 'label', children: 'children' }, header, footer }
|
|
30
|
+
// })
|
|
31
|
+
// expect(container.textContent).toContain('Header')
|
|
32
|
+
// expect(container.textContent).toContain('Footer')
|
|
33
|
+
// expect(container).toMatchSnapshot()
|
|
34
|
+
// })
|
|
35
|
+
|
|
36
|
+
it('renders empty state when items are empty', () => {
|
|
37
|
+
const { container } = render(Root, {
|
|
38
|
+
props: { items: [], fields: { label: 'label', children: 'children' } }
|
|
39
|
+
})
|
|
40
|
+
expect(container.textContent).toContain('No data available')
|
|
41
|
+
expect(container).toMatchSnapshot()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// it('calls event handlers on select', async () => {
|
|
45
|
+
// let selectedValue = null
|
|
46
|
+
// const handleSelect = (e) => {
|
|
47
|
+
// selectedValue = e.detail.value
|
|
48
|
+
// }
|
|
49
|
+
// const { container } = render(Root, {
|
|
50
|
+
// props: {
|
|
51
|
+
// items,
|
|
52
|
+
// fields: { label: 'label', children: 'children' },
|
|
53
|
+
// onselect: handleSelect
|
|
54
|
+
// }
|
|
55
|
+
// })
|
|
56
|
+
// const contentEls = container.querySelectorAll('[data-tree-content]')
|
|
57
|
+
// const node = Array.from(contentEls).find((el) => el.textContent.includes('Node 1'))
|
|
58
|
+
// expect(node).not.toBeNull()
|
|
59
|
+
// await fireEvent.click(node)
|
|
60
|
+
// expect(selectedValue).toBe(items[0])
|
|
61
|
+
// expect(container).toMatchSnapshot()
|
|
62
|
+
// })
|
|
63
|
+
})
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { createEmitter, defaultFields } from '@rokkit/core'
|
|
3
|
+
import { navigator } from '@rokkit/actions'
|
|
4
|
+
import List from './List.svelte'
|
|
5
|
+
import { NestedController } from '@rokkit/states'
|
|
6
|
+
import { omit, has } from 'ramda'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} Props
|
|
10
|
+
* @property {string} [class]
|
|
11
|
+
* @property {Array<any>} [items]
|
|
12
|
+
* @property {any} [value]
|
|
13
|
+
* @property {import('@rokkit/core').FieldMapping} [fields]
|
|
14
|
+
* @property {Object} [icons]
|
|
15
|
+
* @property {boolean} [autoCloseSiblings=false]
|
|
16
|
+
* @property {boolean} [multiselect=false]
|
|
17
|
+
* @property {Function} [header]
|
|
18
|
+
* @property {Function} [footer]
|
|
19
|
+
* @property {Function} [empty]
|
|
20
|
+
* @property {Function} [stub]
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** @type {Props & { [key: string]: any }} */
|
|
24
|
+
let {
|
|
25
|
+
class: classes = 'h-full overflow-scroll flex flex-col',
|
|
26
|
+
items = $bindable([]),
|
|
27
|
+
value = $bindable(null),
|
|
28
|
+
fields,
|
|
29
|
+
icons = {},
|
|
30
|
+
autoCloseSiblings = false,
|
|
31
|
+
multiselect = false,
|
|
32
|
+
header,
|
|
33
|
+
footer,
|
|
34
|
+
empty,
|
|
35
|
+
stub,
|
|
36
|
+
...events
|
|
37
|
+
} = $props()
|
|
38
|
+
|
|
39
|
+
let emitter = createEmitter(events, ['select', 'move', 'toggle'])
|
|
40
|
+
let wrapper = new NestedController(items, value, fields, { autoCloseSiblings, multiselect })
|
|
41
|
+
let snippets = omit(['onselect', 'onmove', 'ontoggle'], events)
|
|
42
|
+
let derivedFields = $derived({ ...defaultFields, ...fields })
|
|
43
|
+
|
|
44
|
+
function handleAction(event) {
|
|
45
|
+
const { name, data } = event.detail
|
|
46
|
+
if (name === 'select') value = data.value
|
|
47
|
+
if (has([name], emitter)) emitter[name](data)
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<div
|
|
52
|
+
data-tree-root
|
|
53
|
+
tabindex="0"
|
|
54
|
+
class={classes}
|
|
55
|
+
use:navigator={{ wrapper, nested: true }}
|
|
56
|
+
onaction={handleAction}
|
|
57
|
+
>
|
|
58
|
+
{#if header}
|
|
59
|
+
<div data-tree-header>{@render header()}</div>
|
|
60
|
+
{/if}
|
|
61
|
+
{#if items.length === 0}
|
|
62
|
+
{#if empty}
|
|
63
|
+
{@render empty()}
|
|
64
|
+
{:else}
|
|
65
|
+
<div class="m-auto p-4 text-center text-gray-500" data-tree-empty>No data available</div>
|
|
66
|
+
{/if}
|
|
67
|
+
{/if}
|
|
68
|
+
<List
|
|
69
|
+
items={items}
|
|
70
|
+
fields={derivedFields}
|
|
71
|
+
value={value}
|
|
72
|
+
icons={icons}
|
|
73
|
+
focusedKey={wrapper.currentKey}
|
|
74
|
+
selectedKeys={wrapper.selectedKeys}
|
|
75
|
+
stub={stub}
|
|
76
|
+
snippets={snippets}
|
|
77
|
+
/>
|
|
78
|
+
{#if footer}
|
|
79
|
+
<div data-tree-footer>{@render footer()}</div>
|
|
80
|
+
{/if}
|
|
81
|
+
</div>
|
package/dist/input/types.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export namespace types {
|
|
2
|
-
export let string: any;
|
|
3
|
-
export let integer: any;
|
|
4
|
-
export { CheckBox as boolean };
|
|
5
|
-
export { InputSelect as enum };
|
|
6
|
-
export let phone: any;
|
|
7
|
-
}
|
|
8
|
-
import CheckBox from '../CheckBox.svelte';
|
|
9
|
-
import InputSelect from './InputSelect.svelte';
|
package/src/DataEditor.svelte
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { setContext } from 'svelte'
|
|
3
|
-
import { writable } from 'svelte/store'
|
|
4
|
-
import { types } from './input/types'
|
|
5
|
-
import Wrapper from './wrappers/Wrapper.svelte'
|
|
6
|
-
import Item from './Item.svelte'
|
|
7
|
-
import Tabs from './Tabs.svelte'
|
|
8
|
-
import FieldLayout from './FieldLayout.svelte'
|
|
9
|
-
import { noop } from '@rokkit/core'
|
|
10
|
-
|
|
11
|
-
const registry = $state({})
|
|
12
|
-
setContext('registry', registry)
|
|
13
|
-
|
|
14
|
-
import { deriveSchemaFromValue, deriveLayoutFromValue, getSchemaWithLayout } from './lib'
|
|
15
|
-
|
|
16
|
-
let { value, schema = null, layout = null, using = {}, onchange = noop } = $props()
|
|
17
|
-
|
|
18
|
-
registry.editors = { ...types, ...using?.editors }
|
|
19
|
-
registry.components = { default: Item, ...using?.components }
|
|
20
|
-
registry.wrappers = { default: Wrapper, ...using?.wrappers }
|
|
21
|
-
registry.navigators = { default: Tabs, ...using?.navigators }
|
|
22
|
-
|
|
23
|
-
let schemaWithLayout = $derived.by(() => {
|
|
24
|
-
return getSchemaWithLayout(
|
|
25
|
-
schema ?? deriveSchemaFromValue(value),
|
|
26
|
-
layout ?? deriveLayoutFromValue(value)
|
|
27
|
-
)
|
|
28
|
-
})
|
|
29
|
-
</script>
|
|
30
|
-
|
|
31
|
-
<FieldLayout schema={schemaWithLayout} bind:value {onchange} />
|
package/src/FieldLayout.svelte
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getContext } from 'svelte'
|
|
3
|
-
import { omit } from 'ramda'
|
|
4
|
-
import InputField from './input/InputField.svelte'
|
|
5
|
-
import FieldLayout from './FieldLayout.svelte'
|
|
6
|
-
|
|
7
|
-
// const dispatch = createEventDispatcher()
|
|
8
|
-
const registry = getContext('registry')
|
|
9
|
-
|
|
10
|
-
export let value = {}
|
|
11
|
-
export let schema = {}
|
|
12
|
-
export let path = []
|
|
13
|
-
|
|
14
|
-
function handle() {
|
|
15
|
-
dispatch('change', value)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
let Wrapper = registry.wrappers[schema.wrapper] ?? registry.wrappers.default
|
|
19
|
-
let wrapperProps = omit(['wrapper', 'elements', 'key'], schema)
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
{#if !Array.isArray(schema.elements)}
|
|
23
|
-
<error> Invalid schema. Expected schema to include an 'elements' array. </error>
|
|
24
|
-
{:else}
|
|
25
|
-
<Wrapper {...wrapperProps}>
|
|
26
|
-
{#each schema.elements as item, index (index)}
|
|
27
|
-
{@const elementPath = item.key ? [...path, item.key] : path}
|
|
28
|
-
{@const props = { ...item.props, path: elementPath }}
|
|
29
|
-
{@const nested = Array.isArray(item.elements) && item.elements.length > 0}
|
|
30
|
-
{@const Component = item.component
|
|
31
|
-
? (registry.components[item.component] ?? registry.components.default)
|
|
32
|
-
: null}
|
|
33
|
-
|
|
34
|
-
{#if nested}
|
|
35
|
-
{#if item.key}
|
|
36
|
-
<FieldLayout {...props} schema={item} bind:value={value[item.key]} on:change={handle} />
|
|
37
|
-
{:else}
|
|
38
|
-
<FieldLayout {...props} schema={item} bind:value on:change={handle} />
|
|
39
|
-
{/if}
|
|
40
|
-
{:else if Component}
|
|
41
|
-
<Component {...item.props} value={item.key ? value[item.key] : null} />
|
|
42
|
-
{:else}
|
|
43
|
-
{@const name = elementPath.join('.')}
|
|
44
|
-
<InputField {name} bind:value={value[item.key]} {...item.props} on:change={handle} />
|
|
45
|
-
{/if}
|
|
46
|
-
{/each}
|
|
47
|
-
</Wrapper>
|
|
48
|
-
{/if}
|
package/src/Form.svelte
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import DataEditor from './DataEditor.svelte'
|
|
3
|
-
|
|
4
|
-
export let value
|
|
5
|
-
export let schema = null
|
|
6
|
-
export let layout = null
|
|
7
|
-
export let using = {}
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
<form on:submit>
|
|
11
|
-
<DataEditor bind:value {schema} {layout} {using} />
|
|
12
|
-
<span>
|
|
13
|
-
<slot>
|
|
14
|
-
<button type="submit">Submit</button>
|
|
15
|
-
</slot>
|
|
16
|
-
</span>
|
|
17
|
-
</form>
|
package/src/ListEditor.svelte
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import List from './List.svelte'
|
|
3
|
-
import FieldLayout from './FieldLayout.svelte'
|
|
4
|
-
import { defaultFields } from '@rokkit/core'
|
|
5
|
-
import { getContext } from 'svelte'
|
|
6
|
-
|
|
7
|
-
// const dispatch = createEventDispatcher()
|
|
8
|
-
const registry = getContext('registry')
|
|
9
|
-
|
|
10
|
-
let {
|
|
11
|
-
class: className,
|
|
12
|
-
value,
|
|
13
|
-
fields = defaultFields,
|
|
14
|
-
schema,
|
|
15
|
-
path = [],
|
|
16
|
-
below = false,
|
|
17
|
-
children
|
|
18
|
-
} = $props()
|
|
19
|
-
|
|
20
|
-
let index = 0
|
|
21
|
-
let item = $state(value[index])
|
|
22
|
-
let location = $state([...path, index])
|
|
23
|
-
|
|
24
|
-
function handleSelect(event) {
|
|
25
|
-
index = event.detail.indices[0]
|
|
26
|
-
item = event.detail.item
|
|
27
|
-
location = [...path, ...event.detail.indices]
|
|
28
|
-
dispatch('select', { item: value, indices: path })
|
|
29
|
-
}
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
<list-editor class="flex {className}">
|
|
33
|
-
<List
|
|
34
|
-
bind:items={value}
|
|
35
|
-
bind:value={item}
|
|
36
|
-
{fields}
|
|
37
|
-
using={registry.components}
|
|
38
|
-
on:select={handleSelect}
|
|
39
|
-
/>
|
|
40
|
-
<item-editor class="flex" class:below>
|
|
41
|
-
{@render children?.()}
|
|
42
|
-
<FieldLayout bind:value={item} {schema} path={location} />
|
|
43
|
-
</item-editor>
|
|
44
|
-
</list-editor>
|
package/src/NestedEditor.svelte
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { pick } from 'ramda'
|
|
3
|
-
import { createEventDispatcher } from 'svelte'
|
|
4
|
-
import Tree from './Tree.svelte'
|
|
5
|
-
import DataEditor from './DataEditor.svelte'
|
|
6
|
-
import TreeTable from './TreeTable.svelte'
|
|
7
|
-
import Tabs from './Tabs.svelte'
|
|
8
|
-
import { generateTreeTable, deriveNestedSchema } from './lib'
|
|
9
|
-
|
|
10
|
-
const dispatch = createEventDispatcher()
|
|
11
|
-
|
|
12
|
-
export let value
|
|
13
|
-
export let schema = deriveNestedSchema(value)
|
|
14
|
-
export let using = {}
|
|
15
|
-
export let fields = {
|
|
16
|
-
text: 'key',
|
|
17
|
-
icon: 'type',
|
|
18
|
-
iconPrefix: 'type'
|
|
19
|
-
}
|
|
20
|
-
let node = {
|
|
21
|
-
schema: null,
|
|
22
|
-
layout: null
|
|
23
|
-
}
|
|
24
|
-
let nodeValue = value
|
|
25
|
-
let nodeType = null
|
|
26
|
-
let nodeItem = null
|
|
27
|
-
let columns = [
|
|
28
|
-
{ key: 'scope', path: true, label: 'path', fields: { text: 'key' } },
|
|
29
|
-
{ key: 'value', label: 'value', fields: { text: 'value', icon: 'type', iconPrefix: 'type' } }
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
function handleChange() {
|
|
33
|
-
dispatch('change', value)
|
|
34
|
-
}
|
|
35
|
-
function handleMove(event) {
|
|
36
|
-
dispatch('change', value)
|
|
37
|
-
const scope = event.detail.scope.split('/').slice(1)
|
|
38
|
-
|
|
39
|
-
node.schema = pick(['type', 'properties', 'items'], event.detail)
|
|
40
|
-
node.layout = event.detail.layout
|
|
41
|
-
|
|
42
|
-
nodeValue = value
|
|
43
|
-
nodeType = event.detail.type
|
|
44
|
-
|
|
45
|
-
for (let i = 0; i < scope.length; i++) {
|
|
46
|
-
nodeValue = nodeValue[scope[i]]
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
$: tableData = node?.layout ? [] : generateTreeTable(nodeValue ?? value, 'scope', true)
|
|
51
|
-
</script>
|
|
52
|
-
|
|
53
|
-
<container class="flex h-full w-full flex-row">
|
|
54
|
-
<aside class="border-r-neutral-subtle flex h-full w-80 border-r">
|
|
55
|
-
<Tree items={schema} {fields} class="h-full w-full" on:move={handleMove} />
|
|
56
|
-
</aside>
|
|
57
|
-
<content class="flex h-full w-full flex-col gap-4 overflow-hidden p-8">
|
|
58
|
-
<slot />
|
|
59
|
-
<section class="flex w-full flex-grow flex-col overflow-auto">
|
|
60
|
-
{#if !nodeValue}
|
|
61
|
-
<p>Select a node to edit</p>
|
|
62
|
-
<TreeTable data={tableData} {columns} class="" />
|
|
63
|
-
{:else if node.layout}
|
|
64
|
-
{#if nodeType === 'array'}
|
|
65
|
-
<p>Arrays are not supported yet.</p>
|
|
66
|
-
<Tabs options={nodeValue} bind:value={nodeItem} />
|
|
67
|
-
{#if nodeItem}
|
|
68
|
-
<DataEditor
|
|
69
|
-
bind:value={nodeItem}
|
|
70
|
-
layout={node.layout}
|
|
71
|
-
schema={node.schema.items}
|
|
72
|
-
{using}
|
|
73
|
-
/>
|
|
74
|
-
<pre>{JSON.stringify(nodeItem, null, 2)}</pre>
|
|
75
|
-
{/if}
|
|
76
|
-
{:else}
|
|
77
|
-
<DataEditor bind:value={nodeValue} {...node} {using} on:change={handleChange} />
|
|
78
|
-
{/if}
|
|
79
|
-
{:else}
|
|
80
|
-
<p>
|
|
81
|
-
No atomic attributes at this level. Select a child node to edit. Current value is below.
|
|
82
|
-
</p>
|
|
83
|
-
<TreeTable data={tableData} {columns} />
|
|
84
|
-
{/if}
|
|
85
|
-
</section>
|
|
86
|
-
<slot name="footer" />
|
|
87
|
-
</content>
|
|
88
|
-
</container>
|
package/src/input/Input.svelte
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getContext } from 'svelte'
|
|
3
|
-
import { types } from './types'
|
|
4
|
-
|
|
5
|
-
const registry = getContext('registry')
|
|
6
|
-
|
|
7
|
-
let { value, type = 'text', using = {}, ...restProps } = $props()
|
|
8
|
-
|
|
9
|
-
using = { ...types, ...using, ...registry?.editors }
|
|
10
|
-
let Template = using[type]
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
{#if type in using}
|
|
14
|
-
<Template bind:value {...restProps} on:change on:focus on:blur />
|
|
15
|
-
{:else}
|
|
16
|
-
<error>Type "{type}" is not supported by Input</error>
|
|
17
|
-
{/if}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getContext } from 'svelte'
|
|
3
|
-
import { pick, omit } from 'ramda'
|
|
4
|
-
import Icon from '../Icon.svelte'
|
|
5
|
-
import Input from './Input.svelte'
|
|
6
|
-
import { types } from './types'
|
|
7
|
-
|
|
8
|
-
const registry = getContext('registry')
|
|
9
|
-
|
|
10
|
-
let {
|
|
11
|
-
class: className,
|
|
12
|
-
name,
|
|
13
|
-
value,
|
|
14
|
-
type,
|
|
15
|
-
required,
|
|
16
|
-
status,
|
|
17
|
-
disabled,
|
|
18
|
-
message,
|
|
19
|
-
using,
|
|
20
|
-
nolabel,
|
|
21
|
-
icon,
|
|
22
|
-
label,
|
|
23
|
-
description,
|
|
24
|
-
...restProps
|
|
25
|
-
} = $props()
|
|
26
|
-
|
|
27
|
-
using = { ...types, ...registry, ...using }
|
|
28
|
-
let pass = status === 'pass'
|
|
29
|
-
let fail = status === 'fail'
|
|
30
|
-
let warn = status === 'warn'
|
|
31
|
-
let rootProps = pick(['id'], restProps)
|
|
32
|
-
let properties = {
|
|
33
|
-
required,
|
|
34
|
-
readOnly: disabled,
|
|
35
|
-
...omit(['id'], restProps),
|
|
36
|
-
name
|
|
37
|
-
}
|
|
38
|
-
</script>
|
|
39
|
-
|
|
40
|
-
<input-field
|
|
41
|
-
{...rootProps}
|
|
42
|
-
class="flex flex-col input-{type} {className} "
|
|
43
|
-
class:disabled
|
|
44
|
-
class:pass
|
|
45
|
-
class:fail
|
|
46
|
-
class:warn
|
|
47
|
-
class:empty={!value}
|
|
48
|
-
>
|
|
49
|
-
{#if label && !nolabel && !['switch', 'checkbox'].includes(type)}
|
|
50
|
-
<label for={name} class:required>
|
|
51
|
-
{label}
|
|
52
|
-
</label>
|
|
53
|
-
{/if}
|
|
54
|
-
<field class="flex w-full flex-row items-center" aria-label={description ?? label ?? name}>
|
|
55
|
-
{#if icon}
|
|
56
|
-
<Icon name={icon} />
|
|
57
|
-
{/if}
|
|
58
|
-
{#if type === 'switch'}
|
|
59
|
-
<label for={name} class:required>{label}</label>
|
|
60
|
-
{/if}
|
|
61
|
-
<Input id={name} bind:value {type} {...properties} {using} on:change />
|
|
62
|
-
{#if type === 'checkbox'}
|
|
63
|
-
<label for={name} class:required>{label}</label>
|
|
64
|
-
{/if}
|
|
65
|
-
</field>
|
|
66
|
-
{#if message}
|
|
67
|
-
<message class={status}>{message}</message>
|
|
68
|
-
{/if}
|
|
69
|
-
</input-field>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getValue, defaultFields } from '@rokkit/core'
|
|
3
|
-
import Select from '../Select.svelte'
|
|
4
|
-
|
|
5
|
-
let { name, value, options = [], fields, onchange, ...restProps } = $props()
|
|
6
|
-
|
|
7
|
-
let selected = $state()
|
|
8
|
-
let configFields = $derived({ ...defaultFields, ...fields })
|
|
9
|
-
|
|
10
|
-
function handle(data) {
|
|
11
|
-
value = getValue(data.value, configFields)
|
|
12
|
-
onchange?.(data)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
$effect(() => {
|
|
16
|
-
if (value !== getValue(selected, configFields)) {
|
|
17
|
-
selected = options.find((option) => getValue(option, configFields) === value)
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
<input {name} type="hidden" bind:value />
|
|
23
|
-
<Select name="" value={selected} {options} {fields} {...restProps} onchange={handle} />
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getValue, defaultFields } from '@rokkit/core'
|
|
3
|
-
import Switch from '../Switch.svelte'
|
|
4
|
-
|
|
5
|
-
let { name, value, options, fields, ...restProps } = $props()
|
|
6
|
-
let selected = $state(null)
|
|
7
|
-
let configFields = $derived({ ...defaultFields, ...fields })
|
|
8
|
-
function handle(data) {
|
|
9
|
-
value = getValue(data.value, configFields)
|
|
10
|
-
dispatch('change', data.value)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
$effect(() => {
|
|
14
|
-
selected = options.find((option) => getValue(option, configFields) === value)
|
|
15
|
-
})
|
|
16
|
-
</script>
|
|
17
|
-
|
|
18
|
-
<input {name} type="hidden" bind:value />
|
|
19
|
-
<Switch bind:value={selected} {options} {fields} {...restProps} onchange={handle} />
|
package/src/input/types.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { toHyphenCase } from '@rokkit/core'
|
|
2
|
-
// skipcq: JS-C1003 - Importing all components from atoms
|
|
3
|
-
import * as NativeInput from '@rokkit/input'
|
|
4
|
-
// skipcq: JS-C1003 - Importing all components from molecules
|
|
5
|
-
import CheckBox from '../CheckBox.svelte'
|
|
6
|
-
|
|
7
|
-
import InputSelect from './InputSelect.svelte'
|
|
8
|
-
import InputSwitch from './InputSwitch.svelte'
|
|
9
|
-
|
|
10
|
-
function extractComponentMap(components, prefix = /^Input/) {
|
|
11
|
-
return Object.entries(components).reduce(
|
|
12
|
-
(acc, [name, component]) => ({
|
|
13
|
-
...acc,
|
|
14
|
-
[toHyphenCase(name.replace(prefix, ''))]: component
|
|
15
|
-
}),
|
|
16
|
-
{}
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
const native = extractComponentMap(NativeInput)
|
|
20
|
-
|
|
21
|
-
export const types = {
|
|
22
|
-
string: NativeInput.InputText,
|
|
23
|
-
integer: NativeInput.InputNumber,
|
|
24
|
-
boolean: CheckBox,
|
|
25
|
-
enum: InputSelect,
|
|
26
|
-
phone: NativeInput.InputTel,
|
|
27
|
-
...native,
|
|
28
|
-
...extractComponentMap({ InputSelect, InputSwitch })
|
|
29
|
-
}
|