diff --git a/frontend/e2e/tests/onboarding-tests.pw.ts b/frontend/e2e/tests/onboarding-tests.pw.ts index a59d0e4ae944..2bada321f222 100644 --- a/frontend/e2e/tests/onboarding-tests.pw.ts +++ b/frontend/e2e/tests/onboarding-tests.pw.ts @@ -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'); @@ -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' }) diff --git a/frontend/web/components/pages/onboarding/InlineInput/InlineInput.scss b/frontend/web/components/pages/onboarding/InlineInput/InlineInput.scss index 80fb93e7b9da..045c13b15612 100644 --- a/frontend/web/components/pages/onboarding/InlineInput/InlineInput.scss +++ b/frontend/web/components/pages/onboarding/InlineInput/InlineInput.scss @@ -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 + // 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; diff --git a/frontend/web/components/pages/onboarding/InlineInput/InlineInput.tsx b/frontend/web/components/pages/onboarding/InlineInput/InlineInput.tsx index 82ac5f2b173e..2a4d6082fdc6 100644 --- a/frontend/web/components/pages/onboarding/InlineInput/InlineInput.tsx +++ b/frontend/web/components/pages/onboarding/InlineInput/InlineInput.tsx @@ -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 = ({ @@ -67,7 +67,7 @@ const InlineInput: FC = ({ value={draft} placeholder={label} maxLength={maxLength} - aria-label={`${label} name`} + aria-label={`Edit ${label.toLowerCase()}`} onChange={(e) => { const raw = e.target.value setDraft(transform ? transform(raw) : raw) diff --git a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectWithAiPanel.tsx b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectWithAiPanel.tsx index 626a1000f44e..f16683da39c6 100644 --- a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectWithAiPanel.tsx +++ b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectWithAiPanel.tsx @@ -32,7 +32,7 @@ Detect my stack, install the SDK, and wire ${featureName} into one place. Then r return ( <> - + Paste this into your AI coding agent’s chat
@@ -50,7 +50,9 @@ Detect my stack, install the SDK, and wire ${featureName} into one place. Then r
- What happens next + + What happens next +
  • Detects your stack: language, framework and package manager.
  • Installs the Flagsmith SDK and wires it into your code.
  • diff --git a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectYourCodePanel.tsx b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectYourCodePanel.tsx index b66882d24569..a32a58387b42 100644 --- a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectYourCodePanel.tsx +++ b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/ConnectYourCodePanel.tsx @@ -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' @@ -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 ( + + + {lang.label} + + ) +} + export type ConnectYourCodePanelProps = { environmentKey: string featureName: string @@ -40,7 +53,9 @@ const ConnectYourCodePanel: FC = ({
    1 - Install the SDK + + Install the SDK +
    = ({ ))}
    ) : ( - - {sdkLang.label} - + ) } /> @@ -74,7 +87,7 @@ const ConnectYourCodePanel: FC = ({
    2 - + Wire it in & take instant control of what users see
    @@ -83,11 +96,7 @@ const ConnectYourCodePanel: FC = ({ language={sdkSnippet.language} onCopy={onCopyWire} copyLabel='Copy code snippet' - headerLeft={ - - {sdkLang.label} - - } + headerLeft={} />
    diff --git a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/OnboardingConnectPanel.scss b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/OnboardingConnectPanel.scss index 55e5df84ecd0..bd7ad277621a 100644 --- a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/OnboardingConnectPanel.scss +++ b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/OnboardingConnectPanel.scss @@ -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; diff --git a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/SdkPicker.tsx b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/SdkPicker.tsx index e3f4ea0a3772..fb477210edc1 100644 --- a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/SdkPicker.tsx +++ b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/SdkPicker.tsx @@ -69,6 +69,7 @@ const SdkPicker: FC = ({ onSelect, selected }) => { ref={(el) => { refs.current[lang.label] = el }} + className='font-weight-medium' role='radio' aria-checked={isSelected} tabIndex={lang.label === tabStopLabel ? 0 : -1} @@ -91,6 +92,7 @@ const SdkPicker: FC = ({ onSelect, selected }) => {
    {popularLangs.map(renderOption)} setMoreOpen((open) => !open)} aria-expanded={moreOpen} > diff --git a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/logos/javascript-logo.tsx b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/logos/javascript-logo.tsx index f7299f0ae2f8..dca252b249f8 100644 --- a/frontend/web/components/pages/onboarding/OnboardingConnectPanel/logos/javascript-logo.tsx +++ b/frontend/web/components/pages/onboarding/OnboardingConnectPanel/logos/javascript-logo.tsx @@ -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 = () => ( - - - + + + + ) diff --git a/frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.scss b/frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.scss index 8b923ee20edd..9bee42832fe9 100644 --- a/frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.scss +++ b/frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.scss @@ -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; }