@stonecrop/atable 0.2.23 → 0.2.25
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/src/tsdoc-metadata.json +11 -0
- package/dist/atable.d.ts +46 -0
- package/dist/atable.js +463 -416
- package/dist/atable.js.map +1 -1
- package/dist/atable.tsbuildinfo +1 -0
- package/dist/atable.umd.cjs +1 -1
- package/dist/atable.umd.cjs.map +1 -1
- package/dist/components/index.js +97 -0
- package/dist/index.js +21 -0
- package/dist/src/components/index.d.ts +23 -0
- package/dist/src/components/index.d.ts.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/types/index.d.ts +46 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/style.css +1 -1
- package/dist/types/index.js +0 -0
- package/package.json +26 -31
- package/src/components/ACell.vue +1 -1
- package/src/components/AExpansionRow.vue +5 -6
- package/src/components/ARow.vue +15 -28
- package/src/components/ATable.vue +8 -8
- package/src/components/ATableHeader.vue +2 -3
- package/src/components/ATableModal.vue +8 -9
- package/src/components/index.ts +1 -1
- package/src/index.ts +6 -0
- package/src/themes/default.css +0 -2
- package/src/types/index.ts +53 -0
- package/src/histoire.setup.ts +0 -24
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { v4 } from 'uuid';
|
|
2
|
+
import { computed, reactive } from 'vue';
|
|
3
|
+
export default class TableDataStore {
|
|
4
|
+
id;
|
|
5
|
+
rows;
|
|
6
|
+
columns;
|
|
7
|
+
config;
|
|
8
|
+
table;
|
|
9
|
+
display;
|
|
10
|
+
modal;
|
|
11
|
+
constructor(id, columns, rows, config, table, display) {
|
|
12
|
+
this.id = id || v4();
|
|
13
|
+
this.rows = rows;
|
|
14
|
+
this.columns = reactive(columns);
|
|
15
|
+
this.config = reactive(config);
|
|
16
|
+
this.table = table || reactive(this.createTableObject());
|
|
17
|
+
this.display = this.createDisplayObject(display);
|
|
18
|
+
this.modal = reactive({ visible: false });
|
|
19
|
+
}
|
|
20
|
+
createTableObject() {
|
|
21
|
+
const table = {};
|
|
22
|
+
for (const [colIndex, column] of this.columns.entries()) {
|
|
23
|
+
for (const [rowIndex, row] of this.rows.entries()) {
|
|
24
|
+
table[`${colIndex}:${rowIndex}`] = row[column.name];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return table;
|
|
28
|
+
}
|
|
29
|
+
createDisplayObject(display) {
|
|
30
|
+
const defaultDisplay = [Object.assign({}, { modified: false })];
|
|
31
|
+
// TODO: (typing) what is the type of `display` here?
|
|
32
|
+
if (display) {
|
|
33
|
+
if ('0:0' in display) {
|
|
34
|
+
return display;
|
|
35
|
+
}
|
|
36
|
+
// else if ('default' in display) {
|
|
37
|
+
// // TODO: (typing) what is the possible input here for 'default'?
|
|
38
|
+
// defaultDisplay = display.default
|
|
39
|
+
// }
|
|
40
|
+
}
|
|
41
|
+
// TODO: (typing) is this type correct for the parent set?
|
|
42
|
+
const parents = new Set();
|
|
43
|
+
for (let rowIndex = this.rows.length - 1; rowIndex >= 0; rowIndex--) {
|
|
44
|
+
const row = this.rows[rowIndex];
|
|
45
|
+
if (row.parent) {
|
|
46
|
+
parents.add(row.parent);
|
|
47
|
+
}
|
|
48
|
+
defaultDisplay[rowIndex] = {
|
|
49
|
+
childrenOpen: false,
|
|
50
|
+
expanded: false,
|
|
51
|
+
indent: row.indent || null,
|
|
52
|
+
isParent: parents.has(rowIndex),
|
|
53
|
+
isRoot: row.parent === null || row.parent === undefined,
|
|
54
|
+
modified: false,
|
|
55
|
+
open: row.parent === null || row.parent === undefined,
|
|
56
|
+
parent: row.parent,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return reactive(defaultDisplay);
|
|
60
|
+
}
|
|
61
|
+
get zeroColumn() {
|
|
62
|
+
return ['list', 'tree', 'list-expansion'].includes(this.config.view);
|
|
63
|
+
}
|
|
64
|
+
get numberedRowWidth() {
|
|
65
|
+
return computed(() => {
|
|
66
|
+
return String(Math.ceil(this.rows.length / 100) + 1) + 'ch';
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
cellData(colIndex, rowIndex) {
|
|
70
|
+
return this.table[`${colIndex}:${rowIndex}`];
|
|
71
|
+
}
|
|
72
|
+
setCellData(rowIndex, colIndex, value) {
|
|
73
|
+
if (this.table[`${colIndex}:${rowIndex}`] !== value) {
|
|
74
|
+
this.display[rowIndex].modified = true;
|
|
75
|
+
}
|
|
76
|
+
this.table[`${colIndex}:${rowIndex}`] = value;
|
|
77
|
+
const col = this.columns[colIndex];
|
|
78
|
+
this.rows[rowIndex][col.name] = value;
|
|
79
|
+
return this.table[`${colIndex}:${rowIndex}`];
|
|
80
|
+
}
|
|
81
|
+
toggleRowExpand(rowIndex) {
|
|
82
|
+
if (this.config.view === 'tree') {
|
|
83
|
+
this.display[rowIndex].childrenOpen = !this.display[rowIndex].childrenOpen;
|
|
84
|
+
for (let index = this.rows.length - 1; index >= 0; index--) {
|
|
85
|
+
if (this.display[index].parent === rowIndex) {
|
|
86
|
+
this.display[index].open = !this.display[index].open;
|
|
87
|
+
if (this.display[index].childrenOpen) {
|
|
88
|
+
this.toggleRowExpand(index);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (this.config.view === 'list-expansion') {
|
|
94
|
+
this.display[rowIndex].expanded = !this.display[rowIndex].expanded;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import ACell from '@/components/ACell.vue';
|
|
2
|
+
import AExpansionRow from '@/components/AExpansionRow.vue';
|
|
3
|
+
import ARow from '@/components/ARow.vue';
|
|
4
|
+
import ATable from '@/components/ATable.vue';
|
|
5
|
+
import ATableHeader from '@/components/ATableHeader.vue';
|
|
6
|
+
import ATableModal from '@/components/ATableModal.vue';
|
|
7
|
+
import TableDataStore from './components';
|
|
8
|
+
/**
|
|
9
|
+
* Install all ATable components
|
|
10
|
+
* @param app - Vue app instance
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
function install(app /* options */) {
|
|
14
|
+
app.component('ACell', ACell);
|
|
15
|
+
app.component('AExpansionRow', AExpansionRow);
|
|
16
|
+
app.component('ARow', ARow);
|
|
17
|
+
app.component('ATable', ATable);
|
|
18
|
+
app.component('ATableHeader', ATableHeader);
|
|
19
|
+
app.component('ATableModal', ATableModal);
|
|
20
|
+
}
|
|
21
|
+
export { install, ACell, AExpansionRow, ARow, ATable, ATableHeader, ATableModal, TableDataStore };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TableDisplay, TableRow, TableColumn, TableConfig, TableModal } from '@/types';
|
|
2
|
+
export default class TableDataStore {
|
|
3
|
+
id: string;
|
|
4
|
+
rows: TableRow[];
|
|
5
|
+
columns: TableColumn[];
|
|
6
|
+
config: TableConfig;
|
|
7
|
+
table: {
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
};
|
|
10
|
+
display: TableDisplay[];
|
|
11
|
+
modal: TableModal;
|
|
12
|
+
constructor(id?: string, columns?: TableColumn[], rows?: TableRow[], config?: TableConfig, table?: {
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}, display?: TableDisplay[]);
|
|
15
|
+
createTableObject(): {};
|
|
16
|
+
createDisplayObject(display?: TableDisplay[]): (TableDisplay[] & Record<"0:0", unknown>) | import("vue").Reactive<TableDisplay[]>;
|
|
17
|
+
get zeroColumn(): boolean;
|
|
18
|
+
get numberedRowWidth(): import("vue").ComputedRef<string>;
|
|
19
|
+
cellData<T>(colIndex: number, rowIndex: number): T;
|
|
20
|
+
setCellData(rowIndex: number, colIndex: number, value: any): any;
|
|
21
|
+
toggleRowExpand(rowIndex: number): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAE3F,MAAM,CAAC,OAAO,OAAO,cAAc;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,KAAK,EAAE,UAAU,CAAA;gBAGhB,EAAE,CAAC,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,WAAW,EAAE,EACvB,IAAI,CAAC,EAAE,QAAQ,EAAE,EACjB,MAAM,CAAC,EAAE,WAAW,EACpB,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAC9B,OAAO,CAAC,EAAE,YAAY,EAAE;IAWzB,iBAAiB;IAUjB,mBAAmB,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE;IAqC5C,IAAI,UAAU,YAEb;IAED,IAAI,gBAAgB,sCAInB;IAED,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC;IAIlD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG;IAU1D,eAAe,CAAC,QAAQ,EAAE,MAAM;CAehC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
import ACell from '@/components/ACell.vue';
|
|
3
|
+
import AExpansionRow from '@/components/AExpansionRow.vue';
|
|
4
|
+
import ARow from '@/components/ARow.vue';
|
|
5
|
+
import ATable from '@/components/ATable.vue';
|
|
6
|
+
import ATableHeader from '@/components/ATableHeader.vue';
|
|
7
|
+
import ATableModal from '@/components/ATableModal.vue';
|
|
8
|
+
import TableDataStore from './components';
|
|
9
|
+
export type { TableColumn, TableConfig, TableDisplay, TableRow, TableModal } from '@/types';
|
|
10
|
+
/**
|
|
11
|
+
* Install all ATable components
|
|
12
|
+
* @param app - Vue app instance
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
declare function install(app: App): void;
|
|
16
|
+
export { install, ACell, AExpansionRow, ARow, ATable, ATableHeader, ATableModal, TableDataStore };
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,OAAO,KAAK,MAAM,wBAAwB,CAAA;AAC1C,OAAO,aAAa,MAAM,gCAAgC,CAAA;AAC1D,OAAO,IAAI,MAAM,uBAAuB,CAAA;AACxC,OAAO,MAAM,MAAM,yBAAyB,CAAA;AAC5C,OAAO,YAAY,MAAM,+BAA+B,CAAA;AACxD,OAAO,WAAW,MAAM,8BAA8B,CAAA;AACtD,OAAO,cAAc,MAAM,cAAc,CAAA;AACzC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAE3F;;;;GAIG;AACH,iBAAS,OAAO,CAAC,GAAG,EAAE,GAAG,QAOxB;AAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type TableColumn = {
|
|
2
|
+
name: string;
|
|
3
|
+
align?: CanvasTextAlign;
|
|
4
|
+
edit?: boolean;
|
|
5
|
+
label?: string;
|
|
6
|
+
type?: string;
|
|
7
|
+
width?: string;
|
|
8
|
+
cellComponent?: string;
|
|
9
|
+
cellComponentProps?: Record<string, any>;
|
|
10
|
+
modalComponent?: string;
|
|
11
|
+
modalComponentProps?: Record<string, any>;
|
|
12
|
+
format?: string | ((value: any) => any);
|
|
13
|
+
mask?: (value: any) => any;
|
|
14
|
+
};
|
|
15
|
+
export type TableConfig = {
|
|
16
|
+
view?: 'list' | 'tree' | 'list-expansion';
|
|
17
|
+
fullWidth?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type TableDisplay = {
|
|
20
|
+
childrenOpen?: boolean;
|
|
21
|
+
expanded?: boolean;
|
|
22
|
+
indent?: number;
|
|
23
|
+
isParent?: boolean;
|
|
24
|
+
isRoot?: boolean;
|
|
25
|
+
modified?: boolean;
|
|
26
|
+
open?: boolean;
|
|
27
|
+
parent?: number;
|
|
28
|
+
};
|
|
29
|
+
export type TableRow = {
|
|
30
|
+
[key: string]: any;
|
|
31
|
+
indent?: number;
|
|
32
|
+
parent?: number;
|
|
33
|
+
};
|
|
34
|
+
export type TableModal = {
|
|
35
|
+
colIndex?: number;
|
|
36
|
+
event?: string;
|
|
37
|
+
left?: number;
|
|
38
|
+
parent?: HTMLElement;
|
|
39
|
+
rowIndex?: number;
|
|
40
|
+
top?: number;
|
|
41
|
+
visible?: boolean;
|
|
42
|
+
width?: string;
|
|
43
|
+
component?: string;
|
|
44
|
+
componentProps?: Record<string, any>;
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IAEZ,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACxC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEzC,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAAA;IACzC,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CACpC,CAAA"}
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import"https://fonts.googleapis.com/css2?family=Arimo:ital,wght@0,400..700;1,400..700&display=swap";.list-index{color:var(--header-text-color);font-weight:700;padding-left:var(--atable-row-padding);padding-right:1em;text-align:center;-webkit-user-select:none;user-select:none;width:var(--
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Arimo:ital,wght@0,400..700;1,400..700&display=swap";.list-index{color:var(--header-text-color);font-weight:700;padding-left:var(--atable-row-padding);padding-right:1em;text-align:center;-webkit-user-select:none;user-select:none;width:var(--722e5e5e);max-width:var(--722e5e5e)}.atable #header-index{width:var(--722e5e5e);max-width:var(--722e5e5e)}.list-index{color:var(--header-text-color);font-weight:700;padding-left:var(--atable-row-padding);padding-right:1em;text-align:center;-webkit-user-select:none;user-select:none;width:var(--17f6dbaa);max-width:var(--17f6dbaa)}.atable #header-index{width:var(--17f6dbaa);max-width:var(--17f6dbaa)}.list-index{color:var(--header-text-color);font-weight:700;padding-left:var(--atable-row-padding);padding-right:1em;text-align:center;-webkit-user-select:none;user-select:none;width:var(--315a3b84);max-width:var(--315a3b84)}.atable #header-index{width:var(--315a3b84);max-width:var(--315a3b84)}.list-index{color:var(--header-text-color);font-weight:700;padding-left:var(--atable-row-padding);padding-right:1em;text-align:center;-webkit-user-select:none;user-select:none;width:var(--5eb5a868);max-width:var(--5eb5a868)}.atable #header-index{width:var(--5eb5a868);max-width:var(--5eb5a868)}.list-index{color:var(--header-text-color);font-weight:700;padding-left:var(--atable-row-padding);padding-right:1em;text-align:center;-webkit-user-select:none;user-select:none;width:var(--78ba2ab2);max-width:var(--78ba2ab2)}.atable #header-index{width:var(--78ba2ab2);max-width:var(--78ba2ab2)}:root{--primary-color: #0098c9;--primary-text-color: #ffffff;--brand-color: #202a44;--gray-5: #f2f2f2;--gray-10: #e6e6e6;--gray-20: #cccccc;--gray-50: #808080;--gray-60: #666666;--gray-80: #333333;--brand-danger: #e63c28;--brand-success: #155724;--row-color-zebra-light: #eeeeee;--row-color-zebra-dark: #dddddd;--focus-cell-background: #ffffff;--focus-cell-outline: #000000;--cell-border-color: #ffffff;--cell-text-color: #3a3c41;--active-cell-background: #ffffff;--active-cell-outline: #e6a92d;--row-border-color: var(--gray-20);--header-border-color: #ffffff;--header-text-color: var(--gray-20);--row-number-background-color: #ffffff;--input-border-color: var(--gray-20);--input-label-color: var(--gray-60);--input-active-border-color: #000000;--input-active-label-color: #000000;--required-border: #e63c28;--font-size: 10px;--font-family: Arimo, Arial, sans-serif;--table-font-size: 16px;--atable-font-family: "Arimo", sans-serif;--atable-row-padding: 0px;--atable-row-height: 1.5em;--btn-color: white;--btn-border: #cccccc;--btn-hover: #f2f2f2;--btn-label-color: black}.aform{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:baseline;padding:1rem;border:1px solid var(--gray-5);border-left:4px solid var(--gray-5);margin-bottom:1rem}.aform__form-element{min-width:30%;flex-basis:32%;border:1px solid transparent;padding:0;margin:0;margin-right:.5rem;margin-bottom:.5rem;display:grid;position:relative;margin:.5rem 0}.aform__input-field{outline:1px solid transparent;border:1px solid var(--input-border-color);font-size:1rem;padding:.5rem .25rem .25rem .5rem;margin:0;border-radius:0;box-sizing:border-box;width:100%;position:relative;color:var(--cell-text-color)}.aform__field-label{color:var(--input-label-color);display:inline-block;position:absolute;padding:0 .25rem;margin:0rem;z-index:2;font-size:.7rem;font-weight:300;letter-spacing:.05rem;width:auto;box-sizing:border-box;background:#fff;margin:0;border:1px solid var(--input-border-color);grid-row:1;top:0;left:10px;border:none;transform:translateY(-50%)}p.error{display:block;display:inline-block;display:none;padding:0rem 0rem 0rem .5rem;margin:.5rem 0 .25rem 0rem;border:1px solid transparent;width:100%;width:auto;color:var(--brand-danger);font-size:.8rem;position:absolute;right:0;top:0;background:#fff;padding:.25rem;transform:translate(-1rem,-50%);margin:0}.aform__input-field:focus{border:1px solid var(--input-active-border-color)}.aform__input-field:focus+.aform__field-label{color:var(--input-active-label-color)}.aform__checkbox{cursor:pointer;width:auto}.aform__checkbox:checked{accent-color:var(--primary-color);border:1px solid black}.aform__checkbox-container{width:100%;display:inline-block;text-align:left}.aform__checkbox-container input{width:auto}.aform__checkbox-container:hover+.aform__field-label{color:var(--input-active-label-color)}.aform-primary-action{font-size:100%;text-align:center;min-height:2em;padding:.25rem 1rem;border:1px solid var(--primary-color);color:var(--primary-text-color);background-color:var(--primary-color);outline:2px solid var(--primary-text-color);transition:outline-offset .2s ease;font-size:var(--font-size);margin:.5ch}.aform-primary-action:hover,.aform-primary-action:active{outline:2px solid var(--primary-text-color);outline-offset:-4px;transition:outline-offset .2s ease}tr:focus{background-color:#add8e6;outline:auto}.atable{font-family:var(--atable-font-family);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:var(--table-font-size);border-collapse:collapse}.row-index{color:var(--header-text-color);font-weight:700;text-align:center;-webkit-user-select:none;user-select:none;width:2ch}.expandable-row{border-top:1px solid var(--row-border-color);height:var(--atable-row-height);border-left:4px solid var(--row-border-color)}.expanded-row{border-bottom:1px solid var(--row-border-color);border-top:1px solid var(--row-border-color)}.expanded-row-content{border-bottom:1px solid var(--row-border-color);border-top:1px solid var(--row-border-color);padding:1.5rem}.atable__cell{border-radius:0;box-sizing:border-box;margin:0;outline:none;box-shadow:none;color:var(--cell-text-color);text-overflow:ellipsis;overflow:hidden;padding-left:.5ch!important;padding-right:.5ch;padding-top:var(--atable-row-padding);padding-bottom:var(--atable-row-padding);border-spacing:0px;border-collapse:collapse}.atable__cell:focus,.atable__cell:focus-within{background-color:var(--focus-cell-background);outline-width:2px;outline-style:solid;outline-color:var(--focus-cell-outline);box-shadow:none;min-height:1.15em;max-height:1.15em;overflow:hidden}.table-row{border-top:1px solid var(--row-border-color);height:var(--atable-row-height)}.list-index{color:var(--header-text-color);font-weight:700;padding-left:var(--atable-row-padding);padding-right:1em;text-align:center;-webkit-user-select:none;user-select:none;width:var(--469fca09);max-width:var(--469fca09)}.tree-index{color:var(--header-text-color);font-weight:700;text-align:center;-webkit-user-select:none;user-select:none;width:2ch}.atable #header-index{width:var(--469fca09);max-width:var(--469fca09)}.atable th{border-width:0px;border-style:solid;border-radius:0;padding-left:.5ch;padding-right:.5ch;padding-top:var(--atable-row-padding);padding-bottom:var(--atable-row-padding);color:var(--gray-60);height:var(--atable-row-height);font-weight:300;letter-spacing:.05rem}.atable th:focus{outline:none}.amodal{z-index:100;position:absolute;background-color:var(--row-color-zebra-dark)}.login-container{width:100%;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;font-family:var(--font-family)}.account-container{width:100%;margin-left:auto;margin-top:.5rem;margin-right:auto;display:flex;flex-direction:column;justify-content:center}.account-header{display:flex;flex-direction:column;text-align:center;margin-top:.5rem}#account-title{font-size:1.5rem;line-height:2rem;font-weight:600;letter-spacing:-.025em;margin:0}#account-subtitle{font-size:.875rem;line-height:1.25rem;margin:1rem}.login-form-container{display:grid;gap:.5rem}.login-form-element{display:grid;margin:.5rem 0}.login-field{padding:.5rem .25rem .25rem .5rem;outline:1px solid transparent;border:1px solid var(--input-border-color);border-radius:.25rem}.login-field:focus{border:1px solid black}.btn{background-color:var(--btn-color);color:var(--btn-label-color);border:1px solid var(--btn-border);margin:.5rem 0;padding:.25rem;position:relative;cursor:pointer}.btn:hover{background-color:var(--btn-hover)}.btn:disabled{background-color:light-dark(rgba(239,239,239,.3),rgba(59,59,59,.3));color:light-dark(rgb(84,84,84),rgb(170,170,170))}.disabled{opacity:.5}.loading-icon{animation:spin 1s linear infinite forwards;display:inline-block;margin-right:.2rem;line-height:0;font-size:1rem;position:relative;top:.2rem}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/atable",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": {
|
|
@@ -17,50 +17,47 @@
|
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
|
20
|
-
"import":
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/atable/src/index.d.ts",
|
|
22
|
+
"default": "./dist/atable.js"
|
|
23
|
+
},
|
|
21
24
|
"require": "./dist/atable.umd.cjs"
|
|
22
25
|
},
|
|
23
26
|
"./styles": "./dist/style.css"
|
|
24
27
|
},
|
|
25
|
-
"
|
|
26
|
-
"module": "dist/atable.js",
|
|
27
|
-
"umd": "dist/atable.umd.cjs",
|
|
28
|
-
"types": "src/index",
|
|
28
|
+
"typings": "./dist/atable/src/index.d.ts",
|
|
29
29
|
"files": [
|
|
30
30
|
"dist/*",
|
|
31
31
|
"src/*"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
34
|
+
"@vueuse/components": "^10.11.0",
|
|
35
|
+
"@vueuse/core": "^10.11.0",
|
|
36
|
+
"uuid": "^10.0.0",
|
|
37
|
+
"vue": "^3.4.31",
|
|
38
|
+
"@stonecrop/utilities": "0.2.25",
|
|
39
|
+
"@stonecrop/themes": "0.2.25"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"@typescript-eslint/
|
|
44
|
-
"@
|
|
42
|
+
"@microsoft/api-documenter": "^7.25.3",
|
|
43
|
+
"@rushstack/heft": "^0.66.18",
|
|
44
|
+
"@types/uuid": "^10.0.0",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
|
46
|
+
"@typescript-eslint/parser": "^7.14.1",
|
|
47
|
+
"@vitejs/plugin-vue": "^5.0.5",
|
|
45
48
|
"@vitest/coverage-istanbul": "^1.6.0",
|
|
46
49
|
"@vitest/ui": "^1.6.0",
|
|
47
50
|
"@vue/test-utils": "^2.4.6",
|
|
48
|
-
"
|
|
49
|
-
"@vueuse/core": "^10.9.0",
|
|
50
|
-
"cypress": "^12.11.0",
|
|
51
|
+
"cypress": "^13.11.0",
|
|
51
52
|
"eslint-config-prettier": "^8.8.0",
|
|
52
53
|
"eslint-plugin-vue": "^9.11.1",
|
|
53
54
|
"eslint": "^8.40.0",
|
|
54
|
-
"histoire": "^0.17.17",
|
|
55
55
|
"jsdom": "^24.0.0",
|
|
56
|
-
"typescript": "^5.
|
|
57
|
-
"vite": "^5.2
|
|
56
|
+
"typescript": "^5.5.2",
|
|
57
|
+
"vite": "^5.3.2",
|
|
58
58
|
"vitest": "^1.6.0",
|
|
59
|
-
"vue-router": "^4",
|
|
60
|
-
"
|
|
61
|
-
},
|
|
62
|
-
"peerDependencies": {
|
|
63
|
-
"@stonecrop/aform": "0.2.23"
|
|
59
|
+
"vue-router": "^4.4.0",
|
|
60
|
+
"stonecrop-rig": "0.2.22"
|
|
64
61
|
},
|
|
65
62
|
"publishConfig": {
|
|
66
63
|
"access": "public"
|
|
@@ -69,14 +66,12 @@
|
|
|
69
66
|
"node": ">=20.11.0"
|
|
70
67
|
},
|
|
71
68
|
"scripts": {
|
|
72
|
-
"prepublish": "
|
|
73
|
-
"build": "
|
|
69
|
+
"prepublish": "heft build && vite build && rushx docs",
|
|
70
|
+
"build": "heft build && vite build && rushx docs",
|
|
74
71
|
"dev": "vite",
|
|
72
|
+
"docs": "api-documenter markdown -i temp -o ../docs/atable",
|
|
75
73
|
"lint": "eslint . --ext .ts,.vue",
|
|
76
74
|
"preview": "vite preview",
|
|
77
|
-
"story:build": "histoire build",
|
|
78
|
-
"story:dev": "histoire dev",
|
|
79
|
-
"story:preview": "histoire preview",
|
|
80
75
|
"test": "vitest",
|
|
81
76
|
"test:coverage": "vitest run --coverage",
|
|
82
77
|
"test:ui": "vitest --ui"
|
package/src/components/ACell.vue
CHANGED
|
@@ -69,7 +69,7 @@ const displayValue = computed(() => {
|
|
|
69
69
|
}
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
-
const handleInput = (
|
|
72
|
+
const handleInput = () => {
|
|
73
73
|
if (tableData.columns[props.colIndex].mask) {
|
|
74
74
|
// TODO: add masking to cell values
|
|
75
75
|
// tableData.columns[props.colIndex].mask(event)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<tr v-bind="$attrs" ref="rowEl" :tabindex="tabIndex" class="expandable-row">
|
|
3
3
|
<td :tabIndex="-1" @click="tableData.toggleRowExpand(rowIndex)" class="row-index">
|
|
4
|
-
{{
|
|
4
|
+
{{ rowExpandSymbol }}
|
|
5
5
|
</td>
|
|
6
6
|
<slot name="row" />
|
|
7
7
|
</tr>
|
|
@@ -13,12 +13,11 @@
|
|
|
13
13
|
</template>
|
|
14
14
|
|
|
15
15
|
<script setup lang="ts">
|
|
16
|
-
import { TableRow } from 'types'
|
|
17
|
-
import { inject, ref } from 'vue'
|
|
18
|
-
|
|
19
16
|
import { type KeypressHandlers, useKeyboardNav } from '@stonecrop/utilities'
|
|
17
|
+
import { computed, inject, ref } from 'vue'
|
|
20
18
|
|
|
21
19
|
import TableDataStore from '.'
|
|
20
|
+
import type { TableRow } from '@/types'
|
|
22
21
|
|
|
23
22
|
const props = withDefaults(
|
|
24
23
|
defineProps<{
|
|
@@ -37,9 +36,9 @@ const tableData = inject<TableDataStore>(props.tableid)
|
|
|
37
36
|
const rowEl = ref<HTMLTableRowElement>(null)
|
|
38
37
|
const rowExpanded = ref<HTMLDivElement>(null)
|
|
39
38
|
|
|
40
|
-
const
|
|
39
|
+
const rowExpandSymbol = computed(() => {
|
|
41
40
|
return tableData.display[props.rowIndex].expanded ? '▼' : '►'
|
|
42
|
-
}
|
|
41
|
+
})
|
|
43
42
|
|
|
44
43
|
if (props.addNavigation) {
|
|
45
44
|
const handlers: KeypressHandlers = {
|
package/src/components/ARow.vue
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
:tabIndex="-1"
|
|
11
11
|
class="tree-index"
|
|
12
12
|
@click="toggleRowExpand(rowIndex)">
|
|
13
|
-
{{
|
|
13
|
+
{{ rowExpandSymbol }}
|
|
14
14
|
</td>
|
|
15
15
|
</slot>
|
|
16
16
|
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
</template>
|
|
21
21
|
|
|
22
22
|
<script setup lang="ts">
|
|
23
|
-
import { TableRow } from 'types'
|
|
24
|
-
import { computed, inject, ref } from 'vue'
|
|
25
23
|
import { type KeypressHandlers, useKeyboardNav, defaultKeypressHandlers } from '@stonecrop/utilities'
|
|
24
|
+
import { computed, inject, ref } from 'vue'
|
|
26
25
|
|
|
27
26
|
import TableDataStore from '.'
|
|
27
|
+
import type { TableRow } from '@/types'
|
|
28
28
|
|
|
29
29
|
const props = withDefaults(
|
|
30
30
|
defineProps<{
|
|
@@ -42,31 +42,6 @@ const props = withDefaults(
|
|
|
42
42
|
|
|
43
43
|
const tableData = inject<TableDataStore>(props.tableid)
|
|
44
44
|
const rowEl = ref<HTMLTableRowElement>(null)
|
|
45
|
-
const numberedRowWidth = tableData.numberedRowWidth.value
|
|
46
|
-
|
|
47
|
-
const getRowExpandSymbol = () => {
|
|
48
|
-
if (tableData.config.view !== 'tree') {
|
|
49
|
-
return ''
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (tableData.display[props.rowIndex].isRoot) {
|
|
53
|
-
if (tableData.display[props.rowIndex].childrenOpen) {
|
|
54
|
-
return '-'
|
|
55
|
-
} else {
|
|
56
|
-
return '+'
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (tableData.display[props.rowIndex].isParent) {
|
|
61
|
-
if (tableData.display[props.rowIndex].childrenOpen) {
|
|
62
|
-
return '-'
|
|
63
|
-
} else {
|
|
64
|
-
return '+'
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
return ''
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
45
|
|
|
71
46
|
const isRowVisible = computed(() => {
|
|
72
47
|
return (
|
|
@@ -76,6 +51,18 @@ const isRowVisible = computed(() => {
|
|
|
76
51
|
)
|
|
77
52
|
})
|
|
78
53
|
|
|
54
|
+
const rowExpandSymbol = computed(() => {
|
|
55
|
+
if (tableData.config.view !== 'tree') {
|
|
56
|
+
return ''
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (tableData.display[props.rowIndex].isRoot || tableData.display[props.rowIndex].isParent) {
|
|
60
|
+
return tableData.display[props.rowIndex].childrenOpen ? '-' : '+'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return ''
|
|
64
|
+
})
|
|
65
|
+
|
|
79
66
|
const toggleRowExpand = (rowIndex: number) => {
|
|
80
67
|
tableData.toggleRowExpand(rowIndex)
|
|
81
68
|
}
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
<slot name="body" :data="tableData">
|
|
12
12
|
<ARow
|
|
13
13
|
v-for="(row, rowIndex) in tableData.rows"
|
|
14
|
-
:key="row.id
|
|
14
|
+
:key="row.id"
|
|
15
15
|
:row="row"
|
|
16
16
|
:rowIndex="rowIndex"
|
|
17
17
|
:tableid="tableData.id">
|
|
18
18
|
<ACell
|
|
19
19
|
v-for="(col, colIndex) in tableData.columns"
|
|
20
|
-
:key="
|
|
20
|
+
:key="col.name"
|
|
21
21
|
:tableid="tableData.id"
|
|
22
22
|
:col="col"
|
|
23
23
|
spellcheck="false"
|
|
@@ -60,16 +60,15 @@
|
|
|
60
60
|
</template>
|
|
61
61
|
|
|
62
62
|
<script setup lang="ts">
|
|
63
|
-
import { v4 } from 'uuid'
|
|
64
|
-
import { nextTick, provide, watch } from 'vue'
|
|
65
63
|
import { vOnClickOutside } from '@vueuse/components'
|
|
64
|
+
import { nextTick, provide, watch } from 'vue'
|
|
66
65
|
|
|
67
|
-
import { TableColumn, TableConfig, TableRow } from 'types'
|
|
68
66
|
import TableDataStore from '.'
|
|
69
67
|
import ACell from '@/components/ACell.vue'
|
|
70
68
|
import ARow from '@/components/ARow.vue'
|
|
71
69
|
import ATableHeader from '@/components/ATableHeader.vue'
|
|
72
70
|
import ATableModal from '@/components/ATableModal.vue'
|
|
71
|
+
import type { TableColumn, TableConfig, TableRow } from '@/types'
|
|
73
72
|
|
|
74
73
|
const props = withDefaults(
|
|
75
74
|
defineProps<{
|
|
@@ -158,7 +157,7 @@ const closeModal = (event: MouseEvent) => {
|
|
|
158
157
|
}
|
|
159
158
|
}
|
|
160
159
|
|
|
161
|
-
window.addEventListener('keydown',
|
|
160
|
+
window.addEventListener('keydown', (event: KeyboardEvent) => {
|
|
162
161
|
if (event.key === 'Escape') {
|
|
163
162
|
if (tableData.modal.visible) {
|
|
164
163
|
tableData.modal.visible = false
|
|
@@ -167,8 +166,9 @@ window.addEventListener('keydown', async (event: KeyboardEvent) => {
|
|
|
167
166
|
const $parent = tableData.modal.parent
|
|
168
167
|
if ($parent) {
|
|
169
168
|
// wait for the modal to close before focusing
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
void nextTick().then(() => {
|
|
170
|
+
$parent.focus()
|
|
171
|
+
})
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<thead id="resizable" v-if="columns.length">
|
|
3
3
|
<tr class="atable-header-row" tabindex="-1">
|
|
4
4
|
<th v-if="tableData.zeroColumn" id="header-index" />
|
|
5
|
-
<th v-for="(column, colKey) in columns" :key="
|
|
5
|
+
<th v-for="(column, colKey) in columns" :key="column.name" tabindex="-1" :style="getHeaderCellStyle(column)">
|
|
6
6
|
<slot>{{ column.label || String.fromCharCode(colKey + 97).toUpperCase() }}</slot>
|
|
7
7
|
</th>
|
|
8
8
|
</tr>
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
<script setup lang="ts">
|
|
13
13
|
import { CSSProperties, inject } from 'vue'
|
|
14
14
|
|
|
15
|
-
import { TableColumn, TableConfig } from 'types'
|
|
16
15
|
import TableDataStore from '.'
|
|
16
|
+
import type { TableColumn, TableConfig } from '@/types'
|
|
17
17
|
|
|
18
18
|
const props = defineProps<{
|
|
19
19
|
columns: TableColumn[]
|
|
@@ -23,7 +23,6 @@ const props = defineProps<{
|
|
|
23
23
|
|
|
24
24
|
const tableData = inject<TableDataStore>(props.tableid)
|
|
25
25
|
|
|
26
|
-
const numberedRowWidth = tableData.numberedRowWidth.value
|
|
27
26
|
const getHeaderCellStyle = (column: TableColumn): CSSProperties => ({
|
|
28
27
|
minWidth: column.width || '40ch',
|
|
29
28
|
textAlign: column.align || 'center',
|
|
@@ -5,22 +5,17 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import { inject } from 'vue'
|
|
8
|
+
// import { inject } from 'vue'
|
|
9
9
|
|
|
10
|
-
import TableDataStore from '.'
|
|
10
|
+
// import TableDataStore from '.'
|
|
11
11
|
|
|
12
|
-
const props = defineProps<{
|
|
12
|
+
/* const props = */ defineProps<{
|
|
13
13
|
colIndex?: number
|
|
14
14
|
rowIndex?: number
|
|
15
15
|
tableid?: string
|
|
16
16
|
}>()
|
|
17
17
|
|
|
18
|
-
const tableData = inject<TableDataStore>(props.tableid)
|
|
19
|
-
|
|
20
|
-
const handleInput = (event: Event) => {
|
|
21
|
-
event.stopPropagation()
|
|
22
|
-
}
|
|
23
|
-
|
|
18
|
+
// const tableData = inject<TableDataStore>(props.tableid)
|
|
24
19
|
// const cellBackgroundColor = computed(() => {
|
|
25
20
|
// if (tableData.modal.parent) {
|
|
26
21
|
// let computedstyle = window.getComputedStyle(tableData.modal.parent)
|
|
@@ -29,6 +24,10 @@ const handleInput = (event: Event) => {
|
|
|
29
24
|
// return 'inherit'
|
|
30
25
|
// }
|
|
31
26
|
// })
|
|
27
|
+
|
|
28
|
+
const handleInput = (event: Event) => {
|
|
29
|
+
event.stopPropagation()
|
|
30
|
+
}
|
|
32
31
|
</script>
|
|
33
32
|
|
|
34
33
|
<style>
|
package/src/components/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { v4 } from 'uuid'
|
|
2
2
|
import { computed, reactive } from 'vue'
|
|
3
3
|
|
|
4
|
-
import type { TableDisplay, TableRow, TableColumn, TableConfig, TableModal } from '
|
|
4
|
+
import type { TableDisplay, TableRow, TableColumn, TableConfig, TableModal } from '@/types'
|
|
5
5
|
|
|
6
6
|
export default class TableDataStore {
|
|
7
7
|
id: string
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,13 @@ import ATable from '@/components/ATable.vue'
|
|
|
7
7
|
import ATableHeader from '@/components/ATableHeader.vue'
|
|
8
8
|
import ATableModal from '@/components/ATableModal.vue'
|
|
9
9
|
import TableDataStore from './components'
|
|
10
|
+
export type { TableColumn, TableConfig, TableDisplay, TableRow, TableModal } from '@/types'
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Install all ATable components
|
|
14
|
+
* @param app - Vue app instance
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
11
17
|
function install(app: App /* options */) {
|
|
12
18
|
app.component('ACell', ACell)
|
|
13
19
|
app.component('AExpansionRow', AExpansionRow)
|
package/src/themes/default.css
CHANGED