@stonecrop/atable 0.34.0 → 0.36.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/atable.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, mergeModels, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onMounted, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, toValue, unref, useCssVars, useModel, useTemplateRef, vModelCheckbox, vModelSelect, vModelText, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
2
- import { defaultKeypressHandlers, useKeyboardNav } from "@stonecrop/utilities";
2
+ import { defaultKeypressHandlers, fromISODate, useKeyboardNav } from "@stonecrop/utilities";
3
3
  import { componentCategory, hasBadgeOptions, isBadgeDescriptor } from "@stonecrop/schema";
4
4
  import { onClickOutside, useDebounceFn, useDraggable, useElementBounding, useMutationObserver, useResizeObserver } from "@vueuse/core";
5
5
  import { defineStore } from "pinia";
6
+ import { Temporal } from "temporal-polyfill";
6
7
  import { vOnClickOutside, vResizeObserver } from "@vueuse/components";
7
8
  import './assets/index.css';//#region src/linkSearchableText.ts
8
9
  /**
@@ -46,6 +47,7 @@ var CATEGORY_FILTER = {
46
47
  boolean: "checkbox",
47
48
  date: "date",
48
49
  datetime: "dateRange",
50
+ duration: "text",
49
51
  select: "select",
50
52
  code: "text",
51
53
  link: "text",
@@ -121,6 +123,19 @@ function isNodeOpen(rowIndex, treeDisplay) {
121
123
  if (parentIndex < 0 || parentIndex >= treeDisplay.length) return false;
122
124
  return (treeDisplay[parentIndex].childrenOpen || false) && isNodeOpen(parentIndex, treeDisplay);
123
125
  }
126
+ /**
127
+ * The `YYYY-MM-DD` day a date cell shows as: a day column's day, a date-time's day in the user's zone,
128
+ * and for a column declaring no date component, the UTC day its value parses to. Undefined when the
129
+ * cell holds no date.
130
+ */
131
+ function dayOfCell(cellValue, column) {
132
+ const category = componentCategory(column.component);
133
+ if (category === "date") return fromISODate(String(cellValue))?.toString();
134
+ const epochMilliseconds = new Date(String(cellValue)).getTime();
135
+ if (isNaN(epochMilliseconds)) return void 0;
136
+ const zone = category === "datetime" ? Temporal.Now.timeZoneId() : "UTC";
137
+ return Temporal.Instant.fromEpochMilliseconds(epochMilliseconds).toZonedDateTimeISO(zone).toPlainDate().toString();
138
+ }
124
139
  function applyFilter(cellValue, filter, column) {
125
140
  const filterType = resolveFilterType(column);
126
141
  const value = filter.value;
@@ -136,28 +151,15 @@ function applyFilter(cellValue, filter, column) {
136
151
  case "checkbox":
137
152
  if (value === true) return !!cellValue;
138
153
  return true;
139
- case "date": {
140
- let cellDate;
141
- if (typeof cellValue === "number") {
142
- const originalDate = new Date(cellValue);
143
- const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
144
- cellDate = new Date(currentYear, originalDate.getMonth(), originalDate.getDate());
145
- } else cellDate = new Date(String(cellValue));
146
- const filterDate = new Date(String(value));
147
- return cellDate.toDateString() === filterDate.toDateString();
148
- }
154
+ case "date": return dayOfCell(cellValue, column) === String(value);
149
155
  case "dateRange": {
150
156
  const startValue = filter.startValue;
151
157
  const endValue = filter.endValue;
152
158
  if (!startValue && !endValue) return true;
153
- let cellDateRange;
154
- if (typeof cellValue === "number") {
155
- const originalDate = new Date(cellValue);
156
- const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
157
- cellDateRange = new Date(currentYear, originalDate.getMonth(), originalDate.getDate());
158
- } else cellDateRange = new Date(String(cellValue));
159
- if (startValue && cellDateRange < new Date(String(startValue))) return false;
160
- if (endValue && cellDateRange > new Date(String(endValue))) return false;
159
+ const cellDay = dayOfCell(cellValue, column);
160
+ if (cellDay === void 0) return false;
161
+ if (startValue && cellDay < String(startValue)) return false;
162
+ if (endValue && cellDay > String(endValue)) return false;
161
163
  return true;
162
164
  }
163
165
  default: return true;
@@ -410,7 +412,7 @@ var createTableStore = (initData) => {
410
412
  if (!format) {
411
413
  const category = componentCategory(column.component);
412
414
  if (category === "boolean") return value ? "✓" : "✗";
413
- if (category === "date") return value != null ? new Date(String(value)).toLocaleDateString() : value;
415
+ if (category === "date") return value != null ? fromISODate(String(value))?.toLocaleString() ?? "Invalid Date" : value;
414
416
  if (category === "datetime") return value != null ? new Date(String(value)).toLocaleString() : value;
415
417
  if (category === "quantity") return formatQuantity(value);
416
418
  if (category === "currency") return formatCurrency(value);
@@ -1746,7 +1748,7 @@ var ARow_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__
1746
1748
  }, void 0, true)], 8, _hoisted_3$4)], 8, _hoisted_2$6)) : createCommentVNode("", true)], 64);
