readonly spreadsheet cells
This commit is contained in:
parent
a69840c8ab
commit
d2feab9e04
|
|
@ -21,10 +21,16 @@
|
|||
folk-shape {
|
||||
background: rgb(187, 178, 178);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
width: fit-content;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<folk-space-projector>
|
||||
<h1>Spatial projection into a spreadsheet</h1>
|
||||
<folk-shape x="100" y="100" width="50" height="50"></folk-shape>
|
||||
<folk-shape x="100" y="200" width="50" height="50"></folk-shape>
|
||||
<folk-shape x="100" y="300" width="50" height="50" rotation="45"></folk-shape>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { css, PropertyValues } from '@lit/reactive-element';
|
||||
import { FolkBaseSet } from './folk-base-set';
|
||||
import { FolkShape } from './folk-shape';
|
||||
import { FolkSpreadsheet, FolkSpreadSheetCell, templateCells } from './folk-spreadsheet';
|
||||
import { CellTemplate, FolkSpreadsheet, FolkSpreadSheetCell, templateCells } from './folk-spreadsheet';
|
||||
import { DOMRectTransform } from './common/DOMRectTransform';
|
||||
|
||||
FolkShape.define();
|
||||
|
|
@ -120,17 +120,31 @@ export class FolkSpaceProjector extends FolkBaseSet {
|
|||
super.update(changedProperties);
|
||||
|
||||
if (changedProperties.has('sourceElements')) {
|
||||
const cells = templateCells(this.sourceElements.size, 5, {});
|
||||
this.#spreadsheet.setHTMLUnsafe(cells);
|
||||
const cells: Record<string, CellTemplate> = {};
|
||||
|
||||
let row = 1;
|
||||
for (const el of this.sourceElements) {
|
||||
if (!(el instanceof FolkShape)) {
|
||||
cells[`A${row}`] = { readonly: true };
|
||||
cells[`B${row}`] = { readonly: true };
|
||||
cells[`C${row}`] = { readonly: true };
|
||||
cells[`D${row}`] = { readonly: true };
|
||||
cells[`E${row}`] = { readonly: true };
|
||||
}
|
||||
row++;
|
||||
}
|
||||
|
||||
const html = templateCells(this.sourceElements.size, 5, cells);
|
||||
this.#spreadsheet.setHTMLUnsafe(html);
|
||||
}
|
||||
|
||||
if (this.sourcesMap.size !== this.sourceElements.size) return;
|
||||
|
||||
this.#lock = true;
|
||||
const rects = this.sourceRects;
|
||||
for (let i = 0; i < rects.length; i += 1) {
|
||||
const row = i + 1;
|
||||
const rect = rects[i];
|
||||
let row = 1;
|
||||
for (const el of this.sourceElements) {
|
||||
const rect = this.sourcesMap.get(el)!;
|
||||
|
||||
if (rect instanceof DOMRectTransform) {
|
||||
const { x, y } = rect.toParentSpace(rect.topLeft);
|
||||
this.#spreadsheet.getCell('A', row)!.expression = Math.round(x);
|
||||
|
|
@ -143,8 +157,11 @@ export class FolkSpaceProjector extends FolkBaseSet {
|
|||
this.#spreadsheet.getCell('B', row)!.expression = Math.round(rect.y);
|
||||
this.#spreadsheet.getCell('C', row)!.expression = Math.round(rect.width);
|
||||
this.#spreadsheet.getCell('D', row)!.expression = Math.round(rect.height);
|
||||
this.#spreadsheet.getCell('E', row)!.expression = 0;
|
||||
}
|
||||
row += 1;
|
||||
}
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
this.#lock = false;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -106,6 +106,10 @@ const styles = css`
|
|||
justify-content: end;
|
||||
}
|
||||
|
||||
::slotted(folk-cell[readonly]) {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
::slotted(folk-cell:hover) {
|
||||
outline: 1px solid #1b73e8;
|
||||
z-index: 5;
|
||||
|
|
@ -132,21 +136,30 @@ export function relativeColumnName(name: string, num: number) {
|
|||
return alphabet[index + num];
|
||||
}
|
||||
|
||||
export function templateCells(numberOfRows: number, numberOfColumns: number, expressions: Record<string, string> = {}) {
|
||||
const cells: string[] = [];
|
||||
export interface CellTemplate {
|
||||
expression?: string;
|
||||
readonly?: boolean;
|
||||
}
|
||||
|
||||
export function templateCells(numberOfRows: number, numberOfColumns: number, cells: Record<string, CellTemplate> = {}) {
|
||||
const html: string[] = [];
|
||||
for (let i = 0; i < numberOfRows; i += 1) {
|
||||
for (let j = 0; j < numberOfColumns; j += 1) {
|
||||
const column = getColumnName(j);
|
||||
const row = i + 1;
|
||||
const expression = expressions[`${column}${row}`];
|
||||
cells.push(
|
||||
`<folk-cell column="${column}" row="${row}" tabindex="0" ${
|
||||
expression ? `expression="${expression}"` : ''
|
||||
}></folk-cell>`
|
||||
const { expression, readonly } = cells[`${column}${row}`] || {};
|
||||
html.push(
|
||||
`<folk-cell
|
||||
column="${column}"
|
||||
row="${row}"
|
||||
tabindex="0"
|
||||
${expression ? `expression="${expression}"` : ''}
|
||||
${readonly ? 'readonly' : ''}
|
||||
></folk-cell>`
|
||||
);
|
||||
}
|
||||
}
|
||||
return cells.join('\n');
|
||||
return html.join('\n');
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
|
@ -168,7 +181,7 @@ export class FolkSpreadsheet extends HTMLElement {
|
|||
|
||||
#shadow = this.attachShadow({ mode: 'open' });
|
||||
|
||||
#textarea: HTMLTextAreaElement | null = null;
|
||||
#textarea!: HTMLTextAreaElement;
|
||||
|
||||
#editedCell: FolkSpreadSheetCell | null = null;
|
||||
|
||||
|
|
@ -326,7 +339,7 @@ export class FolkSpreadsheet extends HTMLElement {
|
|||
}
|
||||
|
||||
#focusTextarea(cell: FolkSpreadSheetCell) {
|
||||
if (this.#textarea === null) return;
|
||||
if (cell.readonly) return;
|
||||
this.#editedCell = cell;
|
||||
const gridColumn = getColumnIndex(cell.column) + 2;
|
||||
const gridRow = cell.row + 1;
|
||||
|
|
@ -339,7 +352,6 @@ export class FolkSpreadsheet extends HTMLElement {
|
|||
|
||||
#resetTextarea() {
|
||||
if (this.#editedCell === null) return;
|
||||
if (this.#textarea === null) return;
|
||||
this.#textarea.style.setProperty('--text-column', '0');
|
||||
this.#textarea.style.setProperty('--text-row', '0');
|
||||
this.#editedCell.expression = this.#textarea.value;
|
||||
|
|
@ -471,6 +483,13 @@ export class FolkSpreadSheetCell extends HTMLElement {
|
|||
this.#evaluate();
|
||||
}
|
||||
|
||||
get readonly() {
|
||||
return this.hasAttribute('readonly');
|
||||
}
|
||||
set readonly(readonly) {
|
||||
readonly ? this.setAttribute('readonly', '') : this.removeAttribute('readonly');
|
||||
}
|
||||
|
||||
#value: any;
|
||||
get value() {
|
||||
return this.#value;
|
||||
|
|
|
|||
Loading…
Reference in New Issue