Skip to content

Commit d9f9bfb

Browse files
committed
chore(DataTable): updated the way items is rendered
1 parent 8e8cf72 commit d9f9bfb

5 files changed

Lines changed: 329 additions & 29 deletions

File tree

playground/DataTable.html

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,30 @@
2828
.container h3 {
2929
margin-bottom: 12px;
3030
}
31+
32+
.event-log {
33+
margin-top: 12px;
34+
border: 1px solid var(--sgds-border-color-default);
35+
border-radius: 8px;
36+
background: var(--sgds-bg-subtle);
37+
padding: 10px;
38+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
39+
font-size: 12px;
40+
line-height: 1.5;
41+
max-height: 220px;
42+
overflow: auto;
43+
white-space: pre-wrap;
44+
}
45+
46+
.cell-inline {
47+
display: inline-flex;
48+
align-items: center;
49+
gap: 8px;
50+
}
51+
52+
.badge-click-target {
53+
cursor: pointer;
54+
}
3155
</style>
3256

3357
<div class="theme-toggle">
@@ -510,6 +534,103 @@ <h3>Row Colspan Example (5 data rows, 5 columns)</h3>
510534
</sgds-data-table>
511535
</div>
512536

537+
<!-- Interactive slotted controls demo -->
538+
<div class="container">
539+
<h3>Interactive Slotted Content (Event Hooks)</h3>
540+
<sgds-data-table id="interactive-table" currentPage="1" dataLength="2" itemsPerPage="5" layout="fixed">
541+
<sgds-data-table-row>
542+
<sgds-data-table-head width="80">ID</sgds-data-table-head>
543+
<sgds-data-table-head width="170">Dropdown</sgds-data-table-head>
544+
<sgds-data-table-head width="120">Overflow</sgds-data-table-head>
545+
<sgds-data-table-head width="120">Button</sgds-data-table-head>
546+
<sgds-data-table-head width="220">Combobox</sgds-data-table-head>
547+
<sgds-data-table-head width="220">Input</sgds-data-table-head>
548+
<sgds-data-table-head width="180">Badges</sgds-data-table-head>
549+
</sgds-data-table-row>
550+
551+
<sgds-data-table-row>
552+
<sgds-data-table-cell>1</sgds-data-table-cell>
553+
<sgds-data-table-cell>
554+
<sgds-dropdown id="table-dropdown-1">
555+
<sgds-button slot="toggler" variant="secondary" size="sm">
556+
Action
557+
<sgds-icon name="chevron-down" slot="rightIcon"></sgds-icon>
558+
</sgds-button>
559+
<sgds-dropdown-item><a href="#" data-action="open">Open</a></sgds-dropdown-item>
560+
<sgds-dropdown-item><a href="#" data-action="archive">Archive</a></sgds-dropdown-item>
561+
</sgds-dropdown>
562+
</sgds-data-table-cell>
563+
<sgds-data-table-cell>
564+
<sgds-overflow-menu id="table-overflow-1" size="sm">
565+
<sgds-dropdown-item>View</sgds-dropdown-item>
566+
<sgds-dropdown-item>Edit</sgds-dropdown-item>
567+
<sgds-dropdown-item>Delete</sgds-dropdown-item>
568+
</sgds-overflow-menu>
569+
</sgds-data-table-cell>
570+
<sgds-data-table-cell>
571+
<sgds-button id="table-button-1" size="sm">Run</sgds-button>
572+
</sgds-data-table-cell>
573+
<sgds-data-table-cell>
574+
<sgds-combo-box id="table-combobox-1" placeholder="Select" clearable>
575+
<sgds-combo-box-option value="opt-a">Option A</sgds-combo-box-option>
576+
<sgds-combo-box-option value="opt-b">Option B</sgds-combo-box-option>
577+
<sgds-combo-box-option value="opt-c">Option C</sgds-combo-box-option>
578+
</sgds-combo-box>
579+
</sgds-data-table-cell>
580+
<sgds-data-table-cell>
581+
<sgds-input id="table-input-1" placeholder="Type and blur"></sgds-input>
582+
</sgds-data-table-cell>
583+
<sgds-data-table-cell>
584+
<div class="cell-inline" id="table-badges-1">
585+
<sgds-badge class="badge-click-target" variant="primary" outlined>New</sgds-badge>
586+
<sgds-badge class="badge-click-target" variant="success" outlined>Synced</sgds-badge>
587+
</div>
588+
</sgds-data-table-cell>
589+
</sgds-data-table-row>
590+
591+
<sgds-data-table-row>
592+
<sgds-data-table-cell>2</sgds-data-table-cell>
593+
<sgds-data-table-cell>
594+
<sgds-dropdown id="table-dropdown-2">
595+
<sgds-button slot="toggler" variant="secondary" size="sm">
596+
Action
597+
<sgds-icon name="chevron-down" slot="rightIcon"></sgds-icon>
598+
</sgds-button>
599+
<sgds-dropdown-item><a href="#" data-action="approve">Approve</a></sgds-dropdown-item>
600+
<sgds-dropdown-item><a href="#" data-action="reject">Reject</a></sgds-dropdown-item>
601+
</sgds-dropdown>
602+
</sgds-data-table-cell>
603+
<sgds-data-table-cell>
604+
<sgds-overflow-menu id="table-overflow-2" size="sm">
605+
<sgds-dropdown-item>Copy</sgds-dropdown-item>
606+
<sgds-dropdown-item>Export</sgds-dropdown-item>
607+
</sgds-overflow-menu>
608+
</sgds-data-table-cell>
609+
<sgds-data-table-cell>
610+
<sgds-button id="table-button-2" size="sm" variant="outline">Retry</sgds-button>
611+
</sgds-data-table-cell>
612+
<sgds-data-table-cell>
613+
<sgds-combo-box id="table-combobox-2" placeholder="Choose" clearable>
614+
<sgds-combo-box-option value="p1">Priority 1</sgds-combo-box-option>
615+
<sgds-combo-box-option value="p2">Priority 2</sgds-combo-box-option>
616+
<sgds-combo-box-option value="p3">Priority 3</sgds-combo-box-option>
617+
</sgds-combo-box>
618+
</sgds-data-table-cell>
619+
<sgds-data-table-cell>
620+
<sgds-input id="table-input-2" value="Editable"></sgds-input>
621+
</sgds-data-table-cell>
622+
<sgds-data-table-cell>
623+
<div class="cell-inline" id="table-badges-2">
624+
<sgds-badge class="badge-click-target" variant="warning" outlined>Review</sgds-badge>
625+
<sgds-badge class="badge-click-target" variant="danger" outlined>Alert</sgds-badge>
626+
</div>
627+
</sgds-data-table-cell>
628+
</sgds-data-table-row>
629+
</sgds-data-table>
630+
631+
<div id="interactive-event-log" class="event-log">Event log ready.</div>
632+
</div>
633+
513634
<script type="module">
514635
const nightModeToggle = document.getElementById("night-mode-toggle");
515636