1747
1749
  };
1748
1750
  }
1749
- }), [["__scopeId", "data-v-f159cfbe"]]);
1751
+ }), [["__scopeId", "data-v-e0056486"]]);
1750
1752
  //#endregion
1751
1753
  //#region src/components/AGanttConnection.vue?vue&type=script&setup=true&lang.ts
1752
1754
  var _hoisted_1$6 = { class: "gantt-connection-overlay" };
@@ -2016,7 +2018,7 @@ var ATableColumnFilter_default = /*#__PURE__*/ _plugin_vue_export_helper_default
2016
2018
  }, "×")) : createCommentVNode("", true)]);
2017
2019
  };
2018
2020
  }
2019
- }), [["__scopeId", "data-v-f9c23db9"]]);
2021
+ }), [["__scopeId", "data-v-fc482b5d"]]);
2020
2022
  //#endregion
2021
2023
  //#region src/components/ATableHeader.vue?vue&type=script&setup=true&lang.ts
2022
2024
  var _hoisted_1$4 = { key: 0 };
@@ -2136,19 +2138,19 @@ var ATableModal_default = /* @__PURE__ */ defineComponent({
2136
2138
  props: { store: {} },
2137
2139
  setup(__props) {
2138
2140
  const amodalRef = useTemplateRef("amodal");
2139
- const { width: modalWidth, height: modalHeight } = useElementBounding(amodalRef);
2141
+ const { width: modalWidth } = useElementBounding(amodalRef);
2140
2142
  const amodalStyles = computed(() => {
2141
2143
  if (!(__props.store.modal.height && __props.store.modal.width && __props.store.modal.left && __props.store.modal.bottom)) return {};
2142
- const table = __props.store.modal.cell?.closest("table");
2143
- if (!table) return {};
2144
- const maxHeight = table.offsetHeight || 0;
2145
- const maxWidth = table.offsetWidth || 0;
2146
- let modalY = __props.store.modal.cell?.offsetTop || 0;
2147
- const headerHeight = table.querySelector("thead")?.offsetHeight || 0;
2148
- modalY += headerHeight;
2149
- modalY = modalY + modalHeight.value < maxHeight ? modalY : modalY - (modalHeight.value + __props.store.modal.height);
2150
- let modalX = __props.store.modal.cell?.offsetLeft || 0;
2151
- modalX = modalX + modalWidth.value <= maxWidth ? modalX : modalX - (modalWidth.value - __props.store.modal.width);
2144
+ const cell = __props.store.modal.cell;
2145
+ if (!cell) return {};
2146
+ const container = cell.closest(".atable-container") ?? cell.closest("table");
2147
+ if (!(container instanceof HTMLElement)) return {};
2148
+ const cellRect = cell.getBoundingClientRect();
2149
+ const containerRect = container.getBoundingClientRect();
2150
+ const modalY = cellRect.bottom - containerRect.top;
2151
+ let modalX = cellRect.left - containerRect.left;
2152
+ const maxWidth = container.clientWidth || containerRect.width;
2153
+ if (modalWidth.value && modalX + modalWidth.value > maxWidth) modalX = Math.max(0, maxWidth - modalWidth.value);
2152
2154
  return {
2153
2155
  left: `${modalX}px`,
2154
2156
  top: `${modalY}px`
@@ -2658,107 +2660,110 @@ var ATable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
2658
2660
  moveRow: store.moveRow
2659
2661
  });
2660
2662
  return (_ctx, _cache) => {
2661
- return openBlock(), createElementBlock("div", _hoisted_1$2, [withDirectives((openBlock(), createElementBlock("table", {
2662
- ref: "table",
2663
- class: "atable",
2664
- style: normalizeStyle({ width: unref(store).config.fullWidth ? "100%" : "auto" })
2665
- }, [
2666
- renderSlot(_ctx.$slots, "header", { data: unref(store) }, () => [createVNode(ATableHeader_default, {
2667
- columns: unref(store).columns,
2668
- store: unref(store)
2669
- }, null, 8, ["columns", "store"])], true),
2670
- createElementVNode("tbody", null, [renderSlot(_ctx.$slots, "body", { data: unref(store) }, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(visibleRows), (row, filteredIndex) => {
2671
- return openBlock(), createBlock(ARow_default, {
2672
- key: `${row.originalIndex}-${filteredIndex}`,
2673
- row,
2674
- "row-index": row.originalIndex,
2675
- store: unref(store),
2676
- "onRow:action": handleRowAction,
2677
- "onRow:click": handleRowClick
2678
- }, {
2679
- default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(getProcessedColumnsForRow(row), (column, colIndex) => {
2680
- return openBlock(), createElementBlock(Fragment, { key: column.name }, [column.isGantt ? (openBlock(), createBlock(resolveDynamicComponent(column.ganttComponent || "AGanttCell"), {
2681
- key: 0,
2682
- store: unref(store),
2683
- "columns-count": unref(store).columns.length - pinnedColumnCount.value,
2684
- color: row.gantt?.color,
2685
- start: row.gantt?.startIndex,
2686
- end: row.gantt?.endIndex,
2687
- colspan: column.colspan,
2688
- pinned: column.pinned,
2689
- "row-index": row.originalIndex,
2690
- "col-index": column.originalIndex ?? colIndex,
2691
- style: normalizeStyle({
2692
- textAlign: column?.align || "center",
2693
- minWidth: column?.width || "40ch",
2694
- width: unref(store).config.fullWidth ? "auto" : null
2695
- }),
2696
- "onConnection:create": handleConnectionCreate
2697
- }, null, 40, [
2698
- "store",
2699
- "columns-count",
2700
- "color",
2701
- "start",
2702
- "end",
2703
- "colspan",
2704
- "pinned",
2705
- "row-index",
2706
- "col-index",
2707
- "style"
2708
- ])) : (openBlock(), createBlock(resolveDynamicComponent(column.cellComponent || "ACell"), {
2709
- key: 1,
2710
- store: unref(store),
2711
- pinned: column.pinned,
2712
- "row-index": row.originalIndex,
2713
- "col-index": colIndex,
2714
- style: normalizeStyle({
2715
- textAlign: column?.align || "center",
2716
- width: unref(store).config.fullWidth ? "auto" : null
2717
- }),
2718
- spellcheck: "false"
2719
- }, null, 8, [
2720
- "store",
2721
- "pinned",
2722
- "row-index",
2723
- "col-index",
2724
- "style"
2725
- ]))], 64);
2726
- }), 128))]),
2727
- _: 2
2728
- }, 1032, [
2729
- "row",
2730
- "row-index",
2731
- "store"
2732
- ]);
2733
- }), 128))], true)]),
2734
- renderSlot(_ctx.$slots, "footer", {
2735
- data: unref(store),
2736
- page: unref(pagination)
2737
- }, () => [createVNode(ATablePaginationFooter_default, {
2738
- "column-count": footerColumnCount.value,
2739
- "show-footer": unref(showFooter),
2740
- "has-more": unref(hasMore),
2741
- "has-prev": unref(hasPrev),
2742
- "has-next": unref(hasNext),
2743
- "has-local-next": unref(hasLocalNext),
2744
- "has-ever-had-more": unref(hasEverHadMore),
2745
- "loaded-count": unref(loadedCount),
2746
- loading: unref(paginationLoading),
2747
- next: unref(paginationNext),
2748
- prev: unref(paginationPrev)
2749
- }, null, 8, [
2750
- "column-count",
2751
- "show-footer",
2752
- "has-more",
2753
- "has-prev",
2754
- "has-next",
2755
- "has-local-next",
2756
- "has-ever-had-more",
2757
- "loaded-count",
2758
- "loading",
2759
- "next",
2760
- "prev"
2761
- ])], true),
2663
+ return withDirectives((openBlock(), createElementBlock("div", _hoisted_1$2, [
2664
+ createElementVNode("table", {
2665
+ ref: "table",
2666
+ class: normalizeClass(["atable", { "atable--zebra": unref(store).config.zebra }]),
2667
+ style: normalizeStyle({ width: unref(store).config.fullWidth ? "100%" : "auto" })
2668
+ }, [
2669
+ renderSlot(_ctx.$slots, "header", { data: unref(store) }, () => [createVNode(ATableHeader_default, {
2670
+ columns: unref(store).columns,
2671
+ store: unref(store)
2672
+ }, null, 8, ["columns", "store"])], true),
2673
+ createElementVNode("tbody", null, [renderSlot(_ctx.$slots, "body", { data: unref(store) }, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(visibleRows), (row, filteredIndex) => {
2674
+ return openBlock(), createBlock(ARow_default, {
2675
+ key: `${row.originalIndex}-${filteredIndex}`,
2676
+ row,
2677
+ "row-index": row.originalIndex,
2678
+ store: unref(store),
2679
+ "onRow:action": handleRowAction,
2680
+ "onRow:click": handleRowClick
2681
+ }, {
2682
+ content: withCtx((slotProps) => [renderSlot(_ctx.$slots, "content", mergeProps({ ref_for: true }, slotProps), void 0, true)]),
2683
+ default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(getProcessedColumnsForRow(row), (column, colIndex) => {
2684
+ return openBlock(), createElementBlock(Fragment, { key: column.name }, [column.isGantt ? (openBlock(), createBlock(resolveDynamicComponent(column.ganttComponent || "AGanttCell"), {
2685
+ key: 0,
2686
+ store: unref(store),
2687
+ "columns-count": unref(store).columns.length - pinnedColumnCount.value,
2688
+ color: row.gantt?.color,
2689
+ start: row.gantt?.startIndex,
2690
+ end: row.gantt?.endIndex,
2691
+ colspan: column.colspan,
2692
+ pinned: column.pinned,
2693
+ "row-index": row.originalIndex,
2694
+ "col-index": column.originalIndex ?? colIndex,
2695
+ style: normalizeStyle({
2696
+ textAlign: column?.align || "center",
2697
+ minWidth: column?.width || "40ch",
2698
+ width: unref(store).config.fullWidth ? "auto" : null
2699
+ }),
2700
+ "onConnection:create": handleConnectionCreate
2701
+ }, null, 40, [
2702
+ "store",
2703
+ "columns-count",
2704
+ "color",
2705
+ "start",
2706
+ "end",
2707
+ "colspan",
2708
+ "pinned",
2709
+ "row-index",
2710
+ "col-index",
2711
+ "style"
2712
+ ])) : (openBlock(), createBlock(resolveDynamicComponent(column.cellComponent || "ACell"), {
2713
+ key: 1,
2714
+ store: unref(store),
2715
+ pinned: column.pinned,
2716
+ "row-index": row.originalIndex,
2717
+ "col-index": colIndex,
2718
+ style: normalizeStyle({
2719
+ textAlign: column?.align || "center",
2720
+ width: unref(store).config.fullWidth ? "auto" : null
2721
+ }),
2722
+ spellcheck: "false"
2723
+ }, null, 8, [
2724
+ "store",
2725
+ "pinned",
2726
+ "row-index",
2727
+ "col-index",
2728
+ "style"
2729
+ ]))], 64);
2730
+ }), 128))]),
2731
+ _: 2
2732
+ }, 1032, [
2733
+ "row",
2734
+ "row-index",
2735
+ "store"
2736
+ ]);
2737
+ }), 128))], true)]),
2738
+ renderSlot(_ctx.$slots, "footer", {
2739
+ data: unref(store),
2740
+ page: unref(pagination)
2741
+ }, () => [createVNode(ATablePaginationFooter_default, {
2742
+ "column-count": footerColumnCount.value,
2743
+ "show-footer": unref(showFooter),
2744
+ "has-more": unref(hasMore),
2745
+ "has-prev": unref(hasPrev),
2746
+ "has-next": unref(hasNext),
2747
+ "has-local-next": unref(hasLocalNext),
2748
+ "has-ever-had-more": unref(hasEverHadMore),
2749
+ "loaded-count": unref(loadedCount),
2750
+ loading: unref(paginationLoading),
2751
+ next: unref(paginationNext),
2752
+ prev: unref(paginationPrev)
2753
+ }, null, 8, [
2754
+ "column-count",
2755
+ "show-footer",
2756
+ "has-more",
2757
+ "has-prev",
2758
+ "has-next",
2759
+ "has-local-next",
2760
+ "has-ever-had-more",
2761
+ "loaded-count",
2762
+ "loading",
2763
+ "next",
2764
+ "prev"
2765
+ ])], true)
2766
+ ], 6),
2762
2767
  renderSlot(_ctx.$slots, "modal", { data: unref(store) }, () => [withDirectives(createVNode(ATableModal_default, { store: unref(store) }, {
2763
2768
  default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(unref(store).modal.component), mergeProps({
2764
2769
  key: `${unref(store).modal.rowIndex}:${unref(store).modal.colIndex}`,
@@ -2771,15 +2776,16 @@ var ATable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
2771
2776
  "store"
2772
2777
  ]))]),
2773
2778
  _: 1
2774
- }, 8, ["store"]), [[vShow, unref(store).modal.visible]])], true)
2775
- ], 4)), [[unref(vOnClickOutside), unref(store).closeModal]]), unref(store).isGanttView && unref(store).isDependencyGraphEnabled ? (openBlock(), createBlock(AGanttConnection_default, {
2776
- key: 0,
2777
- store: unref(store),
2778
- "onConnection:delete": handleConnectionDelete
2779
- }, null, 8, ["store"])) : createCommentVNode("", true)]);
2779
+ }, 8, ["store"]), [[vShow, unref(store).modal.visible]])], true),
2780
+ unref(store).isGanttView && unref(store).isDependencyGraphEnabled ? (openBlock(), createBlock(AGanttConnection_default, {
2781
+ key: 0,
2782
+ store: unref(store),
2783
+ "onConnection:delete": handleConnectionDelete
2784
+ }, null, 8, ["store"])) : createCommentVNode("", true)
2785
+ ])), [[unref(vOnClickOutside), unref(store).closeModal]]);
2780
2786
  };
