@neeloong/form 0.16.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 +12 -9
- package/{index.js → index.full.js} +207 -122
- 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 +207 -122
- 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,11 +1174,12 @@ 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;
|
|
1182
1183
|
colStart?: number | undefined;
|
|
1183
1184
|
colSpan?: number | undefined;
|
|
1184
1185
|
colEnd?: number | undefined;
|
|
@@ -1186,7 +1187,9 @@ type GridFormItemTemplate = {
|
|
|
1186
1187
|
rowSpan?: number | undefined;
|
|
1187
1188
|
rowEnd?: number | undefined;
|
|
1188
1189
|
};
|
|
1189
|
-
type
|
|
1190
|
+
type GridLayout = {
|
|
1191
|
+
fields?: GridFieldLayout[] | null | undefined;
|
|
1192
|
+
};
|
|
1190
1193
|
type Options = object;
|
|
1191
1194
|
type FieldRenderer = (store: Store<any, any>, component: any, Options: Options) => [HTMLElement, () => void];
|
|
1192
1195
|
|
|
@@ -1196,9 +1199,9 @@ type FieldRenderer = (store: Store<any, any>, component: any, Options: Options)
|
|
|
1196
1199
|
* @param {HTMLElement} root
|
|
1197
1200
|
* @param {FieldRenderer} fieldRenderer
|
|
1198
1201
|
* @param {boolean} editable
|
|
1199
|
-
* @param {
|
|
1202
|
+
* @param {GridLayout?} [layout]
|
|
1200
1203
|
*/
|
|
1201
|
-
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;
|
|
1202
1205
|
|
|
1203
1206
|
/**
|
|
1204
1207
|
* @param {Store} store 存储实例
|
|
@@ -1250,4 +1253,4 @@ declare function effect(fn: () => void): () => void;
|
|
|
1250
1253
|
*/
|
|
1251
1254
|
declare function renderHtml(renderField: (store: Store<any, any>, component: any) => [HTMLElement, () => void] | null, store: Store, root: HTMLElement, html?: string | ParentNode, clone?: boolean): () => void;
|
|
1252
1255
|
|
|
1253
|
-
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,7 +5521,7 @@
|
|
|
5521
5521
|
|
|
5522
5522
|
* @returns {[HTMLTableSectionElement, () => void]}
|
|
5523
5523
|
*/
|
|
5524
|
-
function Line(store, fieldRenderer, editable,
|
|
5524
|
+
function Line(store, fieldRenderer, editable, layout, {
|
|
5525
5525
|
columns,
|
|
5526
5526
|
remove, dragenter, dragstart, dragend, deletable
|
|
5527
5527
|
}, options) {
|
|
@@ -5536,74 +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.classList.add('NeeloongFormGrid-table-line-handle');
|
|
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.classList.add('NeeloongFormGrid-table-line-open');
|
|
5568
|
-
ext.addEventListener('click', () => {
|
|
5569
|
-
if (body.hidden) {
|
|
5570
|
-
body.hidden = false;
|
|
5571
|
-
ext.classList.remove('NeeloongFormGrid-table-line-open');
|
|
5572
|
-
ext.classList.add('NeeloongFormGrid-table-line-close');
|
|
5573
|
-
} else {
|
|
5574
|
-
body.hidden = true;
|
|
5575
|
-
ext.classList.remove('NeeloongFormGrid-table-line-close');
|
|
5576
|
-
ext.classList.add('NeeloongFormGrid-table-line-open');
|
|
5590
|
+
}
|
|
5577
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;
|
|
5578
5601
|
}
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
const
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
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
|
+
}
|
|
5592
5638
|
}
|
|
5593
|
-
|
|
5594
|
-
window.addEventListener('pointercancel', pointerup, { capture: true });
|
|
5595
|
-
});
|
|
5596
|
-
destroyList.push(watch(() => store.readonly || store.disabled, disabled => {
|
|
5597
|
-
move.disabled = disabled;
|
|
5598
|
-
}, true));
|
|
5599
|
-
const del = handle.appendChild(document.createElement('button'));
|
|
5600
|
-
del.classList.add('NeeloongFormGrid-table-remove');
|
|
5601
|
-
// @ts-ignore
|
|
5602
|
-
destroyList.push(watch(() => !deletable.get() || store.readonly || store.disabled, disabled => {
|
|
5603
|
-
move.disabled = disabled;
|
|
5604
|
-
}, true));
|
|
5605
|
-
del.addEventListener('click', remove);
|
|
5639
|
+
}
|
|
5606
5640
|
}
|
|
5641
|
+
|
|
5607
5642
|
return [root, () => {
|
|
5608
5643
|
for (const destroy of destroyList) {
|
|
5609
5644
|
destroy();
|
|
@@ -5613,65 +5648,90 @@
|
|
|
5613
5648
|
|
|
5614
5649
|
/** @import { Store, ArrayStore } from '../Store/index.mjs' */
|
|
5615
5650
|
/** @import { Relatedness } from '../types.mjs' */
|
|
5616
|
-
/** @import { FieldRenderer,
|
|
5651
|
+
/** @import { FieldRenderer, GridFieldLayout, GridFormItemTemplateTableAction } from './types.mjs' */
|
|
5617
5652
|
|
|
5618
5653
|
/**
|
|
5619
5654
|
*
|
|
5620
5655
|
* @param {HTMLElement} parent
|
|
5621
|
-
* @param {
|
|
5656
|
+
* @param {({ field: string; width: any; label: any; } | GridFormItemTemplateTableAction[])[]} columns
|
|
5622
5657
|
* @param {() => any} add
|
|
5623
5658
|
* @param {{get(): boolean}} addable
|
|
5624
5659
|
* @param {boolean?} [editable]
|
|
5625
5660
|
*/
|
|
5626
5661
|
function renderHead(parent, columns, add, addable, editable) {
|
|
5627
5662
|
const tr = parent.appendChild(document.createElement('tr'));
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
if (
|
|
5632
|
-
|
|
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
|
+
}
|
|
5633
5686
|
}
|
|
5634
|
-
td.innerText = label;
|
|
5635
|
-
}
|
|
5636
|
-
if (!editable) {
|
|
5637
|
-
return () => {}
|
|
5638
5687
|
}
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5688
|
+
return () => {
|
|
5689
|
+
for (const destroy of destroyList) {
|
|
5690
|
+
destroy();
|
|
5691
|
+
}
|
|
5692
|
+
};
|
|
5643
5693
|
}
|
|
5644
5694
|
/**
|
|
5645
5695
|
*
|
|
5646
5696
|
* @param {ArrayStore} store
|
|
5647
5697
|
* @param {FieldRenderer} fieldRenderer
|
|
5648
5698
|
* @param {boolean} editable
|
|
5649
|
-
* @param {
|
|
5699
|
+
* @param {GridFieldLayout?} layout
|
|
5650
5700
|
* @param {object} options
|
|
5651
5701
|
* @param {(store: Store, el: Element | Relatedness) => () => void} [options.relate]
|
|
5652
5702
|
* @returns {[HTMLTableElement, () => void]}
|
|
5653
5703
|
*/
|
|
5654
|
-
function Table(store, fieldRenderer, editable,
|
|
5655
|
-
const headerColumns =
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
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[])[]} */
|
|
5659
5710
|
let columns = [];
|
|
5660
|
-
if (headerColumns) {
|
|
5661
|
-
const map = new Map(fieldList.map(v => [v
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
if (
|
|
5665
|
-
|
|
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);
|
|
5720
|
+
}
|
|
5721
|
+
if (!columns.length) {
|
|
5722
|
+
columns = [['add', 'trigger', 'move', 'remove', 'serial']];
|
|
5666
5723
|
}
|
|
5667
|
-
if (!columns.
|
|
5724
|
+
if (!columns.find(v => !Array.isArray(v))) {
|
|
5725
|
+
columns.push(...fieldList.slice(0, 3));
|
|
5726
|
+
}
|
|
5727
|
+
|
|
5728
|
+
|
|
5668
5729
|
|
|
5669
5730
|
const table = document.createElement('table');
|
|
5670
5731
|
table.className = 'NeeloongFormGrid-table';
|
|
5671
5732
|
const thead = table.appendChild(document.createElement('thead'));
|
|
5672
5733
|
|
|
5673
5734
|
|
|
5674
|
-
const tfoot = table.appendChild(document.createElement('tfoot'));
|
|
5675
5735
|
|
|
5676
5736
|
const addable = new exports.Signal.Computed(() => store.addable);
|
|
5677
5737
|
const deletable = { get: () => editable };
|
|
@@ -5700,7 +5760,6 @@
|
|
|
5700
5760
|
dragRow = index;
|
|
5701
5761
|
}
|
|
5702
5762
|
}
|
|
5703
|
-
tfoot.addEventListener('dragenter', () => {dragenter();});
|
|
5704
5763
|
/**
|
|
5705
5764
|
*
|
|
5706
5765
|
* @param {Store} child
|
|
@@ -5713,8 +5772,31 @@
|
|
|
5713
5772
|
dragRow = -1;
|
|
5714
5773
|
|
|
5715
5774
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
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
|
+
}
|
|
5718
5800
|
const start = thead;
|
|
5719
5801
|
/** @type {Map<Store, [HTMLTableSectionElement, () => void]>} */
|
|
5720
5802
|
let seMap = new Map();
|
|
@@ -5726,7 +5808,7 @@
|
|
|
5726
5808
|
}
|
|
5727
5809
|
|
|
5728
5810
|
}
|
|
5729
|
-
const columnNames = columns.map((
|
|
5811
|
+
const columnNames = columns.map((v) => Array.isArray(v) ? v : v.field);
|
|
5730
5812
|
const childrenResult = watch(() => store.children, function render(children) {
|
|
5731
5813
|
let nextNode = thead.nextSibling;
|
|
5732
5814
|
const oldSeMap = seMap;
|
|
@@ -5734,12 +5816,12 @@
|
|
|
5734
5816
|
for (let child of children) {
|
|
5735
5817
|
const old = oldSeMap.get(child);
|
|
5736
5818
|
if (!old) {
|
|
5737
|
-
const [el, destroy] = Line(child, fieldRenderer, editable,
|
|
5819
|
+
const [el, destroy] = Line(child, fieldRenderer, editable, layout, {
|
|
5738
5820
|
columns: columnNames,
|
|
5739
5821
|
remove: remove.bind(null, child),
|
|
5740
5822
|
dragenter: dragenter.bind(null, child),
|
|
5741
5823
|
dragstart: dragstart.bind(null, child),
|
|
5742
|
-
dragend,
|
|
5824
|
+
dragend,
|
|
5743
5825
|
deletable,
|
|
5744
5826
|
}, options);
|
|
5745
5827
|
table.insertBefore(el, nextNode);
|
|
@@ -5752,7 +5834,6 @@
|
|
|
5752
5834
|
nextNode = nextNode.nextSibling;
|
|
5753
5835
|
continue;
|
|
5754
5836
|
}
|
|
5755
|
-
console.log(table, old[0], nextNode);
|
|
5756
5837
|
table.insertBefore(old[0], nextNode);
|
|
5757
5838
|
}
|
|
5758
5839
|
destroyMap(oldSeMap);
|
|
@@ -5763,6 +5844,9 @@
|
|
|
5763
5844
|
thead.remove();
|
|
5764
5845
|
destroyMap(seMap);
|
|
5765
5846
|
childrenResult();
|
|
5847
|
+
for (const destroy of destroyList) {
|
|
5848
|
+
destroy();
|
|
5849
|
+
}
|
|
5766
5850
|
}];
|
|
5767
5851
|
}
|
|
5768
5852
|
|
|
@@ -5771,14 +5855,13 @@
|
|
|
5771
5855
|
* @param {Store<any, any>} store
|
|
5772
5856
|
* @param {FieldRenderer} fieldRenderer
|
|
5773
5857
|
* @param {boolean} editable
|
|
5774
|
-
* @param {
|
|
5858
|
+
* @param {GridFieldLayout?} layout
|
|
5775
5859
|
* @param {object} options
|
|
5776
5860
|
* @param {(store: Store, el: Element | Relatedness) => () => void} [options.relate]
|
|
5777
5861
|
* @param {boolean} [inline]
|
|
5778
5862
|
* @returns {[HTMLElement, () => void]}
|
|
5779
5863
|
*/
|
|
5780
|
-
function FormItem(store, fieldRenderer, editable,
|
|
5781
|
-
const subFields = template?.subFields;
|
|
5864
|
+
function FormItem(store, fieldRenderer, editable, layout, options, inline = false) {
|
|
5782
5865
|
const { type, component } = store;
|
|
5783
5866
|
if (inline) {
|
|
5784
5867
|
if (component) {
|
|
@@ -5794,16 +5877,16 @@
|
|
|
5794
5877
|
const summary = root.appendChild(document.createElement('summary'));
|
|
5795
5878
|
destroyList.push(effect(() => summary.innerText = store.label || ''));
|
|
5796
5879
|
destroyList.push(effect(() => root.hidden = store.hidden));
|
|
5797
|
-
if (
|
|
5880
|
+
if (typeof component === 'function') {
|
|
5798
5881
|
const [el, destroy] = fieldRenderer(store, component, options);
|
|
5799
5882
|
root.appendChild(el);
|
|
5800
5883
|
destroyList.push(destroy);
|
|
5801
5884
|
} else if (store instanceof ArrayStore) {
|
|
5802
|
-
const [table, destroy] = Table(store, fieldRenderer, editable,
|
|
5885
|
+
const [table, destroy] = Table(store, fieldRenderer, editable, layout, options);
|
|
5803
5886
|
root.appendChild(table);
|
|
5804
5887
|
destroyList.push(destroy);
|
|
5805
5888
|
} else {
|
|
5806
|
-
const [form, destroy] = Form(store, fieldRenderer, editable,
|
|
5889
|
+
const [form, destroy] = Form(store, fieldRenderer, editable, layout, options);
|
|
5807
5890
|
root.appendChild(form);
|
|
5808
5891
|
destroyList.push(destroy);
|
|
5809
5892
|
}
|
|
@@ -5817,18 +5900,20 @@
|
|
|
5817
5900
|
const root = document.createElement('div');
|
|
5818
5901
|
root.className = "NeeloongFormGrid-item";
|
|
5819
5902
|
destroyList.push(effect(() => root.hidden = store.hidden));
|
|
5820
|
-
const { colStart, colSpan, colEnd, rowStart, rowSpan, rowEnd } =
|
|
5821
|
-
if (colStart
|
|
5822
|
-
|
|
5823
|
-
|
|
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}`;
|
|
5824
5908
|
} else if (colSpan) {
|
|
5825
|
-
root.style.
|
|
5909
|
+
root.style.gridColumn = `span ${colSpan}`;
|
|
5826
5910
|
}
|
|
5827
|
-
if (rowStart
|
|
5828
|
-
|
|
5829
|
-
|
|
5911
|
+
if (rowStart && rowEnd) {
|
|
5912
|
+
root.style.gridRow = `${rowStart} / ${rowEnd}`;
|
|
5913
|
+
} else if (rowStart && rowSpan) {
|
|
5914
|
+
root.style.gridRow = `${rowStart} / span ${rowSpan}`;
|
|
5830
5915
|
} else if (rowSpan) {
|
|
5831
|
-
root.style.
|
|
5916
|
+
root.style.gridRow = `span ${rowSpan}`;
|
|
5832
5917
|
}
|
|
5833
5918
|
const label = root.appendChild(document.createElement('div'));
|
|
5834
5919
|
label.className = 'NeeloongFormGrid-item-label';
|
|
@@ -5855,27 +5940,27 @@
|
|
|
5855
5940
|
|
|
5856
5941
|
/** @import { Store } from '../Store/index.mjs' */
|
|
5857
5942
|
/** @import { Relatedness } from '../types.mjs' */
|
|
5858
|
-
/** @import { FieldRenderer,
|
|
5943
|
+
/** @import { FieldRenderer, GridLayout } from './types.mjs' */
|
|
5859
5944
|
|
|
5860
5945
|
/**
|
|
5861
5946
|
*
|
|
5862
5947
|
* @param {Store<any, any>} store
|
|
5863
5948
|
* @param {FieldRenderer} fieldRenderer
|
|
5864
5949
|
* @param {boolean} editable
|
|
5865
|
-
* @param {
|
|
5950
|
+
* @param {GridLayout?} layout
|
|
5866
5951
|
* @param {object} options
|
|
5867
5952
|
* @param {(store: Store, el: Element | Relatedness) => () => void} [options.relate]
|
|
5868
5953
|
* @param {HTMLElement} [options.parent]
|
|
5869
5954
|
* @returns {[HTMLElement, () => void]}
|
|
5870
5955
|
*/
|
|
5871
|
-
function Form(store, fieldRenderer, editable,
|
|
5956
|
+
function Form(store, fieldRenderer, editable, layout, {parent, relate}) {
|
|
5872
5957
|
const root = parent instanceof HTMLElement ? parent : document.createElement('div');
|
|
5873
5958
|
root.className = 'NeeloongFormGrid';
|
|
5874
5959
|
/** @type {(() => void)[]} */
|
|
5875
5960
|
const destroyList = [];
|
|
5876
|
-
|
|
5877
|
-
if (
|
|
5878
|
-
for (const fieldTemplate of
|
|
5961
|
+
const fieldLayouts = layout?.fields;
|
|
5962
|
+
if (fieldLayouts) {
|
|
5963
|
+
for (const fieldTemplate of fieldLayouts) {
|
|
5879
5964
|
const fieldStore = store.child(fieldTemplate.field);
|
|
5880
5965
|
if (!fieldStore) { continue; }
|
|
5881
5966
|
const [el, destroy] = FormItem(fieldStore, fieldRenderer, editable, fieldTemplate, {relate});
|
|
@@ -5901,7 +5986,7 @@
|
|
|
5901
5986
|
}
|
|
5902
5987
|
|
|
5903
5988
|
/** @import { Store } from '../Store/index.mjs' */
|
|
5904
|
-
/** @import { FieldRenderer,
|
|
5989
|
+
/** @import { FieldRenderer, GridLayout } from './types.mjs' */
|
|
5905
5990
|
|
|
5906
5991
|
/**
|
|
5907
5992
|
*
|
|
@@ -5909,10 +5994,10 @@
|
|
|
5909
5994
|
* @param {HTMLElement} root
|
|
5910
5995
|
* @param {FieldRenderer} fieldRenderer
|
|
5911
5996
|
* @param {boolean} editable
|
|
5912
|
-
* @param {
|
|
5997
|
+
* @param {GridLayout?} [layout]
|
|
5913
5998
|
*/
|
|
5914
|
-
function index (store, root, fieldRenderer, editable,
|
|
5915
|
-
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});
|
|
5916
6001
|
return s[1];
|
|
5917
6002
|
}
|
|
5918
6003
|
|