@@ -630,14 +751,133 @@ <h3>Row Colspan Example (5 data rows, 5 columns)</h3>
630751
};
631752

632753
serverTable.addEventListener("sgds-page-change", async () => {
754+
console.log("[DataTable playground] server-table sgds-page-change", {
755+
currentPage: Number(serverTable.currentPage || 1)
756+
});
633757
await loadServerPage(Number(serverTable.currentPage || 1));
634758
});
635759

636760
serverTable.addEventListener("sgds-sort", async event => {
761+
console.log("[DataTable playground] server-table sgds-sort", {
762+
key: event.detail.key,
763+
direction: event.detail.direction,
764+
currentPage: Number(serverTable.currentPage || 1)
765+
});
637766
serverSort.key = event.detail.key;
638767
serverSort.direction = event.detail.direction;
639768
await loadServerPage(Number(serverTable.currentPage || 1));
640769
});
641770

771+
const eventLog = document.getElementById("interactive-event-log");
772+
const safeStringify = value => {
773+
const seen = new WeakSet();
774+
775+
return JSON.stringify(value, (_key, currentValue) => {
776+
if (typeof currentValue === "object" && currentValue !== null) {
777+
if (seen.has(currentValue)) return "[Circular]";
778+
seen.add(currentValue);
779+
780+
if (currentValue instanceof HTMLElement) {
781+
return {
782+
tagName: currentValue.tagName.toLowerCase(),
783+
id: currentValue.id || undefined,
784+
className: currentValue.className || undefined
785+
};
786+
}
787+
}
788+
789+
if (typeof currentValue === "function") return "[Function]";
790+
return currentValue;
791+
});
792+
};
793+
794+
const appendEventLog = (source, eventName, detail) => {
795+
if (!eventLog) return;
796+
797+
const renderedDetail = detail ? safeStringify(detail) : "-";
798+
const timestamp = new Date().toLocaleTimeString();
799+
const nextLine = `[${timestamp}] ${source} :: ${eventName} :: ${renderedDetail}`;
800+
const lines = eventLog.textContent ? eventLog.textContent.split("\n") : [];
801+
lines.push(nextLine);
802+
eventLog.textContent = lines.slice(-18).join("\n");
803+
eventLog.scrollTop = eventLog.scrollHeight;
804+
};
805+
806+
const bindLoggedEvent = (selector, eventName, source, mapDetail) => {
807+
const element = document.querySelector(selector);
808+
if (!element) return;
809+
element.addEventListener(eventName, event => {
810+
const detail = mapDetail ? mapDetail(event) : event.detail;
811+
console.log("[DataTable playground] interactive event", {
812+
source,
813+
eventName,
814+
detail,
815+
target: event.target
816+
});
817+
appendEventLog(source, eventName, detail);
818+
});
819+
};
820+
821+
bindLoggedEvent("#table-dropdown-1", "sgds-select", "dropdown-1", event => ({
822+
selectedText: event.target?.textContent?.trim() || ""
823+
}));
824+
bindLoggedEvent("#table-dropdown-2", "sgds-select", "dropdown-2", event => ({
825+
selectedText: event.target?.textContent?.trim() || ""
826+
}));
827+
828+
bindLoggedEvent("#table-overflow-1", "sgds-select", "overflow-1");
829+
bindLoggedEvent("#table-overflow-2", "sgds-select", "overflow-2");
830+
831+
bindLoggedEvent("#table-button-1", "click", "button-1");
832+
bindLoggedEvent("#table-button-2", "click", "button-2");
833+
834+
bindLoggedEvent("#table-combobox-1", "sgds-change", "combobox-1", event => ({
835+
value: event.currentTarget?.value || ""
836+
}));
837+
bindLoggedEvent("#table-combobox-1", "sgds-select", "combobox-1", event => ({
838+
value: event.currentTarget?.value || ""
839+
}));
840+
bindLoggedEvent("#table-combobox-2", "sgds-change", "combobox-2", event => ({
841+
value: event.currentTarget?.value || ""
842+
}));
843+
bindLoggedEvent("#table-combobox-2", "sgds-select", "combobox-2", event => ({
844+
value: event.currentTarget?.value || ""
845+
}));
846+
847+
bindLoggedEvent("#table-input-1", "sgds-input", "input-1", event => ({
848+
value: event.currentTarget?.value || ""
849+
}));
850+
bindLoggedEvent("#table-input-1", "sgds-change", "input-1", event => ({
851+
value: event.currentTarget?.value || ""
852+
}));
853+
bindLoggedEvent("#table-input-2", "sgds-input", "input-2", event => ({
854+
value: event.currentTarget?.value || ""
855+
}));
856+
bindLoggedEvent("#table-input-2", "sgds-change", "input-2", event => ({
857+
value: event.currentTarget?.value || ""
858+
}));
859+
860+
bindLoggedEvent("#table-badges-1", "click", "badges-1", event => ({
861+
text: event.target?.textContent?.trim() || ""
862+
}));
863+
bindLoggedEvent("#table-badges-2", "click", "badges-2", event => ({
864+
text: event.target?.textContent?.trim() || ""
865+
}));
866+
867+
const interactiveTable = document.getElementById("interactive-table");
868+
interactiveTable?.addEventListener("sgds-change", event => {
869+
const sourceElement = event.target;
870+
const detail = {
871+
sourceTag: sourceElement?.tagName?.toLowerCase?.() || "unknown",
872+
sourceId: sourceElement?.id || "",
873+
value: sourceElement?.value,
874+
checked: sourceElement?.checked,
875+
detail: event.detail
876+
};
877+
878+
console.log("[DataTable playground] interactive-table delegated sgds-change", detail);
879+
appendEventLog("interactive-table", "sgds-change", detail);
880+
});
881+
642882
loadServerPage(1);
643883
</script>

