diff --git a/README.md b/README.md index b33cdf1..4f8eba5 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,28 @@ The `Tabled` class will accept the following options: Also there are several CSS variables that can be overridden from your theme CSS, these include colors, spacing and column widths. The reference for these can be found at [tabled_core.scss](src/styles/tabled_core.scss). +## Custom controls + +By default Tabled generates its own previous/next buttons. If you'd rather supply your own, wrap the table in a `.tabled` element and add buttons with the `tabled__previous` and `tabled__next` classes. When Tabled initializes a table that is already inside a `.tabled` element, it adopts the existing markup instead of generating its own: it reuses your container, navigation, and buttons, wiring up the click handlers and managing their disabled state. Only the structural pieces you don't provide are created. + +```html +
+
+ + +
+ + +
+
+``` + +```js +new Tabled({ table: document.querySelector('.tabled table') }); +``` + +The `tabled__navigation` wrapper is optional, and you can provide just one of the two buttons; Tabled creates whatever is missing. Initialization itself is synchronous, the only asynchronous work happens afterwards via the scroll listener and resize observer that keep the fade and disabled states in sync. + ## Styling The styling for the tables is divided in two SASS files, `tabled_core.scss` which compiles to `styles.css` and `tabled_theme.scss` which compiles to `theme.css`. diff --git a/dist/tabled.d.ts b/dist/tabled.d.ts index e14aa1e..51f59e3 100644 --- a/dist/tabled.d.ts +++ b/dist/tabled.d.ts @@ -30,6 +30,7 @@ declare class Tabled { private wrap; private applyFade; private move; + private wireControl; private addTableControls; private checkConditions; } diff --git a/dist/tabled.js b/dist/tabled.js index 867f0ae..31f0d7f 100644 --- a/dist/tabled.js +++ b/dist/tabled.js @@ -34,8 +34,9 @@ class Tabled { options.index = Math.floor(Math.random() * 10000); } if (this.checkConditions(options.table)) { + const providedContainer = options.table.closest("." + Selectors.container); options.table.classList.add(Selectors.table); - this.wrap(options.table); + this.wrap(options.table, providedContainer); const wrapper = this.getWrapper(options.table); wrapper.setAttribute("id", "tabled-n" + options.index); this.adjustColumnsWidth(options); @@ -93,35 +94,40 @@ class Tabled { }); } } - wrap(table) { - const wrapper = document.createElement("div"); - wrapper.classList.add(Selectors.wrapper); + wrap(table, providedContainer) { + let wrapper = table.closest("." + Selectors.wrapper); + if (!wrapper) { + wrapper = document.createElement("div"); + wrapper.classList.add(Selectors.wrapper); + table.parentNode.insertBefore(wrapper, table); + wrapper.appendChild(table); + } wrapper.setAttribute("tabindex", "0"); - table.parentNode.insertBefore(wrapper, table); - wrapper.appendChild(table); - const container = document.createElement("div"); - container.classList.add(Selectors.container); - wrapper.parentNode.insertBefore(container, wrapper); - container.appendChild(wrapper); + if (!providedContainer) { + const container = document.createElement("div"); + container.classList.add(Selectors.container); + wrapper.parentNode.insertBefore(container, wrapper); + container.appendChild(wrapper); + } } applyFade(table) { const wrapper = this.getWrapper(table), container = wrapper.parentNode, previousButton = container.getElementsByClassName(Selectors.previous)[0], nextButton = container.getElementsByClassName(Selectors.next)[0]; if (wrapper.scrollLeft > 1) { container.classList.add(Selectors.fadeLeft); - previousButton.removeAttribute("disabled"); + previousButton === null || previousButton === void 0 ? void 0 : previousButton.removeAttribute("disabled"); } else { container.classList.remove(Selectors.fadeLeft); - previousButton.setAttribute("disabled", "disabled"); + previousButton === null || previousButton === void 0 ? void 0 : previousButton.setAttribute("disabled", "disabled"); } const width = wrapper.offsetWidth, scrollWidth = wrapper.scrollWidth; if (scrollWidth - wrapper.scrollLeft - width <= 1) { container.classList.remove(Selectors.fadeRight); - nextButton.setAttribute("disabled", "disabled"); + nextButton === null || nextButton === void 0 ? void 0 : nextButton.setAttribute("disabled", "disabled"); } else { container.classList.add(Selectors.fadeRight); - nextButton.removeAttribute("disabled"); + nextButton === null || nextButton === void 0 ? void 0 : nextButton.removeAttribute("disabled"); } } move(table, direction = "previous") { @@ -159,30 +165,48 @@ class Tabled { behavior: "smooth", }); } + wireControl(button, table, direction) { + button.classList.add("tabled__" + direction); + button.setAttribute("aria-label", direction + " table column"); + button.setAttribute("aria-controls", this.getWrapper(table).getAttribute("id")); + button.setAttribute("disabled", "disabled"); + button.setAttribute("type", "button"); + button.addEventListener("click", () => { + this.move(table, direction); + }); + } addTableControls(options) { const table = options.table; - const navigationContainer = document.createElement("div"); - navigationContainer.classList.add(Selectors.navigation); - ["previous", "next"].forEach((direction) => { - let button = document.createElement("button"); - button.classList.add("tabled__" + direction); - button.setAttribute("aria-label", direction + " table column"); - button.setAttribute("aria-controls", this.getWrapper(table).getAttribute("id")); - button.setAttribute("disabled", "disabled"); - button.setAttribute("type", "button"); - button.addEventListener("click", () => { - this.move(table, direction); - }); - navigationContainer.appendChild(button); - }); const tableContainer = this.getContainer(table); - if (tableContainer) { - tableContainer.prepend(navigationContainer); - } + if (!tableContainer) { + return; + } + let navigationContainer = tableContainer.querySelector("." + Selectors.navigation); + const ensureNavigation = () => { + if (!navigationContainer) { + navigationContainer = document.createElement("div"); + navigationContainer.classList.add(Selectors.navigation); + tableContainer.prepend(navigationContainer); + } + return navigationContainer; + }; + const directions = [ + { name: "previous", selector: Selectors.previous }, + { name: "next", selector: Selectors.next }, + ]; + directions.forEach(({ name, selector }) => { + let button = tableContainer.querySelector("." + selector); + if (!button) { + button = document.createElement("button"); + ensureNavigation().appendChild(button); + } + this.wireControl(button, table, name); + }); const caption = table.querySelector("caption"); if (caption) { caption.classList.add("visually-hidden"); - if (!caption.classList.contains("hide-caption")) { + const existingCaption = tableContainer.querySelector("." + Selectors.caption); + if (!existingCaption && !caption.classList.contains("hide-caption")) { const captionDiv = document.createElement("div"); captionDiv.classList.add(Selectors.caption); if (options.captionSide === "bottom") { @@ -190,12 +214,9 @@ class Tabled { } captionDiv.innerHTML = sanitizeHTML(caption.innerHTML); captionDiv.setAttribute("aria-hidden", "true"); - const container = this.getContainer(table); - if (container) { - options.captionSide === "bottom" - ? container.appendChild(captionDiv) - : container.prepend(captionDiv); - } + options.captionSide === "bottom" + ? tableContainer.appendChild(captionDiv) + : tableContainer.prepend(captionDiv); } } } diff --git a/dist/tabled.js.map b/dist/tabled.js.map index 6fc55d4..54339af 100644 --- a/dist/tabled.js.map +++ b/dist/tabled.js.map @@ -1 +1 @@ -{"version":3,"file":"tabled.js","sourceRoot":"","sources":["../src/tabled.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"tabled.js","sourceRoot":"","sources":["../src/tabled.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/tabled.min.js b/dist/tabled.min.js index fa3ed0a..279f01b 100644 --- a/dist/tabled.min.js +++ b/dist/tabled.min.js @@ -1 +1 @@ -var Selectors;(e=>{e.stacked="tabled--stacked",e.table="tabled__table",e.columnLarge="tabled__column--large",e.columnSmall="tabled__column--small",e.wrapper="tabled__wrapper",e.container="tabled",e.fadeLeft="tabled--fade-left",e.fadeRight="tabled--fade-right",e.navigation="tabled__navigation",e.previous="tabled__previous",e.next="tabled__next",e.caption="tabled__caption"})(Selectors=Selectors||{});let ALLOWED_INLINE_TAGS=new Set(["A","ABBR","B","BR","CITE","CODE","EM","I","IMG","Q","SMALL","SPAN","STRONG","SUB","SUP","SVG","TIME","U","CIRCLE","DEFS","ELLIPSE","G","LINE","PATH","POLYGON","POLYLINE","RECT","TEXT","TSPAN","USE"]);function sanitizeHTML(e,t=ALLOWED_INLINE_TAGS){e=(new DOMParser).parseFromString(e,"text/html");return e.body.querySelectorAll("*").forEach(e=>{t.has(e.tagName.toUpperCase())||e.replaceWith(...e.childNodes)}),e.body.innerHTML}class Tabled{constructor(e){if(e.index||(e.index=Math.floor(1e4*Math.random())),this.checkConditions(e.table)){e.table.classList.add(Selectors.table),this.wrap(e.table);var t=this.getWrapper(e.table);t.setAttribute("id","tabled-n"+e.index),this.adjustColumnsWidth(e),this.addTableControls(e),this.applyFade(e.table),t.addEventListener("scroll",()=>{this.applyFade(e.table)}),new ResizeObserver(()=>{this.applyFade(e.table)}).observe(t)}else if(e.table.classList.contains(Selectors.stacked)){let a=Array.from(e.table.querySelectorAll("thead th"));Array.from(e.table.querySelectorAll("tbody tr")).forEach(e=>{Array.from(e.querySelectorAll("td, th")).forEach((e,t)=>{t=a[t];t&&e.setAttribute("data-label",t.innerText+": ")})})}else e.failClass&&e.table.classList.add(e.failClass)}getWrapper(e){return e.parentNode}getContainer(e){return e.parentNode?e.parentNode.parentNode:null}adjustColumnsWidth(e){let t,a,l=/|<\/?(?:p|div|li|ul|ol|blockquote|h[1-6])\b[^>]*>/gi,r=/<[^>]*>/g,s=null!=(t=e.characterThresholdLarge)?t:30,i=null!=(a=e.characterThresholdSmall)?a:10;for(var o of e.table.rows)Array.from(o.cells).forEach(e=>{var t=e.innerHTML.split(l).map(e=>e.replace(r,"").trim()).filter(e=>0e.length>s),t=t.every(e=>e.length<=i);a?e.classList.add(Selectors.columnLarge):t&&e.classList.add(Selectors.columnSmall)})}wrap(e){var t=document.createElement("div"),e=(t.classList.add(Selectors.wrapper),t.setAttribute("tabindex","0"),e.parentNode.insertBefore(t,e),t.appendChild(e),document.createElement("div"));e.classList.add(Selectors.container),t.parentNode.insertBefore(e,t),e.appendChild(t)}applyFade(e){var e=this.getWrapper(e),t=e.parentNode,a=t.getElementsByClassName(Selectors.previous)[0],l=t.getElementsByClassName(Selectors.next)[0],a=(1{var t=document.createElement("button");t.classList.add("tabled__"+e),t.setAttribute("aria-label",e+" table column"),t.setAttribute("aria-controls",this.getWrapper(a).getAttribute("id")),t.setAttribute("disabled","disabled"),t.setAttribute("type","button"),t.addEventListener("click",()=>{this.move(a,e)}),l.appendChild(t)});var t,r=this.getContainer(a),r=(r&&r.prepend(l),a.querySelector("caption"));r&&(r.classList.add("visually-hidden"),!r.classList.contains("hide-caption"))&&((t=document.createElement("div")).classList.add(Selectors.caption),"bottom"===e.captionSide&&t.classList.add("tabled__caption--bottom"),t.innerHTML=sanitizeHTML(r.innerHTML),t.setAttribute("aria-hidden","true"),r=this.getContainer(a))&&("bottom"===e.captionSide?r.appendChild(t):r.prepend(t))}checkConditions(e){return!(e.classList.contains(Selectors.stacked)||e.querySelector("table")||!e.querySelector("table > tbody")||document.evaluate("ancestor::table",e,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue)}} \ No newline at end of file +var Selectors;(e=>{e.stacked="tabled--stacked",e.table="tabled__table",e.columnLarge="tabled__column--large",e.columnSmall="tabled__column--small",e.wrapper="tabled__wrapper",e.container="tabled",e.fadeLeft="tabled--fade-left",e.fadeRight="tabled--fade-right",e.navigation="tabled__navigation",e.previous="tabled__previous",e.next="tabled__next",e.caption="tabled__caption"})(Selectors=Selectors||{});let ALLOWED_INLINE_TAGS=new Set(["A","ABBR","B","BR","CITE","CODE","EM","I","IMG","Q","SMALL","SPAN","STRONG","SUB","SUP","SVG","TIME","U","CIRCLE","DEFS","ELLIPSE","G","LINE","PATH","POLYGON","POLYLINE","RECT","TEXT","TSPAN","USE"]);function sanitizeHTML(e,t=ALLOWED_INLINE_TAGS){e=(new DOMParser).parseFromString(e,"text/html");return e.body.querySelectorAll("*").forEach(e=>{t.has(e.tagName.toUpperCase())||e.replaceWith(...e.childNodes)}),e.body.innerHTML}class Tabled{constructor(e){if(e.index||(e.index=Math.floor(1e4*Math.random())),this.checkConditions(e.table)){var t=e.table.closest("."+Selectors.container),t=(e.table.classList.add(Selectors.table),this.wrap(e.table,t),this.getWrapper(e.table));t.setAttribute("id","tabled-n"+e.index),this.adjustColumnsWidth(e),this.addTableControls(e),this.applyFade(e.table),t.addEventListener("scroll",()=>{this.applyFade(e.table)}),new ResizeObserver(()=>{this.applyFade(e.table)}).observe(t)}else if(e.table.classList.contains(Selectors.stacked)){let l=Array.from(e.table.querySelectorAll("thead th"));Array.from(e.table.querySelectorAll("tbody tr")).forEach(e=>{Array.from(e.querySelectorAll("td, th")).forEach((e,t)=>{t=l[t];t&&e.setAttribute("data-label",t.innerText+": ")})})}else e.failClass&&e.table.classList.add(e.failClass)}getWrapper(e){return e.parentNode}getContainer(e){return e.parentNode?e.parentNode.parentNode:null}adjustColumnsWidth(e){let t,l,a=/|<\/?(?:p|div|li|ul|ol|blockquote|h[1-6])\b[^>]*>/gi,r=/<[^>]*>/g,s=null!=(t=e.characterThresholdLarge)?t:30,o=null!=(l=e.characterThresholdSmall)?l:10;for(var i of e.table.rows)Array.from(i.cells).forEach(e=>{var t=e.innerHTML.split(a).map(e=>e.replace(r,"").trim()).filter(e=>0e.length>s),t=t.every(e=>e.length<=o);l?e.classList.add(Selectors.columnLarge):t&&e.classList.add(Selectors.columnSmall)})}wrap(e,t){let l=e.closest("."+Selectors.wrapper);l||((l=document.createElement("div")).classList.add(Selectors.wrapper),e.parentNode.insertBefore(l,e),l.appendChild(e)),l.setAttribute("tabindex","0"),t||((e=document.createElement("div")).classList.add(Selectors.container),l.parentNode.insertBefore(e,l),e.appendChild(l))}applyFade(e){var e=this.getWrapper(e),t=e.parentNode,l=t.getElementsByClassName(Selectors.previous)[0],a=t.getElementsByClassName(Selectors.next)[0],l=(1{this.move(t,l)})}addTableControls(e){let r=e.table,s=this.getContainer(r);if(s){let a=s.querySelector("."+Selectors.navigation);[{name:"previous",selector:Selectors.previous},{name:"next",selector:Selectors.next}].forEach(({name:e,selector:t})=>{let l=s.querySelector("."+t);l||(l=document.createElement("button"),a||((a=document.createElement("div")).classList.add(Selectors.navigation),s.prepend(a)),a.appendChild(l)),this.wireControl(l,r,e)});var t,l=r.querySelector("caption");l&&(l.classList.add("visually-hidden"),s.querySelector("."+Selectors.caption)||l.classList.contains("hide-caption")||((t=document.createElement("div")).classList.add(Selectors.caption),"bottom"===e.captionSide&&t.classList.add("tabled__caption--bottom"),t.innerHTML=sanitizeHTML(l.innerHTML),t.setAttribute("aria-hidden","true"),"bottom"===e.captionSide?s.appendChild(t):s.prepend(t)))}}checkConditions(e){return!(e.classList.contains(Selectors.stacked)||e.querySelector("table")||!e.querySelector("table > tbody")||document.evaluate("ancestor::table",e,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue)}} \ No newline at end of file diff --git a/docs/examples.html b/docs/examples.html index 58f8316..dbfc47f 100644 --- a/docs/examples.html +++ b/docs/examples.html @@ -1136,6 +1136,106 @@

Table with complex headers

+

Table with custom controls

+

+Wrap the table in a .tabled element and add your own previous/next +buttons (using the tabled__previous and tabled__next +classes). Tabled detects the existing markup, wires the buttons, and manages +their disabled state instead of generating its own controls. +

+
<div class="tabled">
+  <div class="tabled__navigation">
+    <button type="button" class="tabled__previous custom__previous" aria-label="Previous column">Previous</button>
+    <button type="button" class="tabled__next custom__next" aria-label="Next column">Next</button>
+  </div>
+  <table>
+    ...
+  </table>
+</div>
+ + + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Animals around the world
AnimalGroupHabitatDietLifespanRegionFun fact
ElephantMammalSavannaHerbivore60 yearsAfricaCan recognise themselves in a mirror
PenguinBirdCoastCarnivore20 yearsAntarcticaCannot fly, but swims very well
KangarooMammalGrasslandHerbivore23 yearsAustraliaCarries its young in a pouch
OwlBirdForestCarnivore15 yearsWorldwideCan turn its head around almost fully
+
+

Stacked rows table

It will switch the table to "stacked" mode where each cell represents a row under the specified breakpoint (1024px). diff --git a/src/tabled.ts b/src/tabled.ts index 94d916d..37f1f71 100644 --- a/src/tabled.ts +++ b/src/tabled.ts @@ -86,11 +86,17 @@ class Tabled { // Check if the table met the necessary conditions. if (this.checkConditions(options.table)) { + // Detect an author-provided container before adding any classes, so that + // existing Tabled markup (controls, wrapper, etc.) can be adopted. + const providedContainer = options.table.closest( + "." + Selectors.container + ) as HTMLElement | null; + // Set up attributes options.table.classList.add(Selectors.table); // Add the wrapper - this.wrap(options.table); + this.wrap(options.table, providedContainer); const wrapper: HTMLDivElement = this.getWrapper(options.table); wrapper.setAttribute("id", "tabled-n" + options.index); @@ -190,23 +196,30 @@ class Tabled { } /** - * Wraps an element with another. + * Wraps the table in the structural elements Tabled needs, adopting any that + * the author already provided in the markup and creating only what is missing. * * @param {HTMLTableElement} table + * @param {HTMLElement | null} providedContainer An existing ".tabled" root. */ - private wrap(table: HTMLTableElement) { - // Wrap the table in the scrollable div - const wrapper: HTMLDivElement = document.createElement("div"); - wrapper.classList.add(Selectors.wrapper); + private wrap(table: HTMLTableElement, providedContainer: HTMLElement | null) { + // Adopt an existing scrollable wrapper, or create one around the table. + let wrapper = table.closest("." + Selectors.wrapper) as HTMLDivElement | null; + if (!wrapper) { + wrapper = document.createElement("div"); + wrapper.classList.add(Selectors.wrapper); + table.parentNode!.insertBefore(wrapper, table); + wrapper.appendChild(table); + } wrapper.setAttribute("tabindex", "0"); - table.parentNode!.insertBefore(wrapper, table); - wrapper.appendChild(table); - - // Wrap in another div for containing navigation and fading. - const container: HTMLDivElement = document.createElement("div"); - container.classList.add(Selectors.container); - wrapper.parentNode!.insertBefore(container, wrapper); - container.appendChild(wrapper); + + // Use the author-provided container, or create one around the wrapper. + if (!providedContainer) { + const container: HTMLDivElement = document.createElement("div"); + container.classList.add(Selectors.container); + wrapper.parentNode!.insertBefore(container, wrapper); + container.appendChild(wrapper); + } } /** @@ -219,18 +232,18 @@ class Tabled { container = wrapper.parentNode as HTMLDivElement, previousButton = container.getElementsByClassName( Selectors.previous - )[0] as HTMLButtonElement, + )[0] as HTMLButtonElement | undefined, nextButton = container.getElementsByClassName( Selectors.next - )[0] as HTMLButtonElement; + )[0] as HTMLButtonElement | undefined; // Left fading if (wrapper.scrollLeft > 1) { container.classList.add(Selectors.fadeLeft); - previousButton.removeAttribute("disabled"); + previousButton?.removeAttribute("disabled"); } else { container.classList.remove(Selectors.fadeLeft); - previousButton.setAttribute("disabled", "disabled"); + previousButton?.setAttribute("disabled", "disabled"); } // Right fading @@ -240,10 +253,10 @@ class Tabled { // If there is less than a pixel of difference between the table if (scrollWidth - wrapper.scrollLeft - width <= 1) { container.classList.remove(Selectors.fadeRight); - nextButton.setAttribute("disabled", "disabled"); + nextButton?.setAttribute("disabled", "disabled"); } else { container.classList.add(Selectors.fadeRight); - nextButton.removeAttribute("disabled"); + nextButton?.removeAttribute("disabled"); } } @@ -301,45 +314,91 @@ class Tabled { } /** - * Creates and attaches the table navigation. + * Wires a navigation button to scroll the table, adding the attributes and + * click handler Tabled relies on. Works for both generated and author-provided + * buttons. + * + * @param {HTMLButtonElement} button + * @param {HTMLTableElement} table + * @param {string} direction ["previous", "next"] + */ + private wireControl( + button: HTMLButtonElement, + table: HTMLTableElement, + direction: string + ) { + button.classList.add("tabled__" + direction); + button.setAttribute("aria-label", direction + " table column"); + button.setAttribute( + "aria-controls", + this.getWrapper(table).getAttribute("id")! + ); + button.setAttribute("disabled", "disabled"); + button.setAttribute("type", "button"); + button.addEventListener("click", () => { + this.move(table, direction); + }); + } + + /** + * Sets up the table navigation, adopting any author-provided navigation + * container or buttons and creating only the pieces that are missing. * * @param {TabledOptions} options */ private addTableControls(options: TabledOptions) { const table: HTMLTableElement = options.table; - const navigationContainer: HTMLDivElement = document.createElement("div"); - navigationContainer.classList.add(Selectors.navigation); - - // Set up the navigation. - ["previous", "next"].forEach((direction) => { - let button: HTMLButtonElement = document.createElement("button"); - button.classList.add("tabled__" + direction); - button.setAttribute("aria-label", direction + " table column"); - button.setAttribute( - "aria-controls", - this.getWrapper(table).getAttribute("id")! - ); - button.setAttribute("disabled", "disabled"); - button.setAttribute("type", "button"); - button.addEventListener("click", () => { - this.move(table, direction); - }); - - navigationContainer.appendChild(button); - }); - const tableContainer: HTMLDivElement | null = this.getContainer(table); - if (tableContainer) { - tableContainer.prepend(navigationContainer); + + if (!tableContainer) { + return; } + // Reuse an author-provided navigation container, or lazily create one only + // when a button needs a home. + let navigationContainer = tableContainer.querySelector( + "." + Selectors.navigation + ) as HTMLDivElement | null; + + const ensureNavigation = (): HTMLDivElement => { + if (!navigationContainer) { + navigationContainer = document.createElement("div"); + navigationContainer.classList.add(Selectors.navigation); + tableContainer.prepend(navigationContainer); + } + return navigationContainer; + }; + + // Adopt existing buttons where present, create the rest. + const directions: { name: string; selector: Selectors }[] = [ + { name: "previous", selector: Selectors.previous }, + { name: "next", selector: Selectors.next }, + ]; + + directions.forEach(({ name, selector }) => { + let button = tableContainer.querySelector( + "." + selector + ) as HTMLButtonElement | null; + + if (!button) { + button = document.createElement("button"); + ensureNavigation().appendChild(button); + } + + this.wireControl(button, table, name); + }); + // Tweak the caption. const caption: HTMLTableCaptionElement | null = table.querySelector("caption"); if (caption) { caption.classList.add("visually-hidden"); - if (!caption.classList.contains("hide-caption")) { + const existingCaption = tableContainer.querySelector( + "." + Selectors.caption + ); + + if (!existingCaption && !caption.classList.contains("hide-caption")) { const captionDiv = document.createElement("div"); captionDiv.classList.add(Selectors.caption); @@ -349,13 +408,10 @@ class Tabled { captionDiv.innerHTML = sanitizeHTML(caption.innerHTML); captionDiv.setAttribute("aria-hidden", "true"); - const container = this.getContainer(table); - if (container) { - options.captionSide === "bottom" - ? container.appendChild(captionDiv) - : container.prepend(captionDiv); - } + options.captionSide === "bottom" + ? tableContainer.appendChild(captionDiv) + : tableContainer.prepend(captionDiv); } } }