From 42f5a80126b9409396f2fa05c33f1ce58a55ec0f Mon Sep 17 00:00:00 2001 From: David Newell Date: Tue, 5 Dec 2023 14:12:37 +0000 Subject: [PATCH] chore: migrate tabs from custom to lemon (#19041) --- .../src/lib/lemon-ui/LemonTabs/LemonTabs.scss | 146 ++++++++++-------- .../src/lib/lemon-ui/LemonTabs/LemonTabs.tsx | 11 +- frontend/src/scenes/web-analytics/WebTabs.tsx | 48 +----- 3 files changed, 99 insertions(+), 106 deletions(-) diff --git a/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss b/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss index 371bb05d23964..3696f6b12c088 100644 --- a/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss +++ b/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss @@ -1,4 +1,8 @@ .LemonTabs { + --lemon-tabs-margin-bottom: 1rem; + --lemon-tabs-margin-right: 2rem; + --lemon-tabs-content-padding: 0.75rem 0; + position: relative; display: flex; flex-direction: column; @@ -8,83 +12,95 @@ .Navigation3000__scene > :first-child > &:first-child { margin-top: -0.75rem; } -} -.LemonTabs__bar { - position: relative; - display: flex; - flex-direction: row; - flex-shrink: 0; - align-items: stretch; - margin-bottom: 1rem; - overflow-x: auto; - list-style: none; - - &::before { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 1px; - - // The bottom border - content: ''; - background: var(--border); + &.LemonTabs--inline { + --lemon-tabs-margin-bottom: 0; + --lemon-tabs-margin-right: 1rem; + --lemon-tabs-content-padding: 0.25rem 0rem; + } + + &.LemonTabs--borderless { + .LemonTabs__bar::before { + content: none; + } } - &::after { - position: absolute; - bottom: 0; - left: 0; - width: var(--lemon-tabs-slider-width); - height: 0.125rem; + .LemonTabs__bar { + position: relative; + display: flex; + flex-direction: row; + flex-shrink: 0; + align-items: stretch; + margin-bottom: var(--lemon-tabs-margin-bottom); + overflow-x: auto; + list-style: none; - // The active tab slider - content: ''; - background: var(--link); - transform: translateX(var(--lemon-tabs-slider-offset)); + &::before { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 1px; - .LemonTabs--transitioning & { - transition: width 200ms ease, transform 200ms ease; + // The bottom border + content: ''; + background: var(--border); } - } -} -.LemonTabs__tab { - .LemonTabs--transitioning & { - transition: color 200ms ease; - } + &::after { + position: absolute; + bottom: 0; + left: 0; + width: var(--lemon-tabs-slider-width); + height: 0.125rem; - &:not(:last-child) { - margin-right: 2rem; - } + // The active tab slider + content: ''; + background: var(--link); + transform: translateX(var(--lemon-tabs-slider-offset)); - &:hover { - color: var(--link); - } + .LemonTabs--transitioning & { + transition: width 200ms ease, transform 200ms ease; + } + } - &:active { - color: var(--primary-3000-active); - } + .LemonTabs__tab { + .LemonTabs--transitioning & { + transition: color 200ms ease; + } - &.LemonTabs__tab--active { - color: var(--link); - text-shadow: 0 0 0.25px currentColor; // Simulate increased weight without affecting width - } + &:not(:last-child) { + margin-right: var(--lemon-tabs-margin-right); + } - a { - color: inherit; + &:hover { + color: var(--link); + } - // Make tab labels that are links the same colors as regular tab labels - text-decoration: none; - transition: none; - } -} + &:active { + color: var(--primary-3000-active); + } -.LemonTabs__tab-content { - display: flex; - align-items: center; - padding: 0.75rem 0; - white-space: nowrap; - cursor: pointer; + &.LemonTabs__tab--active { + color: var(--link); + text-shadow: 0 0 0.25px currentColor; // Simulate increased weight without affecting width + } + + a { + color: inherit; + + // Make tab labels that are links the same colors as regular tab labels + text-decoration: none; + transition: none; + } + + .LemonTabs__tab-content { + display: flex; + align-items: center; + padding: var(--lemon-tabs-content-padding); + white-space: nowrap; + cursor: pointer; + } + } + } } diff --git a/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.tsx b/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.tsx index d94f9732623cd..44820a6523698 100644 --- a/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.tsx +++ b/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.tsx @@ -29,6 +29,8 @@ export interface LemonTabsProps { onChange?: (key: T) => void /** List of tabs. Falsy entries are ignored - they're there to make conditional tabs convenient. */ tabs: (LemonTab | null | false)[] + inline?: boolean + borderless?: boolean 'data-attr'?: string } @@ -53,6 +55,8 @@ export function LemonTabs({ activeKey, onChange, tabs, + inline = false, + borderless = false, 'data-attr': dataAttr, }: LemonTabsProps): JSX.Element { const { containerRef, selectionRef, sliderWidth, sliderOffset, transitioning } = useSliderPositioning< @@ -66,7 +70,12 @@ export function LemonTabs({ return (
void }): JSX.Element => { const activeTab = tabs.find((t) => t.id === activeTabId) - const { containerRef, selectionRef, sliderWidth, sliderOffset, transitioning } = useSliderPositioning< - HTMLUListElement, - HTMLLIElement - >(activeTabId, TRANSITION_MS) return (
{

{activeTab?.title}

} -
- {tabs.length > 1 && ( - // TODO switch to a select if more than 3 -
    - {tabs.map(({ id, linkText }) => ( -
  • - -
  • - ))} -
- )} -
-
-
-
+ ({ key: id, label: linkText }))} + />
{activeTab?.content}