Jelajahi Sumber

CMS Bootstrap 5 migration - Tabs using bootstrap 5 classes (#20478)

* adding classes according to bootstrap 5 tabs

* adding JS for tabs handeling in BS5

* adding styling for tabs to match the redesign styling

* making sure tabs are being highlighted when active

* adding a scroll-margin-top to have some extra space

* removing extra import, it is not needed here because we already import it in bootstrap-x.js files

* using the media-breakpoint-down for a media query styling

* introducing .nav-tabs-container to make the tab triggers horizontally scrollable

* creating a mixin box-shadow-button-input under scss for bootstrap-5

* moving border-width-base to tabs.scss

* aligning tabs to the left under screen size of 768px

* removing focus-style mixin from scss files becuase it was a duplicate

GitOrigin-RevId: 45780c62681fc9b61961f5436d2d55de66a976b6
Davinder Singh 1 tahun lalu
induk
melakukan
248fc3699a

+ 1 - 1
services/web/frontend/js/bootstrap-3.ts

@@ -1,6 +1,6 @@
 import 'bootstrap'
 import './features/contact-form'
-import './features/bookmarkable-tab'
+import './features/bookmarkable-tab/index'
 
 $('[data-ol-lang-selector-tooltip]').tooltip({ trigger: 'hover' })
 $('[data-toggle="tooltip"]').tooltip()

+ 1 - 0
services/web/frontend/js/bootstrap-5.ts

@@ -1 +1,2 @@
 import 'bootstrap-5'
+import './features/bookmarkable-tab/index-bs5'

+ 30 - 0
services/web/frontend/js/features/bookmarkable-tab/index-bs5.ts

@@ -0,0 +1,30 @@
+import { Tab } from 'bootstrap-5'
+
+function bookmarkableTab(tabEl: HTMLElement) {
+  tabEl.addEventListener('click', () => {
+    window.location.hash = tabEl.getAttribute('href') as string
+  })
+}
+
+function handleHashChange() {
+  const hash = window.location.hash
+  if (!hash) return
+
+  // Find the bookmarkable tab that links to the hash
+  const tabEl = document.querySelector(
+    `[data-ol-bookmarkable-tab][href="${hash}"]`
+  )
+
+  if (!tabEl) return
+
+  // Select the tab via Bootstrap 5
+  const tab = new Tab(tabEl)
+  tab.show()
+}
+
+document
+  .querySelectorAll('[data-ol-bookmarkable-tab]')
+  .forEach(tabEl => bookmarkableTab(tabEl as HTMLElement))
+
+window.addEventListener('hashchange', handleHashChange)
+handleHashChange()

+ 1 - 1
services/web/frontend/stylesheets/bootstrap-5/abstracts/mixins.scss

@@ -97,6 +97,6 @@
   }
 }
 
-@mixin focus-style() {
+@mixin box-shadow-button-input {
   box-shadow: 0 0 0 2px var(--blue-30);
 }

+ 1 - 0
services/web/frontend/stylesheets/bootstrap-5/components/all.scss

@@ -17,3 +17,4 @@
 @import 'navbar';
 @import 'styled-text';
 @import 'table';
+@import 'tabs';

+ 83 - 0
services/web/frontend/stylesheets/bootstrap-5/components/tabs.scss

@@ -0,0 +1,83 @@
+.ol-tabs {
+  --border-width-base: 3px;
+
+  .nav-tabs-container {
+    overflow-x: auto;
+    display: flex;
+    flex-direction: column;
+
+    @include media-breakpoint-down(md) {
+      display: block;
+    }
+
+    .nav-tabs {
+      display: inline-flex;
+      gap: var(--spacing-04);
+      margin: 0 auto;
+      padding: 0;
+      border-bottom: var(--border-width-base) solid var(--neutral-20);
+      text-align: center;
+      border-top: 2px solid transparent; // so that top focus border is visible
+      min-width: max-content; // This is for horizontal scrolling
+
+      li {
+        display: inline-block;
+        float: none;
+        margin-bottom: calc(var(--border-width-base) * -0.6);
+
+        &:last-child {
+          margin-right: 0;
+        }
+
+        a {
+          border: 0;
+          border-radius: 0;
+          color: var(--neutral-70);
+          margin-right: unset;
+          padding: var(--spacing-04);
+          line-height: var(--line-height-03);
+
+          &:focus,
+          &:hover {
+            border: 0;
+          }
+
+          &:focus,
+          &:focus-visible {
+            background-color: unset;
+            outline: 0;
+          }
+
+          &:hover {
+            background-color: var(--neutral-10);
+          }
+
+          &:focus-visible {
+            @include box-shadow-button-input;
+          }
+        }
+      }
+
+      li > a.active {
+        background-color: transparent !important;
+        border: 0 !important;
+        border-bottom: 3px solid var(--green-50) !important;
+        color: var(--neutral-90) !important;
+
+        &:hover {
+          border-bottom: 3px solid var(--green-50) !important;
+        }
+      }
+    }
+  }
+
+  .tab-content {
+    margin-top: var(--spacing-11);
+  }
+}
+
+// Scroll the page up a bit to allow tab links to be shown when navigating to
+// a bookmarked tab hash
+[data-ol-bookmarkable-tabset] .tab-pane {
+  scroll-margin-top: 120px;
+}

+ 1 - 1
services/web/frontend/stylesheets/bootstrap-5/pages/website-redesign.scss

@@ -13,7 +13,7 @@
     }
 
     &:focus-visible {
-      @include focus-style;
+      @include box-shadow-button-input;
     }
 
     // TODO: remove visited?