src/components/DataTable/sgds-data-table-cell.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { nothing } from "lit";
1+
import { css, html } from "lit";
22
import SgdsElement from "../../base/sgds-element";
33
import { property } from "lit/decorators.js";
44

@@ -8,14 +8,23 @@ import { property } from "lit/decorators.js";
88
* @slot default - Content to display inside the cell.
99
*/
1010
export class SgdsDataTableCell extends SgdsElement {
11+
static styles = [
12+
...SgdsElement.styles,
13+
css`
14+
:host {
15+
display: contents;
16+
}
17+
`
18+
];
19+
1120
/** Number of columns this cell spans. */
1221
@property({ type: Number, reflect: true }) colspan: number | undefined;
1322

1423
/** Number of rows this cell spans. */
1524
@property({ type: Number, reflect: true }) rowspan: number | undefined;
1625

1726
render() {
18-
return nothing;
27+
return html`<slot></slot>`;
1928
}
2029
}
2130

src/components/DataTable/sgds-data-table-head.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { nothing } from "lit";
1+
import { css, html } from "lit";
22
import SgdsElement from "../../base/sgds-element";
33
import { property } from "lit/decorators.js";
44

@@ -9,6 +9,15 @@ import { property } from "lit/decorators.js";
99
*
1010
*/
1111
export class SgdsDataTableHead extends SgdsElement {
12+
static styles = [
13+
...SgdsElement.styles,
14+
css`
15+
:host {
16+
display: contents;
17+
}
18+
`
19+
];
20+
1221
/** Sets the column width. */
1322
@property({ type: String, reflect: true }) width: string | undefined;
1423

@@ -43,7 +52,7 @@ export class SgdsDataTableHead extends SgdsElement {
4352
}
4453

4554
render() {
46-
return nothing;
55+
return html`<slot></slot>`;
4756
}
4857
}
4958

0 commit comments

Comments
 (0)