@rokkit/ui 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.
Files changed (146) hide show
  1. package/README.md +198 -101
  2. package/package.json +52 -34
  3. package/src/components/BreadCrumbs.svelte +82 -0
  4. package/src/components/Button.svelte +87 -0
  5. package/src/components/ButtonGroup.svelte +18 -0
  6. package/src/components/Card.svelte +61 -0
  7. package/src/components/Carousel.svelte +169 -0
  8. package/src/components/Code.svelte +185 -0
  9. package/src/components/Connector.svelte +46 -0
  10. package/src/components/FloatingAction.svelte +331 -0
  11. package/src/components/FloatingNavigation.svelte +228 -0
  12. package/src/components/ItemContent.svelte +24 -0
  13. package/src/components/List.svelte +476 -0
  14. package/src/components/Menu.svelte +421 -0
  15. package/src/components/MultiSelect.svelte +521 -0
  16. package/src/components/PaletteManager.svelte +354 -0
  17. package/src/components/Pill.svelte +78 -0
  18. package/src/components/ProgressBar.svelte +31 -0
  19. package/src/components/Range.svelte +325 -0
  20. package/src/components/Rating.svelte +91 -0
  21. package/src/components/Reveal.svelte +58 -0
  22. package/src/components/SearchFilter.svelte +80 -0
  23. package/src/components/Select.svelte +585 -0
  24. package/src/{Shine.svelte → components/Shine.svelte} +29 -21
  25. package/src/components/Stepper.svelte +169 -0
  26. package/src/components/Switch.svelte +75 -0
  27. package/src/components/Table.svelte +243 -0
  28. package/src/components/Tabs.svelte +268 -0
  29. package/src/components/Tilt.svelte +68 -0
  30. package/src/components/Timeline.svelte +61 -0
  31. package/src/components/Toggle.svelte +157 -0
  32. package/src/components/Toolbar.svelte +307 -0
  33. package/src/components/ToolbarGroup.svelte +17 -0
  34. package/src/components/Tree.svelte +613 -0
  35. package/src/components/index.ts +33 -0
  36. package/src/index.ts +41 -0
  37. package/src/types/button.ts +83 -0
  38. package/src/types/code.ts +46 -0
  39. package/src/types/floating-action.ts +118 -0
  40. package/src/types/floating-navigation.ts +68 -0
  41. package/src/types/index.ts +53 -0
  42. package/src/types/item-proxy.ts +358 -0
  43. package/src/types/list.ts +196 -0
  44. package/src/types/menu.ts +195 -0
  45. package/src/types/palette.ts +143 -0
  46. package/src/types/range.ts +51 -0
  47. package/src/types/search-filter.ts +67 -0
  48. package/src/types/select.ts +206 -0
  49. package/src/types/switch.ts +64 -0
  50. package/src/types/table.ts +210 -0
  51. package/src/types/tabs.ts +124 -0
  52. package/src/types/timeline.ts +51 -0
  53. package/src/types/toggle.ts +109 -0
  54. package/src/types/toolbar.ts +164 -0
  55. package/src/types/tree.ts +259 -0
  56. package/src/utils/palette.ts +582 -0
  57. package/src/utils/shiki.ts +122 -0
  58. package/dist/constants.d.ts +0 -2
  59. package/dist/index.d.ts +0 -41
  60. package/dist/lib/fields.d.ts +0 -16
  61. package/dist/lib/form.d.ts +0 -95
  62. package/dist/lib/index.d.ts +0 -6
  63. package/dist/lib/layout.d.ts +0 -7
  64. package/dist/lib/nested.d.ts +0 -48
  65. package/dist/lib/schema.d.ts +0 -7
  66. package/dist/lib/select.d.ts +0 -8
  67. package/dist/lib/tree.d.ts +0 -9
  68. package/dist/tree/List.spec.svelte.d.ts +0 -1
  69. package/dist/tree/Node.spec.svelte.d.ts +0 -1
  70. package/dist/tree/Root.spec.svelte.d.ts +0 -1
  71. package/dist/types.d.ts +0 -5
  72. package/dist/wrappers/index.d.ts +0 -3
  73. package/src/Accordion.svelte +0 -118
  74. package/src/BreadCrumbs.svelte +0 -32
  75. package/src/Button.svelte +0 -57
  76. package/src/Calendar.svelte +0 -93
  77. package/src/Card.svelte +0 -45
  78. package/src/Carousel.svelte +0 -49
  79. package/src/CheckBox.svelte +0 -56
  80. package/src/Connector.svelte +0 -40
  81. package/src/DropDown.svelte +0 -68
  82. package/src/DropSearch.svelte +0 -37
  83. package/src/Fillable.svelte +0 -19
  84. package/src/GraphPaper.svelte +0 -43
  85. package/src/Icon.svelte +0 -81
  86. package/src/Item.svelte +0 -25
  87. package/src/Link.svelte +0 -21
  88. package/src/List.svelte +0 -89
  89. package/src/ListBody.svelte +0 -43
  90. package/src/Message.svelte +0 -11
  91. package/src/MultiSelect.svelte +0 -48
  92. package/src/NestedList.svelte +0 -78
  93. package/src/NestedPaginator.svelte +0 -63
  94. package/src/Node.svelte +0 -76
  95. package/src/Overlay.svelte +0 -21
  96. package/src/PageNavigator.svelte +0 -94
  97. package/src/PickOne.svelte +0 -60
  98. package/src/Pill.svelte +0 -41
  99. package/src/ProgressBar.svelte +0 -21
  100. package/src/ProgressDots.svelte +0 -53
  101. package/src/RadioGroup.svelte +0 -52
  102. package/src/Range.svelte +0 -45
  103. package/src/RangeMinMax.svelte +0 -124
  104. package/src/RangeSlider.svelte +0 -79
  105. package/src/RangeTick.svelte +0 -28
  106. package/src/Rating.svelte +0 -95
  107. package/src/ResponsiveGrid.svelte +0 -88
  108. package/src/Scrollable.svelte +0 -7
  109. package/src/Select.svelte +0 -114
  110. package/src/Separator.svelte +0 -1
  111. package/src/Slider.svelte +0 -14
  112. package/src/SlidingColumns.svelte +0 -50
  113. package/src/Stage.svelte +0 -41
  114. package/src/Stepper.svelte +0 -66
  115. package/src/Summary.svelte +0 -22
  116. package/src/Switch.svelte +0 -106
  117. package/src/TableCell.svelte +0 -51
  118. package/src/TableHeaderCell.svelte +0 -54
  119. package/src/Tabs.svelte +0 -176
  120. package/src/Tilt.svelte +0 -66
  121. package/src/Toggle.svelte +0 -58
  122. package/src/ToggleThemeMode.svelte +0 -23
  123. package/src/Tree.svelte +0 -80
  124. package/src/TreeTable.svelte +0 -171
  125. package/src/ValidationReport.svelte +0 -23
  126. package/src/constants.js +0 -4
  127. package/src/index.js +0 -48
  128. package/src/lib/fields.js +0 -118
  129. package/src/lib/form.js +0 -72
  130. package/src/lib/index.js +0 -13
  131. package/src/lib/layout.js +0 -63
  132. package/src/lib/nested.js +0 -192
  133. package/src/lib/schema.js +0 -32
  134. package/src/lib/select.js +0 -38
  135. package/src/lib/tree.js +0 -22
  136. package/src/tree/List.spec.svelte.js +0 -84
  137. package/src/tree/List.svelte +0 -78
  138. package/src/tree/Node.spec.svelte.js +0 -104
  139. package/src/tree/Node.svelte +0 -80
  140. package/src/tree/Root.spec.svelte.js +0 -63
  141. package/src/tree/Root.svelte +0 -81
  142. package/src/types.js +0 -9
  143. package/src/wrappers/Category.svelte +0 -27
  144. package/src/wrappers/Section.svelte +0 -16
  145. package/src/wrappers/Wrapper.svelte +0 -12
  146. package/src/wrappers/index.js +0 -3
