@revolist/revogrid
Version:
Virtual reactive data grid spreadsheet component - RevoGrid.
584 lines (583 loc) • 23.8 kB
JavaScript
/*!
* Built by Revolist OU ❤️
*/
import { h, } from "@stencil/core";
import keyBy from "lodash/keyBy";
import { getItemByIndex } from "../../store/index";
import { HEADER_ACTUAL_ROW_CLASS, HEADER_ROW_CLASS } from "../../utils/consts";
import HeaderRenderer from "./header-renderer";
import GroupHeaderRenderer from "./header-group-renderer";
export class RevogrHeaderComponent {
constructor() {
/**
* Grouping depth, how many levels of grouping
*/
this.groupingDepth = 0;
/**
* Extra properties to pass into header renderer, such as vue or react components to handle parent
*/
this.additionalData = {};
}
onResize({ width }, index) {
const col = this.colData[index];
const event = this.beforeResize.emit([
Object.assign(Object.assign({}, col), { size: width || undefined }),
]);
if (event.defaultPrevented) {
return;
}
this.headerresize.emit({ [index]: width || 0 });
}
onResizeGroup(changedX, startIndex, endIndex) {
const sizes = {};
const cols = keyBy(this.viewportCol.get('items'), 'itemIndex');
const change = changedX / (endIndex - startIndex + 1);
for (let i = startIndex; i <= endIndex; i++) {
const item = cols[i];
if (item) {
sizes[i] = item.size + change;
}
}
this.headerresize.emit(sizes);
}
componentDidRender() {
this.afterHeaderRender.emit(this.providers);
}
render() {
var _a;
const cols = this.viewportCol.get('items');
const range = (_a = this.selectionStore) === null || _a === void 0 ? void 0 : _a.get('range');
const { cells } = this.renderHeaderColumns(cols, range);
const groupRow = this.renderGroupingColumns();
return [
h("div", { key: 'a8d57270f4758b454fb4900808453e0c4663c91c', class: "group-rgRow" }, groupRow),
h("div", { key: '41a270ff6bde9943a81d9c46482f2a40312afb50', class: `${HEADER_ROW_CLASS} ${HEADER_ACTUAL_ROW_CLASS}` }, cells),
];
}
renderHeaderColumns(cols, range) {
const cells = [];
for (let rgCol of cols) {
const colData = this.colData[rgCol.itemIndex];
const props = {
range,
column: rgCol,
data: Object.assign(Object.assign({}, colData), { index: rgCol.itemIndex, providers: this.providers }),
canFilter: !!this.columnFilter,
canResize: this.canResize,
active: this.resizeHandler,
additionalData: this.additionalData,
onResize: e => this.onResize(e, rgCol.itemIndex),
onDblClick: e => this.headerdblClick.emit(e),
onClick: e => this.initialHeaderClick.emit(e),
};
const event = this.beforeHeaderRender.emit(props);
if (!event.defaultPrevented) {
cells.push(h(HeaderRenderer, Object.assign({}, event.detail)));
}
}
return { cells };
}
renderGroupingColumns() {
var _a;
const groupRow = [];
for (let i = 0; i < this.groupingDepth; i++) {
if (this.groups[i]) {
for (let group of this.groups[i]) {
const groupStartIndex = (_a = group.indexes[0]) !== null && _a !== void 0 ? _a : -1;
if (groupStartIndex > -1) {
const groupEndIndex = groupStartIndex + group.indexes.length - 1;
const groupStart = getItemByIndex(this.dimensionCol.state, groupStartIndex).start;
const groupEnd = getItemByIndex(this.dimensionCol.state, groupEndIndex).end;
const props = {
providers: this.providers,
start: groupStart,
end: groupEnd,
group,
active: this.resizeHandler,
canResize: this.canResize,
additionalData: this.additionalData,
onResize: e => {
var _a;
return this.onResizeGroup((_a = e.changedX) !== null && _a !== void 0 ? _a : 0, groupStartIndex, groupEndIndex);
},
};
const event = this.beforeGroupHeaderRender.emit(props);
if (!event.defaultPrevented) {
groupRow.push(h(GroupHeaderRenderer, Object.assign({}, event.detail)));
}
}
}
}
groupRow.push(h("div", { class: `${HEADER_ROW_CLASS} group` }));
}
return groupRow;
}
get providers() {
return {
type: this.type,
readonly: this.readonly,
data: this.colData,
viewport: this.viewportCol,
dimension: this.dimensionCol,
selection: this.selectionStore,
};
}
static get is() { return "revogr-header"; }
static get originalStyleUrls() {
return {
"$": ["revogr-header-style.scss"]
};
}
static get styleUrls() {
return {
"$": ["revogr-header-style.css"]
};
}
static get properties() {
return {
"viewportCol": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "Observable<ViewportState>",
"resolved": "ViewportState",
"references": {
"Observable": {
"location": "import",
"path": "../../utils",
"id": "src/utils/index.ts::Observable",
"referenceLocation": "Observable"
},
"ViewportState": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::ViewportState",
"referenceLocation": "ViewportState"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Viewport X"
},
"getter": false,
"setter": false
},
"dimensionCol": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "Observable<DimensionSettingsState>",
"resolved": "DimensionSettingsState",
"references": {
"Observable": {
"location": "import",
"path": "../../utils",
"id": "src/utils/index.ts::Observable",
"referenceLocation": "Observable"
},
"DimensionSettingsState": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::DimensionSettingsState",
"referenceLocation": "DimensionSettingsState"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Dimension settings X"
},
"getter": false,
"setter": false
},
"selectionStore": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "Observable<SelectionStoreState>",
"resolved": "{ range: RangeArea | null; tempRange: RangeArea | null; tempRangeType: string | null; focus: Cell | null; edit: EditCellStore | null; lastCell: Cell | null; nextFocus: Cell | null; }",
"references": {
"Observable": {
"location": "import",
"path": "../../utils",
"id": "src/utils/index.ts::Observable",
"referenceLocation": "Observable"
},
"SelectionStoreState": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::SelectionStoreState",
"referenceLocation": "SelectionStoreState"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Selection, range, focus"
},
"getter": false,
"setter": false
},
"groups": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "Groups",
"resolved": "{ [x: number]: Group[]; }",
"references": {
"Groups": {
"location": "import",
"path": "@store",
"id": "src/store/index.ts::Groups",
"referenceLocation": "Groups"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Column groups"
},
"getter": false,
"setter": false
},
"groupingDepth": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Grouping depth, how many levels of grouping"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "grouping-depth",
"defaultValue": "0"
},
"readonly": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Readonly mode"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "readonly"
},
"canResize": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "If columns can be resized"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "can-resize"
},
"resizeHandler": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "ResizeProps['active']",
"resolved": "(\"r\" | \"b\" | \"rt\" | \"lt\" | \"rb\" | \"lb\" | \"l\" | \"t\")[]",
"references": {
"ResizeProps": {
"location": "import",
"path": "./resizable.directive",
"id": "src/components/header/resizable.directive.tsx::ResizeProps",
"referenceLocation": "ResizeProps"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Defines resize position"
},
"getter": false,
"setter": false
},
"colData": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "ColumnRegular[]",
"resolved": "ColumnRegular<ColumnProp, DataType<any, ColumnProp>>[]",
"references": {
"ColumnRegular": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::ColumnRegular",
"referenceLocation": "ColumnRegular"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Columns - defines an array of grid columns."
},
"getter": false,
"setter": false
},
"columnFilter": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Column filter"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "column-filter"
},
"type": {
"type": "string",
"mutable": false,
"complexType": {
"original": "DimensionCols | 'rowHeaders'",
"resolved": "\"colPinEnd\" | \"colPinStart\" | \"rgCol\" | \"rowHeaders\"",
"references": {
"DimensionCols": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::DimensionCols",
"referenceLocation": "DimensionCols"
}
}
},
"required": true,
"optional": false,
"docs": {
"tags": [],
"text": "Column type"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "type"
},
"additionalData": {
"type": "any",
"mutable": false,
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Extra properties to pass into header renderer, such as vue or react components to handle parent"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "additional-data",
"defaultValue": "{}"
}
};
}
static get events() {
return [{
"method": "initialHeaderClick",
"name": "beforeheaderclick",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "On initial header click"
},
"complexType": {
"original": "InitialHeaderClick",
"resolved": "{ index: number; originalEvent: MouseEvent; column: ColumnRegular<ColumnProp, DataType<any, ColumnProp>>; providers: ProvidersColumns<DimensionCols | \"rowHeaders\">; }",
"references": {
"InitialHeaderClick": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::InitialHeaderClick",
"referenceLocation": "InitialHeaderClick"
}
}
}
}, {
"method": "headerresize",
"name": "headerresize",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "On header resize"
},
"complexType": {
"original": "ViewSettingSizeProp",
"resolved": "{ [x: string]: number; }",
"references": {
"ViewSettingSizeProp": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::ViewSettingSizeProp",
"referenceLocation": "ViewSettingSizeProp"
}
}
}
}, {
"method": "beforeResize",
"name": "beforeheaderresize",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "On before header resize"
},
"complexType": {
"original": "ColumnRegular[]",
"resolved": "ColumnRegular<ColumnProp, DataType<any, ColumnProp>>[]",
"references": {
"ColumnRegular": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::ColumnRegular",
"referenceLocation": "ColumnRegular"
}
}
}
}, {
"method": "headerdblClick",
"name": "headerdblclick",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "On header double click"
},
"complexType": {
"original": "InitialHeaderClick",
"resolved": "{ index: number; originalEvent: MouseEvent; column: ColumnRegular<ColumnProp, DataType<any, ColumnProp>>; providers: ProvidersColumns<DimensionCols | \"rowHeaders\">; }",
"references": {
"InitialHeaderClick": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::InitialHeaderClick",
"referenceLocation": "InitialHeaderClick"
}
}
}
}, {
"method": "beforeHeaderRender",
"name": "beforeheaderrender",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Before each header cell render function. Allows to override cell properties"
},
"complexType": {
"original": "HeaderRenderProps",
"resolved": "{ column: VirtualPositionItem; additionalData: any; data: ColumnTemplateProp<ColumnProp>; range?: RangeArea | null | undefined; canResize?: boolean | undefined; canFilter?: boolean | undefined; onResize?(e: ResizeEvent): void; onClick?(data: InitialHeaderClick): void; onDblClick?(data: InitialHeaderClick): void; } & Partial<Pick<ResizeProps, \"active\">>",
"references": {
"HeaderRenderProps": {
"location": "import",
"path": "./header-renderer",
"id": "src/components/header/header-renderer.tsx::HeaderRenderProps",
"referenceLocation": "HeaderRenderProps"
}
}
}
}, {
"method": "beforeGroupHeaderRender",
"name": "beforegroupheaderrender",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Before each group header cell render function. Allows to override group header cell properties"
},
"complexType": {
"original": "HeaderGroupRendererProps",
"resolved": "{ start: number; end: number; group: Group; providers: ProvidersColumns<DimensionCols | \"rowHeaders\">; additionalData: any; canResize?: boolean | undefined; onResize?(e: ResizeEvent): void; } & Partial<Pick<ResizeProps, \"active\">>",
"references": {
"HeaderGroupRendererProps": {
"location": "import",
"path": "./header-group-renderer",
"id": "src/components/header/header-group-renderer.tsx::HeaderGroupRendererProps",
"referenceLocation": "HeaderGroupRendererProps"
}
}
}
}, {
"method": "afterHeaderRender",
"name": "afterheaderrender",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "After all header cells rendered. Finalizes cell rendering."
},
"complexType": {
"original": "ProvidersColumns",
"resolved": "ProvidersColumns<DimensionCols | \"rowHeaders\">",
"references": {
"ProvidersColumns": {
"location": "import",
"path": "@type",
"id": "src/types/index.ts::ProvidersColumns",
"referenceLocation": "ProvidersColumns"
}
}
}
}];
}
static get elementRef() { return "element"; }
}