@neeloong/form 0.15.0 → 0.16.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 CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.15.0
2
+ * @neeloong/form v0.16.0
3
3
  * (c) 2024-2025 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -1179,6 +1179,12 @@ type GridFormItemTemplate = {
1179
1179
  subFields?: GridFormTemplate | null | undefined;
1180
1180
  span: number;
1181
1181
  headers?: string[] | undefined;
1182
+ colStart?: number | undefined;
1183
+ colSpan?: number | undefined;
1184
+ colEnd?: number | undefined;
1185
+ rowStart?: number | undefined;
1186
+ rowSpan?: number | undefined;
1187
+ rowEnd?: number | undefined;
1182
1188
  };
1183
1189
  type GridFormTemplate = GridFormItemTemplate[];
1184
1190
  type Options = object;
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.15.0
2
+ * @neeloong/form v0.16.0
3
3
  * (c) 2024-2025 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -5522,7 +5522,7 @@
5522
5522
  * @returns {[HTMLTableSectionElement, () => void]}
5523
5523
  */
5524
5524
  function Line(store, fieldRenderer, editable, template, {
5525
- columns,
5525
+ columns,
5526
5526
  remove, dragenter, dragstart, dragend, deletable
5527
5527
  }, options) {
5528
5528
  const root = document.createElement('tbody');
@@ -5537,13 +5537,13 @@
5537
5537
  const head = root.appendChild(document.createElement('tr'));
5538
5538
 
5539
5539
  const handle = head.appendChild(document.createElement('th'));
5540
- handle.className = 'button-group';
5540
+ handle.classList.add('NeeloongFormGrid-table-line-handle');
5541
5541
  /** @type {(() => void)[]} */
5542
5542
  const destroyList = [];
5543
5543
  for (const name of columns) {
5544
5544
  const td = head.appendChild(document.createElement('td'));
5545
5545
  const child = store.child(name);
5546
- if (!child) { continue }
5546
+ if (!child) { continue; }
5547
5547
  const [el, destroy] = FormItem(child, fieldRenderer, editable, null, options, true);
5548
5548
  destroyList.push(destroy);
5549
5549
  td.appendChild(el);
@@ -5554,7 +5554,7 @@
5554
5554
  const body = root.appendChild(document.createElement('tr'));
5555
5555
  const main = body.appendChild(document.createElement('td'));
5556
5556
  main.colSpan = columns.length + 1;
5557
-
5557
+
5558
5558
  const subFields = template?.subFields;
5559
5559
  const [form, destroy] = Form(store, fieldRenderer, editable, Array.isArray(subFields) ? subFields : null, options);
5560
5560
  main.appendChild(form);
@@ -5563,39 +5563,41 @@
5563
5563
 
5564
5564
 
5565
5565
  const ext = handle.appendChild(document.createElement('button'));
5566
- body.hidden = true;
5567
- ext.innerText = '+';
5566
+ body.hidden = true;
5567
+ ext.classList.add('NeeloongFormGrid-table-line-open');
5568
5568
  ext.addEventListener('click', () => {
5569
- if(body.hidden) {
5569
+ if (body.hidden) {
5570
5570
  body.hidden = false;
5571
- ext.innerText = '-';
5571
+ ext.classList.remove('NeeloongFormGrid-table-line-open');
5572
+ ext.classList.add('NeeloongFormGrid-table-line-close');
5572
5573
  } else {
5573
5574
  body.hidden = true;
5574
- ext.innerText = '+';
5575
+ ext.classList.remove('NeeloongFormGrid-table-line-close');
5576
+ ext.classList.add('NeeloongFormGrid-table-line-open');
5575
5577
 
5576
5578
  }
5577
5579
  });
5578
5580
  if (editable) {
5579
5581
  const move = handle.appendChild(document.createElement('button'));
5580
- move.classList.add('GridForm-table-move');
5581
- move.addEventListener('pointerdown', ({pointerId}) => {
5582
+ move.classList.add('NeeloongFormGrid-table-move');
5583
+ move.addEventListener('pointerdown', ({ pointerId }) => {
5582
5584
  root.draggable = true;
5583
5585
  /** @param {PointerEvent} event */
5584
5586
  function pointerup(event) {
5585
- if (event.pointerId !== pointerId) { return }
5586
- if (!root) { return }
5587
+ if (event.pointerId !== pointerId) { return; }
5588
+ if (!root) { return; }
5587
5589
  root.draggable = false;
5588
- window.removeEventListener('pointerup', pointerup, {capture: true});
5589
- window.removeEventListener('pointercancel', pointerup, {capture: true});
5590
+ window.removeEventListener('pointerup', pointerup, { capture: true });
5591
+ window.removeEventListener('pointercancel', pointerup, { capture: true });
5590
5592
  }
5591
- window.addEventListener('pointerup', pointerup, {capture: true});
5592
- window.addEventListener('pointercancel', pointerup, {capture: true});
5593
+ window.addEventListener('pointerup', pointerup, { capture: true });
5594
+ window.addEventListener('pointercancel', pointerup, { capture: true });
5593
5595
  });
5594
5596
  destroyList.push(watch(() => store.readonly || store.disabled, disabled => {
5595
5597
  move.disabled = disabled;
5596
5598
  }, true));
5597
5599
  const del = handle.appendChild(document.createElement('button'));
5598
- del.classList.add('GridForm-table-remove');
5600
+ del.classList.add('NeeloongFormGrid-table-remove');
5599
5601
  // @ts-ignore
5600
5602
  destroyList.push(watch(() => !deletable.get() || store.readonly || store.disabled, disabled => {
5601
5603
  move.disabled = disabled;
@@ -5636,7 +5638,7 @@
5636
5638
  }
5637
5639
  const button = th.appendChild(document.createElement('button'));
5638
5640
  button.addEventListener('click', add);
5639
- button.classList.add('GridForm-table-add');
5641
+ button.classList.add('NeeloongFormGrid-table-add');
5640
5642
  return watch(() => !addable.get(), disabled => { button.disabled = disabled; }, true);
5641
5643
  }
5642
5644
  /**
@@ -5662,15 +5664,10 @@
5662
5664
  if (f) { columns.push(f); }
5663
5665
  }
5664
5666
  }
5665
- if (!columns.length) {
5666
- columns = fieldList
5667
- .filter(([, v]) => v.meta.headOrder)
5668
- .sort(([, a], [, b]) => (a.headOrder || 0) - (b.headOrder || 0));
5669
- }
5670
5667
  if (!columns.length) { columns = fieldList.filter(([k, v]) => typeof v?.type !== 'object').slice(0, 3); }
5671
5668
 
5672
5669
  const table = document.createElement('table');
5673
- table.className = 'GridForm-table';
5670
+ table.className = 'NeeloongFormGrid-table';
5674
5671
  const thead = table.appendChild(document.createElement('thead'));
5675
5672
 
5676
5673
 
@@ -5787,54 +5784,73 @@
5787
5784
  if (component) {
5788
5785
  return fieldRenderer(store, component, options);
5789
5786
  }
5790
- return [document.createElement('div'), () => {}];
5787
+ return [document.createElement('div'), () => { }];
5791
5788
  }
5789
+ /** @type {(() => void)[]} */
5790
+ const destroyList = [];
5792
5791
  if (type && typeof type === 'object') {
5793
5792
  const root = document.createElement('details');
5794
5793
  root.open = true;
5795
5794
  const summary = root.appendChild(document.createElement('summary'));
5796
- summary.innerText = store.label || '';
5797
- root.hidden = store.hidden;
5795
+ destroyList.push(effect(() => summary.innerText = store.label || ''));
5796
+ destroyList.push(effect(() => root.hidden = store.hidden));
5798
5797
  if (!Array.isArray(subFields) && typeof component === 'function') {
5799
5798
  const [el, destroy] = fieldRenderer(store, component, options);
5800
5799
  root.appendChild(el);
5801
- return [root, destroy];
5802
- }
5803
- if (store instanceof ArrayStore) {
5800
+ destroyList.push(destroy);
5801
+ } else if (store instanceof ArrayStore) {
5804
5802
  const [table, destroy] = Table(store, fieldRenderer, editable, template, options);
5805
5803
  root.appendChild(table);
5806
- return [root, destroy];
5804
+ destroyList.push(destroy);
5807
5805
  } else {
5808
5806
  const [form, destroy] = Form(store, fieldRenderer, editable, Array.isArray(subFields) ? subFields : null, options);
5809
5807
  root.appendChild(form);
5810
- return [root, destroy];
5808
+ destroyList.push(destroy);
5811
5809
  }
5810
+ return [root, () => {
5811
+ for (const destroy of destroyList) {
5812
+ destroy();
5813
+ }
5814
+ }];
5812
5815
  }
5813
5816
 
5814
5817
  const root = document.createElement('div');
5815
- root.className = "GridForm-item";
5816
- root.hidden = store.hidden;
5817
- const colSpan = store.meta.colSpan;
5818
- if (colSpan) {
5819
- root.style.gridColumn = `span ${colSpan}`;
5818
+ root.className = "NeeloongFormGrid-item";
5819
+ destroyList.push(effect(() => root.hidden = store.hidden));
5820
+ const { colStart, colSpan, colEnd, rowStart, rowSpan, rowEnd } = template || {};
5821
+ if (colStart) { root.style.gridColumnStart = `${colStart}`; }
5822
+ if (colEnd) {
5823
+ root.style.gridColumnEnd = `${colEnd}`;
5824
+ } else if (colSpan) {
5825
+ root.style.gridColumnEnd = `span ${colSpan}`;
5826
+ }
5827
+ if (rowStart) { root.style.gridRowStart = `${rowStart}`; }
5828
+ if (rowEnd) {
5829
+ root.style.gridRowEnd = `${rowEnd}`;
5830
+ } else if (rowSpan) {
5831
+ root.style.gridRowEnd = `span ${rowSpan}`;
5820
5832
  }
5821
5833
  const label = root.appendChild(document.createElement('div'));
5822
- label.className = 'GridForm-item-label';
5823
- label.innerText = store.label || '';
5834
+ label.className = 'NeeloongFormGrid-item-label';
5835
+ destroyList.push(effect(() => label.innerText = store.label || ''));
5824
5836
 
5825
5837
 
5826
5838
  const content = root.appendChild(document.createElement('div'));
5827
- content.className = 'GridForm-item-content';
5839
+ content.className = 'NeeloongFormGrid-item-content';
5828
5840
 
5829
5841
  const description = root.appendChild(document.createElement('div'));
5830
- description.className = 'GridForm-item-description';
5831
- description.innerText = store.description || '';
5842
+ description.className = 'NeeloongFormGrid-item-description';
5843
+ destroyList.push(effect(() => description.innerText = store.description || ''));
5832
5844
  if (typeof component === 'function') {
5833
5845
  const [el, destroy] = fieldRenderer(store, component, options);
5834
5846
  content.appendChild(el);
5835
- return [root, destroy];
5847
+ destroyList.push(destroy);
5836
5848
  }
5837
- return [root, () => {}];
5849
+ return [root, () => {
5850
+ for (const destroy of destroyList) {
5851
+ destroy();
5852
+ }
5853
+ }];
5838
5854
  }
5839
5855
 
5840
5856
  /** @import { Store } from '../Store/index.mjs' */
@@ -5854,7 +5870,7 @@
5854
5870
  */
5855
5871
  function Form(store, fieldRenderer, editable, template, {parent, relate}) {
5856
5872
  const root = parent instanceof HTMLElement ? parent : document.createElement('div');
5857
- root.className = 'GridForm';
5873
+ root.className = 'NeeloongFormGrid';
5858
5874
  /** @type {(() => void)[]} */
5859
5875
  const destroyList = [];
5860
5876
 
@@ -5867,8 +5883,7 @@
5867
5883
  destroyList.push(destroy);
5868
5884
  }
5869
5885
  } else {
5870
- const fields = [...store].map(([, v]) => v)
5871
- .sort((a, b) => (a.meta.layoutOrder || 0) - (b.meta.layoutOrder || 0));
5886
+ const fields = [...store].map(([, v]) => v);
5872
5887
 
5873
5888
 
5874
5889
  for (const field of fields) {