@@ -1,171 +0,0 @@
1
- <script>
2
- import { pick, omit } from 'ramda'
3
- import { defaultMapping } from './constants'
4
- import Connector from './Connector.svelte'
5
- import Icon from './Icon.svelte'
6
- import Item from './Item.svelte'
7
-
8
- // const dispatch = createEventDispatcher()
9
-
10
- /**
11
- * @typedef {Object} Props
12
- * @property {string} [class]
13
- * @property {any} [data]
14
- * @property {any} [columns]
15
- * @property {boolean} [striped]
16
- * @property {any} [value]
17
- * @property {boolean} [multiselect]
18
- * @property {any} [using]
19
- * @property {any} [dataFilter]
20
- */
21
-
22
- /** @type {Props} */
23
- let {
24
- class: className = '',
25
- data = [],
26
- columns = $bindable([]),
27
- striped = true,
28
- value = $bindable(null),
29
- multiselect = false,
30
- using = $bindable({}),
31
- dataFilter = () => true
32
- } = $props()
33
-
34
- let hiddenPaths = []
35
- let currentItem = $state(null)
36
-
37
- function handleItemClick(event, item) {
38
- if (item._isParent) toggle(item)
39
- else {
40
- currentItem = item
41
- value = getValue(item)
42
- dispatch('click', value)
43
-
44
- if (event.metaKey) toggleSelection(event, item)
45
- }
46
- }
47
- function getValue(item) {
48
- return omit(['_levels', '_isParent', '_isExpanded', '_depth', '_path', '_selected'], item)
49
- }
50
-
51
- function toggleSelection(e, item) {
52
- e.stopPropagation()
53
- e.preventDefault()
54
- if (item._selected !== 'checked') item._selected = 'checked'
55
- else item._selected = 'unchecked'
56
-
57
- if (item._isParent) {
58
- data
59
- .filter((i) => i[nestedColumn.key].startsWith(item[nestedColumn.key] + '/'))
60
- .forEach((i) => (i._selected = item._selected))
61
- } else {
62
- const parents = data.filter(
63
- (i) => item[nestedColumn.key].startsWith(i[nestedColumn.key] + '/') && i._isParent
64
- )
65
- parents.map((p) => {
66
- const children = data.filter((i) =>
67
- i[nestedColumn.key].startsWith(p[nestedColumn.key] + '/')
68
- )
69
- const selectedChildren = children.filter((i) => i._selected === 'checked')
70
-
71
- if (selectedChildren.length === children.length) p._selected = 'checked'
72
- else if (selectedChildren.length === 0) p._selected = 'unchecked'
73
- else p._selected = 'unknown'
74
- })
75
- }
76
- visible = [...data.filter(dataFilter).filter(isVisible)]
77
- dispatch('select', data.filter((i) => i._selected === 'checked').map(getValue))
78
- }
79
-
80
- function toggle(item) {
81
- if (nestedColumn === undefined) return
82
-
83
- const parentPath = item[nestedColumn.key] + '/'
84
- if (item._isParent) {
85
- item._isExpanded = !item._isExpanded
86
- if (item._isExpanded) {
87
- hiddenPaths = [...hiddenPaths.filter((i) => i !== parentPath)]
88
- } else {
89
- hiddenPaths = [...hiddenPaths, parentPath]
90
- }
91
- visible = [...data.filter(dataFilter).filter(isVisible)]
92
- }
93
- }
94
-
95
- function isVisible(item) {
96
- if (hiddenPaths.length === 0) return true
97
- return !hiddenPaths.some((i) => item[nestedColumn.key].startsWith(i))
98
- }
99
-
100
- function addMultiSelectColumn(multiselect, data) {
101
- if (multiselect) {
102
- if (columns.some((col) => col.key === '_selected')) return
103
- columns = [{ key: '_selected', label: '', width: '3rem' }, ...columns]
104
- data.forEach((item) => {
105
- item._selected = 'unchecked'
106
- })
107
- } else {
108
- columns = [...columns.filter((col) => col.key !== '_selected')]
109
- }
110
- }
111
-
112
- let visible = $derived(() => data.filter(dataFilter).filter(isVisible))
113
- let nestedColumn = $derived(columns.find((col) => col.path))
114
- $effect(() => {
115
- addMultiSelectColumn(multiselect, data)
116
- })
117
- </script>
118
-
119
- <rk-tree-table class={className}>
120
- <table class:striped>
121
- <thead>
122
- <tr>
123
- {#each columns as col (col.key)}
124
- <th>{col.label ?? col.key}</th>
125
- {/each}
126
- </tr>
127
- </thead>
128
- <tbody>
129
- {#each visible as item, index (index)}
130
- <tr
131
- class:cursor-pointer={!item._isParent}
132
- aria-current={currentItem === item}
133
- onclick={stopPropagation((e) => handleItemClick(e, item))}
134
- >
135
- {#each columns as col, index (index)}
136
- {@const value = { ...pick(['icon'], col), ...item }}
137
- {@const SvelteComponent = mapping.get('component', item)}
138
- <td>
139
- <cell>
140
- {#if multiselect && index === 0}
141
- <!-- {#if !item._isParent} -->
142
- <Icon
143
- name={'checkbox-' + item._selected}
144
- class="small cursor-pointer"
145
- on:click={(e) => toggleSelection(e, item)}
146
- />
147
- <!-- {/if} -->
148
- {:else}
149
- {#if col.path}
150
- {#each item._levels.slice(0, -1) as _, index (index)}
151
- <Connector type="empty" />
152
- {/each}
153
- {#if item._isParent}
154
- <Icon
155
- name={item._isExpanded ? 'node-opened' : 'node-closed'}
156
- class="small cursor-pointer"
157
- />
158
- {:else if item._depth > 0}
159
- <Connector type="empty" />
160
- {/if}
161
- {/if}
162
- <SvelteComponent {value} {mapping} />
163
- {/if}
164
- </cell>
165
- </td>
166
- {/each}
167
- </tr>
168
- {/each}
169
- </tbody>
170
- </table>
171
- </rk-tree-table>
@@ -1,23 +0,0 @@
1
- <script>
2
- import { defaultStateIcons } from '@rokkit/core'
3
- import Icon from './Icon.svelte'
4
-
5
- /**
6
- * @typedef {Object} Props
7
- * @property {string} [class]
8
- * @property {any} items
9
- * @property {any} [icons]
10
- */
11
-
12
- /** @type {Props} */
13
- let { class: classes = '', items, icons = defaultStateIcons.badge } = $props()
14
- </script>
15
-
16
- <rk-status-report class={classes}>
17
- {#each items as { text, status }, index (index)}
18
- <rk-message class={status}>
19
- <Icon name={icons[status]} />
20
- <p>{text}</p>
21
- </rk-message>
22
- {/each}
23
- </rk-status-report>
package/src/constants.js DELETED
@@ -1,4 +0,0 @@
1
- import { FieldMapper } from '@rokkit/core'
2
- import Item from './Item.svelte'
3
-
4
- export const defaultMapping = new FieldMapper({}, { default: Item })
package/src/index.js DELETED
@@ -1,48 +0,0 @@
1
- // skipcq: JS-E1004 - Needed for exposing JS Doc types
2
- export * from './types.js'
3
- export { default as Button } from './Button.svelte'
4
- export { default as Icon } from './Icon.svelte'
5
- export { default as Item } from './Item.svelte'
6
- export { default as Pill } from './Pill.svelte'
7
- export { default as ProgressBar } from './ProgressBar.svelte'
8
- export { default as Separator } from './Separator.svelte'
9
- export { default as Connector } from './Connector.svelte'
10
- export { default as RangeTick } from './RangeTick.svelte'
11
- export { default as RangeSlider } from './RangeSlider.svelte'
12
-
13
- export { default as Node } from './Node.svelte'
14
- export { default as Summary } from './Summary.svelte'
15
- export { default as BreadCrumbs } from './BreadCrumbs.svelte'
16
- export { default as Rating } from './Rating.svelte'
17
- export { default as RangeMinMax } from './RangeMinMax.svelte'
18
- export { default as Range } from './Range.svelte'
19
- export { default as RadioGroup } from './RadioGroup.svelte'
20
- export { default as CheckBox } from './CheckBox.svelte'
21
- export { default as Calendar } from './Calendar.svelte'
22
- export { default as ValidationReport } from './ValidationReport.svelte'
23
- export { default as ResponsiveGrid } from './ResponsiveGrid.svelte'
24
-
25
- export { default as Toggle } from './Toggle.svelte'
26
- export { default as Switch } from './Switch.svelte'
27
- export { default as List } from './List.svelte'
28
- export { default as Accordion } from './Accordion.svelte'
29
- export { default as Tree } from './Tree.svelte'
30
- export { default as Tabs } from './Tabs.svelte'
31
- export { default as Select } from './Select.svelte'
32
- export { default as MultiSelect } from './MultiSelect.svelte'
33
- export { default as DropDown } from './DropDown.svelte'
34
- export { default as Table } from './TreeTable.svelte'
35
-
36
- export { default as ToggleThemeMode } from './ToggleThemeMode.svelte'
37
-
38
- export { default as Overlay } from './Overlay.svelte'
39
- export { default as Message } from './Message.svelte'
40
- export { default as SlidingColumns } from './SlidingColumns.svelte'
41
-
42
- export { default as Stepper } from './Stepper.svelte'
43
- export { default as ProgressDots } from './ProgressDots.svelte'
44
-
45
- export { default as Card } from './Card.svelte'
46
- export { default as Shine } from './Shine.svelte'
47
- export { default as Tilt } from './Tilt.svelte'
48
- export { default as GraphPaper } from './GraphPaper.svelte'
package/src/lib/fields.js DELETED
@@ -1,118 +0,0 @@
1
- import { omit, pick } from 'ramda'
2
-
3
- /**
4
- * Combines array elements with schema
5
- *
6
- * @param {import('../types').LayoutElement} element
7
- * @param {import('../types').LayoutSchema} attribute
8
- */
9
- function combineArrayElementsWithSchema(element, attribute) {
10
- // eslint-disable-next-line no-use-before-define
11
- const schema = getSchemaWithLayout(attribute.props.items, element.schema)
12
- return {
13
- ...attribute,
14
- ...pick(['component'], element),
15
- props: {
16
- ...omit(['items'], attribute.props),
17
- schema
18
- }
19
- }
20
- }
21
-
22
- /**
23
- * Combines basic elements with schema
24
- * @param {import('../types').LayoutElement} element
25
- * @param {import('../types').LayoutSchema} attribute
26
- * @returns
27
- */
28
- function combineBasicElementsWithSchema(element, attribute) {
29
- return {
30
- ...attribute,
31
- ...pick(['component'], element),
32
- props: {
33
- ...omit(['scope', 'props', 'component', 'key'], element),
34
- ...attribute.props,
35
- ...element.props
36
- }
37
- }
38
- }
39
-
40
- /**
41
- * Find an attribute in a schema by path
42
- * @param {string} scope
43
- * @param {import('../types').DataSchema} schema
44
- * @returns {import('../types').LayoutSchema}
45
- * @throws {Error} Invalid path
46
- */
47
- export function findAttributeByPath(scope, schema) {
48
- if (!scope) return { props: { ...schema } }
49
-
50
- const pathArray = scope.split('/').slice(1)
51
- let schemaPointer = schema
52
- let currentKey = ''
53
-
54
- pathArray.forEach((key) => {
55
- schemaPointer = schemaPointer.properties[key]
56
- currentKey = key
57
- })
58
-
59
- if (!schemaPointer) throw new Error(`Invalid scope: ${scope}`)
60
-
61
- return {
62
- key: currentKey,
63
- props: { ...schemaPointer }
64
- }
65
- }
66
-
67
- /**
68
- * Combines an element from layout with schema
69
- *
70
- * @param {import('../types').LayoutElement} element
71
- * @param {import('../types').DataSchema} schema
72
- * @returns
73
- */
74
- function combineElementWithSchema(element, schema) {
75
- const { scope } = element
76
- let attribute = findAttributeByPath(scope, schema)
77
-
78
- if (Array.isArray(element.elements)) {
79
- // eslint-disable-next-line no-use-before-define
80
- attribute = combineNestedElementsWithSchema(element, attribute, schema)
81
- } else if (element.schema || attribute.props?.type === 'array') {
82
- attribute = combineArrayElementsWithSchema(element, attribute)
83
- } else {
84
- attribute = combineBasicElementsWithSchema(element, attribute)
85
- }
86
-
87
- return attribute
88
- }
89
- /**
90
- * Combines nested elements with schema
91
- *
92
- * @param {import('../types').LayoutElement} element
93
- * @param {import('../types').LayoutSchema} attribute
94
- * @param {import('../types').DataSchema} schema
95
- * @returns
96
- */
97
- function combineNestedElementsWithSchema(element, attribute, schema) {
98
- const temp = element.elements.map((el) => combineElementWithSchema(el, schema))
99
- return {
100
- ...omit(['component', 'props'], attribute),
101
- ...omit(['scope', 'elements'], element),
102
- elements: temp
103
- }
104
- }
105
-
106
- /**
107
- * Get combined schema and layout
108
- * @param {*} data
109
- * @param {import('../types').DataSchema} schema
110
- * @param {import('../types').LayoutSchema} layout
111
- * @returns {import('../types').LayoutSchema}
112
- */
113
- export function getSchemaWithLayout(schema, layout) {
114
- const combined = omit(['elements'], layout)
115
- combined.elements = layout.elements.map((element) => combineElementWithSchema(element, schema))
116
-
117
- return combined
118
- }
package/src/lib/form.js DELETED
@@ -1,72 +0,0 @@
1
- export const messages = {
2
- required: '{name} is required',
3
- email: '{name} should be a valid email address',
4
- url: '{name} should be a valid URL',
5
- color: '{name} should be a valid color',
6
- number: '{name} should be a valid number',
7
- min: '{name} should be greater than or equal to {min}',
8
- max: '{name} should be less than or equal to {max}',
9
- pattern: '{name} should match the pattern {pattern}',
10
- exclusiveMin: '{name} should be greater than {min}',
11
- exclusiveMax: '{name} should be less than {max}',
12
- minLength: '{name} should be at least {minLength} characters',
13
- maxLength: '{name} should be at most {maxLength} characters',
14
- minItems: '{name} should have at least {minItems} items',
15
- maxItems: '{name} should have at most {maxItems} items',
16
- uniqueItems: '{name} should have unique items',
17
- contains: '{name} should contain {contains}',
18
- exclude: '{name} should not contain {exclude}',
19
- integer: '{name} should be an integer'
20
- }
21
-
22
- export const dataTypes = {
23
- integer: {
24
- editor: 'inputText',
25
- props: { type: 'number', step: 1 },
26
- availableProps: ['min', 'max']
27
- },
28
- number: {
29
- editor: 'inputText',
30
- props: { type: 'number', step: 0.01 },
31
- availableProps: ['min', 'max']
32
- },
33
- range: {
34
- editor: 'inputRange',
35
- props: { type: 'range' }
36
- },
37
-
38
- string: {
39
- default: 'inputText',
40
- text: 'inputText',
41
- password: 'inputPassword',
42
- email: 'inputEmail',
43
- url: 'inputUrl',
44
- tel: 'inputTel',
45
- date: 'inputDate',
46
- 'datetime-local': 'inputDateTimeLocal',
47
- time: 'inputTime',
48
- week: 'inputWeek',
49
- month: 'inputMonth',
50
- file: 'inputFile',
51
- hidden: 'inputHidden',
52
- color: 'inputColor',
53
- colorpicker: 'inputColorPicker'
54
- },
55
- enum: {
56
- default: 'inputSelect',
57
- select: 'inputSelect',
58
- radio: 'inputRadio'
59
- },
60
- boolean: {
61
- default: 'inputCheckbox',
62
- checkbox: 'inputCheckbox',
63
- switch: 'inputSwitch',
64
- radio: 'inputRadio'
65
- },
66
- array: {
67
- default: 'inputArray'
68
- },
69
- object: {
70
- default: 'inputObject'
71
- }
72
- }
package/src/lib/index.js DELETED
@@ -1,13 +0,0 @@
1
- export { addRootNode } from './tree'
2
- export { messages, dataTypes } from './form'
3
- export { deriveSchemaFromValue } from './schema'
4
- export { deriveLayoutFromValue } from './layout'
5
- export { getSchemaWithLayout, findAttributeByPath } from './fields'
6
- export {
7
- deriveNestedSchema,
8
- flattenAttributes,
9
- flattenObject,
10
- flattenElement,
11
- generateIndex,
12
- generateTreeTable
13
- } from './nested'
package/src/lib/layout.js DELETED
@@ -1,63 +0,0 @@
1
- import { isObject } from '@rokkit/core'
2
-
3
- /**
4
- * Derives a layout from a given object value.
5
- * @param {Object} val
6
- * @param {string} scope
7
- * @param {string} label
8
- * @returns {import('../types').DataLayout}
9
- */
10
- function deriveElementLayout(val, scope, label) {
11
- const path = `${scope}/${label}`
12
- if (isObject(val)) {
13
- return {
14
- title: label,
15
- scope: path,
16
- // eslint-disable-next-line no-use-before-define
17
- ...deriveLayoutFromValue(val, path)
18
- }
19
- }
20
- return { label, scope: path }
21
- }
22
-
23
- /**
24
- * Derives a layout from a given object value.
25
- * @param {Object} value
26
- * @param {string} scope
27
- * @returns {import('../types').DataLayout}
28
- */
29
- function deriveObjectLayout(value, scope) {
30
- const elements = Object.entries(value).map(([label, val]) =>
31
- deriveElementLayout(val, scope, label)
32
- )
33
- return { type: 'vertical', elements }
34
- }
35
-
36
- /**
37
- * Derives a layout from a given array value.
38
- * @param {Array<any>} value
39
- * @param {string} scope
40
- * @returns {import('../types').DataLayout}
41
- */
42
- function deriveArrayLayout(value, scope) {
43
- // eslint-disable-next-line no-use-before-define
44
- const schema = deriveLayoutFromValue(value[0], '#')
45
- return {
46
- scope,
47
- schema
48
- }
49
- }
50
- /**
51
- * Derives a layout from a given value.
52
- * @param {any} value
53
- * @param {string} scope
54
- * @returns {import('../types').DataLayout}
55
- */
56
- export function deriveLayoutFromValue(value, scope = '#') {
57
- if (Array.isArray(value)) {
58
- return deriveArrayLayout(value, scope)
59
- } else if (typeof value === 'object' && value !== null) {
60
- return deriveObjectLayout(value, scope)
61
- }
62
- return { type: 'vertical', elements: [{ scope }] }
63
- }