@rokkit/forms 1.0.0-next.125 → 1.0.0-next.127
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 +251 -0
- package/dist/src/display/index.d.ts +5 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/input/index.d.ts +3 -0
- package/dist/src/lib/builder.svelte.d.ts +114 -4
- package/dist/src/lib/lookup.svelte.d.ts +87 -0
- package/dist/src/lib/renderers.d.ts +23 -0
- package/package.json +6 -4
- package/src/FieldLayout.svelte +4 -11
- package/src/FormRenderer.svelte +202 -61
- package/src/InfoField.svelte +26 -0
- package/src/Input.svelte +17 -61
- package/src/InputField.svelte +15 -11
- package/src/ValidationReport.svelte +52 -0
- package/src/display/DisplayCardGrid.svelte +68 -0
- package/src/display/DisplayList.svelte +31 -0
- package/src/display/DisplaySection.svelte +20 -0
- package/src/display/DisplayTable.svelte +68 -0
- package/src/display/DisplayValue.svelte +44 -0
- package/src/display/index.js +5 -0
- package/src/index.js +14 -0
- package/src/input/ArrayEditor.svelte +108 -0
- package/src/input/InputCheckbox.svelte +2 -3
- package/src/input/InputColor.svelte +6 -1
- package/src/input/InputDate.svelte +6 -1
- package/src/input/InputDateTime.svelte +6 -1
- package/src/input/InputEmail.svelte +6 -1
- package/src/input/InputFile.svelte +6 -2
- package/src/input/InputMonth.svelte +6 -1
- package/src/input/InputNumber.svelte +6 -1
- package/src/input/InputPassword.svelte +6 -1
- package/src/input/InputRange.svelte +6 -1
- package/src/input/InputSelect.svelte +31 -53
- package/src/input/InputSwitch.svelte +4 -15
- package/src/input/InputTel.svelte +6 -1
- package/src/input/InputText.svelte +6 -1
- package/src/input/InputTextArea.svelte +6 -1
- package/src/input/InputTime.svelte +6 -1
- package/src/input/InputToggle.svelte +28 -0
- package/src/input/InputUrl.svelte +6 -1
- package/src/input/InputWeek.svelte +6 -1
- package/src/input/index.js +3 -1
- package/src/lib/Input.svelte +3 -3
- package/src/lib/builder.svelte.js +425 -30
- package/src/lib/fields.js +2 -2
- package/src/lib/layout.js +2 -2
- package/src/lib/lookup.svelte.js +334 -0
- package/src/lib/renderers.js +83 -0
- package/src/lib/schema.js +1 -1
- package/src/types.js +0 -9
- package/dist/src/forms-old/input/types.d.ts +0 -7
- package/dist/src/forms-old/lib/form.d.ts +0 -95
- package/dist/src/forms-old/lib/index.d.ts +0 -1
- package/dist/src/lib/deprecated/nested.d.ts +0 -48
- package/dist/src/lib/deprecated/nested.spec.d.ts +0 -1
- package/dist/src/lib/deprecated/validator.d.ts +0 -30
- package/dist/src/lib/deprecated/validator.spec.d.ts +0 -1
- package/src/DataEditor.svelte +0 -30
- package/src/ListEditor.svelte +0 -44
- package/src/NestedEditor.svelte +0 -85
- package/src/forms-old/CheckBox.svelte +0 -56
- package/src/forms-old/DataEditor.svelte +0 -30
- package/src/forms-old/FieldLayout.svelte +0 -48
- package/src/forms-old/Form.svelte +0 -17
- package/src/forms-old/Icon.svelte +0 -76
- package/src/forms-old/Item.svelte +0 -25
- package/src/forms-old/ListEditor.svelte +0 -44
- package/src/forms-old/Tabs.svelte +0 -57
- package/src/forms-old/Wrapper.svelte +0 -12
- package/src/forms-old/input/Input.svelte +0 -17
- package/src/forms-old/input/InputField.svelte +0 -70
- package/src/forms-old/input/InputSelect.svelte +0 -23
- package/src/forms-old/input/InputSwitch.svelte +0 -19
- package/src/forms-old/input/types.js +0 -29
- package/src/forms-old/lib/form.js +0 -72
- package/src/forms-old/lib/index.js +0 -12
- package/src/forms-old/mocks/CustomField.svelte +0 -7
- package/src/forms-old/mocks/CustomWrapper.svelte +0 -8
- package/src/forms-old/mocks/Register.svelte +0 -25
- package/src/inp/Input.svelte +0 -17
- package/src/inp/InputField.svelte +0 -69
- package/src/inp/InputSelect.svelte +0 -23
- package/src/inp/InputSwitch.svelte +0 -19
- package/src/lib/deprecated/Form.svelte +0 -17
- package/src/lib/deprecated/FormRenderer.svelte +0 -121
- package/src/lib/deprecated/nested.js +0 -192
- package/src/lib/deprecated/nested.spec.js +0 -512
- package/src/lib/deprecated/validator.js +0 -137
- package/src/lib/deprecated/validator.spec.js +0 -348
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,85 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { pick } from 'ramda'
|
|
3
|
-
import { createEventDispatcher } from 'svelte'
|
|
4
|
-
import { Tree, DataEditor, Tree as TreeTable, Tabs } from '@rokkit/ui'
|
|
5
|
-
import { generateTreeTable, deriveNestedSchema } from './lib'
|
|
6
|
-
|
|
7
|
-
const dispatch = createEventDispatcher()
|
|
8
|
-
|
|
9
|
-
export let value
|
|
10
|
-
export let schema = deriveNestedSchema(value)
|
|
11
|
-
export let using = {}
|
|
12
|
-
export let fields = {
|
|
13
|
-
text: 'key',
|
|
14
|
-
icon: 'type',
|
|
15
|
-
iconPrefix: 'type'
|
|
16
|
-
}
|
|
17
|
-
let node = {
|
|
18
|
-
schema: null,
|
|
19
|
-
layout: null
|
|
20
|
-
}
|
|
21
|
-
let nodeValue = value
|
|
22
|
-
let nodeType = null
|
|
23
|
-
let nodeItem = null
|
|
24
|
-
let columns = [
|
|
25
|
-
{ key: 'scope', path: true, label: 'path', fields: { text: 'key' } },
|
|
26
|
-
{ key: 'value', label: 'value', fields: { text: 'value', icon: 'type', iconPrefix: 'type' } }
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
function handleChange() {
|
|
30
|
-
dispatch('change', value)
|
|
31
|
-
}
|
|
32
|
-
function handleMove(event) {
|
|
33
|
-
dispatch('change', value)
|
|
34
|
-
const scope = event.detail.scope.split('/').slice(1)
|
|
35
|
-
|
|
36
|
-
node.schema = pick(['type', 'properties', 'items'], event.detail)
|
|
37
|
-
node.layout = event.detail.layout
|
|
38
|
-
|
|
39
|
-
nodeValue = value
|
|
40
|
-
nodeType = event.detail.type
|
|
41
|
-
|
|
42
|
-
for (let i = 0; i < scope.length; i++) {
|
|
43
|
-
nodeValue = nodeValue[scope[i]]
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
$: tableData = node?.layout ? [] : generateTreeTable(nodeValue ?? value, 'scope', true)
|
|
48
|
-
</script>
|
|
49
|
-
|
|
50
|
-
<container class="flex h-full w-full flex-row">
|
|
51
|
-
<aside class="border-r-surface-z2 flex h-full w-80 border-r">
|
|
52
|
-
<Tree items={schema} {fields} class="h-full w-full" on:move={handleMove} />
|
|
53
|
-
</aside>
|
|
54
|
-
<content class="flex h-full w-full flex-col gap-4 overflow-hidden p-8">
|
|
55
|
-
<slot />
|
|
56
|
-
<section class="flex w-full flex-grow flex-col overflow-auto">
|
|
57
|
-
{#if !nodeValue}
|
|
58
|
-
<p>Select a node to edit</p>
|
|
59
|
-
<TreeTable data={tableData} {columns} class="" />
|
|
60
|
-
{:else if node.layout}
|
|
61
|
-
{#if nodeType === 'array'}
|
|
62
|
-
<p>Arrays are not supported yet.</p>
|
|
63
|
-
<Tabs options={nodeValue} bind:value={nodeItem} />
|
|
64
|
-
{#if nodeItem}
|
|
65
|
-
<DataEditor
|
|
66
|
-
bind:value={nodeItem}
|
|
67
|
-
layout={node.layout}
|
|
68
|
-
schema={node.schema.items}
|
|
69
|
-
{using}
|
|
70
|
-
/>
|
|
71
|
-
<pre>{JSON.stringify(nodeItem, null, 2)}</pre>
|
|
72
|
-
{/if}
|
|
73
|
-
{:else}
|
|
74
|
-
<DataEditor bind:value={nodeValue} {...node} {using} on:change={handleChange} />
|
|
75
|
-
{/if}
|
|
76
|
-
{:else}
|
|
77
|
-
<p>
|
|
78
|
-
No atomic attributes at this level. Select a child node to edit. Current value is below.
|
|
79
|
-
</p>
|
|
80
|
-
<TreeTable data={tableData} {columns} />
|
|
81
|
-
{/if}
|
|
82
|
-
</section>
|
|
83
|
-
<slot name="footer" />
|
|
84
|
-
</content>
|
|
85
|
-
</container>
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { defaultStateIcons } from '@rokkit/core'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {Object} Props
|
|
6
|
-
* @property {string} [class]
|
|
7
|
-
* @property {any} [id]
|
|
8
|
-
* @property {any} name
|
|
9
|
-
* @property {boolean} [value]
|
|
10
|
-
* @property {boolean} [readOnly]
|
|
11
|
-
* @property {any} [stateIcons]
|
|
12
|
-
* @property {number} [tabindex]
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/** @type {Props} */
|
|
16
|
-
let {
|
|
17
|
-
class: classes = '',
|
|
18
|
-
id = null,
|
|
19
|
-
name,
|
|
20
|
-
value = $bindable(false),
|
|
21
|
-
readOnly = false,
|
|
22
|
-
stateIcons = defaultStateIcons.checkbox,
|
|
23
|
-
tabindex = 0
|
|
24
|
-
} = $props()
|
|
25
|
-
|
|
26
|
-
let state = $derived(value === null ? 'unknown' : value ? 'checked' : 'unchecked')
|
|
27
|
-
|
|
28
|
-
function toggle(event) {
|
|
29
|
-
event.preventDefault()
|
|
30
|
-
event.stopPropagation()
|
|
31
|
-
value = !value
|
|
32
|
-
}
|
|
33
|
-
function handleClick(event) {
|
|
34
|
-
if (!readOnly) toggle(event)
|
|
35
|
-
}
|
|
36
|
-
function handleKeydown(event) {
|
|
37
|
-
if (readOnly) return
|
|
38
|
-
if (event.key === 'Enter' || event.key === ' ') toggle(event)
|
|
39
|
-
}
|
|
40
|
-
</script>
|
|
41
|
-
|
|
42
|
-
<rk-checkbox
|
|
43
|
-
{id}
|
|
44
|
-
class={classes}
|
|
45
|
-
class:disabled={readOnly}
|
|
46
|
-
role="checkbox"
|
|
47
|
-
aria-checked={state}
|
|
48
|
-
aria-disabled={readOnly}
|
|
49
|
-
onclick={handleClick}
|
|
50
|
-
onkeydown={handleKeydown}
|
|
51
|
-
{tabindex}
|
|
52
|
-
>
|
|
53
|
-
<input hidden type="checkbox" {name} {readOnly} bind:checked={value} />
|
|
54
|
-
|
|
55
|
-
<icon class={stateIcons[state]}></icon>
|
|
56
|
-
</rk-checkbox>
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { setContext } from 'svelte'
|
|
3
|
-
import { types } from './input/types'
|
|
4
|
-
import Wrapper from './Wrapper.svelte'
|
|
5
|
-
import Item from './Item.svelte'
|
|
6
|
-
import Tabs from './Tabs.svelte'
|
|
7
|
-
import FieldLayout from './FieldLayout.svelte'
|
|
8
|
-
import { noop } from '@rokkit/core'
|
|
9
|
-
|
|
10
|
-
const registry = $state({})
|
|
11
|
-
setContext('registry', registry)
|
|
12
|
-
|
|
13
|
-
import { deriveSchemaFromValue, deriveLayoutFromValue, getSchemaWithLayout } from './lib'
|
|
14
|
-
|
|
15
|
-
let { value, schema = null, layout = null, using = {}, onchange = noop } = $props()
|
|
16
|
-
|
|
17
|
-
registry.editors = { ...types, ...using?.editors }
|
|
18
|
-
registry.components = { default: Item, ...using?.components }
|
|
19
|
-
registry.wrappers = { default: Wrapper, ...using?.wrappers }
|
|
20
|
-
registry.navigators = { default: Tabs, ...using?.navigators }
|
|
21
|
-
|
|
22
|
-
let schemaWithLayout = $derived.by(() => {
|
|
23
|
-
return getSchemaWithLayout(
|
|
24
|
-
schema ?? deriveSchemaFromValue(value),
|
|
25
|
-
layout ?? deriveLayoutFromValue(value)
|
|
26
|
-
)
|
|
27
|
-
})
|
|
28
|
-
</script>
|
|
29
|
-
|
|
30
|
-
<FieldLayout schema={schemaWithLayout} bind:value {onchange} />
|
|
@@ -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}
|
|
@@ -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>
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEmitter } from '@rokkit/core'
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {Object} Props
|
|
5
|
-
* @property {string} [class]
|
|
6
|
-
* @property {any} name
|
|
7
|
-
* @property {any} [state]
|
|
8
|
-
* @property {string} [size]
|
|
9
|
-
* @property {'img'|'button'|'checkbox'|'option'} [role]
|
|
10
|
-
* @property {any} [label]
|
|
11
|
-
* @property {boolean} [disabled]
|
|
12
|
-
* @property {number} [tabindex]
|
|
13
|
-
* @property {any} [checked]
|
|
14
|
-
* @event {MouseEvent} [onclick]
|
|
15
|
-
* @event {CustomEvent} [onchange]
|
|
16
|
-
* @event {MouseEvent} [onmouseenter]
|
|
17
|
-
* @event {MouseEvent} [onmouseleave]
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/** @type {Props} */
|
|
21
|
-
let {
|
|
22
|
-
ref = $bindable(),
|
|
23
|
-
class: classes = '',
|
|
24
|
-
name,
|
|
25
|
-
state = null,
|
|
26
|
-
size = 'base',
|
|
27
|
-
role = 'img',
|
|
28
|
-
label = null,
|
|
29
|
-
disabled = false,
|
|
30
|
-
tabindex = $bindable(0),
|
|
31
|
-
checked = $bindable(null),
|
|
32
|
-
...events
|
|
33
|
-
} = $props()
|
|
34
|
-
|
|
35
|
-
let emitter = $derived(createEmitter(events, ['click', 'change', 'mouseenter', 'mouseleave']))
|
|
36
|
-
function handleClick(e) {
|
|
37
|
-
if (role === 'img') return
|
|
38
|
-
e.preventDefault()
|
|
39
|
-
|
|
40
|
-
if (!disabled) {
|
|
41
|
-
if (isCheckbox) {
|
|
42
|
-
checked = !checked
|
|
43
|
-
emitter?.change(checked)
|
|
44
|
-
}
|
|
45
|
-
emitter?.click()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let isCheckbox = $derived(role === 'checkbox' || role === 'option')
|
|
50
|
-
let validatedTabindex = $derived(role === 'img' || disabled ? -1 : tabindex)
|
|
51
|
-
let ariaChecked = $derived(
|
|
52
|
-
['checkbox', 'option'].includes(role) ? (checked !== null ? checked : false) : null
|
|
53
|
-
)
|
|
54
|
-
</script>
|
|
55
|
-
|
|
56
|
-
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
57
|
-
<rk-icon
|
|
58
|
-
bind:this={ref}
|
|
59
|
-
data-tag-icon
|
|
60
|
-
data-state={state}
|
|
61
|
-
data-tag-button={role === 'button' ? true : undefined}
|
|
62
|
-
data-tag-checkbox={isCheckbox ? true : undefined}
|
|
63
|
-
data-size={size}
|
|
64
|
-
data-disabled={disabled}
|
|
65
|
-
class={classes}
|
|
66
|
-
{role}
|
|
67
|
-
aria-label={label ?? name}
|
|
68
|
-
aria-checked={ariaChecked}
|
|
69
|
-
onclick={handleClick}
|
|
70
|
-
onkeydown={(e) => e.key === 'Enter' && e.currentTarget.click()}
|
|
71
|
-
tabindex={validatedTabindex}
|
|
72
|
-
onmouseenter={emitter.mouseenter}
|
|
73
|
-
onnmouseleave={emitter.nmouseleave}
|
|
74
|
-
>
|
|
75
|
-
<i class={name} aria-hidden="true"></i>
|
|
76
|
-
</rk-icon>
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Icon from './Icon.svelte'
|
|
3
|
-
import { Proxy } from '@rokkit/states'
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {Object} Props
|
|
6
|
-
* @property {import('@rokkit/states').NodeProxy} [value]
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/** @type {Props} */
|
|
10
|
-
let { value, fields } = $props()
|
|
11
|
-
let proxy = $derived(new Proxy(value, fields))
|
|
12
|
-
let content = $derived(proxy.get('text'))
|
|
13
|
-
let ariaLabel = $derived(proxy.get('label') ?? content)
|
|
14
|
-
let icon = $derived(proxy.get('icon'))
|
|
15
|
-
let image = $derived(proxy.get('image'))
|
|
16
|
-
</script>
|
|
17
|
-
|
|
18
|
-
{#if icon}
|
|
19
|
-
<Icon name={icon} label={ariaLabel} />
|
|
20
|
-
{:else if image}
|
|
21
|
-
<img src={image} alt={ariaLabel} />
|
|
22
|
-
{/if}
|
|
23
|
-
{#if content}
|
|
24
|
-
<p>{content}</p>
|
|
25
|
-
{/if}
|
|
@@ -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>
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { Tabs } from 'bits-ui'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {Object} TabGroupProps
|
|
6
|
-
* @property {string} [class] - Additional CSS class names
|
|
7
|
-
* @property {any[]} [options] Array of options to display
|
|
8
|
-
* @property {FieldMapping} [fields] - Field mappings for extracting data
|
|
9
|
-
* @property {any} [value] - Selected value (bindable)
|
|
10
|
-
* @property {number} [tabindex] - Tabindex for keyboard navigation
|
|
11
|
-
* @property {import('svelte').Snippet} [child] - Snippet for rendering individual items
|
|
12
|
-
* @property {import('svelte').Snippet} [children] Snippet for rendering content
|
|
13
|
-
* @property {Function} [onselect] - Callback when item is selected
|
|
14
|
-
*/
|
|
15
|
-
/** @type TabGroupProps */
|
|
16
|
-
let { options = [], value = $bindable(), fields, child, children, onchange } = $props()
|
|
17
|
-
|
|
18
|
-
// let selectedGroup = options.find
|
|
19
|
-
let tabOptions = $derived(options.map((option) => new Proxy(option, fields)))
|
|
20
|
-
let initialValue = $state()
|
|
21
|
-
let activeOption = $state()
|
|
22
|
-
let childSnippet = $derived(child ?? defaultChild)
|
|
23
|
-
|
|
24
|
-
$effect.pre(() => {
|
|
25
|
-
activeOption = tabOptions.find((proxy) => equals(proxy.value, value))
|
|
26
|
-
if (activeOption) initialValue = activeOption.id
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
function handleChange() {
|
|
30
|
-
activeOption = tabOptions.find((proxy) => equals(proxy.id, initialValue))
|
|
31
|
-
value = activeOption?.value
|
|
32
|
-
onchange?.(value)
|
|
33
|
-
// value = data
|
|
34
|
-
// onSelect?.(data)
|
|
35
|
-
}
|
|
36
|
-
</script>
|
|
37
|
-
|
|
38
|
-
{#snippet defaultChild(item)}
|
|
39
|
-
{item.get('text')}
|
|
40
|
-
{/snippet}
|
|
41
|
-
|
|
42
|
-
<Tabs.Root onValueChange={handleChange} bind:value={initialValue}>
|
|
43
|
-
<Tabs.List>
|
|
44
|
-
{#each tabOptions as tab (tab.id)}
|
|
45
|
-
<Tabs.Trigger value={tab.id}>
|
|
46
|
-
{@render childSnippet(tab)}
|
|
47
|
-
</Tabs.Trigger>
|
|
48
|
-
{/each}
|
|
49
|
-
</Tabs.List>
|
|
50
|
-
|
|
51
|
-
<!-- {#each tabOptions as tab (tab.id)} -->
|
|
52
|
-
<Tabs.Content>
|
|
53
|
-
{@render children()}
|
|
54
|
-
<!-- <ComparisonCharts {logs} groupBy={tab.value} {m} /> -->
|
|
55
|
-
</Tabs.Content>
|
|
56
|
-
<!-- {/each} -->
|
|
57
|
-
</Tabs.Root>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
let { class: className = '', type = 'vertical', title = '', children } = $props()
|
|
3
|
-
</script>
|
|
4
|
-
|
|
5
|
-
<field-layout
|
|
6
|
-
class={className}
|
|
7
|
-
class:vertical={type === 'vertical'}
|
|
8
|
-
class:horizontal={type === 'horizontal'}
|
|
9
|
-
aria-label={title}
|
|
10
|
-
>
|
|
11
|
-
{@render children?.()}
|
|
12
|
-
</field-layout>
|
|
@@ -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 = {}, onchange, onfocus, onblur, ...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} {onchange} {onfocus} {onblur} />
|
|
15
|
-
{:else}
|
|
16
|
-
<error>Type "{type}" is not supported by Input</error>
|
|
17
|
-
{/if}
|
|
@@ -1,70 +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
|
-
onchange,
|
|
25
|
-
...restProps
|
|
26
|
-
} = $props()
|
|
27
|
-
|
|
28
|
-
using = { ...types, ...registry, ...using }
|
|
29
|
-
let pass = status === 'pass'
|
|
30
|
-
let fail = status === 'fail'
|
|
31
|
-
let warn = status === 'warn'
|
|
32
|
-
let rootProps = pick(['id'], restProps)
|
|
33
|
-
let properties = {
|
|
34
|
-
required,
|
|
35
|
-
readOnly: disabled,
|
|
36
|
-
...omit(['id'], restProps),
|
|
37
|
-
name
|
|
38
|
-
}
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<input-field
|
|
42
|
-
{...rootProps}
|
|
43
|
-
class="flex flex-col input-{type} {className} "
|
|
44
|
-
class:disabled
|
|
45
|
-
class:pass
|
|
46
|
-
class:fail
|
|
47
|
-
class:warn
|
|
48
|
-
class:empty={!value}
|
|
49
|
-
>
|
|
50
|
-
{#if label && !nolabel && !['switch', 'checkbox'].includes(type)}
|
|
51
|
-
<label for={name} class:required>
|
|
52
|
-
{label}
|
|
53
|
-
</label>
|
|
54
|
-
{/if}
|
|
55
|
-
<field class="flex w-full flex-row items-center" aria-label={description ?? label ?? name}>
|
|
56
|
-
{#if icon}
|
|
57
|
-
<Icon name={icon} />
|
|
58
|
-
{/if}
|
|
59
|
-
{#if type === 'switch'}
|
|
60
|
-
<label for={name} class:required>{label}</label>
|
|
61
|
-
{/if}
|
|
62
|
-
<Input id={name} bind:value {type} {...properties} {using} {onchange} />
|
|
63
|
-
{#if type === 'checkbox'}
|
|
64
|
-
<label for={name} class:required>{label}</label>
|
|
65
|
-
{/if}
|
|
66
|
-
</field>
|
|
67
|
-
{#if message}
|
|
68
|
-
<message class={status}>{message}</message>
|
|
69
|
-
{/if}
|
|
70
|
-
</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, onchange, ...restProps } = $props()
|
|
6
|
-
// let selected = $state(null)
|
|
7
|
-
let configFields = $derived({ ...defaultFields, ...fields })
|
|
8
|
-
function handle(data) {
|
|
9
|
-
value = getValue(data.value, configFields)
|
|
10
|
-
onchange?.(data.value)
|
|
11
|
-
}
|
|
12
|
-
let selected = $derived(options.find((option) => getValue(option, configFields) === value))
|
|
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} />
|
|
@@ -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/forms'
|
|
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
|
-
}
|