Skip to content

Commit

Permalink
chore: improve onboarding spacing consistency (#20838)
Browse files Browse the repository at this point in the history
* Make the space between sections consistent

* add more space above team section

* Improve the topbar spacing and positioning

* Move the breadcrumbs above and center the title

* Make spacing consistent across all SDKs

* Add chain op to plans for when they aren't available

* Make sdk margin top consistent with other steps

* Update the invite onboarding step title

* Move the breadcrumbs to be left aligned

* Set top bar title to onboarding in onboarding

* Fix cypress tests

* Update cypress tests

* Remove stale snapshots

* remove billing changes

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
zlwaterfield and github-actions[bot] authored Mar 14, 2024
1 parent 92fa539 commit 64c8d2d
Show file tree
Hide file tree
Showing 13 changed files with 43 additions and 28 deletions.
8 changes: 5 additions & 3 deletions cypress/e2e/onboarding.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ describe('Onboarding', () => {
cy.get('[data-attr=product_analytics-onboarding-card]').click()

// Confirm product intro is not included as the first step in the upper right breadcrumbs
cy.get('[data-attr=onboarding-breadcrumbs] > :first-child > * span').should('not.contain', 'Product Intro')
cy.get('[data-attr=onboarding-breadcrumbs] > :first-child > * span').should('not.contain', 'Product intro')

// Navigate to the product intro page by clicking the left side bar
cy.get('[data-attr=menu-item-replay').click()

// Confirm we're on the product_intro page
cy.get('[data-attr=top-bar-name] > span').contains('Product intro')
cy.get('[data-attr=top-bar-name] > span').contains('Onboarding')
cy.get('[data-attr=product-intro-title]').contains('Watch how users experience your app')

// Go back to /products
cy.visit('/products')
Expand All @@ -37,6 +38,7 @@ describe('Onboarding', () => {
cy.visit(urls.onboarding('session_replay', 'product_intro'))

// Confirm we're on the product intro page
cy.get('[data-attr=top-bar-name] > span').contains('Product intro')
cy.get('[data-attr=top-bar-name] > span').contains('Onboarding')
cy.get('[data-attr=product-intro-title]').contains('Watch how users experience your app')
})
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 21 additions & 10 deletions frontend/src/layout/navigation-3000/components/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IconChevronDown } from '@posthog/icons'
import { LemonButton, LemonSkeleton } from '@posthog/lemon-ui'
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { router } from 'kea-router'
import { EditableField } from 'lib/components/EditableField/EditableField'
import { IconMenu } from 'lib/lemon-ui/icons'
import { Link } from 'lib/lemon-ui/Link'
Expand All @@ -29,6 +30,7 @@ export function TopBar(): JSX.Element | null {

// Always show in full on mobile, as there we are very constrained in width, but not so much height
const effectiveCompactionRate = mobileLayout ? 0 : compactionRate
const isOnboarding = router.values.location.pathname.includes('/onboarding/')

useLayoutEffect(() => {
function handleScroll(): void {
Expand Down Expand Up @@ -94,10 +96,14 @@ export function TopBar(): JSX.Element | null {
<div className="TopBar3000__separator" />
</React.Fragment>
))}
<Breadcrumb breadcrumb={breadcrumbs[breadcrumbs.length - 1]} here />
<Breadcrumb
breadcrumb={breadcrumbs[breadcrumbs.length - 1]}
here
isOnboarding={isOnboarding}
/>
</div>
)}
<Here breadcrumb={breadcrumbs[breadcrumbs.length - 1]} />
<Here breadcrumb={breadcrumbs[breadcrumbs.length - 1]} isOnboarding={isOnboarding} />
</div>
<div className="TopBar3000__actions" ref={setActionsContainer} />
</div>
Expand All @@ -108,29 +114,32 @@ export function TopBar(): JSX.Element | null {
interface BreadcrumbProps {
breadcrumb: IBreadcrumb
here?: boolean
isOnboarding?: boolean
}

function Breadcrumb({ breadcrumb, here }: BreadcrumbProps): JSX.Element {
function Breadcrumb({ breadcrumb, here, isOnboarding }: BreadcrumbProps): JSX.Element {
const { renameState } = useValues(breadcrumbsLogic)
const { tentativelyRename, finishRenaming } = useActions(breadcrumbsLogic)
const [popoverShown, setPopoverShown] = useState(false)

const joinedKey = joinBreadcrumbKey(breadcrumb.key)

const breadcrumbName = isOnboarding && here ? 'Onboarding' : (breadcrumb.name as string)

let nameElement: JSX.Element
if (breadcrumb.name != null && breadcrumb.onRename) {
nameElement = (
<EditableField
name="item-name-small"
value={renameState && renameState[0] === joinedKey ? renameState[1] : breadcrumb.name}
value={renameState && renameState[0] === joinedKey ? renameState[1] : breadcrumbName}
onChange={(newName) => tentativelyRename(joinedKey, newName)}
onSave={(newName) => {
void breadcrumb.onRename?.(newName)
}}
mode={renameState && renameState[0] === joinedKey ? 'edit' : 'view'}
onModeToggle={(newMode) => {
if (newMode === 'edit') {
tentativelyRename(joinedKey, breadcrumb.name as string)
tentativelyRename(joinedKey, breadcrumbName)
} else {
finishRenaming()
}
Expand All @@ -142,7 +151,7 @@ function Breadcrumb({ breadcrumb, here }: BreadcrumbProps): JSX.Element {
/>
)
} else {
nameElement = <span>{breadcrumb.name || <i>Unnamed</i>}</span>
nameElement = <span>{breadcrumbName || <i>Unnamed</i>}</span>
}

const Component = breadcrumb.path ? Link : 'div'
Expand Down Expand Up @@ -191,13 +200,15 @@ function Breadcrumb({ breadcrumb, here }: BreadcrumbProps): JSX.Element {

interface HereProps {
breadcrumb: IBreadcrumb
isOnboarding?: boolean
}

function Here({ breadcrumb }: HereProps): JSX.Element {
function Here({ breadcrumb, isOnboarding }: HereProps): JSX.Element {
const { renameState } = useValues(breadcrumbsLogic)
const { tentativelyRename, finishRenaming } = useActions(breadcrumbsLogic)

const joinedKey = joinBreadcrumbKey(breadcrumb.key)
const hereName = isOnboarding ? 'Onboarding' : (breadcrumb.name as string)

return (
<h1 className="TopBar3000__here" data-attr="top-bar-name">
Expand All @@ -206,7 +217,7 @@ function Here({ breadcrumb }: HereProps): JSX.Element {
) : breadcrumb.onRename ? (
<EditableField
name="item-name-large"
value={renameState && renameState[0] === joinedKey ? renameState[1] : breadcrumb.name}
value={renameState && renameState[0] === joinedKey ? renameState[1] : hereName}
onChange={(newName) => {
tentativelyRename(joinedKey, newName)
if (breadcrumb.forceEditMode) {
Expand All @@ -222,7 +233,7 @@ function Here({ breadcrumb }: HereProps): JSX.Element {
!breadcrumb.forceEditMode
? (newMode) => {
if (newMode === 'edit') {
tentativelyRename(joinedKey, breadcrumb.name as string)
tentativelyRename(joinedKey, hereName)
} else {
finishRenaming()
}
Expand All @@ -235,7 +246,7 @@ function Here({ breadcrumb }: HereProps): JSX.Element {
autoFocus
/>
) : (
<span>{breadcrumb.name}</span>
<span>{hereName}</span>
)}
</h1>
)
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/scenes/onboarding/OnboardingInviteTeammates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const OnboardingInviteTeammates = ({ stepKey }: { stepKey: OnboardingStep

return (
<OnboardingStep
title={`${titlePrefix()} better with friends.`}
title="Invite teammates"
stepKey={stepKey}
continueAction={() =>
preflight?.email_service_available &&
Expand All @@ -55,9 +55,10 @@ export const OnboardingInviteTeammates = ({ stepKey }: { stepKey: OnboardingStep
inviteTeamMembers()
}
>
<div className="mb-6">
<div className="mb-6 mt-6">
<p>
...or maybe even just coworkers. Ya know the ones who like to {likeTo()}?{' '}
{titlePrefix()} better with friends ... or maybe even just coworkers. Ya know the ones who like to{' '}
{likeTo()}?{' '}
{preflight?.email_service_available && (
<span>
Enter their email below and we'll send them a custom invite link. Invites expire after 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,9 @@ export function OnboardingProductIntroduction({ stepKey }: { stepKey: Onboarding
<header className="bg-primary-alt-highlight border-b border-t border-border flex justify-center p-8">
<div className="grid md:grid-cols-2 items-center gap-8 w-full max-w-screen-xl">
<div className="">
<h3 className="text-4xl font-bold">{product.headline}</h3>
<h3 className="text-4xl font-bold" data-attr="product-intro-title">
{product.headline}
</h3>
<p>{product.description}</p>
<GetStartedButton product={product} />
</div>
Expand Down
17 changes: 8 additions & 9 deletions frontend/src/scenes/onboarding/OnboardingStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,11 @@ export const OnboardingStep = ({
return (
<>
<div className="pb-2">
<div
className={`flex justify-between items-center text-muted max-w-screen-lg mx-auto ${
hideHeader && 'hidden'
}`}
>
<h1 className="font-bold m-0 pl-2">
{title || stepKeyToTitle(currentOnboardingStep?.props.stepKey)}
</h1>
<div className="flex items-center gap-x-3" data-attr="onboarding-breadcrumbs">
<div className={`text-muted max-w-screen-md mx-auto ${hideHeader && 'hidden'}`}>
<div
className="flex items-center justify-start gap-x-3 px-2 shrink-0 w-full"
data-attr="onboarding-breadcrumbs"
>
{onboardingStepKeys.map((stepName, idx) => {
return (
<React.Fragment key={`stepKey-${idx}`}>
Expand All @@ -76,6 +72,9 @@ export const OnboardingStep = ({
)
})}
</div>
<h1 className="font-bold m-0 mt-3 px-2">
{title || stepKeyToTitle(currentOnboardingStep?.props.stepKey)}
</h1>
</div>
</div>
<div className={`${stepKey !== 'product_intro' && 'p-2 max-w-screen-md mx-auto'}`}>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/onboarding/sdks/SDKSnippet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const SDKSnippet = ({ sdk, sdkInstructions }: { sdk: SDK; sdkInstructions
Read the docs
</Link>
</div>
{sdkInstructions()}
<div className="space-y-4">{sdkInstructions()}</div>
</div>
)
}
2 changes: 1 addition & 1 deletion frontend/src/scenes/onboarding/sdks/SDKs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export function SDKs({
</div>
}
>
<div className="flex gap-x-8 mt-8">
<div className="flex gap-x-8 mt-6">
<div
className={`flex-col gap-y-2 flex-wrap gap-x-4 ${showSideBySide && 'min-w-[12.5rem] w-50'} ${
!showSideBySide && panel !== 'options' ? 'hidden' : 'flex'
Expand Down

0 comments on commit 64c8d2d

Please sign in to comment.