@alaarab/ogrid-vue-vuetify 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.
@@ -1,55 +0,0 @@
1
- import { defineComponent, h } from 'vue';
2
- import { VMenu, VList, VListItem, VDivider } from 'vuetify/components';
3
- import { GRID_CONTEXT_MENU_ITEMS, getContextMenuHandlers, formatShortcut, } from '@alaarab/ogrid-vue';
4
- export const GridContextMenu = defineComponent({
5
- name: 'GridContextMenu',
6
- props: {
7
- x: { type: Number, required: true },
8
- y: { type: Number, required: true },
9
- hasSelection: { type: Boolean, required: true },
10
- canUndo: { type: Boolean, required: true },
11
- canRedo: { type: Boolean, required: true },
12
- onUndo: { type: Function, required: true },
13
- onRedo: { type: Function, required: true },
14
- onCopy: { type: Function, required: true },
15
- onCut: { type: Function, required: true },
16
- onPaste: { type: Function, required: true },
17
- onSelectAll: { type: Function, required: true },
18
- onClose: { type: Function, required: true },
19
- },
20
- setup(props) {
21
- const handlers = getContextMenuHandlers(props);
22
- const isDisabled = (item) => {
23
- if (item.disabledWhenNoSelection && !props.hasSelection)
24
- return true;
25
- if (item.id === 'undo' && !props.canUndo)
26
- return true;
27
- if (item.id === 'redo' && !props.canRedo)
28
- return true;
29
- return false;
30
- };
31
- return () => h(VMenu, {
32
- modelValue: true,
33
- 'onUpdate:modelValue': (v) => { if (!v)
34
- props.onClose(); },
35
- target: [props.x, props.y],
36
- location: 'bottom start',
37
- }, {
38
- default: () => h(VList, { density: 'compact', 'aria-label': 'Grid context menu' }, () => GRID_CONTEXT_MENU_ITEMS.map((item) => [
39
- ...(item.dividerBefore ? [h(VDivider, { key: `${item.id}-div` })] : []),
40
- h(VListItem, {
41
- key: item.id,
42
- disabled: isDisabled(item),
43
- onClick: () => { handlers[item.id](); },
44
- }, () => h('div', { style: { display: 'flex', alignItems: 'center', width: '100%' } }, [
45
- h('span', { style: { flex: '1' } }, item.label),
46
- ...(item.shortcut ? [
47
- h('span', {
48
- style: { marginLeft: '24px', color: 'rgba(0,0,0,0.4)', fontSize: '0.8em' },
49
- }, formatShortcut(item.shortcut)),
50
- ] : []),
51
- ])),
52
- ]).flat()),
53
- });
54
- },
55
- });
@@ -1,37 +0,0 @@
1
- import { h } from 'vue';
2
- import { VCheckbox } from 'vuetify/components';
3
- import { createInlineCellEditor } from '@alaarab/ogrid-vue';
4
- export const InlineCellEditor = createInlineCellEditor({
5
- renderCheckbox: ({ checked, onChange, onCancel }) => h(VCheckbox, {
6
- modelValue: checked,
7
- hideDetails: true,
8
- density: 'compact',
9
- 'onUpdate:modelValue': (c) => onChange(c),
10
- onKeydown: (e) => {
11
- if (e.key === 'Escape') {
12
- e.preventDefault();
13
- onCancel();
14
- }
15
- },
16
- }),
17
- renderDatePicker: ({ value, onChange, onCancel }) => h('input', {
18
- type: 'date',
19
- value,
20
- style: { width: '100%', height: '100%', border: 'none', outline: 'none', padding: '0 4px', fontSize: 'inherit' },
21
- onKeydown: (e) => {
22
- if (e.key === 'Enter') {
23
- e.preventDefault();
24
- onChange(e.target.value);
25
- }
26
- if (e.key === 'Escape') {
27
- e.preventDefault();
28
- onCancel();
29
- }
30
- if (e.key === 'Tab') {
31
- e.preventDefault();
32
- onChange(e.target.value);
33
- }
34
- },
35
- onBlur: (e) => onChange(e.target.value),
36
- }),
37
- });
@@ -1,9 +0,0 @@
1
- import { createOGrid } from '@alaarab/ogrid-vue';
2
- import { DataGridTable } from '../DataGridTable/DataGridTable';
3
- import { ColumnChooser } from '../ColumnChooser/ColumnChooser';
4
- import { PaginationControls } from '../PaginationControls/PaginationControls';
5
- export const OGrid = createOGrid({
6
- DataGridTable,
7
- ColumnChooser,
8
- PaginationControls,
9
- });
@@ -1,131 +0,0 @@
1
- import { defineComponent, computed, h } from 'vue';
2
- import { VBtn, VSelect } from 'vuetify/components';
3
- import { getPaginationViewModel } from '@alaarab/ogrid-vue';
4
- export const PaginationControls = defineComponent({
5
- name: 'PaginationControls',
6
- props: {
7
- currentPage: { type: Number, required: true },
8
- pageSize: { type: Number, required: true },
9
- totalCount: { type: Number, required: true },
10
- onPageChange: { type: Function, required: true },
11
- onPageSizeChange: { type: Function, required: true },
12
- pageSizeOptions: { type: Array, default: undefined },
13
- entityLabelPlural: { type: String, default: 'items' },
14
- },
15
- setup(props) {
16
- const vm = computed(() => getPaginationViewModel(props.currentPage, props.pageSize, props.totalCount, props.pageSizeOptions ? { pageSizeOptions: props.pageSizeOptions } : undefined));
17
- return () => {
18
- const v = vm.value;
19
- if (!v)
20
- return null;
21
- const { pageNumbers, showStartEllipsis, showEndEllipsis, totalPages, startItem, endItem } = v;
22
- const label = props.entityLabelPlural ?? 'items';
23
- return h('div', {
24
- role: 'navigation',
25
- 'aria-label': 'Pagination',
26
- style: {
27
- display: 'flex',
28
- alignItems: 'center',
29
- justifyContent: 'space-between',
30
- flexWrap: 'wrap',
31
- gap: '16px',
32
- padding: '0 12px',
33
- width: '100%',
34
- minWidth: '0',
35
- boxSizing: 'border-box',
36
- },
37
- }, [
38
- // Summary text
39
- h('span', {
40
- style: { fontSize: '0.875rem', color: 'var(--ogrid-fg-secondary, rgba(0,0,0,0.6))' },
41
- }, `Showing ${startItem} to ${endItem} of ${props.totalCount.toLocaleString()} ${label}`),
42
- // Page buttons
43
- h('div', { style: { display: 'flex', alignItems: 'center', gap: '4px' } }, [
44
- // First page
45
- h(VBtn, {
46
- icon: 'mdi-page-first',
47
- size: 'small',
48
- variant: 'text',
49
- disabled: props.currentPage === 1,
50
- 'aria-label': 'First page',
51
- onClick: () => props.onPageChange(1),
52
- }),
53
- // Previous
54
- h(VBtn, {
55
- icon: 'mdi-chevron-left',
56
- size: 'small',
57
- variant: 'text',
58
- disabled: props.currentPage === 1,
59
- 'aria-label': 'Previous page',
60
- onClick: () => props.onPageChange(props.currentPage - 1),
61
- }),
62
- // Start ellipsis
63
- ...(showStartEllipsis ? [
64
- h(VBtn, {
65
- size: 'small',
66
- variant: 'outlined',
67
- 'aria-label': 'Page 1',
68
- style: { minWidth: '32px' },
69
- onClick: () => props.onPageChange(1),
70
- }, () => '1'),
71
- h('span', { style: { margin: '0 4px', color: 'var(--ogrid-fg-secondary, rgba(0,0,0,0.6))' }, 'aria-hidden': 'true' }, '\u2026'),
72
- ] : []),
73
- // Page numbers
74
- ...pageNumbers.map((pageNum) => h(VBtn, {
75
- key: pageNum,
76
- size: 'small',
77
- variant: props.currentPage === pageNum ? 'flat' : 'outlined',
78
- color: props.currentPage === pageNum ? 'primary' : undefined,
79
- 'aria-label': `Page ${pageNum}`,
80
- 'aria-current': props.currentPage === pageNum ? 'page' : undefined,
81
- style: { minWidth: '32px' },
82
- onClick: () => props.onPageChange(pageNum),
83
- }, () => String(pageNum))),
84
- // End ellipsis
85
- ...(showEndEllipsis ? [
86
- h('span', { style: { margin: '0 4px', color: 'var(--ogrid-fg-secondary, rgba(0,0,0,0.6))' }, 'aria-hidden': 'true' }, '\u2026'),
87
- h(VBtn, {
88
- size: 'small',
89
- variant: 'outlined',
90
- 'aria-label': `Page ${totalPages}`,
91
- style: { minWidth: '32px' },
92
- onClick: () => props.onPageChange(totalPages),
93
- }, () => String(totalPages)),
94
- ] : []),
95
- // Next
96
- h(VBtn, {
97
- icon: 'mdi-chevron-right',
98
- size: 'small',
99
- variant: 'text',
100
- disabled: props.currentPage >= totalPages,
101
- 'aria-label': 'Next page',
102
- onClick: () => props.onPageChange(props.currentPage + 1),
103
- }),
104
- // Last page
105
- h(VBtn, {
106
- icon: 'mdi-page-last',
107
- size: 'small',
108
- variant: 'text',
109
- disabled: props.currentPage >= totalPages,
110
- 'aria-label': 'Last page',
111
- onClick: () => props.onPageChange(totalPages),
112
- }),
113
- ]),
114
- // Page size selector
115
- h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } }, [
116
- h('span', { style: { fontSize: '0.875rem', color: 'var(--ogrid-fg-secondary, rgba(0,0,0,0.6))' } }, 'Rows'),
117
- h(VSelect, {
118
- modelValue: props.pageSize,
119
- items: v.pageSizeOptions,
120
- density: 'compact',
121
- hideDetails: true,
122
- variant: 'outlined',
123
- 'aria-label': 'Rows per page',
124
- style: { minWidth: '70px', maxWidth: '90px' },
125
- 'onUpdate:modelValue': (val) => props.onPageSizeChange(Number(val)),
126
- }),
127
- ]),
128
- ]);
129
- };
130
- },
131
- });