elements icon indicating copy to clipboard operation
elements copied to clipboard

Add rows to a table

Open qarlosalberto opened this issue 10 months ago • 5 comments

How can I add rows to a table without to break the style? I have this table:

    <vscode-table id="timingTable" class="scrollable-example" resizable zebra bordered-columns bordered-rows style="table-layout: fixed;"
        columns='["60px", "120px", "100px", "200px", "200px", "1fr", "1fr"]'>
        <vscode-table-header slot="header" style="user-select: none; cursor: pointer;">
            <vscode-table-header-cell id="h0">#
                <!-- <span class="sorting">&#8597;</span> -->
            </vscode-table-header-cell>

            <vscode-table-header-cell id="h1">Logic Levels
                <!-- <span class="sorting">&#8597;</span> -->
            </vscode-table-header-cell>

            <vscode-table-header-cell id="h2">Slack (ns)
                <!-- <span class="sorting">&#8597;</span> -->
            </vscode-table-header-cell>

            <vscode-table-header-cell id="h3">From Clock
                <!-- <span class="sorting">&#8597;</span> -->
            </vscode-table-header-cell>

            <vscode-table-header-cell id="h4">To Clock
                <!-- <span class="sorting">&#8597;</span> -->
            </vscode-table-header-cell>

            <vscode-table-header-cell id="h3">From
                <!-- <span class="sorting">&#8597;</span> -->
            </vscode-table-header-cell>

            <vscode-table-header-cell id="h4">To
                <!-- <span class="sorting">&#8597;</span> -->
            </vscode-table-header-cell>

        </vscode-table-header>

        <vscode-table-body slot="body" id="table-body">
        </vscode-table-body>
    </vscode-table>

If I have static rows the resize works fine. But if I add the rows from TypeScript:

const row = document.createElement('vscode-table-row') as HTMLElement;
const tableCell = document.createElement('vscode-table-cell');
tableCell.style.width = cell.width;
ow.appendChild(tableCell);

const tableBody = document.getElementById('table-body') as HTMLElement;
tableBody.appendChild(row);

It fails when I resize the window. The columns aren't aligned:

Image

qarlosalberto avatar Feb 25 '25 19:02 qarlosalberto

Could you provide me a minimal working example to reproduce te bug? Checkout the repo, install dependencies with npm ci and run the npm run start command. In the dev directory create a demo html. This is a good starting point: https://github.com/vscode-elements/elements/blob/main/dev/_template.html

Finally, please attach the demo HTML file to your comment on this ticket.

bendera avatar Feb 25 '25 23:02 bendera

It's really useful to use that approach to test it.

Here the example. The problem is in the onload(). This code fails:

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VSCode Elements</title>
    <link rel="stylesheet" href="/node_modules/@vscode/codicons/dist/codicon.css" id="vscode-codicon-stylesheet">
    <script type="module" src="/node_modules/@vscode-elements/webview-playground/dist/index.js"></script>
    <script type="module" src="/dist/main.js"></script>
</head>

<style>
    .tableContainer {
        margin: 0;
        padding: 16px;
        padding-top: 0;
        display: flex;
        flex-direction: column;
        overflow-y: hidden;
        ;
    }
</style>

<body>
    <h1>%%TITLE%%</h1>
    <vscode-demo>

        <div id="tableContainer">
            <vscode-table id="timingTable" class="scrollable-example" resizable responsive zebra bordered-columns
                bordered-rows style="table-layout: fixed;"
                columns='["60px", "120px", "100px", "200px", "200px", "1fr", "1fr"]'>
                <vscode-table-header slot="header" style="user-select: none; cursor: pointer;">
                    <vscode-table-header-cell id="h0">#
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h1">Logic Levels
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h2">Slack (ns)
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h3">From Clock
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h4">To Clock
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h3">From
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h4">To
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                </vscode-table-header>

                <vscode-table-body slot="body" id="table-body">
                </vscode-table-body>
            </vscode-table>
        </div>


    </vscode-demo>

    <script>
        const logEvents = (selector, eventType) => {
            document.querySelector(selector).addEventListener(eventType, (ev) => {
                console.log(ev);
            });
        };

        window.onload = function () {
            const tableBody = document.getElementById('table-body');
            tableBody.innerHTML = '';
            const rowList = [];
            for (let i = 0; i < 100; i++) {
                const row = document.createElement('vscode-table-row');

                const cell1 = document.createElement('vscode-table-cell');
                cell1.textContent = i;
                row.appendChild(cell1);

                const cell2 = document.createElement('vscode-table-cell');
                cell2.textContent = Math.random() * 100;
                row.appendChild(cell2);

                const cell3 = document.createElement('vscode-table-cell');
                cell3.textContent = Math.random() * 100;
                row.appendChild(cell3);

                const cell4 = document.createElement('vscode-table-cell');
                cell4.textContent = Math.random() * 100;
                row.appendChild(cell4);

                const cell5 = document.createElement('vscode-table-cell');
                cell5.textContent = Math.random() * 100;
                row.appendChild(cell5);

                const cell6 = document.createElement('vscode-table-cell');
                cell6.textContent = Math.random() * 100;
                row.appendChild(cell6);

                rowList.push(row);
            }
            rowList.forEach(row => {
                tableBody.appendChild(row);
            });
            console.log(4)
        };
    </script>

