Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/e2e/tests/onboarding-tests.pw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ test.describe('Onboarding', () => {
// Rename the flag. Names are immutable, so this delete + recreates; the
// Onboarding tag must survive (the recreate carries the old flag's tags).
log('Rename the flag');
const flagInput = page.getByLabel('Flag name');
const flagInput = page.getByLabel('Edit flag');
await flagInput.fill('renamed_demo_flag');
await flagInput.press('Enter');

Expand All @@ -114,7 +114,7 @@ test.describe('Onboarding', () => {
// Reload to prove it persisted (bootstrap reuses the renamed flag).
await page.reload();
await flowReady();
await expect(page.getByLabel('Flag name')).toHaveValue('renamed_demo_flag');
await expect(page.getByLabel('Edit flag')).toHaveValue('renamed_demo_flag');
await expect(
page
.getByRole('region', { name: 'Your flags' })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
// Inline editable value in the welcome sentence: an action underline + pencil,
// with a faint highlight on hover/focus. Rationale lives in InlineInput.tsx.
.inline-input {
display: inline-flex;
align-items: center;
vertical-align: baseline;
gap: 4px;
padding: 0 4px;
border-radius: var(--radius-xs);
padding: 1px 8px;
// Round the top only; the bottom stays square so it sits flush with the
Comment thread
talissoncosta marked this conversation as resolved.
// action underline (rounded bottom corners fight the border).
border-radius: var(--radius-xs) var(--radius-xs) 0 0;
border-bottom: 1px solid var(--color-border-action);
// Resting fill so it reads as editable, not only on hover.
background-color: var(--color-surface-subtle);
cursor: text;
transition: background-color var(--duration-fast) var(--easing-standard);

svg {
opacity: 0.8;
transition: opacity var(--duration-fast) var(--easing-standard);
}

&:hover,
&:focus-within {
background-color: var(--color-surface-subtle);

svg {
opacity: 1;
}
background-color: var(--color-surface-muted);
}

// The hero value (flag name): a filled soft-purple pill instead of an
// underline, so it reads as the thing the user will reference in code.
// Flag name: a filled pill rather than an underline (it's referenced in code).
&--accent {
padding: 1px 8px;
border-bottom: none;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export type InlineInputProps = {
}

// Onboarding-local inline editable value (GhostInput + pencil) for the welcome
// sentence: an action underline + pencil mark it editable, it commits on
// blur/Enter, and an empty value reverts. Shares the VariationKeyLabel inline
// sentence: a resting fill, action underline and pencil mark it editable; it
// commits on blur/Enter, and an empty value reverts. Shares the VariationKeyLabel inline
// edit's visual language but drops its buttons/validation to stay prose-like;
// feature-local for now, both should converge on one primitive.
const InlineInput: FC<InlineInputProps> = ({
Expand Down Expand Up @@ -67,7 +67,7 @@ const InlineInput: FC<InlineInputProps> = ({
value={draft}
placeholder={label}
maxLength={maxLength}
aria-label={`${label} name`}
aria-label={`Edit ${label.toLowerCase()}`}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"name" in the accessible label makes Safari offer contact autofill over the field, so it reads "Edit flag" now. The e2e label change is the same fix. We also gave the field a fill so it's more visible when editing.

onChange={(e) => {
const raw = e.target.value
setDraft(transform ? transform(raw) : raw)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Detect my stack, install the SDK, and wire ${featureName} into one place. Then r

return (
<>
<span className='text-default fw-semibold'>
<span className='text-default font-weight-semibold'>

@talissoncosta talissoncosta Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kyle's catch: fw-semibold has no effect in this codebase; font-weight-semibold is the working class, same weight as intended. Swapped on all the section headings.

Paste this into your AI coding agent’s chat
</span>
<div className='bg-surface-muted p-3 d-flex align-items-start gap-3 rounded-md'>
Expand All @@ -50,7 +50,9 @@ Detect my stack, install the SDK, and wire ${featureName} into one place. Then r
</Button>
</div>
<div>
<span className='text-default fw-semibold'>What happens next</span>
<span className='text-default font-weight-semibold'>
What happens next
</span>
<ul className='onboarding-connect__steps text-muted mt-2 mb-0'>
<li>Detects your stack: language, framework and package manager.</li>
<li>Installs the Flagsmith SDK and wires it into your code.</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { FC, useState } from 'react'
import classNames from 'classnames'
import Chip from 'components/base/Chip'
import CodeCard from './CodeCard'
import SdkPicker from './SdkPicker'
import { getSdkSnippet } from './sdkSnippets'
Expand All @@ -9,6 +10,18 @@ type PackageManager = 'npm' | 'yarn'

const PACKAGE_MANAGERS: PackageManager[] = ['npm', 'yarn']

// The chosen SDK as an accent badge (logo + label), matching the picker's
// selected chip - the code card labels its language with this.
const SdkBadge: FC<{ lang: SdkLang }> = ({ lang }) => {
const Logo = lang.logo
return (
<Chip variant='accent' className='font-weight-medium'>
<Logo />
{lang.label}
</Chip>
)
}

Comment thread
talissoncosta marked this conversation as resolved.
export type ConnectYourCodePanelProps = {
environmentKey: string
featureName: string
Expand Down Expand Up @@ -40,7 +53,9 @@ const ConnectYourCodePanel: FC<ConnectYourCodePanelProps> = ({
<div>
<div className='onboarding-connect__step-head d-flex align-items-center gap-2 mb-2'>
<span className='onboarding-connect__step-num'>1</span>
<span className='text-default fw-semibold'>Install the SDK</span>
<span className='text-default font-weight-semibold'>
Install the SDK
</span>
</div>
<CodeCard
code={installCode}
Expand All @@ -64,17 +79,15 @@ const ConnectYourCodePanel: FC<ConnectYourCodePanelProps> = ({
))}
</div>
) : (
<span className='onboarding-connect__codecard-lang'>
{sdkLang.label}
</span>
<SdkBadge lang={sdkLang} />
)
}
/>
</div>
<div>
<div className='onboarding-connect__step-head d-flex align-items-center gap-2 mb-2'>
<span className='onboarding-connect__step-num'>2</span>
<span className='text-default fw-semibold'>
<span className='text-default font-weight-semibold'>
Wire it in &amp; take instant control of what users see
</span>
</div>
Expand All @@ -83,11 +96,7 @@ const ConnectYourCodePanel: FC<ConnectYourCodePanelProps> = ({
language={sdkSnippet.language}
onCopy={onCopyWire}
copyLabel='Copy code snippet'
headerLeft={
<span className='onboarding-connect__codecard-lang'>
{sdkLang.label}
</span>
}
headerLeft={<SdkBadge lang={sdkLang} />}
/>
</div>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,6 @@
border-bottom: 1px solid var(--color-border-default);
}

&__codecard-lang {
font-size: 0.75rem;
font-weight: 600;
color: var(--color-text-secondary);
}

&__pm {
border-radius: 6px;
overflow: hidden;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const SdkPicker: FC<SdkPickerProps> = ({ onSelect, selected }) => {
ref={(el) => {
refs.current[lang.label] = el
}}
className='font-weight-medium'
role='radio'
aria-checked={isSelected}
tabIndex={lang.label === tabStopLabel ? 0 : -1}
Expand All @@ -91,6 +92,7 @@ const SdkPicker: FC<SdkPickerProps> = ({ onSelect, selected }) => {
<div className='d-flex flex-wrap align-items-center gap-2'>
{popularLangs.map(renderOption)}
<Chip
className='font-weight-medium'
onClick={() => setMoreOpen((open) => !open)}
aria-expanded={moreOpen}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import React from 'react'
import Svg from './svg'

// Two-tone on purpose: the other logos are single-fill glyphs, but JS is a
// filled badge. Drawing the "JS" as solid black over the yellow square (rather
// than the shared wrapper's hole-punch, which shows the chip through it and
// washes out on a light chip) keeps it readable on both light and dark. Rounded
// so it reads as a badge.
export const JavascriptLogo = () => (
<Svg color='#F7DF1E'>
<path d='M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z' />
</Svg>
<svg viewBox='0 0 24 24' width={16} height={16} aria-hidden>
<rect width={24} height={24} rx={4} fill='#F7DF1E' />
<path
fill='#000'
d='M22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z'
/>
</svg>
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// Centring is the `mx-auto` utility on the element.
.onboarding-flow {
max-width: 1100px;
// Minimal top padding so the theme-toggle row isn't flush to the very edge;
// Top padding gives the theme-toggle row room to breathe from the very edge;
// sides + bottom keep the reading column off the edges.
padding: 4px 24px 40px;
padding: 24px 24px 40px;
}
Loading