Skip to content

Commit 87b9ba1

Browse files
committed
Fixes bug when <table-saw> in shadow root
1 parent 28baeea commit 87b9ba1

File tree

2 files changed

+76
-19
lines changed

2 files changed

+76
-19
lines changed

demo.html

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,62 @@ <h2>Console logs an error when missing `th` elements</h2>
373373
</tbody>
374374
</table>
375375
</table-saw>
376+
377+
<h2>Hidden in details</h2>
378+
<details>
379+
<summary>Expand to show</summary>
380+
<table-saw breakpoint="(max-width: 30em)">
381+
<table>
382+
<thead>
383+
<tr>
384+
<th>Pricing Strategies</th>
385+
<th>Hourly-based</th>
386+
<th>Project-based</th>
387+
</tr>
388+
</thead>
389+
<tbody>
390+
<tr>
391+
<td><strong>Ideal projects or clients</strong></td>
392+
<td>
393+
Small projects, or projects subject to change due to timelines
394+
or requirements.
395+
</td>
396+
<td>Projects with clear expectations and scope.</td>
397+
</tr>
398+
</tbody>
399+
</table>
400+
</table-saw>
401+
</details>
402+
403+
<h2>Shadow root</h2>
404+
<script type="module">
405+
const host = document.querySelector("#myHost");
406+
const shadow = host.attachShadow({ mode: "open" });
407+
const div = document.createElement("div");
408+
div.innerHTML = `<table-saw breakpoint="(max-width: 30em)">
409+
<table>
410+
<thead>
411+
<tr>
412+
<th>Pricing Strategies</th>
413+
<th>Hourly-based</th>
414+
<th>Project-based</th>
415+
</tr>
416+
</thead>
417+
<tbody>
418+
<tr>
419+
<td><strong>Ideal projects or clients</strong></td>
420+
<td>
421+
Small projects, or projects subject to change due to timelines
422+
or requirements.
423+
</td>
424+
<td>Projects with clear expectations and scope.</td>
425+
</tr>
426+
</tbody>
427+
</table>
428+
</table-saw>`;
429+
shadow.appendChild(div);
430+
</script>
431+
<div id="myHost"></div>
376432
</main>
377433
</body>
378434
</html>

table-saw.js

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class Tablesaw extends HTMLElement {
2-
static identifiers = {};
2+
static dupes = {};
33

44
constructor() {
55
super();
@@ -34,43 +34,43 @@ class Tablesaw extends HTMLElement {
3434

3535
generateCss(breakpoint, type) {
3636
return `
37-
table-saw.${this._identifier} {
37+
table-saw.${this._id} {
3838
display: block;
3939
${type === "container" ? "container-type: inline-size;" : ""}
4040
}
4141
4242
@${type} ${breakpoint} {
43-
table-saw.${this._identifier} thead :is(th, td) {
43+
table-saw.${this._id} thead :is(th, td) {
4444
position: absolute;
4545
height: 1px;
4646
width: 1px;
4747
overflow: hidden;
4848
clip: rect(1px, 1px, 1px, 1px);
4949
}
50-
table-saw.${this._identifier} :is(tbody, tfoot) tr {
50+
table-saw.${this._id} :is(tbody, tfoot) tr {
5151
display: block;
5252
}
53-
table-saw.${this._identifier} :is(tbody, tfoot) :is(th, td):before {
53+
table-saw.${this._id} :is(tbody, tfoot) :is(th, td):before {
5454
font-weight: var(${this.props.bold});
5555
content: attr(${this.attrs.label});
5656
}
57-
table-saw.${this._identifier} :is(tbody, tfoot) :is(th, td) {
57+
table-saw.${this._id} :is(tbody, tfoot) :is(th, td) {
5858
display: grid;
5959
gap: 0 1em;
6060
grid-template-columns: var(${this.props.ratio}, ${this.defaults.ratio});
6161
}
62-
table-saw.${this._identifier}[${this.attrs.forceTextAlign}] :is(tbody, tfoot) :is(th, td) {
62+
table-saw.${this._id}[${this.attrs.forceTextAlign}] :is(tbody, tfoot) :is(th, td) {
6363
text-align: ${this.getAttribute(this.attrs.forceTextAlign) || "left"};
6464
}
65-
table-saw.${this._identifier}[${this.attrs.zeropad}] :is(tbody, tfoot) :is(th, td) {
65+
table-saw.${this._id}[${this.attrs.zeropad}] :is(tbody, tfoot) :is(th, td) {
6666
padding-left: 0;
6767
padding-right: 0;
6868
}
6969
}`;
7070
}
7171

7272
connectedCallback() {
73-
// Cut the mustard
73+
// Cut-the-mustard
7474
// https://caniuse.com/mdn-api_cssstylesheet_replacesync
7575
if(!("replaceSync" in CSSStyleSheet.prototype)) {
7676
return;
@@ -87,20 +87,20 @@ table-saw.${this._identifier} {
8787
let breakpoint = this.getAttribute(this.attrs.breakpoint) || this.getAttribute(this.attrs.breakpointBackwardsCompat) || this.defaults.breakpoint;
8888
let type = this.getAttribute(this.attrs.type) || "media";
8989

90-
this._identifier = `ts_${type.slice(0, 1)}${breakpoint.replace(/[^a-z0-9]/gi, "_")}`;
91-
this.classList.add(this._identifier);
90+
this._id = `ts_${type.slice(0, 1)}${breakpoint.replace(/[^a-z0-9]/gi, "_")}`;
91+
this.classList.add(this._id);
9292

93-
if(!Tablesaw.identifiers[this._identifier]) {
93+
if(!Tablesaw.dupes[this._id]) {
9494
let css = this.generateCss(breakpoint, type);
9595
sheet.replaceSync(css);
9696

97-
if(this.getRootNode().host.shadowRoot) {
98-
this.getRootNode().host.shadowRoot.adoptedStyleSheets.push(sheet);
99-
} else {
100-
document.adoptedStyleSheets.push(sheet);
101-
}
97+
let root = this.getRootNode();
98+
root.adoptedStyleSheets.push(sheet);
10299

103-
Tablesaw.identifiers[this._identifier] = true;
100+
// only add to global de-dupe if not a shadow root
101+
if(root.host && root !== root.host.shadowRoot) {
102+
Tablesaw.dupes[this._id] = true;
103+
}
104104
}
105105
}
106106

@@ -124,9 +124,10 @@ table-saw.${this._identifier} {
124124

125125
return label;
126126
});
127+
127128
if(labels.length === 0) {
128129
this._needsStylesheet = false;
129-
console.error("No `<th>` elements for Tablesaw were found:", this);
130+
console.error("No `<th>` elements found:", this);
130131
return;
131132
}
132133

0 commit comments

Comments
 (0)