</body>

</html>

Image

And this code works fine (I have removed onload()):

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VSCode Elements</title>
    <link rel="stylesheet" href="/node_modules/@vscode/codicons/dist/codicon.css" id="vscode-codicon-stylesheet">
    <script type="module" src="/node_modules/@vscode-elements/webview-playground/dist/index.js"></script>
    <script type="module" src="/dist/main.js"></script>
</head>

<style>
    .tableContainer {
        margin: 0;
        padding: 16px;
        padding-top: 0;
        display: flex;
        flex-direction: column;
        overflow-y: hidden;
        ;
    }
</style>

<body>
    <h1>%%TITLE%%</h1>
    <vscode-demo>

        <div id="tableContainer">
            <vscode-table id="timingTable" class="scrollable-example" resizable responsive zebra bordered-columns
                bordered-rows style="table-layout: fixed;"
                columns='["60px", "120px", "100px", "200px", "200px", "1fr", "1fr"]'>
                <vscode-table-header slot="header" style="user-select: none; cursor: pointer;">
                    <vscode-table-header-cell id="h0">#
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h1">Logic Levels
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h2">Slack (ns)
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h3">From Clock
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h4">To Clock
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h3">From
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                    <vscode-table-header-cell id="h4">To
                        <!-- <span class="sorting">&#8597;</span> -->
                    </vscode-table-header-cell>

                </vscode-table-header>

                <vscode-table-body slot="body" id="table-body">
                </vscode-table-body>
            </vscode-table>
        </div>


    </vscode-demo>

    <script>
        const logEvents = (selector, eventType) => {
            document.querySelector(selector).addEventListener(eventType, (ev) => {
                console.log(ev);
            });
        };

        // window.onload = function () {
            const tableBody = document.getElementById('table-body');
            tableBody.innerHTML = '';
            const rowList = [];
            for (let i = 0; i < 100; i++) {
                const row = document.createElement('vscode-table-row');

                const cell1 = document.createElement('vscode-table-cell');
                cell1.textContent = i;
                row.appendChild(cell1);

                const cell2 = document.createElement('vscode-table-cell');
                cell2.textContent = Math.random() * 100;
                row.appendChild(cell2);

                const cell3 = document.createElement('vscode-table-cell');
                cell3.textContent = Math.random() * 100;
                row.appendChild(cell3);

                const cell4 = document.createElement('vscode-table-cell');
                cell4.textContent = Math.random() * 100;
                row.appendChild(cell4);

                const cell5 = document.createElement('vscode-table-cell');
                cell5.textContent = Math.random() * 100;
                row.appendChild(cell5);

                const cell6 = document.createElement('vscode-table-cell');
                cell6.textContent = Math.random() * 100;
                row.appendChild(cell6);

                rowList.push(row);
            }
            rowList.forEach(row => {
                tableBody.appendChild(row);
            });
            console.log(4)
        // };
    </script>

</body>

</html>

Image

qarlosalberto avatar Feb 26 '25 10:02 qarlosalberto

Not sure if this is a bug. Why if the table is resizable you can move the left vertical line in the first column? Currently the behavior is weird in this case.

(left vertical line)

Image

qarlosalberto avatar Feb 26 '25 15:02 qarlosalberto

Hi,

In your example code, I noticed that the header has 7 columns, but the body has only 6. Also, the columns property only accepts px and % units.

bendera avatar Apr 18 '25 11:04 bendera

Also have this issue. Apparently new cells don't get width style from the table. Fixed this by manually setting style="width: n%" on each cell.

bgenia avatar Aug 14 '25 19:08 bgenia