@alaarab/ogrid-vue 2.1.2 → 2.1.4
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/esm/index.js +4336 -15
- package/package.json +4 -4
- package/dist/esm/components/MarchingAntsOverlay.js +0 -144
- package/dist/esm/components/SideBar.js +0 -1
- package/dist/esm/components/StatusBar.js +0 -49
- package/dist/esm/components/createDataGridTable.js +0 -514
- package/dist/esm/components/createInlineCellEditor.js +0 -194
- package/dist/esm/components/createOGrid.js +0 -383
- package/dist/esm/composables/index.js +0 -33
- package/dist/esm/composables/useActiveCell.js +0 -77
- package/dist/esm/composables/useCellEditing.js +0 -27
- package/dist/esm/composables/useCellSelection.js +0 -359
- package/dist/esm/composables/useClipboard.js +0 -87
- package/dist/esm/composables/useColumnChooserState.js +0 -74
- package/dist/esm/composables/useColumnHeaderFilterState.js +0 -189
- package/dist/esm/composables/useColumnHeaderMenuState.js +0 -113
- package/dist/esm/composables/useColumnPinning.js +0 -64
- package/dist/esm/composables/useColumnReorder.js +0 -110
- package/dist/esm/composables/useColumnResize.js +0 -73
- package/dist/esm/composables/useContextMenu.js +0 -23
- package/dist/esm/composables/useDataGridState.js +0 -425
- package/dist/esm/composables/useDataGridTableSetup.js +0 -66
- package/dist/esm/composables/useDateFilterState.js +0 -36
- package/dist/esm/composables/useDebounce.js +0 -60
- package/dist/esm/composables/useFillHandle.js +0 -205
- package/dist/esm/composables/useFilterOptions.js +0 -39
- package/dist/esm/composables/useInlineCellEditorState.js +0 -42
- package/dist/esm/composables/useKeyboardNavigation.js +0 -232
- package/dist/esm/composables/useLatestRef.js +0 -27
- package/dist/esm/composables/useMultiSelectFilterState.js +0 -59
- package/dist/esm/composables/useOGrid.js +0 -491
- package/dist/esm/composables/usePeopleFilterState.js +0 -66
- package/dist/esm/composables/useRichSelectState.js +0 -59
- package/dist/esm/composables/useRowSelection.js +0 -75
- package/dist/esm/composables/useSideBarState.js +0 -41
- package/dist/esm/composables/useTableLayout.js +0 -85
- package/dist/esm/composables/useTextFilterState.js +0 -26
- package/dist/esm/composables/useUndoRedo.js +0 -65
- package/dist/esm/composables/useVirtualScroll.js +0 -87
- package/dist/esm/types/columnTypes.js +0 -1
- package/dist/esm/types/dataGridTypes.js +0 -1
- package/dist/esm/types/index.js +0 -1
- package/dist/esm/utils/dataGridViewModel.js +0 -23
- package/dist/esm/utils/index.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-vue",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "OGrid Vue – Vue 3 composables, headless components, and utilities for OGrid data grids.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/types/index.d.ts",
|
|
11
11
|
"import": "./dist/esm/index.js",
|
|
12
|
-
"
|
|
12
|
+
"default": "./dist/esm/index.js"
|
|
13
13
|
},
|
|
14
14
|
"./styles/*": "./dist/esm/styles/*"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "rimraf dist && tsc -p tsconfig.build.json && node scripts/copy-css.js",
|
|
17
|
+
"build": "rimraf dist && tsup && tsc -p tsconfig.build.json && node scripts/copy-css.js",
|
|
18
18
|
"test": "jest --passWithNoTests"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"node": ">=18"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@alaarab/ogrid-core": "2.1.
|
|
39
|
+
"@alaarab/ogrid-core": "2.1.4"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"vue": "^3.3.0"
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MarchingAntsOverlay — Renders range overlays on top of the grid:
|
|
3
|
-
*
|
|
4
|
-
* 1. **Selection range**: solid green border around the current selection
|
|
5
|
-
* 2. **Copy/Cut range**: animated dashed border (marching ants) like Excel
|
|
6
|
-
*
|
|
7
|
-
* Uses SVG rects positioned via cell data-attribute measurements.
|
|
8
|
-
*/
|
|
9
|
-
import { defineComponent, ref, computed, watch, onMounted, onUnmounted, h, toValue } from 'vue';
|
|
10
|
-
import { Z_INDEX, measureRange, injectGlobalStyles } from '@alaarab/ogrid-core';
|
|
11
|
-
export const MarchingAntsOverlay = defineComponent({
|
|
12
|
-
name: 'MarchingAntsOverlay',
|
|
13
|
-
props: {
|
|
14
|
-
/** Ref to the positioned container that wraps the table (must have position: relative) */
|
|
15
|
-
containerRef: { type: Object, required: true },
|
|
16
|
-
/** Current selection range — solid green border */
|
|
17
|
-
selectionRange: { type: Object, default: null },
|
|
18
|
-
/** Copy range — animated dashed border */
|
|
19
|
-
copyRange: { type: Object, default: null },
|
|
20
|
-
/** Cut range — animated dashed border */
|
|
21
|
-
cutRange: { type: Object, default: null },
|
|
22
|
-
/** Column offset — 1 when checkbox column is present, else 0 */
|
|
23
|
-
colOffset: { type: Number, required: true },
|
|
24
|
-
/** Items array — triggers re-measurement when data changes (e.g., sorting) */
|
|
25
|
-
items: { type: Array, required: true },
|
|
26
|
-
/** Visible columns — triggers re-measurement when columns are hidden/shown */
|
|
27
|
-
visibleColumns: { type: Array, default: undefined },
|
|
28
|
-
/** Column sizing overrides — triggers re-measurement when columns are resized */
|
|
29
|
-
columnSizingOverrides: { type: Object, required: true },
|
|
30
|
-
/** Column order — triggers re-measurement when columns are reordered */
|
|
31
|
-
columnOrder: { type: Array, default: undefined },
|
|
32
|
-
},
|
|
33
|
-
setup(props) {
|
|
34
|
-
const selRect = ref(null);
|
|
35
|
-
const clipRect = ref(null);
|
|
36
|
-
let rafId = 0;
|
|
37
|
-
let ro;
|
|
38
|
-
const clipRange = computed(() => props.copyRange ?? props.cutRange);
|
|
39
|
-
const measureAll = () => {
|
|
40
|
-
// Use toValue to handle both Ref<HTMLElement> and raw HTMLElement
|
|
41
|
-
// (Vue templates may auto-unwrap refs passed as props)
|
|
42
|
-
const container = toValue(props.containerRef);
|
|
43
|
-
if (!container) {
|
|
44
|
-
selRect.value = null;
|
|
45
|
-
clipRect.value = null;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
selRect.value = props.selectionRange ? measureRange(container, props.selectionRange, props.colOffset) : null;
|
|
49
|
-
clipRect.value = clipRange.value ? measureRange(container, clipRange.value, props.colOffset) : null;
|
|
50
|
-
};
|
|
51
|
-
// Inject keyframes on mount
|
|
52
|
-
onMounted(() => {
|
|
53
|
-
injectGlobalStyles('ogrid-marching-ants-keyframes', '@keyframes ogrid-marching-ants{to{stroke-dashoffset:-8}}');
|
|
54
|
-
});
|
|
55
|
-
// Measure when any range changes; re-measure on resize, column changes, data changes
|
|
56
|
-
watch([() => props.selectionRange, clipRange, () => toValue(props.containerRef), () => props.items, () => props.visibleColumns, () => props.columnSizingOverrides, () => props.columnOrder], () => {
|
|
57
|
-
if (!props.selectionRange && !clipRange.value) {
|
|
58
|
-
selRect.value = null;
|
|
59
|
-
clipRect.value = null;
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
// Delay one frame so cells are rendered
|
|
63
|
-
rafId = requestAnimationFrame(measureAll);
|
|
64
|
-
const container = toValue(props.containerRef);
|
|
65
|
-
if (container) {
|
|
66
|
-
ro?.disconnect();
|
|
67
|
-
ro = new ResizeObserver(measureAll);
|
|
68
|
-
ro.observe(container);
|
|
69
|
-
}
|
|
70
|
-
}, { immediate: true });
|
|
71
|
-
onUnmounted(() => {
|
|
72
|
-
cancelAnimationFrame(rafId);
|
|
73
|
-
ro?.disconnect();
|
|
74
|
-
});
|
|
75
|
-
const clipRangeMatchesSel = computed(() => {
|
|
76
|
-
const sel = props.selectionRange;
|
|
77
|
-
const clip = clipRange.value;
|
|
78
|
-
return (sel != null &&
|
|
79
|
-
clip != null &&
|
|
80
|
-
sel.startRow === clip.startRow &&
|
|
81
|
-
sel.startCol === clip.startCol &&
|
|
82
|
-
sel.endRow === clip.endRow &&
|
|
83
|
-
sel.endCol === clip.endCol);
|
|
84
|
-
});
|
|
85
|
-
return () => {
|
|
86
|
-
if (!selRect.value && !clipRect.value)
|
|
87
|
-
return null;
|
|
88
|
-
return h('div', { style: { position: 'relative' } }, [
|
|
89
|
-
// Selection range: solid green border (hidden when clipboard range overlaps)
|
|
90
|
-
selRect.value && !clipRangeMatchesSel.value ? h('svg', {
|
|
91
|
-
style: {
|
|
92
|
-
position: 'absolute',
|
|
93
|
-
top: `${selRect.value.top}px`,
|
|
94
|
-
left: `${selRect.value.left}px`,
|
|
95
|
-
width: `${selRect.value.width}px`,
|
|
96
|
-
height: `${selRect.value.height}px`,
|
|
97
|
-
pointerEvents: 'none',
|
|
98
|
-
zIndex: Z_INDEX.SELECTION_OVERLAY,
|
|
99
|
-
overflow: 'visible',
|
|
100
|
-
},
|
|
101
|
-
'aria-hidden': 'true',
|
|
102
|
-
}, [
|
|
103
|
-
h('rect', {
|
|
104
|
-
x: 1,
|
|
105
|
-
y: 1,
|
|
106
|
-
width: Math.max(0, selRect.value.width - 2),
|
|
107
|
-
height: Math.max(0, selRect.value.height - 2),
|
|
108
|
-
fill: 'none',
|
|
109
|
-
stroke: 'var(--ogrid-selection, #217346)',
|
|
110
|
-
'stroke-width': 2,
|
|
111
|
-
}),
|
|
112
|
-
]) : null,
|
|
113
|
-
// Copy/Cut range: animated marching ants
|
|
114
|
-
clipRect.value ? h('svg', {
|
|
115
|
-
style: {
|
|
116
|
-
position: 'absolute',
|
|
117
|
-
top: `${clipRect.value.top}px`,
|
|
118
|
-
left: `${clipRect.value.left}px`,
|
|
119
|
-
width: `${clipRect.value.width}px`,
|
|
120
|
-
height: `${clipRect.value.height}px`,
|
|
121
|
-
pointerEvents: 'none',
|
|
122
|
-
zIndex: Z_INDEX.CLIPBOARD_OVERLAY,
|
|
123
|
-
overflow: 'visible',
|
|
124
|
-
},
|
|
125
|
-
'aria-hidden': 'true',
|
|
126
|
-
}, [
|
|
127
|
-
h('rect', {
|
|
128
|
-
x: 1,
|
|
129
|
-
y: 1,
|
|
130
|
-
width: Math.max(0, clipRect.value.width - 2),
|
|
131
|
-
height: Math.max(0, clipRect.value.height - 2),
|
|
132
|
-
fill: 'none',
|
|
133
|
-
stroke: 'var(--ogrid-selection, #217346)',
|
|
134
|
-
'stroke-width': 2,
|
|
135
|
-
'stroke-dasharray': '4 4',
|
|
136
|
-
style: {
|
|
137
|
-
animation: 'ogrid-marching-ants 0.5s linear infinite',
|
|
138
|
-
},
|
|
139
|
-
}),
|
|
140
|
-
]) : null,
|
|
141
|
-
]);
|
|
142
|
-
};
|
|
143
|
-
},
|
|
144
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StatusBar component — Shows row counts and aggregations at the bottom of the data grid.
|
|
3
|
-
* Displays filteredCount, totalCount, and optional aggregations (sum, avg, min, max, count).
|
|
4
|
-
*/
|
|
5
|
-
import { defineComponent, h } from 'vue';
|
|
6
|
-
import { getStatusBarParts } from '@alaarab/ogrid-core';
|
|
7
|
-
export const StatusBar = defineComponent({
|
|
8
|
-
name: 'StatusBar',
|
|
9
|
-
props: {
|
|
10
|
-
totalCount: { type: Number, required: true },
|
|
11
|
-
filteredCount: { type: Number, default: undefined },
|
|
12
|
-
selectedCount: { type: Number, default: undefined },
|
|
13
|
-
selectedCellCount: { type: Number, default: undefined },
|
|
14
|
-
aggregation: { type: Object, default: undefined },
|
|
15
|
-
suppressRowCount: { type: Boolean, default: false },
|
|
16
|
-
},
|
|
17
|
-
setup(props) {
|
|
18
|
-
return () => {
|
|
19
|
-
const parts = getStatusBarParts(props);
|
|
20
|
-
return h('div', {
|
|
21
|
-
role: 'status',
|
|
22
|
-
'aria-live': 'polite',
|
|
23
|
-
style: {
|
|
24
|
-
marginTop: 'auto',
|
|
25
|
-
padding: '6px 12px',
|
|
26
|
-
borderTop: '1px solid var(--ogrid-border, rgba(0,0,0,0.12))',
|
|
27
|
-
backgroundColor: 'var(--ogrid-header-bg, rgba(0,0,0,0.04))',
|
|
28
|
-
display: 'flex',
|
|
29
|
-
alignItems: 'center',
|
|
30
|
-
gap: '16px',
|
|
31
|
-
fontSize: '0.875rem',
|
|
32
|
-
},
|
|
33
|
-
}, parts.map((p, i) => h('span', {
|
|
34
|
-
key: p.key,
|
|
35
|
-
style: {
|
|
36
|
-
display: 'inline-flex',
|
|
37
|
-
alignItems: 'center',
|
|
38
|
-
gap: '4px',
|
|
39
|
-
...(i < parts.length - 1
|
|
40
|
-
? { marginRight: '16px', borderRight: '1px solid var(--ogrid-border, rgba(0,0,0,0.12))', paddingRight: '16px' }
|
|
41
|
-
: {}),
|
|
42
|
-
},
|
|
43
|
-
}, [
|
|
44
|
-
h('span', { style: { color: 'var(--ogrid-fg-secondary, rgba(0,0,0,0.6))' } }, p.label),
|
|
45
|
-
h('span', { style: { fontWeight: '600' } }, p.value.toLocaleString()),
|
|
46
|
-
])));
|
|
47
|
-
};
|
|
48
|
-
},
|
|
49
|
-
});
|