Last active
          May 13, 2025 04:47 
        
      - 
      
- 
        Save cferdinandi/7efb6e7f3fa56f51e8c69757952a3e18 to your computer and use it in GitHub Desktop. 
Revisions
- 
        cferdinandi revised this gist Apr 23, 2025 . 6 changed files with 417 additions and 1 deletion.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,39 @@ <!DOCTYPE html> <html> <head> <title>Bootstrap</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7" crossorigin="anonymous"> <style type="text/css"> body { margin: 1em auto; max-width: 30em; width: 88%; } </style> </head> <body> <h1>Bootstrap</h1> <ul class="nav nav-tabs" id="myTab" role="tablist"> <li class="nav-item" role="presentation"> <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="true">Merlin</button> </li> <li class="nav-item" role="presentation"> <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile-tab-pane" type="button" role="tab" aria-controls="profile-tab-pane" aria-selected="false">Gandalf</button> </li> <li class="nav-item" role="presentation"> <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact-tab-pane" type="button" role="tab" aria-controls="contact-tab-pane" aria-selected="false">Radagast</button> </li> </ul> <div class="tab-content" id="myTabContent"> <div class="tab-pane fade show active" id="home-tab-pane" role="tabpanel" aria-labelledby="home-tab" tabindex="0">🪄</div> <div class="tab-pane fade" id="profile-tab-pane" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">🧙♀️</div> <div class="tab-pane fade" id="contact-tab-pane" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">🐿️</div> </div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-k6d4wzSIapyDyv1kpU366/PK5hCdSbCRGRCMv+eplOQJWyd1fbcAu9OCUj5zNLiq" crossorigin="anonymous"></script> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,227 @@ <!DOCTYPE html> <html> <head> <title>Kraken</title> <style type="text/css"> body { margin: 1em auto; max-width: 30em; width: 88%; } toggle-tabs [role="tablist"] { list-style: none; margin: 0 0 2em; padding: 0; } toggle-tabs [role="tablist"] li { display: inline-block; } toggle-tabs [role="tab"] { color: currentColor; margin: 0 0 0.25em; padding: 0.5em 1em; text-decoration: none; } toggle-tabs [role="tab"]:active, toggle-tabs [role="tab"]:hover { background-color: #f7f7f7; } toggle-tabs [role="tab"][aria-selected="true"] { background-color: #e5e5e5; } </style> </head> <body> <h1>Kraken</h1> <toggle-tabs> <ul tabs> <li><a href="#merlin">Merlin</a></li> <li><a href="#gandalf">Gandalf</a></li> <li><a href="#radagast">Radagast</a></li> </ul> <div id="merlin">🪄</div> <div id="gandalf">🧙♀️</div> <div id="radagast">🐿️</div> </toggle-tabs> <script> customElements.define('toggle-tabs', class extends HTMLElement { /** * Instantiate the Web Component */ constructor () { // Get parent class properties super(); // Define properties this.tabList = this.querySelector('[tabs]'); // Setup UI this.setup(); } /** * Handle events on the Web Component * @param {Event} event The event object */ handleEvent (event) { this[`on${event.type}`](event); } /** * Handle click events * @param {Event} event The event object */ onclick (event) { // Only run on tab links if (!event.target.matches('[role="tab"]')) return; // Prevent the link from updating the URL event.preventDefault(); // Ignore the currently active tab if (event.target.matches('[aria-selected="true"]')) return; // Toggle tab visibility this.toggle(event.target); } /** * Handle keydown events * @param {Event} event The event object */ onkeydown (event) { // Only run for left and right arrow keys if (!['ArrowLeft', 'ArrowRight'].includes(event.code)) return; // Only run if element in focus is on a tab let tab = document.activeElement.closest('[role="tab"]'); if (!tab) return; // Only run if focused tab is in this component if (!this.tabList.contains(tab)) return; // Get the currently active tab let currentTab = this.tabList.querySelector('[role="tab"][aria-selected="true"]'); // Get the parent list item let listItem = currentTab.closest('li'); // If right arrow, get the next sibling // Otherwise, get the previous let nextListItem = event.code === 'ArrowRight' ? listItem.nextElementSibling : listItem.previousElementSibling; if (!nextListItem) return; let nextTab = nextListItem.querySelector('a'); // Toggle tab visibility this.toggle(nextTab); nextTab.focus(); } /** * Toggle tab visibility * @param {Node} tab The tab to show */ toggle (tab) { // Get the target tab pane let tabPane = this.querySelector(tab.hash); if (!tabPane) return; // Get the current tab and content let currentTab = tab.closest('[role="tablist"]').querySelector('[aria-selected="true"]'); let currentPane = document.querySelector(currentTab.hash); // Update the selected tab tab.setAttribute('aria-selected', true); currentTab.setAttribute('aria-selected', false); // Update the visible tabPane tabPane.removeAttribute('hidden'); currentPane.setAttribute('hidden', ''); // Make sure current tab can be focused and other tabs cannot tab.removeAttribute('tabindex'); currentTab.setAttribute('tabindex', -1); } /** * Add buttons and hide content on page load */ setup () { // Only run if there are tabs if (!this.tabList) return; // Get the list items and links let listItems = this.tabList.querySelectorAll('li'); let links = this.tabList.querySelectorAll('a'); // Add ARIA to list this.tabList.setAttribute('role', 'tablist'); // Add ARIA to the list items for (let item of listItems) { item.setAttribute('role', 'presentation'); } // Add ARIA to the links and content let instance = this; links.forEach(function (link, index) { // Get the the target element let tabPane = instance.querySelector(link.hash); if (!tabPane) return; // Add [role] and [aria-selected] attributes link.setAttribute('role', 'tab'); link.setAttribute('aria-selected', index === 0 ? true : false); // If it's not the active (first) tab, remove focus if (index > 0) { link.setAttribute('tabindex', -1); } // If there's no ID, add one if (!link.id) { link.id = `tab_${tabPane.id}`; } // Add ARIA to tab pane tabPane.setAttribute('role', 'tabpanel'); tabPane.setAttribute('aria-labelledby', link.id); // If not the active pane, hide it if (index > 0) { tabPane.setAttribute('hidden', ''); } }); // Listen for events this.tabList.addEventListener('click', this); document.addEventListener('keydown', this); } }); </script> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,33 @@ <!DOCTYPE html> <html> <head> <title>Web Awesome</title> <link rel="stylesheet" href="https://early.webawesome.com/[email protected]/dist/styles/themes/default.css" /> <link rel="stylesheet" href="https://early.webawesome.com/[email protected]/dist/styles/webawesome.css" /> <style type="text/css"> body { margin: 1em auto; max-width: 30em; width: 88%; } </style> </head> <body> <h1>Web Awesome</h1> <wa-tab-group> <wa-tab panel="merlin">Merlin</wa-tab> <wa-tab panel="gandalf">Gandalf</wa-tab> <wa-tab panel="radagast">Radagast</wa-tab> <wa-tab-panel name="merlin">🪄</wa-tab-panel> <wa-tab-panel name="gandalf">🧙♀️</wa-tab-panel> <wa-tab-panel name="radagast">🐿️</wa-tab-panel> </wa-tab-group> <script type="module" src="https://early.webawesome.com/[email protected]/dist/webawesome.loader.js"></script> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ <!DOCTYPE html> <html> <head> <title>Relative Time - Kraken</title> <style type="text/css"> body { margin: 1em auto; max-width: 30em; width: 88%; } </style> </head> <body> <h1>Relative Time - Kraken</h1> <relative-time>2025-07-04T09:17:00-04:00</relative-time> <script> customElements.define('relative-time', class extends HTMLElement { /** * Instantiate the Web Component */ constructor () { // Get parent class properties super(); // Get attributes let dateStr = this.textContent; let date = Date.parse(dateStr); this.date = Number.isNaN(date) ? Date.now() - 1 : date; this.locale = this.getAttribute('lang') ?? 'en-US'; let sync = this.hasAttribute('sync'); // Create <time> element this.time = document.createElement('time'); this.time.setAttribute('datetime', dateStr); this.innerHTML = ''; this.append(this.time); // Format relative time this.time.textContent = this.format(); if (sync) { setInterval(() => { this.time.textContent = this.format(); }, 1000 * 60); } } format () { let options = this.getOptions(); let formatter = new Intl.RelativeTimeFormat(this.locale, { style: this.getAttribute('type') ?? undefined, numeric: this.getAttribute('numeric') ?? undefined, }); return formatter.format(...options); } getOptions () { // Date and elapsed time let now = Date.now(); let elapsed = this.date - now; // Units in miliseconds let units = [ ['year', 24 * 60 * 60 * 1000 * 365], ['month', 24 * 60 * 60 * 1000 * 365/12], ['day', 24 * 60 * 60 * 1000], ['hour', 60 * 60 * 1000], ['minute', 60 * 1000], ['second', 1000] ]; // "Math.abs" accounts for both "past" & "future" scenarios for (let [unit, ms] of units) { if (Math.abs(elapsed) > ms || unit === 'second') { return [Math.round(elapsed / ms), unit]; } } } }); </script> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,25 @@ <!DOCTYPE html> <html> <head> <title>Relative Time - Web Awesome</title> <link rel="stylesheet" href="https://early.webawesome.com/[email protected]/dist/styles/themes/default.css" /> <link rel="stylesheet" href="https://early.webawesome.com/[email protected]/dist/styles/webawesome.css" /> <style type="text/css"> body { margin: 1em auto; max-width: 30em; width: 88%; } </style> </head> <body> <h1>Relative Time - Web Awesome</h1> <wa-relative-time date="2025-07-04T09:17:00-04:00"></wa-relative-time> <script type="module" src="https://early.webawesome.com/[email protected]/dist/webawesome.loader.js"></script> </body> </html> 
- 
        cferdinandi created this gist Apr 23, 2025 .There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ 1