2781
2787
  }
2782
- }), [["__scopeId", "data-v-53c8fbad"]]);
2788
+ }), [["__scopeId", "data-v-a1149691"]]);
2783
2789
  //#endregion
2784
2790
  //#region src/components/ATableLoading.vue
2785
2791
  var _sfc_main$1 = {};
@@ -2788,7 +2794,7 @@ var _hoisted_2$1 = { class: "aloading-header" };
2788
2794
  function _sfc_render$1(_ctx, _cache) {
2789
2795
  return openBlock(), createElementBlock("div", _hoisted_1$1, [createElementVNode("h2", _hoisted_2$1, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]), _cache[0] || (_cache[0] = createElementVNode("div", { class: "aloading-bar" }, null, -1))]);
2790
2796
  }
2791
- var ATableLoading_default = /*#__PURE__*/ _plugin_vue_export_helper_default(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-a930a25b"]]);
2797
+ var ATableLoading_default = /*#__PURE__*/ _plugin_vue_export_helper_default(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-6353ec92"]]);
2792
2798
  //#endregion
2793
2799
  //#region src/components/ATableLoadingBar.vue
2794
2800
  var _sfc_main = {};
@@ -2797,7 +2803,7 @@ var _hoisted_2 = { class: "aloading-header" };
2797
2803
  function _sfc_render(_ctx, _cache) {
2798
2804
  return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("h2", _hoisted_2, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]), _cache[0] || (_cache[0] = createElementVNode("div", { class: "aloading-bar" }, null, -1))]);
2799
2805
  }
2800
- var ATableLoadingBar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-e1165876"]]);
2806
+ var ATableLoadingBar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-1daa5d43"]]);
2801
2807
  //#endregion
2802
2808
  //#region src/index.ts
2803
2809
  /**