@ditojs/admin 2.93.0 → 2.95.0
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/dist/dito-admin.css +1 -1
- package/dist/dito-admin.es.js +1672 -1522
- package/dist/dito-admin.umd.js +6 -6
- package/package.json +6 -6
- package/src/components/DitoAccount.vue +7 -1
- package/src/components/DitoCreateButton.vue +6 -2
- package/src/components/DitoDialog.vue +1 -1
- package/src/components/DitoErrors.vue +1 -0
- package/src/components/DitoForm.vue +1 -0
- package/src/components/DitoFormInner.vue +5 -0
- package/src/components/DitoHeader.vue +1 -1
- package/src/components/DitoLabel.vue +6 -1
- package/src/components/DitoMenu.vue +1 -0
- package/src/components/DitoNavigation.vue +1 -1
- package/src/components/DitoNotifications.vue +1 -1
- package/src/components/DitoPane.vue +3 -0
- package/src/components/DitoPanel.vue +2 -0
- package/src/components/DitoSchema.vue +1 -0
- package/src/components/DitoScopes.vue +1 -0
- package/src/components/DitoSpinner.vue +2 -0
- package/src/components/DitoTableHead.vue +10 -0
- package/src/components/DitoTabs.vue +18 -2
- package/src/components/DitoTrail.vue +2 -1
- package/src/components/DitoTreeItem.vue +22 -3
- package/src/mixins/DitoMixin.js +4 -2
- package/src/mixins/PulldownMixin.js +9 -0
- package/src/types/DitoTypeCheckboxes.vue +2 -0
- package/src/types/DitoTypeList.vue +2 -0
- package/src/types/DitoTypeMultiselect.vue +2 -0
- package/src/types/DitoTypeRadio.vue +2 -0
- package/src/types/DitoTypeUpload.vue +4 -4
- package/types/index.d.ts +74 -11
- package/types/tests/admin.test-d.ts +0 -27
- package/types/tests/component-buttons.test-d.ts +0 -44
- package/types/tests/component-list.test-d.ts +0 -159
- package/types/tests/component-misc.test-d.ts +0 -137
- package/types/tests/component-object.test-d.ts +0 -69
- package/types/tests/component-section.test-d.ts +0 -174
- package/types/tests/component-select.test-d.ts +0 -107
- package/types/tests/components.test-d.ts +0 -81
- package/types/tests/context.test-d.ts +0 -31
- package/types/tests/fixtures.ts +0 -24
- package/types/tests/form.test-d.ts +0 -109
- package/types/tests/instance.test-d.ts +0 -20
- package/types/tests/schema-features.test-d.ts +0 -402
- package/types/tests/variance.test-d.ts +0 -125
- package/types/tests/view.test-d.ts +0 -146
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.95.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dito.js Admin is a schema based admin interface for Dito.js Server, featuring auto-generated views and forms and built with Vue.js",
|
|
6
6
|
"repository": "https://github.com/ditojs/dito/tree/main/packages/admin",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"not ie_mob > 0"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@ditojs/ui": "^2.
|
|
44
|
-
"@ditojs/utils": "^2.
|
|
43
|
+
"@ditojs/ui": "^2.95.0",
|
|
44
|
+
"@ditojs/utils": "^2.95.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@kyvg/vue3-notification": "^3.4.2",
|
|
@@ -89,9 +89,9 @@
|
|
|
89
89
|
"vue-upload-component": "^3.1.17"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
|
-
"@ditojs/build": "^2.
|
|
92
|
+
"@ditojs/build": "^2.95.0",
|
|
93
93
|
"typescript": "^6.0.2",
|
|
94
|
-
"vite": "^8.0.
|
|
94
|
+
"vite": "^8.0.8"
|
|
95
95
|
},
|
|
96
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "0cd76446659c5d30c18df8091bedb20cd84fb330"
|
|
97
97
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
.dito-account
|
|
3
3
|
a(
|
|
4
|
+
role="button"
|
|
5
|
+
v-bind="pulldownTriggerAttributes"
|
|
4
6
|
@mousedown.stop="onPulldownMouseDown()"
|
|
5
7
|
)
|
|
6
8
|
span {{ user.username }}
|
|
7
|
-
ul.dito-pulldown(
|
|
9
|
+
ul.dito-pulldown(
|
|
10
|
+
role="menu"
|
|
11
|
+
:class="{ 'dito-pulldown--open': pulldown.open }"
|
|
12
|
+
)
|
|
8
13
|
li(
|
|
9
14
|
v-for="(label, value) of items"
|
|
10
15
|
)
|
|
11
16
|
a.dito-pulldown__item(
|
|
17
|
+
role="menuitem"
|
|
12
18
|
@mousedown.stop="onPulldownMouseDown(value)"
|
|
13
19
|
@mouseup="onPulldownMouseUp(value)"
|
|
14
20
|
) {{ label }}
|
|
@@ -13,15 +13,19 @@
|
|
|
13
13
|
button.dito-button(
|
|
14
14
|
type="button"
|
|
15
15
|
:disabled="disabled"
|
|
16
|
-
v-bind="getButtonAttributes(verb)"
|
|
16
|
+
v-bind="{ ...pulldownTriggerAttributes, ...getButtonAttributes(verb) }"
|
|
17
17
|
@mousedown.stop="onPulldownMouseDown()"
|
|
18
18
|
) {{ text }}
|
|
19
|
-
ul.dito-pulldown(
|
|
19
|
+
ul.dito-pulldown(
|
|
20
|
+
role="menu"
|
|
21
|
+
:class="{ 'dito-pulldown--open': pulldown.open }"
|
|
22
|
+
)
|
|
20
23
|
li(
|
|
21
24
|
v-for="(form, type) in creatableForms"
|
|
22
25
|
v-show="shouldShowSchema(form)"
|
|
23
26
|
)
|
|
24
27
|
a.dito-pulldown__item(
|
|
28
|
+
role="menuitem"
|
|
25
29
|
:class=`{
|
|
26
30
|
'dito-pulldown__item--disabled': shouldDisableSchema(form)
|
|
27
31
|
}`
|
|
@@ -6,6 +6,7 @@ div(
|
|
|
6
6
|
slot
|
|
7
7
|
form.dito-scroll-parent(
|
|
8
8
|
v-else
|
|
9
|
+
:aria-label="label"
|
|
9
10
|
@submit.prevent
|
|
10
11
|
)
|
|
11
12
|
slot
|
|
@@ -20,6 +21,10 @@ export default DitoComponent.component('DitoFormInner', {
|
|
|
20
21
|
nested: {
|
|
21
22
|
type: Boolean,
|
|
22
23
|
default: false
|
|
24
|
+
},
|
|
25
|
+
label: {
|
|
26
|
+
type: String,
|
|
27
|
+
default: null
|
|
23
28
|
}
|
|
24
29
|
}
|
|
25
30
|
})
|
|
@@ -69,7 +69,12 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
69
69
|
},
|
|
70
70
|
|
|
71
71
|
attributes() {
|
|
72
|
-
return this.collapsible
|
|
72
|
+
return this.collapsible
|
|
73
|
+
? {
|
|
74
|
+
'onClick': this.onClick,
|
|
75
|
+
'aria-expanded': !this.collapsed
|
|
76
|
+
}
|
|
77
|
+
: {}
|
|
73
78
|
},
|
|
74
79
|
|
|
75
80
|
isActive() {
|
|
@@ -12,6 +12,7 @@ ul.dito-menu(
|
|
|
12
12
|
a.dito-menu__link(
|
|
13
13
|
:href="getItemHref(item)"
|
|
14
14
|
:class="{ 'dito-menu__link--active': isActiveItem(item) }"
|
|
15
|
+
:aria-current="isActiveItem(item) ? 'page' : null"
|
|
15
16
|
@click.prevent.stop="onClickItem(item)"
|
|
16
17
|
) {{ getLabel(item) }}
|
|
17
18
|
DitoMenu.dito-menu__sub(
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
<template lang="pug">
|
|
3
3
|
.dito-pane(
|
|
4
4
|
v-if="isPopulated && componentSchemas.length > 0"
|
|
5
|
+
:id="tab ? `${dataPath}-tabpanel-${tab}` : null"
|
|
5
6
|
v-resize="onResizePane"
|
|
7
|
+
:role="tab ? 'tabpanel' : null"
|
|
8
|
+
:aria-labelledby="tab ? `${dataPath}-tab-${tab}` : null"
|
|
6
9
|
:class="classes"
|
|
7
10
|
)
|
|
8
11
|
template(
|
|
@@ -6,6 +6,7 @@ thead.dito-table-head
|
|
|
6
6
|
)
|
|
7
7
|
th(
|
|
8
8
|
v-if="shouldRenderSchema(column)"
|
|
9
|
+
scope="col"
|
|
9
10
|
:class="getColumnClass(column)"
|
|
10
11
|
)
|
|
11
12
|
RouterLink(
|
|
@@ -17,6 +18,7 @@ thead.dito-table-head
|
|
|
17
18
|
button.dito-button(
|
|
18
19
|
type="button"
|
|
19
20
|
:class="getSortClass(column)"
|
|
21
|
+
:aria-sort="getSortState(column)"
|
|
20
22
|
@click="navigate"
|
|
21
23
|
)
|
|
22
24
|
.dito-button__order-arrows
|
|
@@ -64,6 +66,14 @@ export default DitoComponent.component('DitoTableHead', {
|
|
|
64
66
|
: null
|
|
65
67
|
},
|
|
66
68
|
|
|
69
|
+
getSortState(column) {
|
|
70
|
+
const states = { asc: 'ascending', desc: 'descending' }
|
|
71
|
+
return (
|
|
72
|
+
states[this.sort.name === column.name && this.sort.order] ||
|
|
73
|
+
'none'
|
|
74
|
+
)
|
|
75
|
+
},
|
|
76
|
+
|
|
67
77
|
getSortLink(column) {
|
|
68
78
|
// Toggle order if the same column is clicked again.
|
|
69
79
|
const order =
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
.dito-tabs
|
|
2
|
+
.dito-tabs(role="tablist")
|
|
3
3
|
template(
|
|
4
4
|
v-for="(tabSchema, key) in tabs"
|
|
5
5
|
)
|
|
6
6
|
a.dito-tabs__link(
|
|
7
7
|
v-if="shouldRenderSchema(tabSchema)"
|
|
8
|
+
:id="getTabId(key)"
|
|
8
9
|
:key="key"
|
|
10
|
+
role="tab"
|
|
11
|
+
:aria-selected="modelValue === key"
|
|
12
|
+
:aria-controls="getPanelId(key)"
|
|
13
|
+
:tabindex="modelValue === key ? 0 : -1"
|
|
9
14
|
:class="{ 'dito-tabs__link--active': modelValue === key }"
|
|
10
15
|
@click="$emit('update:modelValue', key)"
|
|
11
16
|
) {{ getLabel(tabSchema, key) }}
|
|
@@ -19,7 +24,18 @@ export default DitoComponent.component('DitoTabs', {
|
|
|
19
24
|
emits: ['update:modelValue'],
|
|
20
25
|
props: {
|
|
21
26
|
tabs: { type: Object, default: null },
|
|
22
|
-
modelValue: { type: String, default: null }
|
|
27
|
+
modelValue: { type: String, default: null },
|
|
28
|
+
dataPath: { type: String, default: '' }
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
methods: {
|
|
32
|
+
getTabId(key) {
|
|
33
|
+
return `${this.dataPath}-tab-${key}`
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
getPanelId(key) {
|
|
37
|
+
return `${this.dataPath}-tabpanel-${key}`
|
|
38
|
+
}
|
|
23
39
|
}
|
|
24
40
|
})
|
|
25
41
|
</script>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
.dito-trail
|
|
2
|
+
.dito-trail(aria-label="Breadcrumb")
|
|
3
3
|
ul
|
|
4
4
|
li(
|
|
5
5
|
v-for="component in trail"
|
|
6
6
|
)
|
|
7
7
|
a.dito-trail__link(
|
|
8
8
|
:class="{ 'dito-trail__link--active': component.path === $route.path }"
|
|
9
|
+
:aria-current="component.path === $route.path ? 'page' : null"
|
|
9
10
|
:href="getComponentHref(component)"
|
|
10
11
|
@click.prevent.stop="onClickComponent(component)"
|
|
11
12
|
)
|
|
@@ -13,7 +13,12 @@
|
|
|
13
13
|
)
|
|
14
14
|
.dito-tree-branch(
|
|
15
15
|
v-if="numEntries"
|
|
16
|
+
role="button"
|
|
17
|
+
tabindex="0"
|
|
18
|
+
:aria-label="ariaLabel"
|
|
19
|
+
:aria-expanded="opened"
|
|
16
20
|
@click.stop="opened = !opened"
|
|
21
|
+
@keydown.enter.space.prevent="opened = !opened"
|
|
17
22
|
)
|
|
18
23
|
.dito-chevron(
|
|
19
24
|
v-if="numEntries"
|
|
@@ -105,6 +110,7 @@ import SortableMixin from '../mixins/SortableMixin.js'
|
|
|
105
110
|
import { appendDataPath } from '../utils/data.js'
|
|
106
111
|
import { getSchemaAccessor } from '../utils/accessor.js'
|
|
107
112
|
import { getNamedSchemas, hasFormSchema } from '../utils/schema.js'
|
|
113
|
+
import { stripHtml } from '@ditojs/utils'
|
|
108
114
|
|
|
109
115
|
// @vue/component
|
|
110
116
|
export default DitoComponent.component('DitoTreeItem', {
|
|
@@ -222,6 +228,10 @@ export default DitoComponent.component('DitoTreeItem', {
|
|
|
222
228
|
return []
|
|
223
229
|
},
|
|
224
230
|
|
|
231
|
+
ariaLabel() {
|
|
232
|
+
return this.label ? stripHtml(this.label) : null
|
|
233
|
+
},
|
|
234
|
+
|
|
225
235
|
details() {
|
|
226
236
|
const { numChildren } = this
|
|
227
237
|
return (
|
|
@@ -311,8 +321,14 @@ export default DitoComponent.component('DitoTreeItem', {
|
|
|
311
321
|
--chevron-indent: #{$chevron-indent};
|
|
312
322
|
|
|
313
323
|
overflow: hidden;
|
|
324
|
+
padding: 0 $input-padding-hor;
|
|
325
|
+
margin: 0 (-$input-padding-hor);
|
|
314
326
|
|
|
315
327
|
> .dito-tree-header {
|
|
328
|
+
// Extend header into item padding so active background reaches the edge:
|
|
329
|
+
margin: 0 (-$input-padding-hor);
|
|
330
|
+
padding: 0 $input-padding-hor;
|
|
331
|
+
|
|
316
332
|
> .dito-tree-branch,
|
|
317
333
|
> .dito-tree-leaf {
|
|
318
334
|
// Use `--level` CSS variable to calculated the accumulated indent
|
|
@@ -346,8 +362,13 @@ export default DitoComponent.component('DitoTreeItem', {
|
|
|
346
362
|
display: flex;
|
|
347
363
|
align-items: baseline;
|
|
348
364
|
gap: 0.25em;
|
|
349
|
-
|
|
365
|
+
min-width: 0;
|
|
350
366
|
white-space: nowrap;
|
|
367
|
+
|
|
368
|
+
> :first-child {
|
|
369
|
+
overflow: hidden;
|
|
370
|
+
text-overflow: ellipsis;
|
|
371
|
+
}
|
|
351
372
|
}
|
|
352
373
|
|
|
353
374
|
.dito-tree-info {
|
|
@@ -385,8 +406,6 @@ export default DitoComponent.component('DitoTreeItem', {
|
|
|
385
406
|
&--active {
|
|
386
407
|
> .dito-tree-header {
|
|
387
408
|
background: $color-active;
|
|
388
|
-
padding: 0 $input-padding-hor;
|
|
389
|
-
margin: 0 (-$input-padding-hor);
|
|
390
409
|
|
|
391
410
|
> .dito-tree-branch {
|
|
392
411
|
> .dito-chevron::before {
|
package/src/mixins/DitoMixin.js
CHANGED
|
@@ -277,9 +277,11 @@ export default {
|
|
|
277
277
|
},
|
|
278
278
|
|
|
279
279
|
getButtonAttributes(verb) {
|
|
280
|
+
const label = labelize(verb)
|
|
280
281
|
return {
|
|
281
|
-
class: `dito-button--${verb}`,
|
|
282
|
-
title:
|
|
282
|
+
'class': `dito-button--${verb}`,
|
|
283
|
+
'title': label,
|
|
284
|
+
'aria-label': label
|
|
283
285
|
}
|
|
284
286
|
},
|
|
285
287
|
|
|
@@ -27,6 +27,15 @@ export default {
|
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
|
|
30
|
+
computed: {
|
|
31
|
+
pulldownTriggerAttributes() {
|
|
32
|
+
return {
|
|
33
|
+
'aria-haspopup': 'menu',
|
|
34
|
+
'aria-expanded': this.pulldown.open
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
30
39
|
methods: {
|
|
31
40
|
onPulldownMouseDown(value = null) {
|
|
32
41
|
if (value === null) {
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
//- Styling comes from `DitoTableHead`
|
|
25
25
|
thead.dito-table-head
|
|
26
26
|
tr
|
|
27
|
-
th
|
|
27
|
+
th(scope="col")
|
|
28
28
|
span File
|
|
29
|
-
th
|
|
29
|
+
th(scope="col")
|
|
30
30
|
span Size
|
|
31
|
-
th
|
|
31
|
+
th(scope="col")
|
|
32
32
|
span Status
|
|
33
|
-
th
|
|
33
|
+
th(scope="col")
|
|
34
34
|
span
|
|
35
35
|
DitoDraggable(
|
|
36
36
|
v-model="files"
|
package/types/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
TimeFormat
|
|
9
9
|
} from '@ditojs/utils'
|
|
10
10
|
import { RequireAtLeastOne, SetOptional } from 'type-fest'
|
|
11
|
-
import { Component as VueComponent } from 'vue'
|
|
11
|
+
import { Component as VueComponent, ComponentPublicInstance } from 'vue'
|
|
12
12
|
import { Router as VueRouter } from 'vue-router'
|
|
13
13
|
|
|
14
14
|
declare global {
|
|
@@ -695,7 +695,19 @@ export interface SchemaSourceMixin<$Item> {
|
|
|
695
695
|
*
|
|
696
696
|
* @defaultValue `false`
|
|
697
697
|
*/
|
|
698
|
-
creatable?: OrItemAccessor
|
|
698
|
+
creatable?: OrItemAccessor<
|
|
699
|
+
$Item,
|
|
700
|
+
{},
|
|
701
|
+
| boolean
|
|
702
|
+
| {
|
|
703
|
+
label?: string
|
|
704
|
+
/**
|
|
705
|
+
* Returns additional query parameters to include in the
|
|
706
|
+
* URL when navigating to the create form.
|
|
707
|
+
*/
|
|
708
|
+
query?: (context: DitoContext) => Record<string, any>
|
|
709
|
+
}
|
|
710
|
+
>
|
|
699
711
|
/**
|
|
700
712
|
* Whether to add edit buttons next to the list items.
|
|
701
713
|
*
|
|
@@ -788,11 +800,14 @@ export type SchemaOptions<$Item, $Option = any> =
|
|
|
788
800
|
*/
|
|
789
801
|
groupBy?: keyof $Option
|
|
790
802
|
/**
|
|
791
|
-
* Custom equality function for
|
|
803
|
+
* Custom equality function for matching a value to an
|
|
804
|
+
* option. Receives a context with `value` and `option`.
|
|
792
805
|
*/
|
|
793
806
|
equals?: (
|
|
794
|
-
|
|
795
|
-
|
|
807
|
+
context: DitoContext & {
|
|
808
|
+
value: any
|
|
809
|
+
option: $Option
|
|
810
|
+
}
|
|
796
811
|
) => boolean
|
|
797
812
|
/**
|
|
798
813
|
* Relative path to resolve options from data
|
|
@@ -1640,6 +1655,12 @@ export interface CheckboxesSchema<$Item = any>
|
|
|
1640
1655
|
* The type of the component.
|
|
1641
1656
|
*/
|
|
1642
1657
|
type: 'checkboxes'
|
|
1658
|
+
/**
|
|
1659
|
+
* Whether multiple values can be selected.
|
|
1660
|
+
*
|
|
1661
|
+
* @defaultValue `true`
|
|
1662
|
+
*/
|
|
1663
|
+
multiple?: boolean
|
|
1643
1664
|
/**
|
|
1644
1665
|
* @defaultValue `'vertical'`
|
|
1645
1666
|
*/
|
|
@@ -1918,7 +1939,7 @@ export type DitoContext<$Item = any> = {
|
|
|
1918
1939
|
/**
|
|
1919
1940
|
* The current search term in select components.
|
|
1920
1941
|
*/
|
|
1921
|
-
searchTerm: string
|
|
1942
|
+
searchTerm: string
|
|
1922
1943
|
/**
|
|
1923
1944
|
* Whether a button request is currently running.
|
|
1924
1945
|
*/
|
|
@@ -1976,9 +1997,22 @@ export type DitoContext<$Item = any> = {
|
|
|
1976
1997
|
getResourceUrl(resource: Resource): string
|
|
1977
1998
|
/** Displays a notification to the user. */
|
|
1978
1999
|
notify(options: {
|
|
2000
|
+
/** Notification style. @defaultValue `'info'` */
|
|
1979
2001
|
type?: LiteralUnion<'warning' | 'error' | 'info' | 'success'>
|
|
2002
|
+
/** Heading text. Defaults to a label matching `type`. */
|
|
1980
2003
|
title?: string
|
|
2004
|
+
/** Body text, rendered as HTML paragraphs. */
|
|
1981
2005
|
text: OrArrayOf<string>
|
|
2006
|
+
/**
|
|
2007
|
+
* The original error object. When `type` is `'error'`,
|
|
2008
|
+
* this is logged to the console alongside the message.
|
|
2009
|
+
*/
|
|
2010
|
+
error?: unknown
|
|
2011
|
+
/**
|
|
2012
|
+
* Display duration in milliseconds. When omitted, calculated
|
|
2013
|
+
* automatically from content length. Use `0` for sticky.
|
|
2014
|
+
*/
|
|
2015
|
+
duration?: number
|
|
1982
2016
|
}): void
|
|
1983
2017
|
}
|
|
1984
2018
|
|
|
@@ -1997,7 +2031,9 @@ export type DitoComponentInstance<
|
|
|
1997
2031
|
$Members extends Record<string, any> = {}
|
|
1998
2032
|
> = DitoComponentInstanceBase<$Item> & $Members
|
|
1999
2033
|
|
|
2000
|
-
export interface DitoComponentInstanceBase<$Item = any>
|
|
2034
|
+
export interface DitoComponentInstanceBase<$Item = any>
|
|
2035
|
+
extends ComponentPublicInstance,
|
|
2036
|
+
EmitterMixin {
|
|
2001
2037
|
// -- Data access (ValueMixin, ContextMixin, TypeMixin) --
|
|
2002
2038
|
|
|
2003
2039
|
/** The current value of the component (getter/setter). */
|
|
@@ -2968,6 +3004,31 @@ export type SourceComponent<$Item = any> =
|
|
|
2968
3004
|
| TreeListSchema<$Item>
|
|
2969
3005
|
| TreeObjectSchema<$Item>
|
|
2970
3006
|
|
|
3007
|
+
/**
|
|
3008
|
+
* Field components that don't have an options mixin (excludes
|
|
3009
|
+
* select, multiselect, and source components like list/object/tree).
|
|
3010
|
+
*/
|
|
3011
|
+
type NonOptionFieldComponent<$Item = any> = Exclude<
|
|
3012
|
+
NonSectionComponent<$Item>,
|
|
3013
|
+
SelectSchema<$Item> | MultiselectSchema<$Item> | SourceComponent<$Item>
|
|
3014
|
+
>
|
|
3015
|
+
|
|
3016
|
+
/**
|
|
3017
|
+
* Select/multiselect with a typed `$Option` for option callbacks.
|
|
3018
|
+
*
|
|
3019
|
+
* Note: This is intentionally an intersection type rather than
|
|
3020
|
+
* `SelectSchema<$Item, $Option> | MultiselectSchema<$Item, $Option>`,
|
|
3021
|
+
* because using the full interfaces in a union breaks TypeScript's
|
|
3022
|
+
* contextual typing for callbacks in the `Components` mapped type.
|
|
3023
|
+
*/
|
|
3024
|
+
type OptionComponent<$Item, $Option> = BaseSchema<$Item> &
|
|
3025
|
+
SchemaOptionsMixin<$Item, $Option> &
|
|
3026
|
+
SchemaAffixMixin<$Item> &
|
|
3027
|
+
Pick<
|
|
3028
|
+
MultiselectSchema,
|
|
3029
|
+
'multiple' | 'searchable' | 'stayOpen' | 'taggable'
|
|
3030
|
+
> & { type: 'select' | 'multiselect' }
|
|
3031
|
+
|
|
2971
3032
|
/**
|
|
2972
3033
|
* Strips properties with `never` values from a type.
|
|
2973
3034
|
*/
|
|
@@ -3047,14 +3108,16 @@ export type Components<$Item = any> = 0 extends 1 & $Item
|
|
|
3047
3108
|
: {
|
|
3048
3109
|
[K in keyof $Item]?: [$Item[K]] extends [never]
|
|
3049
3110
|
? NonSectionComponent<$Item> | SectionSchema<$Item>
|
|
3050
|
-
:
|
|
3111
|
+
: NonNullable<$Item[K]> extends (infer E)[]
|
|
3051
3112
|
? E extends Record<string, any>
|
|
3052
3113
|
? NonSectionComponent<E>
|
|
3053
3114
|
: NonSectionComponent<$Item>
|
|
3054
|
-
:
|
|
3115
|
+
: NonNullable<$Item[K]> extends Record<string, any>
|
|
3055
3116
|
?
|
|
3056
|
-
|
|
|
3057
|
-
|
|
|
3117
|
+
| NonOptionFieldComponent<$Item>
|
|
3118
|
+
| OptionComponent<$Item, NonNullable<$Item[K]>>
|
|
3119
|
+
| SourceComponent<NonNullable<$Item[K]>>
|
|
3120
|
+
| SectionSchema<$Item, NonNullable<$Item[K]>>
|
|
3058
3121
|
:
|
|
3059
3122
|
| NonSectionComponent<$Item>
|
|
3060
3123
|
| SectionSchema<$Item>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { assertType, describe, it } from 'vitest'
|
|
2
|
-
import type { default as DitoAdmin, View } from '../index.d.ts'
|
|
3
|
-
import type { Entry } from './fixtures.ts'
|
|
4
|
-
|
|
5
|
-
describe('DitoAdmin', () => {
|
|
6
|
-
it('constructor accepts element and views option', () => {
|
|
7
|
-
assertType<ConstructorParameters<typeof DitoAdmin>>([
|
|
8
|
-
document.body,
|
|
9
|
-
{
|
|
10
|
-
views: {
|
|
11
|
-
entries: {
|
|
12
|
-
type: 'view',
|
|
13
|
-
component: {
|
|
14
|
-
type: 'list',
|
|
15
|
-
form: {
|
|
16
|
-
type: 'form',
|
|
17
|
-
components: {
|
|
18
|
-
title: { type: 'text' }
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
} satisfies View<Entry>
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
])
|
|
26
|
-
})
|
|
27
|
-
})
|