Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions dev/vscode-table/shift-table-columns.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,21 @@
<h1>Basic example</h1>
<main>
<vscode-demo>
<vscode-table
class="table"
columns='["100px", "200px"]'
min-column-width="50"
resizable
style="margin-left: 200px"
>
<vscode-table class="table" resizable style="margin-left: 200px">
<vscode-table-header slot="header">
<vscode-table-header-cell min-width="30"
<vscode-table-header-cell min-width="30" preferred-width="25"
>Id</vscode-table-header-cell
>
<vscode-table-header-cell min-width="70"
<vscode-table-header-cell min-width="70" preferred-width="50"
>First name</vscode-table-header-cell
>
<vscode-table-header-cell min-width="70"
<vscode-table-header-cell min-width="70" preferred-width="75"
>Last name</vscode-table-header-cell
>
<vscode-table-header-cell min-width="70"
<vscode-table-header-cell min-width="70" preferred-width="auto"
>Email</vscode-table-header-cell
>
<vscode-table-header-cell min-width="70"
<vscode-table-header-cell min-width="70" preferred-width="auto"
>Company</vscode-table-header-cell
>
</vscode-table-header>
Expand Down Expand Up @@ -101,6 +95,28 @@ <h1>Basic example</h1>
</vscode-table-body>
</vscode-table>
</vscode-demo>
<button id="bt-empty">empty table body</button>
<button id="bt-append">Append row</button>
<script type="module">
const btEmpty = document.querySelector('#bt-empty');
const btAppend = document.querySelector('#bt-append');

btEmpty.addEventListener('click', () => {
document.querySelector('vscode-table-body').innerHTML = '';
});

btAppend.addEventListener('click', () => {
const row = document.createElement('vscode-table-row');
row.innerHTML = `
<vscode-table-cell>cell</vscode-table-cell>
<vscode-table-cell>cell</vscode-table-cell>
<vscode-table-cell>cell</vscode-table-cell>
<vscode-table-cell>cell</vscode-table-cell>
<vscode-table-cell>cell</vscode-table-cell>
`;
document.querySelector('vscode-table-body').append(row);
});
</script>
</main>
</body>
</html>
2 changes: 1 addition & 1 deletion src/includes/VscElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const warn = (message: string, componentInstance?: VscElement) => {
console.warn(`${prefix}${message}\n%o`, componentInstance);
} else {
// eslint-disable-next-line no-console
console.warn(`${message}\n%o`, componentInstance);
console.warn(`${prefix}${message}`);
}
};

Expand Down
13 changes: 12 additions & 1 deletion src/vscode-table-body/vscode-table-body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,24 @@ export class VscodeTableBody extends VscElement {
@property({reflect: true})
override role = 'rowgroup';

private _handleSlotChange() {
/** @internal */
this.dispatchEvent(
new Event('vsc-table-body-slot-changed', {bubbles: true})
);
}

override render(): TemplateResult {
return html` <slot></slot> `;
return html` <slot @slotchange=${this._handleSlotChange}></slot> `;
}
}

declare global {
interface HTMLElementTagNameMap {
'vscode-table-body': VscodeTableBody;
}

interface GlobalEventHandlersEventMap {
'vsc-table-body-slot-changed': Event;
}
}
19 changes: 19 additions & 0 deletions src/vscode-table-header-cell/vscode-table-header-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export type VscTableChangeMinColumnWidthEvent = CustomEvent<{
propertyValue: string;
}>;

export type VscTableChangePreferredColumnWidthEvent = CustomEvent<{
columnIndex: number;
propertyValue: string;
}>;

/**
* @tag vscode-table-header-cell
*
Expand All @@ -22,6 +27,9 @@ export class VscodeTableHeaderCell extends VscElement {
@property({attribute: 'min-width'})
minWidth = '0';

@property({attribute: 'preferred-width'})
preferredWidth = 'auto';

/** @internal */
@property({type: Number})
index = -1;
Expand All @@ -40,6 +48,16 @@ export class VscodeTableHeaderCell extends VscElement {
}) as VscTableChangeMinColumnWidthEvent
);
}

if (changedProperties.has('preferredWidth') && this.index > -1) {
/** @internal */
this.dispatchEvent(
new CustomEvent('vsc-table-change-preferred-column-width', {
detail: {columnIndex: this.index, propertyValue: this.preferredWidth},
bubbles: true,
}) as VscTableChangePreferredColumnWidthEvent
);
}
}

override render(): TemplateResult {
Expand All @@ -58,5 +76,6 @@ declare global {

interface GlobalEventHandlersEventMap {
'vsc-table-change-min-column-width': VscTableChangeMinColumnWidthEvent;
'vsc-table-change-preferred-column-width': VscTableChangePreferredColumnWidthEvent;
}
}
61 changes: 61 additions & 0 deletions src/vscode-table/initial-column-widths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {percent, Percent} from '../includes/sizes.js';

const PERCENT_FULL = percent(100);

export type ColumnWidth = Percent | 'auto';

export interface Column {
preferredWidth: ColumnWidth;
minWidth: Percent;
}

export function calculateInitialWidths(columns: Column[]): Percent[] {
const finalWidths: Percent[] = columns.map(
(c) =>
typeof c.preferredWidth === 'number'
? percent(Math.max(c.preferredWidth, c.minWidth))
: percent(0) // auto placeholder
);

const autoIndices = columns
.map((c, i) => (c.preferredWidth === 'auto' ? i : -1))
.filter((i) => i >= 0);

const totalMinWidth = columns.reduce(
(sum, c) => percent(sum + c.minWidth),
percent(0)
);

if (totalMinWidth > PERCENT_FULL) {
const scale = PERCENT_FULL / totalMinWidth;
return columns.map((c) => percent(c.minWidth * scale));
}

const fixedWidthSum = finalWidths.reduce(
(sum, w) => percent(sum + w),
percent(0)
);
const remainingSpace = percent(PERCENT_FULL - fixedWidthSum);

if (remainingSpace > 0 && autoIndices.length > 0) {
const extraPerAuto = remainingSpace / autoIndices.length;
for (const i of autoIndices) {
finalWidths[i] = percent(Math.max(columns[i].minWidth, extraPerAuto));
}
return finalWidths;
}

if (autoIndices.length > 0) {
for (const i of autoIndices) {
finalWidths[i] = columns[i].minWidth;
}
return finalWidths;
}

if (remainingSpace > 0 && autoIndices.length === 0) {
const scale = PERCENT_FULL / fixedWidthSum;
return finalWidths.map((w) => percent(w * scale));
}

return finalWidths;
}
Loading
Loading