diff --git a/apps/web/src/app/shared/grid/grid.types.ts b/apps/web/src/app/shared/grid/grid.types.ts
index 4c1ebe1..c9a845f 100644
--- a/apps/web/src/app/shared/grid/grid.types.ts
+++ b/apps/web/src/app/shared/grid/grid.types.ts
@@ -17,6 +17,8 @@ export interface GridColumn {
key: string;
title: string;
width?: string;
+ /** Alineación del texto de la columna (encabezado y celdas); por defecto, `right` en las numéricas y `left` en el resto. */
+ align?: 'left' | 'center' | 'right';
/** `number` se alinea a la derecha, se muestra con formato y se interpreta al salir de la celda. */
type?: 'text' | 'number';
/** Decimales fijos para `number` (importes: 2); sin él, hasta 3 sin ceros sobrantes. */
diff --git a/apps/web/src/app/shared/grid/lines-grid.css b/apps/web/src/app/shared/grid/lines-grid.css
index b3a6368..653ba42 100644
--- a/apps/web/src/app/shared/grid/lines-grid.css
+++ b/apps/web/src/app/shared/grid/lines-grid.css
@@ -36,9 +36,6 @@ th {
text-align: left;
white-space: nowrap;
}
-th.num {
- text-align: right;
-}
th.req::after {
content: ' *';
color: var(--err);
@@ -77,9 +74,6 @@ td.ro {
border: 1px solid transparent;
border-radius: var(--radius);
}
-.cell.num {
- text-align: right;
-}
.cell.mono {
font-family: ui-monospace, Menlo, Consolas, monospace;
}
diff --git a/apps/web/src/app/shared/grid/lines-grid.html b/apps/web/src/app/shared/grid/lines-grid.html
index b14fccd..09994af 100644
--- a/apps/web/src/app/shared/grid/lines-grid.html
+++ b/apps/web/src/app/shared/grid/lines-grid.html
@@ -15,7 +15,7 @@
| # |
@for (c of columns(); track c.key) {
- {{ c.title }} |
+ {{ c.title }} |
}
@if (!readonly()) {
Quitar |
@@ -35,6 +35,7 @@
type="text"
autocomplete="off"
[class.mono]="c.mono"
+ [style.text-align]="alignOf(c)"
[attr.data-r]="i"
[attr.data-c]="j"
[attr.aria-label]="c.title + ' de la línea ' + (i + 1)"
@@ -49,7 +50,7 @@
class="cell"
type="text"
autocomplete="off"
- [class.num]="c.type === 'number'"
+ [style.text-align]="alignOf(c)"
[class.mono]="c.mono"
[readOnly]="isReadonly(line, c)"
[attr.data-r]="i"
diff --git a/apps/web/src/app/shared/grid/lines-grid.spec.ts b/apps/web/src/app/shared/grid/lines-grid.spec.ts
index 908e66a..929bbd6 100644
--- a/apps/web/src/app/shared/grid/lines-grid.spec.ts
+++ b/apps/web/src/app/shared/grid/lines-grid.spec.ts
@@ -464,3 +464,29 @@ describe('LinesGrid: columnas bloqueadas', () => {
expect(el.querySelector('input[data-r="0"][data-c="0"]')!.readOnly).toBe(false);
});
});
+
+describe('LinesGrid: alineación de las columnas', () => {
+ it('por defecto las numéricas van a la derecha y el resto a la izquierda; `align` lo cambia', async () => {
+ await TestBed.configureTestingModule({
+ imports: [Host],
+ providers: [provideHttpClient(), provideHttpClientTesting()],
+ }).compileComponents();
+ const fixture = TestBed.createComponent(Host);
+ fixture.componentInstance.columns = [
+ { key: 'Texto', title: 'Texto' },
+ { key: 'Cantidad', title: 'Cantidad', type: 'number' },
+ { key: 'Codigo', title: 'Código', align: 'right' },
+ { key: 'Centrado', title: 'Centrado', align: 'center' },
+ { key: 'Importe', title: 'Importe', type: 'number', align: 'left' },
+ ];
+ fixture.componentInstance.lines.set([{ Texto: 'a', Cantidad: 1, Codigo: 'x', Centrado: 'c', Importe: 5 }]);
+ fixture.detectChanges();
+ await fixture.whenStable();
+ fixture.detectChanges();
+ const el = fixture.nativeElement as HTMLElement;
+ const heads = [...el.querySelectorAll('thead th')].slice(1, -1).map((t) => t.style.textAlign);
+ const cells = [0, 1, 2, 3, 4].map((c) => el.querySelector(`input[data-r="0"][data-c="${c}"]`)!.style.textAlign);
+ expect(heads).toEqual(['left', 'right', 'right', 'center', 'left']);
+ expect(cells).toEqual(['left', 'right', 'right', 'center', 'left']);
+ });
+});
diff --git a/apps/web/src/app/shared/grid/lines-grid.ts b/apps/web/src/app/shared/grid/lines-grid.ts
index 448a7ea..43bd02b 100644
--- a/apps/web/src/app/shared/grid/lines-grid.ts
+++ b/apps/web/src/app/shared/grid/lines-grid.ts
@@ -70,6 +70,11 @@ export class LinesGrid {
});
protected readonly lookupMultiple = computed(() => !!this.lookupTarget()?.column.lookup?.multiple);
+ /** Alineación de una columna: la declarada o, si no, derecha para las numéricas e izquierda para las demás. */
+ protected alignOf(column: GridColumn): 'left' | 'center' | 'right' {
+ return column.align ?? (column.type === 'number' ? 'right' : 'left');
+ }
+
protected cellText(line: GridLine, column: GridColumn): string {
if (column.format) return column.format(line);
const value = line[column.key];