mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
feat(3000): Show the 3000 index-less navbar with labels (#18263)
* feat(3000): Show the 3000 index-less navbar with labels * Use new icons and move "Event explorer" * Update UI snapshots for `chromium` (1) * Update UI snapshots for `chromium` (2) * Update UI snapshots for `chromium` (1) * Update UI snapshots for `chromium` (1) * feat: Allow new nav to be collapsed (#18343) * Add alpha/beta tags, move "Toolbar", rename "Persons" * Fix tooltips not showing when navbar collapsed * Align "Session replay" in using sentence case * Update UI snapshots for `chromium` (1) --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Ben White <ben@posthog.com>
This commit is contained in:
2
.github/workflows/ci-backend.yml
vendored
2
.github/workflows/ci-backend.yml
vendored
@@ -125,7 +125,7 @@ jobs:
|
||||
|
||||
- name: Check for syntax errors, import sort, and code style violations
|
||||
run: |
|
||||
ruff check .
|
||||
ruff check .
|
||||
|
||||
- name: Check formatting
|
||||
run: |
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 99 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 113 KiB |
@@ -33,6 +33,7 @@
|
||||
// Navbar
|
||||
|
||||
.Navbar3000 {
|
||||
position: relative;
|
||||
flex: 0 0 3rem;
|
||||
border-right: 1px solid transparent; // This is just for sizing, the visible border is on the content
|
||||
box-sizing: content-box;
|
||||
@@ -63,12 +64,35 @@
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 100vh;
|
||||
padding: 0 0.375rem;
|
||||
border-right-width: 1px;
|
||||
background: var(--accent-3000);
|
||||
overflow-y: auto;
|
||||
|
||||
.Navbar3000__content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 0 0.375rem;
|
||||
background: var(--accent-3000);
|
||||
overflow-y: auto;
|
||||
z-index: var(--z-main-nav);
|
||||
|
||||
.LemonButton {
|
||||
min-height: 2.25rem !important; // Reduce minimum height
|
||||
padding: 0.375rem !important; // Use a custom padding for the navbar only
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
ul + ul {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.NavbarButton {
|
||||
@@ -93,20 +117,6 @@
|
||||
transform: translateY(-0.25rem);
|
||||
}
|
||||
}
|
||||
&.NavbarButton--popover {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0.1875rem;
|
||||
right: 0.1875rem;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-radius: 1px;
|
||||
border: 0.1875rem solid transparent;
|
||||
border-top-color: currentColor;
|
||||
border-right-color: currentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sidebar
|
||||
|
||||
@@ -12,46 +12,55 @@ import { navigation3000Logic } from '../navigationLogic'
|
||||
import { themeLogic } from '../themeLogic'
|
||||
import { NavbarButton } from './NavbarButton'
|
||||
import { urls } from 'scenes/urls'
|
||||
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
|
||||
import { Resizer } from 'lib/components/Resizer/Resizer'
|
||||
import { useRef } from 'react'
|
||||
|
||||
export function Navbar(): JSX.Element {
|
||||
const { user } = useValues(userLogic)
|
||||
const { isSitePopoverOpen } = useValues(navigationLogic)
|
||||
const { closeSitePopover, toggleSitePopover } = useActions(navigationLogic)
|
||||
const { isSidebarShown, activeNavbarItemId, navbarItems } = useValues(navigation3000Logic)
|
||||
const { showSidebar, hideSidebar } = useActions(navigation3000Logic)
|
||||
const { showSidebar, hideSidebar, toggleNavCollapsed } = useActions(navigation3000Logic)
|
||||
const { isDarkModeOn, darkModeSavedPreference, darkModeSystemPreference, isThemeSyncedWithSystem } =
|
||||
useValues(themeLogic)
|
||||
const { toggleTheme } = useActions(themeLogic)
|
||||
const { featureFlags } = useValues(featureFlagLogic)
|
||||
|
||||
const activeThemeIcon = isDarkModeOn ? <IconNight /> : <IconDay />
|
||||
|
||||
const containerRef = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
return (
|
||||
<nav className="Navbar3000">
|
||||
<nav className="Navbar3000" ref={containerRef}>
|
||||
<div className="Navbar3000__content">
|
||||
<div className="Navbar3000__top">
|
||||
{navbarItems.map((section, index) => (
|
||||
<ul key={index}>
|
||||
{section.map((item) => (
|
||||
<NavbarButton
|
||||
key={item.identifier}
|
||||
title={item.label}
|
||||
identifier={item.identifier}
|
||||
icon={item.icon}
|
||||
to={'to' in item ? item.to : undefined}
|
||||
onClick={
|
||||
'logic' in item
|
||||
? () => {
|
||||
if (activeNavbarItemId === item.identifier && isSidebarShown) {
|
||||
hideSidebar()
|
||||
} else {
|
||||
showSidebar(item.identifier)
|
||||
{section.map((item) =>
|
||||
item.featureFlag && !featureFlags[item.featureFlag] ? null : (
|
||||
<NavbarButton
|
||||
key={item.identifier}
|
||||
title={item.label}
|
||||
identifier={item.identifier}
|
||||
icon={item.icon}
|
||||
tag={item.tag}
|
||||
to={'to' in item ? item.to : undefined}
|
||||
onClick={
|
||||
'logic' in item
|
||||
? () => {
|
||||
if (activeNavbarItemId === item.identifier && isSidebarShown) {
|
||||
hideSidebar()
|
||||
} else {
|
||||
showSidebar(item.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
active={activeNavbarItemId === item.identifier && isSidebarShown}
|
||||
/>
|
||||
))}
|
||||
: undefined
|
||||
}
|
||||
active={activeNavbarItemId === item.identifier && isSidebarShown}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
))}
|
||||
</div>
|
||||
@@ -78,6 +87,7 @@ export function Navbar(): JSX.Element {
|
||||
? 'Switch to light mode'
|
||||
: 'Switch to dark mode'
|
||||
}
|
||||
shortTitle="Toggle theme"
|
||||
onClick={() => toggleTheme()}
|
||||
persistentTooltip
|
||||
/>
|
||||
@@ -87,7 +97,7 @@ export function Navbar(): JSX.Element {
|
||||
icon={<IconQuestion />}
|
||||
identifier="help-button"
|
||||
title="Need any help?"
|
||||
popoverMarker
|
||||
shortTitle="Help"
|
||||
/>
|
||||
}
|
||||
placement="right-end"
|
||||
@@ -95,6 +105,7 @@ export function Navbar(): JSX.Element {
|
||||
<NavbarButton
|
||||
icon={<IconGear />}
|
||||
identifier={Scene.ProjectSettings}
|
||||
title="Project settings"
|
||||
to={urls.projectSettings()}
|
||||
/>
|
||||
<Popover
|
||||
@@ -107,13 +118,20 @@ export function Navbar(): JSX.Element {
|
||||
icon={<ProfilePicture name={user?.first_name} email={user?.email} size="md" />}
|
||||
identifier="me"
|
||||
title={`Hi${user?.first_name ? `, ${user?.first_name}` : ''}!`}
|
||||
shortTitle={user?.first_name || user?.email}
|
||||
onClick={toggleSitePopover}
|
||||
popoverMarker
|
||||
/>
|
||||
</Popover>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<Resizer
|
||||
placement={'right'}
|
||||
containerRef={containerRef}
|
||||
closeThreshold={100}
|
||||
onToggleClosed={(shouldBeClosed) => toggleNavCollapsed(shouldBeClosed)}
|
||||
onDoubleClick={() => toggleNavCollapsed()}
|
||||
/>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,35 +4,69 @@ import { Tooltip } from 'lib/lemon-ui/Tooltip'
|
||||
import clsx from 'clsx'
|
||||
import { useValues } from 'kea'
|
||||
import { sceneLogic } from 'scenes/sceneLogic'
|
||||
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
|
||||
import { FEATURE_FLAGS } from 'lib/constants'
|
||||
import { navigation3000Logic } from '../navigationLogic'
|
||||
import { LemonTag } from '@posthog/lemon-ui'
|
||||
import { useFeatureFlag } from 'lib/hooks/useFeatureFlag'
|
||||
|
||||
export interface NavbarButtonProps {
|
||||
identifier: string
|
||||
icon: ReactElement
|
||||
title?: string
|
||||
shortTitle?: string
|
||||
tag?: 'alpha' | 'beta'
|
||||
onClick?: () => void
|
||||
to?: string
|
||||
persistentTooltip?: boolean
|
||||
active?: boolean
|
||||
popoverMarker?: boolean
|
||||
}
|
||||
|
||||
export const NavbarButton: FunctionComponent<NavbarButtonProps> = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
NavbarButtonProps
|
||||
>(({ identifier, title, onClick, persistentTooltip, popoverMarker, ...buttonProps }, ref): JSX.Element => {
|
||||
>(({ identifier, shortTitle, title, tag, onClick, persistentTooltip, ...buttonProps }, ref): JSX.Element => {
|
||||
const { aliasedActiveScene } = useValues(sceneLogic)
|
||||
const { featureFlags } = useValues(featureFlagLogic)
|
||||
const { isNavCollapsed } = useValues(navigation3000Logic)
|
||||
const isUsingNewNav = useFeatureFlag('POSTHOG_3000_NAV')
|
||||
|
||||
const [hasBeenClicked, setHasBeenClicked] = useState(false)
|
||||
|
||||
const here = featureFlags[FEATURE_FLAGS.POSTHOG_3000_NAV] ? aliasedActiveScene === identifier : false
|
||||
const here = aliasedActiveScene === identifier
|
||||
const isNavCollapsedActually = isNavCollapsed || isUsingNewNav
|
||||
|
||||
if (!isUsingNewNav) {
|
||||
buttonProps.active = here
|
||||
}
|
||||
|
||||
let content: JSX.Element | string | undefined
|
||||
if (!isNavCollapsedActually) {
|
||||
content = shortTitle || title
|
||||
if (tag) {
|
||||
if (tag === 'alpha') {
|
||||
content = (
|
||||
<>
|
||||
{content}
|
||||
<LemonTag type="completion" size="small" className="ml-2">
|
||||
ALPHA
|
||||
</LemonTag>
|
||||
</>
|
||||
)
|
||||
} else if (tag === 'beta') {
|
||||
content = (
|
||||
<>
|
||||
{content}
|
||||
<LemonTag type="warning" size="small" className="ml-2">
|
||||
BETA
|
||||
</LemonTag>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<li>
|
||||
<li className="w-full">
|
||||
<Tooltip
|
||||
title={here ? `${title} (you are here)` : title}
|
||||
title={isNavCollapsedActually ? (here ? `${title} (you are here)` : title) : null}
|
||||
placement="right"
|
||||
delayMs={0}
|
||||
visible={!persistentTooltip && hasBeenClicked ? false : undefined} // Force-hide tooltip after button click
|
||||
@@ -45,13 +79,12 @@ export const NavbarButton: FunctionComponent<NavbarButtonProps> = React.forwardR
|
||||
setHasBeenClicked(true)
|
||||
onClick?.()
|
||||
}}
|
||||
className={clsx(
|
||||
'NavbarButton',
|
||||
here && 'NavbarButton--here',
|
||||
popoverMarker && 'NavbarButton--popover'
|
||||
)}
|
||||
className={clsx('NavbarButton', isUsingNewNav && here && 'NavbarButton--here')}
|
||||
fullWidth
|
||||
{...buttonProps}
|
||||
/>
|
||||
>
|
||||
{content}
|
||||
</LemonButton>
|
||||
</Tooltip>
|
||||
</li>
|
||||
)
|
||||
|
||||
@@ -26,6 +26,10 @@ import {
|
||||
IconTestTube,
|
||||
IconToggle,
|
||||
IconToolbar,
|
||||
IconNotebook,
|
||||
IconRocket,
|
||||
IconServer,
|
||||
IconChat,
|
||||
} from '@posthog/icons'
|
||||
import { urls } from 'scenes/urls'
|
||||
import { annotationsSidebarLogic } from './sidebars/annotations'
|
||||
@@ -53,6 +57,7 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
|
||||
actions({
|
||||
hideSidebar: true,
|
||||
showSidebar: (newNavbarItemId?: string) => ({ newNavbarItemId }),
|
||||
toggleNavCollapsed: (override?: boolean) => ({ override }),
|
||||
toggleSidebar: true,
|
||||
setSidebarWidth: (width: number) => ({ width }),
|
||||
setSidebarOverslide: (overslide: number) => ({ overslide }),
|
||||
@@ -86,6 +91,13 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
|
||||
toggleSidebar: (isSidebarShown) => !isSidebarShown,
|
||||
},
|
||||
],
|
||||
isNavCollapsed: [
|
||||
false,
|
||||
{ persist: true },
|
||||
{
|
||||
toggleNavCollapsed: (state, { override }) => override ?? !state,
|
||||
},
|
||||
],
|
||||
sidebarWidth: [
|
||||
DEFAULT_SIDEBAR_WIDTH_PX,
|
||||
{ persist: true },
|
||||
@@ -289,6 +301,19 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
|
||||
logic: isUsingSidebar ? dashboardsSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.dashboards(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.Notebooks,
|
||||
label: 'Notebooks',
|
||||
icon: <IconNotebook />,
|
||||
to: urls.notebooks(),
|
||||
featureFlag: FEATURE_FLAGS.NOTEBOOKS,
|
||||
},
|
||||
{
|
||||
identifier: Scene.Events,
|
||||
label: 'Event explorer',
|
||||
icon: <IconLive />,
|
||||
to: urls.events(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.DataManagement,
|
||||
label: 'Data management',
|
||||
@@ -298,7 +323,7 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
|
||||
},
|
||||
{
|
||||
identifier: Scene.Persons,
|
||||
label: 'Persons and groups',
|
||||
label: 'People and groups',
|
||||
icon: <IconPerson />,
|
||||
logic: isUsingSidebar ? personsAndGroupsSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.persons(),
|
||||
@@ -317,17 +342,18 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
|
||||
logic: isUsingSidebar ? annotationsSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.annotations(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.ToolbarLaunch,
|
||||
label: 'Toolbar',
|
||||
icon: <IconToolbar />,
|
||||
logic: isUsingSidebar ? toolbarSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.toolbarLaunch(),
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
identifier: Scene.Events,
|
||||
label: 'Events',
|
||||
icon: <IconLive />,
|
||||
to: urls.events(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.SavedInsights,
|
||||
label: 'Product Analytics',
|
||||
label: 'Product analytics',
|
||||
icon: <IconGraph />,
|
||||
logic: isUsingSidebar ? insightsSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.savedInsights(),
|
||||
@@ -335,37 +361,51 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
|
||||
featureFlags[FEATURE_FLAGS.WEB_ANALYTICS]
|
||||
? {
|
||||
identifier: Scene.WebAnalytics,
|
||||
label: 'Web Analytics',
|
||||
label: 'Web analytics',
|
||||
icon: <IconPieChart />,
|
||||
to: isUsingSidebar ? undefined : urls.webAnalytics(),
|
||||
tag: 'alpha' as const,
|
||||
}
|
||||
: null,
|
||||
{
|
||||
identifier: Scene.DataWarehouse,
|
||||
label: 'Data warehouse',
|
||||
icon: <IconServer />,
|
||||
to: urls.dataWarehouse(),
|
||||
featureFlag: FEATURE_FLAGS.DATA_WAREHOUSE,
|
||||
tag: 'beta' as const,
|
||||
},
|
||||
{
|
||||
identifier: Scene.Replay,
|
||||
label: 'Session Replay',
|
||||
label: 'Session replay',
|
||||
icon: <IconRewindPlay />,
|
||||
to: urls.replay(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.Surveys,
|
||||
label: 'Surveys',
|
||||
icon: <IconChat />,
|
||||
to: urls.surveys(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.FeatureFlags,
|
||||
label: 'Feature Flags',
|
||||
label: 'Feature flags',
|
||||
icon: <IconToggle />,
|
||||
logic: isUsingSidebar ? featureFlagsSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.featureFlags(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.Experiments,
|
||||
label: 'A/B Testing',
|
||||
label: 'A/B testing',
|
||||
icon: <IconTestTube />,
|
||||
logic: isUsingSidebar ? experimentsSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.experiments(),
|
||||
},
|
||||
{
|
||||
identifier: Scene.ToolbarLaunch,
|
||||
label: 'Toolbar',
|
||||
icon: <IconToolbar />,
|
||||
logic: isUsingSidebar ? toolbarSidebarLogic : undefined,
|
||||
to: isUsingSidebar ? undefined : urls.toolbarLaunch(),
|
||||
identifier: Scene.EarlyAccessFeatures,
|
||||
label: 'Early access features',
|
||||
icon: <IconRocket />,
|
||||
to: urls.earlyAccessFeatures(),
|
||||
},
|
||||
].filter(isNotNil),
|
||||
[
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { LemonTagType } from '@posthog/lemon-ui'
|
||||
import { Logic, LogicWrapper } from 'kea'
|
||||
import { FEATURE_FLAGS } from 'lib/constants'
|
||||
import { Dayjs } from 'lib/dayjs'
|
||||
import { LemonMenuItems } from 'lib/lemon-ui/LemonMenu'
|
||||
import React from 'react'
|
||||
@@ -27,6 +28,8 @@ interface NavbarItemBase {
|
||||
identifier: string
|
||||
label: string
|
||||
icon: JSX.Element
|
||||
featureFlag?: (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS]
|
||||
tag?: 'alpha' | 'beta'
|
||||
}
|
||||
export interface SceneNavbarItem extends NavbarItemBase {
|
||||
to: string
|
||||
|
||||
@@ -22,6 +22,7 @@ export type ResizerLogicProps = {
|
||||
closeThreshold?: number
|
||||
/** Fired when the "closeThreshold" is crossed */
|
||||
onToggleClosed?: (closed: boolean) => void
|
||||
onDoubleClick?: () => void
|
||||
}
|
||||
|
||||
const removeAllListeners = (cache: Record<string, any>): void => {
|
||||
@@ -83,7 +84,7 @@ export const resizerLogic = kea<resizerLogicType>([
|
||||
return
|
||||
}
|
||||
|
||||
const isDoubleClick = cache.firstClickTimestamp && Date.now() - cache.firstClickTimestamp < 200
|
||||
let isDoubleClick = cache.firstClickTimestamp && Date.now() - cache.firstClickTimestamp < 500
|
||||
cache.firstClickTimestamp = Date.now()
|
||||
|
||||
const originContainerBounds = props.containerRef.current.getBoundingClientRect()
|
||||
@@ -115,6 +116,7 @@ export const resizerLogic = kea<resizerLogicType>([
|
||||
const event = calculateEvent(e, false)
|
||||
props.onResize?.(event)
|
||||
actions.setResizingWidth(event.desiredWidth)
|
||||
isDoubleClick = false
|
||||
|
||||
const newIsClosed = props.closeThreshold ? event.desiredWidth < props.closeThreshold : false
|
||||
|
||||
@@ -128,7 +130,13 @@ export const resizerLogic = kea<resizerLogicType>([
|
||||
if (e.button === 0) {
|
||||
const event = calculateEvent(e, false)
|
||||
|
||||
if (event.desiredWidth !== values.width) {
|
||||
if (isDoubleClick) {
|
||||
// Double click - reset to original width
|
||||
actions.resetDesiredWidth()
|
||||
cache.firstClickTimestamp = null
|
||||
|
||||
props.onDoubleClick?.()
|
||||
} else if (event.desiredWidth !== values.width) {
|
||||
if (!isClosed) {
|
||||
// We only want to persist the value if it is open
|
||||
actions.setDesiredWidth(event.desiredWidth)
|
||||
@@ -142,10 +150,6 @@ export const resizerLogic = kea<resizerLogicType>([
|
||||
originalWidth: originContainerBounds.width,
|
||||
isClosed,
|
||||
})
|
||||
} else if (isDoubleClick) {
|
||||
// Double click - reset to original width
|
||||
actions.resetDesiredWidth()
|
||||
cache.firstClickTimestamp = null
|
||||
}
|
||||
|
||||
actions.endResize()
|
||||
|
||||
@@ -68,7 +68,7 @@ export const Actions: StoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
setIndex(0)
|
||||
}, [])
|
||||
return (
|
||||
<div className="w-fit border rounded p-2 bg-white">
|
||||
<div className="w-fit border rounded p-2">
|
||||
<TaxonomicFilter {...args} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -243,19 +243,6 @@
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
&:not([aria-disabled='true']):hover,
|
||||
&.LemonButton--active {
|
||||
color: var(--default);
|
||||
background: var(--border);
|
||||
.LemonButton__icon {
|
||||
color: var(--default);
|
||||
}
|
||||
}
|
||||
|
||||
&:not([aria-disabled='true']):active {
|
||||
transform: scale(0.96875); // 31/32 (0.5px less on both sides, assuming a 32px tall button)
|
||||
}
|
||||
|
||||
&.LemonButton--status-primary {
|
||||
color: var(--muted);
|
||||
}
|
||||
@@ -289,6 +276,19 @@
|
||||
color: var(--default);
|
||||
}
|
||||
}
|
||||
|
||||
&:not([aria-disabled='true']):hover,
|
||||
&.LemonButton--active {
|
||||
color: var(--default);
|
||||
background: var(--border);
|
||||
.LemonButton__icon {
|
||||
color: var(--default);
|
||||
}
|
||||
}
|
||||
|
||||
&:not([aria-disabled='true']):active {
|
||||
transform: scale(calc(35 / 36));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export function LemonCard({ hoverEffect = true, className, children, onClick, fo
|
||||
<div
|
||||
className={`LemonCard ${hoverEffect && 'LemonCard--hoverEffect'} border ${
|
||||
focused ? 'border-2 border-primary' : 'border-border'
|
||||
} rounded-lg p-6 bg-white ${className}`}
|
||||
} rounded-lg p-6 bg-bg-light ${className}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -35,7 +35,7 @@ export const InlineMenu = ({ editor }: { editor: Editor }): JSX.Element => {
|
||||
>
|
||||
<div
|
||||
ref={menuRef}
|
||||
className="NotebookInlineMenu flex bg-white rounded border items-center text-muted-alt p-1 space-x-0.5"
|
||||
className="NotebookInlineMenu flex bg-bg-light rounded border items-center text-muted-alt p-1 space-x-0.5"
|
||||
>
|
||||
{editor.isActive('link') ? (
|
||||
<>
|
||||
|
||||
@@ -42,6 +42,7 @@ const sceneNavAlias: Partial<Record<Scene, Scene>> = {
|
||||
[Scene.AppMetrics]: Scene.Apps,
|
||||
[Scene.ReplaySingle]: Scene.Replay,
|
||||
[Scene.ReplayPlaylist]: Scene.ReplayPlaylist,
|
||||
[Scene.Site]: Scene.ToolbarLaunch,
|
||||
}
|
||||
|
||||
export const sceneLogic = kea<sceneLogicType>([
|
||||
|
||||
@@ -14,7 +14,7 @@ const Filters = (): JSX.Element => {
|
||||
const { webAnalyticsFilters, dateTo, dateFrom } = useValues(webAnalyticsLogic)
|
||||
const { setWebAnalyticsFilters, setDates } = useActions(webAnalyticsLogic)
|
||||
return (
|
||||
<div className="sticky top-0 bg-white z-20 pt-2">
|
||||
<div className="sticky top-0 z-20 pt-2">
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<DateFilter dateFrom={dateFrom} dateTo={dateTo} onChange={setDates} />
|
||||
<PropertyFilters
|
||||
|
||||
Reference in New Issue
Block a user