@neeloong/form 0.15.0 → 0.17.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/index.d.mts +18 -9
- package/{index.js → index.full.js} +238 -138
- package/{index.min.js → index.full.min.js} +4 -4
- package/index.full.min.mjs +60 -0
- package/index.min.mjs +2 -56
- package/index.mjs +238 -138
- package/package.json +6 -6
package/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @neeloong/form v0.
|
|
2
|
+
* @neeloong/form v0.17.0
|
|
3
3
|
* (c) 2024-2025 Fierflame
|
|
4
4
|
* @license Apache-2.0
|
|
5
5
|
*/
|
|
@@ -1174,13 +1174,22 @@ declare class ArrayStore<T = any, M = any> extends Store<(T | null)[], M> {
|
|
|
1174
1174
|
#private;
|
|
1175
1175
|
}
|
|
1176
1176
|
|
|
1177
|
-
type
|
|
1177
|
+
type GridFormItemTemplateTableAction = "add" | "move" | "trigger" | "remove" | "serial";
|
|
1178
|
+
type GridFieldLayout = {
|
|
1178
1179
|
field: string;
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1180
|
+
fields?: GridFieldLayout[] | null | undefined;
|
|
1181
|
+
tableFoot?: "add" | "header" | "none" | undefined;
|
|
1182
|
+
columns?: (string | GridFormItemTemplateTableAction[])[] | undefined;
|
|
1183
|
+
colStart?: number | undefined;
|
|
1184
|
+
colSpan?: number | undefined;
|
|
1185
|
+
colEnd?: number | undefined;
|
|
1186
|
+
rowStart?: number | undefined;
|
|
1187
|
+
rowSpan?: number | undefined;
|
|
1188
|
+
rowEnd?: number | undefined;
|
|
1189
|
+
};
|
|
1190
|
+
type GridLayout = {
|
|
1191
|
+
fields?: GridFieldLayout[] | null | undefined;
|
|
1182
1192
|
};
|
|
1183
|
-
type GridFormTemplate = GridFormItemTemplate[];
|
|
1184
1193
|
type Options = object;
|
|
1185
1194
|
type FieldRenderer = (store: Store<any, any>, component: any, Options: Options) => [HTMLElement, () => void];
|
|
1186
1195
|
|
|
@@ -1190,9 +1199,9 @@ type FieldRenderer = (store: Store<any, any>, component: any, Options: Options)
|
|
|
1190
1199
|
* @param {HTMLElement} root
|
|
1191
1200
|
* @param {FieldRenderer} fieldRenderer
|
|
1192
1201
|
* @param {boolean} editable
|
|
1193
|
-
* @param {
|
|
1202
|
+
* @param {GridLayout?} [layout]
|
|
1194
1203
|
*/
|
|
1195
|
-
declare function _default(store: Store, root: HTMLElement, fieldRenderer: FieldRenderer, editable: boolean,
|
|
1204
|
+
declare function _default(store: Store, root: HTMLElement, fieldRenderer: FieldRenderer, editable: boolean, layout?: GridLayout | null): () => void;
|
|
1196
1205
|
|
|
1197
1206
|
/**
|
|
1198
1207
|
* @param {Store} store 存储实例
|
|
@@ -1244,4 +1253,4 @@ declare function effect(fn: () => void): () => void;
|
|
|
1244
1253
|
*/
|
|
1245
1254
|
declare function renderHtml(renderField: (store: Store<any, any>, component: any) => [HTMLElement, () => void] | null, store: Store, root: HTMLElement, html?: string | ParentNode, clone?: boolean): () => void;
|
|
1246
1255
|
|
|
1247
|
-
export { ArrayStore, type AsyncValidator, Component, Enhancement, type FieldRenderer, type
|
|
1256
|
+
export { ArrayStore, type AsyncValidator, Component, Enhancement, type FieldRenderer, type GridFieldLayout, type GridFormItemTemplateTableAction, type GridLayout, index_d as Layout, ObjectStore, type Options, type Ref, type Relatedness, Schema, Store, type Validator, type VerifyError, effect, render, _default as renderGrid, renderHtml, watch };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @neeloong/form v0.
|
|
2
|
+
* @neeloong/form v0.17.0
|
|
3
3
|
* (c) 2024-2025 Fierflame
|
|
4
4
|
* @license Apache-2.0
|
|
5
5
|
*/
|
|
@@ -5501,16 +5501,16 @@
|
|
|
5501
5501
|
|
|
5502
5502
|
/** @import { Store } from '../Store/index.mjs' */
|
|
5503
5503
|
/** @import { Relatedness } from '../types.mjs' */
|
|
5504
|
-
/** @import { FieldRenderer,
|
|
5504
|
+
/** @import { FieldRenderer, GridFieldLayout, GridFormItemTemplateTableAction } from './types.mjs' */
|
|
5505
5505
|
|
|
5506
5506
|
/**
|
|
5507
5507
|
*
|
|
5508
5508
|
* @param {Store<any, any>} store
|
|
5509
5509
|
* @param {FieldRenderer} fieldRenderer
|
|
5510
5510
|
* @param {boolean} editable
|
|
5511
|
-
* @param {
|
|
5511
|
+
* @param {GridFieldLayout?} layout
|
|
5512
5512
|
* @param {object} option
|
|
5513
|
-
* @param {string[]} option.columns
|
|
5513
|
+
* @param {(string | GridFormItemTemplateTableAction[])[]} option.columns
|
|
5514
5514
|
* @param {() => void} option.remove
|
|
5515
5515
|
* @param {() => void} option.dragenter
|
|
5516
5516
|
* @param {() => void} option.dragstart
|
|
@@ -5521,8 +5521,8 @@
|
|
|
5521
5521
|
|
|
5522
5522
|
* @returns {[HTMLTableSectionElement, () => void]}
|
|
5523
5523
|
*/
|
|
5524
|
-
function Line(store, fieldRenderer, editable,
|
|
5525
|
-
columns,
|
|
5524
|
+
function Line(store, fieldRenderer, editable, layout, {
|
|
5525
|
+
columns,
|
|
5526
5526
|
remove, dragenter, dragstart, dragend, deletable
|
|
5527
5527
|
}, options) {
|
|
5528
5528
|
const root = document.createElement('tbody');
|
|
@@ -5536,72 +5536,109 @@
|
|
|
5536
5536
|
root.addEventListener('dragend', dragend);
|
|
5537
5537
|
const head = root.appendChild(document.createElement('tr'));
|
|
5538
5538
|
|
|
5539
|
-
const handle = head.appendChild(document.createElement('th'));
|
|
5540
|
-
handle.className = 'button-group';
|
|
5541
5539
|
/** @type {(() => void)[]} */
|
|
5542
5540
|
const destroyList = [];
|
|
5543
|
-
for (const name of columns) {
|
|
5544
|
-
const td = head.appendChild(document.createElement('td'));
|
|
5545
|
-
const child = store.child(name);
|
|
5546
|
-
if (!child) { continue }
|
|
5547
|
-
const [el, destroy] = FormItem(child, fieldRenderer, editable, null, options, true);
|
|
5548
|
-
destroyList.push(destroy);
|
|
5549
|
-
td.appendChild(el);
|
|
5550
|
-
}
|
|
5551
5541
|
|
|
5552
5542
|
|
|
5543
|
+
let trigger = () => { };
|
|
5544
|
+
/** @type {HTMLButtonElement[]} */
|
|
5545
|
+
const triggerList = [];
|
|
5546
|
+
if (columns.find(v => Array.isArray(v) && v.includes('trigger'))) {
|
|
5547
|
+
const body = root.appendChild(document.createElement('tr'));
|
|
5548
|
+
const main = body.appendChild(document.createElement('td'));
|
|
5549
|
+
main.colSpan = columns.length;
|
|
5553
5550
|
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5551
|
+
const [form, destroy] = Form(store, fieldRenderer, editable, layout, options);
|
|
5552
|
+
main.appendChild(form);
|
|
5553
|
+
destroyList.push(destroy);
|
|
5554
|
+
body.hidden = true;
|
|
5555
|
+
trigger = function click() {
|
|
5556
|
+
if (body.hidden) {
|
|
5557
|
+
body.hidden = false;
|
|
5558
|
+
for (const ext of triggerList) {
|
|
5559
|
+
ext.classList.remove('NeeloongFormGrid-table-line-open');
|
|
5560
|
+
ext.classList.add('NeeloongFormGrid-table-line-close');
|
|
5561
|
+
}
|
|
5562
|
+
} else {
|
|
5563
|
+
body.hidden = true;
|
|
5564
|
+
for (const ext of triggerList) {
|
|
5565
|
+
ext.classList.remove('NeeloongFormGrid-table-line-close');
|
|
5566
|
+
ext.classList.add('NeeloongFormGrid-table-line-open');
|
|
5567
|
+
}
|
|
5568
|
+
}
|
|
5569
|
+
};
|
|
5562
5570
|
|
|
5571
|
+
}
|
|
5563
5572
|
|
|
5573
|
+
/**
|
|
5574
|
+
*
|
|
5575
|
+
* @param {PointerEvent} event
|
|
5576
|
+
*/
|
|
5577
|
+
function pointerdown({ pointerId }) {
|
|
5578
|
+
root.draggable = true;
|
|
5579
|
+
/** @param {PointerEvent} event */
|
|
5580
|
+
function pointerup(event) {
|
|
5581
|
+
if (event.pointerId !== pointerId) { return; }
|
|
5582
|
+
if (!root) { return; }
|
|
5583
|
+
root.draggable = false;
|
|
5584
|
+
window.removeEventListener('pointerup', pointerup, { capture: true });
|
|
5585
|
+
window.removeEventListener('pointercancel', pointerup, { capture: true });
|
|
5586
|
+
}
|
|
5587
|
+
window.addEventListener('pointerup', pointerup, { capture: true });
|
|
5588
|
+
window.addEventListener('pointercancel', pointerup, { capture: true });
|
|
5564
5589
|
|
|
5565
|
-
|
|
5566
|
-
body.hidden = true;
|
|
5567
|
-
ext.innerText = '+';
|
|
5568
|
-
ext.addEventListener('click', () => {
|
|
5569
|
-
if(body.hidden) {
|
|
5570
|
-
body.hidden = false;
|
|
5571
|
-
ext.innerText = '-';
|
|
5572
|
-
} else {
|
|
5573
|
-
body.hidden = true;
|
|
5574
|
-
ext.innerText = '+';
|
|
5590
|
+
}
|
|
5575
5591
|
|
|
5592
|
+
for (const name of columns) {
|
|
5593
|
+
if (!Array.isArray(name)) {
|
|
5594
|
+
const td = head.appendChild(document.createElement('td'));
|
|
5595
|
+
const child = store.child(name);
|
|
5596
|
+
if (!child) { continue; }
|
|
5597
|
+
const [el, destroy] = FormItem(child, fieldRenderer, editable, null, options, true);
|
|
5598
|
+
destroyList.push(destroy);
|
|
5599
|
+
td.appendChild(el);
|
|
5600
|
+
continue;
|
|
5576
5601
|
}
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
const
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5602
|
+
const handle = head.appendChild(document.createElement('th'));
|
|
5603
|
+
handle.classList.add('NeeloongFormGrid-table-line-handle');
|
|
5604
|
+
for (const k of name) {
|
|
5605
|
+
switch (k) {
|
|
5606
|
+
case 'trigger': {
|
|
5607
|
+
const ext = handle.appendChild(document.createElement('button'));
|
|
5608
|
+
ext.classList.add('NeeloongFormGrid-table-line-open');
|
|
5609
|
+
triggerList.push(ext);
|
|
5610
|
+
ext.addEventListener('click', trigger);
|
|
5611
|
+
continue;
|
|
5612
|
+
}
|
|
5613
|
+
case 'move': {
|
|
5614
|
+
if (!editable) { continue; }
|
|
5615
|
+
const move = handle.appendChild(document.createElement('button'));
|
|
5616
|
+
move.classList.add('NeeloongFormGrid-table-move');
|
|
5617
|
+
move.addEventListener('pointerdown', pointerdown);
|
|
5618
|
+
destroyList.push(watch(() => store.readonly || store.disabled, disabled => {
|
|
5619
|
+
move.disabled = disabled;
|
|
5620
|
+
}, true));
|
|
5621
|
+
continue;
|
|
5622
|
+
}
|
|
5623
|
+
case 'remove': {
|
|
5624
|
+
if (!editable) { continue; }
|
|
5625
|
+
const del = handle.appendChild(document.createElement('button'));
|
|
5626
|
+
del.classList.add('NeeloongFormGrid-table-remove');
|
|
5627
|
+
del.addEventListener('click', remove);
|
|
5628
|
+
destroyList.push(watch(() => !deletable.get() || store.readonly || store.disabled, disabled => {
|
|
5629
|
+
del.disabled = disabled;
|
|
5630
|
+
}, true));
|
|
5631
|
+
continue;
|
|
5632
|
+
}
|
|
5633
|
+
case 'serial': {
|
|
5634
|
+
const serial = handle.appendChild(document.createElement('span'));
|
|
5635
|
+
serial.classList.add('NeeloongFormGrid-table-serial');
|
|
5636
|
+
continue;
|
|
5637
|
+
}
|
|
5590
5638
|
}
|
|
5591
|
-
|
|
5592
|
-
window.addEventListener('pointercancel', pointerup, {capture: true});
|
|
5593
|
-
});
|
|
5594
|
-
destroyList.push(watch(() => store.readonly || store.disabled, disabled => {
|
|
5595
|
-
move.disabled = disabled;
|
|
5596
|
-
}, true));
|
|
5597
|
-
const del = handle.appendChild(document.createElement('button'));
|
|
5598
|
-
del.classList.add('GridForm-table-remove');
|
|
5599
|
-
// @ts-ignore
|
|
5600
|
-
destroyList.push(watch(() => !deletable.get() || store.readonly || store.disabled, disabled => {
|
|
5601
|
-
move.disabled = disabled;
|
|
5602
|
-
}, true));
|
|
5603
|
-
del.addEventListener('click', remove);
|
|
5639
|
+
}
|
|
5604
5640
|
}
|
|
5641
|
+
|
|
5605
5642
|
return [root, () => {
|
|
5606
5643
|
for (const destroy of destroyList) {
|
|
5607
5644
|
destroy();
|
|
@@ -5611,70 +5648,90 @@
|
|
|
5611
5648
|
|
|
5612
5649
|
/** @import { Store, ArrayStore } from '../Store/index.mjs' */
|
|
5613
5650
|
/** @import { Relatedness } from '../types.mjs' */
|
|
5614
|
-
/** @import { FieldRenderer,
|
|
5651
|
+
/** @import { FieldRenderer, GridFieldLayout, GridFormItemTemplateTableAction } from './types.mjs' */
|
|
5615
5652
|
|
|
5616
5653
|
/**
|
|
5617
5654
|
*
|
|
5618
5655
|
* @param {HTMLElement} parent
|
|
5619
|
-
* @param {
|
|
5656
|
+
* @param {({ field: string; width: any; label: any; } | GridFormItemTemplateTableAction[])[]} columns
|
|
5620
5657
|
* @param {() => any} add
|
|
5621
5658
|
* @param {{get(): boolean}} addable
|
|
5622
5659
|
* @param {boolean?} [editable]
|
|
5623
5660
|
*/
|
|
5624
5661
|
function renderHead(parent, columns, add, addable, editable) {
|
|
5625
5662
|
const tr = parent.appendChild(document.createElement('tr'));
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
if (
|
|
5630
|
-
|
|
5663
|
+
/** @type {(() => void)[]} */
|
|
5664
|
+
const destroyList = [];
|
|
5665
|
+
for (const col of columns) {
|
|
5666
|
+
if (!Array.isArray(col)) {
|
|
5667
|
+
const { width, label } = col;
|
|
5668
|
+
const td = tr.appendChild(document.createElement('th'));
|
|
5669
|
+
if (width) {
|
|
5670
|
+
td.setAttribute('width', width);
|
|
5671
|
+
}
|
|
5672
|
+
td.innerText = label;
|
|
5673
|
+
continue;
|
|
5674
|
+
}
|
|
5675
|
+
const th = tr.appendChild(document.createElement('th'));
|
|
5676
|
+
if (!editable) { continue; }
|
|
5677
|
+
for (const it of col) {
|
|
5678
|
+
switch (it) {
|
|
5679
|
+
case 'add':
|
|
5680
|
+
const button = th.appendChild(document.createElement('button'));
|
|
5681
|
+
button.addEventListener('click', add);
|
|
5682
|
+
button.classList.add('NeeloongFormGrid-table-add');
|
|
5683
|
+
destroyList.push(watch(() => !addable.get(), disabled => { button.disabled = disabled; }, true));
|
|
5684
|
+
continue;
|
|
5685
|
+
}
|
|
5631
5686
|
}
|
|
5632
|
-
td.innerText = label;
|
|
5633
|
-
}
|
|
5634
|
-
if (!editable) {
|
|
5635
|
-
return () => {}
|
|
5636
5687
|
}
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5688
|
+
return () => {
|
|
5689
|
+
for (const destroy of destroyList) {
|
|
5690
|
+
destroy();
|
|
5691
|
+
}
|
|
5692
|
+
};
|
|
5641
5693
|
}
|
|
5642
5694
|
/**
|
|
5643
5695
|
*
|
|
5644
5696
|
* @param {ArrayStore} store
|
|
5645
5697
|
* @param {FieldRenderer} fieldRenderer
|
|
5646
5698
|
* @param {boolean} editable
|
|
5647
|
-
* @param {
|
|
5699
|
+
* @param {GridFieldLayout?} layout
|
|
5648
5700
|
* @param {object} options
|
|
5649
5701
|
* @param {(store: Store, el: Element | Relatedness) => () => void} [options.relate]
|
|
5650
5702
|
* @returns {[HTMLTableElement, () => void]}
|
|
5651
5703
|
*/
|
|
5652
|
-
function Table(store, fieldRenderer, editable,
|
|
5653
|
-
const headerColumns =
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5704
|
+
function Table(store, fieldRenderer, editable, layout, options) {
|
|
5705
|
+
const headerColumns = layout?.columns;
|
|
5706
|
+
const fieldList = Object.entries(store.type || {})
|
|
5707
|
+
.filter(([k, v]) => typeof v?.type !== 'object')
|
|
5708
|
+
.map(([field, {width, label}]) => ({field, width, label}));
|
|
5709
|
+
/** @type {({ field: string; width: any; label: any; } | GridFormItemTemplateTableAction[])[]} */
|
|
5657
5710
|
let columns = [];
|
|
5658
|
-
if (headerColumns) {
|
|
5659
|
-
const map = new Map(fieldList.map(v => [v
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
if (
|
|
5663
|
-
|
|
5711
|
+
if (Array.isArray(headerColumns)) {
|
|
5712
|
+
const map = new Map(fieldList.map(v => [v.field, v]));
|
|
5713
|
+
columns = headerColumns.map(v => {
|
|
5714
|
+
if (typeof v === 'string') { return map.get(v) || [] }
|
|
5715
|
+
if (!Array.isArray(v)) { return []; }
|
|
5716
|
+
/** @type {Set<GridFormItemTemplateTableAction>} */
|
|
5717
|
+
const options = new Set(['add', 'move', 'trigger', 'remove', 'serial']);
|
|
5718
|
+
return v.filter(v => options.delete(v));
|
|
5719
|
+
}).filter(v => !Array.isArray(v) || v.length);
|
|
5664
5720
|
}
|
|
5665
5721
|
if (!columns.length) {
|
|
5666
|
-
columns =
|
|
5667
|
-
|
|
5668
|
-
|
|
5722
|
+
columns = [['add', 'trigger', 'move', 'remove', 'serial']];
|
|
5723
|
+
}
|
|
5724
|
+
if (!columns.find(v => !Array.isArray(v))) {
|
|
5725
|
+
columns.push(...fieldList.slice(0, 3));
|
|
5669
5726
|
}
|
|
5670
|
-
|
|
5727
|
+
|
|
5728
|
+
|
|
5671
5729
|
|
|
5672
5730
|
const table = document.createElement('table');
|
|
5673
|
-
table.className = '
|
|
5731
|
+
table.className = 'NeeloongFormGrid-table';
|
|
5674
5732
|
const thead = table.appendChild(document.createElement('thead'));
|
|
5675
5733
|
|
|
5676
5734
|
|
|
5677
|
-
const tfoot = table.appendChild(document.createElement('tfoot'));
|
|
5678
5735
|
|
|
5679
5736
|
const addable = new exports.Signal.Computed(() => store.addable);
|
|
5680
5737
|
const deletable = { get: () => editable };
|
|
@@ -5703,7 +5760,6 @@
|
|
|
5703
5760
|
dragRow = index;
|
|
5704
5761
|
}
|
|
5705
5762
|
}
|
|
5706
|
-
tfoot.addEventListener('dragenter', () => {dragenter();});
|
|
5707
5763
|
/**
|
|
5708
5764
|
*
|
|
5709
5765
|
* @param {Store} child
|
|
@@ -5716,8 +5772,31 @@
|
|
|
5716
5772
|
dragRow = -1;
|
|
5717
5773
|
|
|
5718
5774
|
}
|
|
5719
|
-
|
|
5720
|
-
|
|
5775
|
+
/** @type {(() => void)[]} */
|
|
5776
|
+
const destroyList = [];
|
|
5777
|
+
destroyList.push(renderHead(thead, columns, add, addable, editable));
|
|
5778
|
+
switch (layout?.tableFoot) {
|
|
5779
|
+
default:
|
|
5780
|
+
case 'header': {
|
|
5781
|
+
const tfoot = table.appendChild(document.createElement('tfoot'));
|
|
5782
|
+
tfoot.addEventListener('dragenter', () => { dragenter(); });
|
|
5783
|
+
destroyList.push(renderHead(tfoot, columns, add, addable, editable));
|
|
5784
|
+
break;
|
|
5785
|
+
}
|
|
5786
|
+
case 'add': {
|
|
5787
|
+
const tfoot = table.appendChild(document.createElement('tfoot'));
|
|
5788
|
+
tfoot.addEventListener('dragenter', () => { dragenter(); });
|
|
5789
|
+
const tr = tfoot.appendChild(document.createElement('tr'));
|
|
5790
|
+
const th = tr.appendChild(document.createElement('th'));
|
|
5791
|
+
th.colSpan = columns.length;
|
|
5792
|
+
const button = th.appendChild(document.createElement('button'));
|
|
5793
|
+
button.addEventListener('click', add);
|
|
5794
|
+
button.classList.add('NeeloongFormGrid-table-foot-add');
|
|
5795
|
+
destroyList.push(watch(() => !addable.get(), disabled => { button.disabled = disabled; }, true));
|
|
5796
|
+
break;
|
|
5797
|
+
}
|
|
5798
|
+
case 'none':
|
|
5799
|
+
}
|
|
5721
5800
|
const start = thead;
|
|
5722
5801
|
/** @type {Map<Store, [HTMLTableSectionElement, () => void]>} */
|
|
5723
5802
|
let seMap = new Map();
|
|
@@ -5729,7 +5808,7 @@
|
|
|
5729
5808
|
}
|
|
5730
5809
|
|
|
5731
5810
|
}
|
|
5732
|
-
const columnNames = columns.map((
|
|
5811
|
+
const columnNames = columns.map((v) => Array.isArray(v) ? v : v.field);
|
|
5733
5812
|
const childrenResult = watch(() => store.children, function render(children) {
|
|
5734
5813
|
let nextNode = thead.nextSibling;
|
|
5735
5814
|
const oldSeMap = seMap;
|
|
@@ -5737,12 +5816,12 @@
|
|
|
5737
5816
|
for (let child of children) {
|
|
5738
5817
|
const old = oldSeMap.get(child);
|
|
5739
5818
|
if (!old) {
|
|
5740
|
-
const [el, destroy] = Line(child, fieldRenderer, editable,
|
|
5819
|
+
const [el, destroy] = Line(child, fieldRenderer, editable, layout, {
|
|
5741
5820
|
columns: columnNames,
|
|
5742
5821
|
remove: remove.bind(null, child),
|
|
5743
5822
|
dragenter: dragenter.bind(null, child),
|
|
5744
5823
|
dragstart: dragstart.bind(null, child),
|
|
5745
|
-
dragend,
|
|
5824
|
+
dragend,
|
|
5746
5825
|
deletable,
|
|
5747
5826
|
}, options);
|
|
5748
5827
|
table.insertBefore(el, nextNode);
|
|
@@ -5755,7 +5834,6 @@
|
|
|
5755
5834
|
nextNode = nextNode.nextSibling;
|
|
5756
5835
|
continue;
|
|
5757
5836
|
}
|
|
5758
|
-
console.log(table, old[0], nextNode);
|
|
5759
5837
|
table.insertBefore(old[0], nextNode);
|
|
5760
5838
|
}
|
|
5761
5839
|
destroyMap(oldSeMap);
|
|
@@ -5766,6 +5844,9 @@
|
|
|
5766
5844
|
thead.remove();
|
|
5767
5845
|
destroyMap(seMap);
|
|
5768
5846
|
childrenResult();
|
|
5847
|
+
for (const destroy of destroyList) {
|
|
5848
|
+
destroy();
|
|
5849
|
+
}
|
|
5769
5850
|
}];
|
|
5770
5851
|
}
|
|
5771
5852
|
|
|
@@ -5774,92 +5855,112 @@
|
|
|
5774
5855
|
* @param {Store<any, any>} store
|
|
5775
5856
|
* @param {FieldRenderer} fieldRenderer
|
|
5776
5857
|
* @param {boolean} editable
|
|
5777
|
-
* @param {
|
|
5858
|
+
* @param {GridFieldLayout?} layout
|
|
5778
5859
|
* @param {object} options
|
|
5779
5860
|
* @param {(store: Store, el: Element | Relatedness) => () => void} [options.relate]
|
|
5780
5861
|
* @param {boolean} [inline]
|
|
5781
5862
|
* @returns {[HTMLElement, () => void]}
|
|
5782
5863
|
*/
|
|
5783
|
-
function FormItem(store, fieldRenderer, editable,
|
|
5784
|
-
const subFields = template?.subFields;
|
|
5864
|
+
function FormItem(store, fieldRenderer, editable, layout, options, inline = false) {
|
|
5785
5865
|
const { type, component } = store;
|
|
5786
5866
|
if (inline) {
|
|
5787
5867
|
if (component) {
|
|
5788
5868
|
return fieldRenderer(store, component, options);
|
|
5789
5869
|
}
|
|
5790
|
-
return [document.createElement('div'), () => {}];
|
|
5870
|
+
return [document.createElement('div'), () => { }];
|
|
5791
5871
|
}
|
|
5872
|
+
/** @type {(() => void)[]} */
|
|
5873
|
+
const destroyList = [];
|
|
5792
5874
|
if (type && typeof type === 'object') {
|
|
5793
5875
|
const root = document.createElement('details');
|
|
5794
5876
|
root.open = true;
|
|
5795
5877
|
const summary = root.appendChild(document.createElement('summary'));
|
|
5796
|
-
summary.innerText = store.label || '';
|
|
5797
|
-
root.hidden = store.hidden;
|
|
5798
|
-
if (
|
|
5878
|
+
destroyList.push(effect(() => summary.innerText = store.label || ''));
|
|
5879
|
+
destroyList.push(effect(() => root.hidden = store.hidden));
|
|
5880
|
+
if (typeof component === 'function') {
|
|
5799
5881
|
const [el, destroy] = fieldRenderer(store, component, options);
|
|
5800
5882
|
root.appendChild(el);
|
|
5801
|
-
|
|
5802
|
-
}
|
|
5803
|
-
|
|
5804
|
-
const [table, destroy] = Table(store, fieldRenderer, editable, template, options);
|
|
5883
|
+
destroyList.push(destroy);
|
|
5884
|
+
} else if (store instanceof ArrayStore) {
|
|
5885
|
+
const [table, destroy] = Table(store, fieldRenderer, editable, layout, options);
|
|
5805
5886
|
root.appendChild(table);
|
|
5806
|
-
|
|
5887
|
+
destroyList.push(destroy);
|
|
5807
5888
|
} else {
|
|
5808
|
-
const [form, destroy] = Form(store, fieldRenderer, editable,
|
|
5889
|
+
const [form, destroy] = Form(store, fieldRenderer, editable, layout, options);
|
|
5809
5890
|
root.appendChild(form);
|
|
5810
|
-
|
|
5891
|
+
destroyList.push(destroy);
|
|
5811
5892
|
}
|
|
5893
|
+
return [root, () => {
|
|
5894
|
+
for (const destroy of destroyList) {
|
|
5895
|
+
destroy();
|
|
5896
|
+
}
|
|
5897
|
+
}];
|
|
5812
5898
|
}
|
|
5813
5899
|
|
|
5814
5900
|
const root = document.createElement('div');
|
|
5815
|
-
root.className = "
|
|
5816
|
-
root.hidden = store.hidden;
|
|
5817
|
-
const colSpan =
|
|
5818
|
-
if (
|
|
5901
|
+
root.className = "NeeloongFormGrid-item";
|
|
5902
|
+
destroyList.push(effect(() => root.hidden = store.hidden));
|
|
5903
|
+
const { colStart, colSpan, colEnd, rowStart, rowSpan, rowEnd } = layout || {};
|
|
5904
|
+
if (colStart && colEnd) {
|
|
5905
|
+
root.style.gridColumn = `${colStart} / ${colEnd}`;
|
|
5906
|
+
} else if (colStart && colSpan) {
|
|
5907
|
+
root.style.gridColumn = `${colStart} / span ${colSpan}`;
|
|
5908
|
+
} else if (colSpan) {
|
|
5819
5909
|
root.style.gridColumn = `span ${colSpan}`;
|
|
5820
5910
|
}
|
|
5911
|
+
if (rowStart && rowEnd) {
|
|
5912
|
+
root.style.gridRow = `${rowStart} / ${rowEnd}`;
|
|
5913
|
+
} else if (rowStart && rowSpan) {
|
|
5914
|
+
root.style.gridRow = `${rowStart} / span ${rowSpan}`;
|
|
5915
|
+
} else if (rowSpan) {
|
|
5916
|
+
root.style.gridRow = `span ${rowSpan}`;
|
|
5917
|
+
}
|
|
5821
5918
|
const label = root.appendChild(document.createElement('div'));
|
|
5822
|
-
label.className = '
|
|
5823
|
-
label.innerText = store.label || '';
|
|
5919
|
+
label.className = 'NeeloongFormGrid-item-label';
|
|
5920
|
+
destroyList.push(effect(() => label.innerText = store.label || ''));
|
|
5824
5921
|
|
|
5825
5922
|
|
|
5826
5923
|
const content = root.appendChild(document.createElement('div'));
|
|
5827
|
-
content.className = '
|
|
5924
|
+
content.className = 'NeeloongFormGrid-item-content';
|
|
5828
5925
|
|
|
5829
5926
|
const description = root.appendChild(document.createElement('div'));
|
|
5830
|
-
description.className = '
|
|
5831
|
-
description.innerText = store.description || '';
|
|
5927
|
+
description.className = 'NeeloongFormGrid-item-description';
|
|
5928
|
+
destroyList.push(effect(() => description.innerText = store.description || ''));
|
|
5832
5929
|
if (typeof component === 'function') {
|
|
5833
5930
|
const [el, destroy] = fieldRenderer(store, component, options);
|
|
5834
5931
|
content.appendChild(el);
|
|
5835
|
-
|
|
5932
|
+
destroyList.push(destroy);
|
|
5836
5933
|
}
|
|
5837
|
-
return [root, () => {
|
|
5934
|
+
return [root, () => {
|
|
5935
|
+
for (const destroy of destroyList) {
|
|
5936
|
+
destroy();
|
|
5937
|
+
}
|
|
5938
|
+
}];
|
|
5838
5939
|
}
|
|
5839
5940
|
|
|
5840
5941
|
/** @import { Store } from '../Store/index.mjs' */
|
|
5841
5942
|
/** @import { Relatedness } from '../types.mjs' */
|
|
5842
|
-
/** @import { FieldRenderer,
|
|
5943
|
+
/** @import { FieldRenderer, GridLayout } from './types.mjs' */
|
|
5843
5944
|
|
|
5844
5945
|
/**
|
|
5845
5946
|
*
|
|
5846
5947
|
* @param {Store<any, any>} store
|
|
5847
5948
|
* @param {FieldRenderer} fieldRenderer
|
|
5848
5949
|
* @param {boolean} editable
|
|
5849
|
-
* @param {
|
|
5950
|
+
* @param {GridLayout?} layout
|
|
5850
5951
|
* @param {object} options
|
|
5851
5952
|
* @param {(store: Store, el: Element | Relatedness) => () => void} [options.relate]
|
|
5852
5953
|
* @param {HTMLElement} [options.parent]
|
|
5853
5954
|
* @returns {[HTMLElement, () => void]}
|
|
5854
5955
|
*/
|
|
5855
|
-
function Form(store, fieldRenderer, editable,
|
|
5956
|
+
function Form(store, fieldRenderer, editable, layout, {parent, relate}) {
|
|
5856
5957
|
const root = parent instanceof HTMLElement ? parent : document.createElement('div');
|
|
5857
|
-
root.className = '
|
|
5958
|
+
root.className = 'NeeloongFormGrid';
|
|
5858
5959
|
/** @type {(() => void)[]} */
|
|
5859
5960
|
const destroyList = [];
|
|
5860
|
-
|
|
5861
|
-
if (
|
|
5862
|
-
for (const fieldTemplate of
|
|
5961
|
+
const fieldLayouts = layout?.fields;
|
|
5962
|
+
if (fieldLayouts) {
|
|
5963
|
+
for (const fieldTemplate of fieldLayouts) {
|
|
5863
5964
|
const fieldStore = store.child(fieldTemplate.field);
|
|
5864
5965
|
if (!fieldStore) { continue; }
|
|
5865
5966
|
const [el, destroy] = FormItem(fieldStore, fieldRenderer, editable, fieldTemplate, {relate});
|
|
@@ -5867,8 +5968,7 @@
|
|
|
5867
5968
|
destroyList.push(destroy);
|
|
5868
5969
|
}
|
|
5869
5970
|
} else {
|
|
5870
|
-
const fields = [...store].map(([, v]) => v)
|
|
5871
|
-
.sort((a, b) => (a.meta.layoutOrder || 0) - (b.meta.layoutOrder || 0));
|
|
5971
|
+
const fields = [...store].map(([, v]) => v);
|
|
5872
5972
|
|
|
5873
5973
|
|
|
5874
5974
|
for (const field of fields) {
|
|
@@ -5886,7 +5986,7 @@
|
|
|
5886
5986
|
}
|
|
5887
5987
|
|
|
5888
5988
|
/** @import { Store } from '../Store/index.mjs' */
|
|
5889
|
-
/** @import { FieldRenderer,
|
|
5989
|
+
/** @import { FieldRenderer, GridLayout } from './types.mjs' */
|
|
5890
5990
|
|
|
5891
5991
|
/**
|
|
5892
5992
|
*
|
|
@@ -5894,10 +5994,10 @@
|
|
|
5894
5994
|
* @param {HTMLElement} root
|
|
5895
5995
|
* @param {FieldRenderer} fieldRenderer
|
|
5896
5996
|
* @param {boolean} editable
|
|
5897
|
-
* @param {
|
|
5997
|
+
* @param {GridLayout?} [layout]
|
|
5898
5998
|
*/
|
|
5899
|
-
function index (store, root, fieldRenderer, editable,
|
|
5900
|
-
const s = Form(store, fieldRenderer, editable,
|
|
5999
|
+
function index (store, root, fieldRenderer, editable, layout) {
|
|
6000
|
+
const s = Form(store, fieldRenderer, editable, layout || null, {parent: root});
|
|
5901
6001
|
return s[1];
|
|
5902
6002
|
}
|
|
5903
6003
|
|