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
36 changes: 17 additions & 19 deletions frontend/common/code-help/init/init-react.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ import Constants from 'common/constants'
export default (
envId,
{ FEATURE_NAME, FEATURE_NAME_ALT, LIB_NAME, NPM_CLIENT },
) => `// App root
import ${LIB_NAME} from "${NPM_CLIENT}";
import { FlagsmithProvider } from '@flagsmith/flagsmith/react';
) => `import ${LIB_NAME} from "${NPM_CLIENT}";
import { FlagsmithProvider, useFlags } from '${NPM_CLIENT}/react';

export function HomePage() {
const flags = useFlags(['${FEATURE_NAME}','${FEATURE_NAME_ALT}']); // only causes re-render if specified flag values / traits change
const ${FEATURE_NAME} = flags.${FEATURE_NAME}.enabled
const ${FEATURE_NAME_ALT} = flags.${FEATURE_NAME_ALT}.value
return (
<>
{\`${FEATURE_NAME}: \${${FEATURE_NAME}}\`}
{\`${FEATURE_NAME_ALT}: \${${FEATURE_NAME_ALT}}\`}
</>
);
}

export default function App() {
return (
Expand All @@ -17,21 +28,8 @@ export default function App() {
: ''
}
}}
flagsmith={flagsmith}>
{...Your app}
</FlagsmithProvider>
);
}

// Home Page
import ${LIB_NAME} from '${NPM_CLIENT}';
import { useFlags, useFlagsmith } from '${NPM_CLIENT}/react';

export default function HomePage() {
const flags = useFlags(['${FEATURE_NAME}','${FEATURE_NAME_ALT}']); // only causes re-render if specified flag values / traits change
const ${FEATURE_NAME} = flags.${FEATURE_NAME}.enabled
const ${FEATURE_NAME_ALT} = flags.${FEATURE_NAME_ALT}.value
return (
<>{...}</>
flagsmith={${LIB_NAME}}>
<HomePage />
</FlagsmithProvider>
);
}`
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// 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;
Expand All @@ -8,25 +6,17 @@
padding: 0 4px;
border-radius: var(--radius-xs);
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
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='fw-semibold'>
<Logo />
{lang.label}
</Chip>
)
}

export type ConnectYourCodePanelProps = {
environmentKey: string
featureName: string
Expand Down Expand Up @@ -64,9 +77,7 @@ const ConnectYourCodePanel: FC<ConnectYourCodePanelProps> = ({
))}
</div>
) : (
<span className='onboarding-connect__codecard-lang'>
{sdkLang.label}
</span>
<SdkBadge lang={sdkLang} />
)
}
/>
Expand All @@ -83,11 +94,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 @@ -47,10 +47,10 @@
border: 0;
border-radius: 0;
color: var(--color-text-default);
// Reserve the scrollbar gutter permanently so hover doesn't shove the
// layout (the global dark-scroll mixin toggles display:none on a
// space-reserving webkit bar otherwise).
overflow-x: scroll;
// Scroll only when the snippet overflows. When it does, the webkit rule
// below forces the bar visible over the global dark-scroll mixin (which
// display:none-s it on hover), so a long snippet's bar doesn't flicker.
overflow-x: auto;
overflow-y: hidden;

&::-webkit-scrollbar,
Expand Down 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='fw-semibold'
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='fw-semibold'
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