Skip to content
Draft
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
2 changes: 2 additions & 0 deletions frontend/.storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ global.Select = (props) =>
window.Tooltip = Tooltip
window.Row = Row
window.FormGroup = FormGroup
// isMobile is set at app boot; stub it so components that read it render in Storybook.
window.isMobile = false

/** @type { import('storybook').Preview } */
const preview = {
Expand Down
13 changes: 13 additions & 0 deletions frontend/common/theme/tokens.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@
"action-subtle": { "cssVar": "--color-surface-action-subtle", "light": "rgba(104, 55, 252, 0.08)", "dark": "rgba(255, 255, 255, 0.08)" },
"action-muted": { "cssVar": "--color-surface-action-muted", "light": "rgba(104, 55, 252, 0.16)", "dark": "rgba(255, 255, 255, 0.16)" },
"danger": { "cssVar": "--color-surface-danger", "light": "rgba(239, 77, 86, 0.08)", "dark": "oklch(from var(--red-500) 0.18 0.02 h)" },
"danger-strong": { "cssVar": "--color-surface-danger-strong", "light": "rgba(239, 77, 86, 0.16)", "dark": "oklch(from var(--red-500) 0.26 0.05 h)", "_comment": "one step above surface-danger, e.g. removed-word emphasis in diffs" },
"success": { "cssVar": "--color-surface-success", "light": "rgba(39, 171, 149, 0.08)", "dark": "oklch(from var(--green-500) 0.18 0.02 h)" },
"success-strong": { "cssVar": "--color-surface-success-strong", "light": "rgba(39, 171, 149, 0.16)", "dark": "oklch(from var(--green-500) 0.26 0.05 h)", "_comment": "one step above surface-success, e.g. added-word emphasis in diffs" },
"warning": { "cssVar": "--color-surface-warning", "light": "rgba(255, 159, 67, 0.08)", "dark": "oklch(from var(--orange-500) 0.18 0.02 h)" },
"info": { "cssVar": "--color-surface-info", "light": "rgba(10, 173, 223, 0.08)", "dark": "oklch(from var(--blue-500) 0.18 0.02 h)" }
},
Expand All @@ -110,6 +112,17 @@
"warning": { "cssVar": "--color-text-warning", "light": "#ff9f43", "dark": "#ff9f43" },
"info": { "cssVar": "--color-text-info", "light": "#0aaddf", "dark": "#0aaddf" }
},
"code": {
"text": { "cssVar": "--color-code-text", "light": "#2d3443", "dark": "#9da4ae" },
"comment": { "cssVar": "--color-code-comment", "light": "#9da4ae", "dark": "#656d7b" },
"keyword": { "cssVar": "--color-code-keyword", "light": "#6837fc", "dark": "#906af6" },
"name": { "cssVar": "--color-code-name", "light": "#ef4d56", "dark": "#f57c78" },
"literal": { "cssVar": "--color-code-literal", "light": "#0b8bb2", "dark": "#45bce0" },
"string": { "cssVar": "--color-code-string", "light": "#27ab95", "dark": "#56ccad" },
"variable": { "cssVar": "--color-code-variable", "light": "#d06907", "dark": "#efb47c" },
"title": { "cssVar": "--color-code-title", "light": "#0aaddf", "dark": "#7ecde2" },
"builtin": { "cssVar": "--color-code-builtin", "light": "#d4b050", "dark": "#f9dc80" }
},
"border": {
"default": { "cssVar": "--color-border-default", "light": "rgba(101, 109, 123, 0.16)", "dark": "rgba(255, 255, 255, 0.16)" },
"strong": { "cssVar": "--color-border-strong", "light": "rgba(101, 109, 123, 0.24)", "dark": "rgba(255, 255, 255, 0.24)" },
Expand Down
15 changes: 15 additions & 0 deletions frontend/common/theme/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@ export const colorBorderStrong =
export const colorBorderSuccess = 'var(--color-border-success, #27ab95)'
export const colorBorderWarning = 'var(--color-border-warning, #ff9f43)'

// Code
export const colorCodeBuiltin = 'var(--color-code-builtin, #d4b050)'
export const colorCodeComment = 'var(--color-code-comment, #9da4ae)'
export const colorCodeKeyword = 'var(--color-code-keyword, #6837fc)'
export const colorCodeLiteral = 'var(--color-code-literal, #0b8bb2)'
export const colorCodeName = 'var(--color-code-name, #ef4d56)'
export const colorCodeString = 'var(--color-code-string, #27ab95)'
export const colorCodeText = 'var(--color-code-text, #2d3443)'
export const colorCodeTitle = 'var(--color-code-title, #0aaddf)'
export const colorCodeVariable = 'var(--color-code-variable, #d06907)'

// Icon
export const colorIconAction = 'var(--color-icon-action, #6837fc)'
export const colorIconDanger = 'var(--color-icon-danger, #ef4d56)'
Expand All @@ -172,6 +183,8 @@ export const colorSurfaceActive =
'var(--color-surface-active, rgba(0, 0, 0, 0.16))'
export const colorSurfaceDanger =
'var(--color-surface-danger, rgba(239, 77, 86, 0.08))'
export const colorSurfaceDangerStrong =
'var(--color-surface-danger-strong, rgba(239, 77, 86, 0.16))'
export const colorSurfaceDefault = 'var(--color-surface-default, #ffffff)'
export const colorSurfaceEmphasis = 'var(--color-surface-emphasis, #e0e3e9)'
export const colorSurfaceHover =
Expand All @@ -182,6 +195,8 @@ export const colorSurfaceMuted = 'var(--color-surface-muted, #eff1f4)'
export const colorSurfaceSubtle = 'var(--color-surface-subtle, #fafafb)'
export const colorSurfaceSuccess =
'var(--color-surface-success, rgba(39, 171, 149, 0.08))'
export const colorSurfaceSuccessStrong =
'var(--color-surface-success-strong, rgba(39, 171, 149, 0.16))'
export const colorSurfaceWarning =
'var(--color-surface-warning, rgba(255, 159, 67, 0.08))'

Expand Down
2 changes: 2 additions & 0 deletions frontend/documentation/SemanticTokens.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const TOKEN_PREFIX = '--color-'
const GROUP_LABELS: Record<string, string> = {
border: 'Border',
brand: 'Brand',
code: 'Code',
danger: 'Danger',
icon: 'Icon',
info: 'Info',
Expand Down Expand Up @@ -83,6 +84,7 @@ function readTokens(): TokenGroupData[] {
'brand',
'surface',
'text',
'code',
'border',
'icon',
'danger',
Expand Down
99 changes: 99 additions & 0 deletions frontend/documentation/TokenReference.generated.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ export const AllTokens: StoryObj = {
<code>oklch(from var(--red-500) l c h / 0.08)</code>
</td>
</tr>
<tr>
<td>
<code>--color-surface-danger-strong</code>
</td>
<td>
<code>oklch(from var(--red-500) l c h / 0.16)</code>
</td>
</tr>
<tr>
<td>
<code>--color-surface-success</code>
Expand All @@ -133,6 +141,14 @@ export const AllTokens: StoryObj = {
<code>oklch(from var(--green-500) l c h / 0.08)</code>
</td>
</tr>
<tr>
<td>
<code>--color-surface-success-strong</code>
</td>
<td>
<code>oklch(from var(--green-500) l c h / 0.16)</code>
</td>
</tr>
<tr>
<td>
<code>--color-surface-warning</code>
Expand Down Expand Up @@ -234,6 +250,89 @@ export const AllTokens: StoryObj = {
</tr>
</tbody>
</table>
<h3>Colour: code</h3>
<table className='docs-table'>
<thead>
<tr>
<th>Token</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>--color-code-text</code>
</td>
<td>
<code>var(--slate-700)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-comment</code>
</td>
<td>
<code>var(--slate-300)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-keyword</code>
</td>
<td>
<code>var(--purple-600)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-name</code>
</td>
<td>
<code>var(--red-500)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-literal</code>
</td>
<td>
<code>var(--blue-600)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-string</code>
</td>
<td>
<code>var(--green-500)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-variable</code>
</td>
<td>
<code>var(--orange-700)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-title</code>
</td>
<td>
<code>var(--blue-500)</code>
</td>
</tr>
<tr>
<td>
<code>--color-code-builtin</code>
</td>
<td>
<code>var(--gold-700)</code>
</td>
</tr>
</tbody>
</table>
<h3>Colour: border</h3>
<table className='docs-table'>
<thead>
Expand Down
51 changes: 51 additions & 0 deletions frontend/documentation/pages/DiffString.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { Meta, StoryObj } from 'storybook'

import DiffString from 'components/diff/DiffString'

const meta: Meta<typeof DiffString> = {
component: DiffString,
parameters: {
docs: {
description: {
component:
'The diff view for flag values (react-diff-viewer + Prism for JSON). ' +
'Uses the same code colour tokens as the Highlight component, so it ' +
'follows light/dark mode. Toggle the theme in the toolbar to QA.',
},
},
layout: 'padded',
},
title: 'Components/DiffString',
}

export default meta

type Story = StoryObj<typeof DiffString>

const oldJson = `{
"id": "london-js",
"title": "Hello London.js!",
"description": "Join us at London.js and get insights on best practices!",
"buttonText": "Register on Meetup",
"isClosable": false
}`

const newJson = `{
"id": "london-js",
"title": "Hello London.js!",
"description": "Join us at London.js!",
"buttonText": "Register now",
"isClosable": true
}`

export const ChangedJson: Story = {
args: { newValue: newJson, oldValue: oldJson },
}

export const ChangedString: Story = {
args: { newValue: 'banner_size: large', oldValue: 'banner_size: small' },
}

export const SameJson: Story = {
args: { newValue: oldJson, oldValue: oldJson },
}
93 changes: 93 additions & 0 deletions frontend/documentation/pages/Highlight.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { Meta, StoryObj } from 'storybook'

import Highlight from 'components/Highlight'

const meta: Meta<typeof Highlight> = {
component: Highlight,
parameters: {
docs: {
description: {
component:
'The code wrapper: renders a `<pre><code class="hljs">` block and runs ' +
'highlight.js over it. This is what the shared code theme styles (surface, ' +
'border, syntax palette). Toggle the theme in the toolbar to QA light vs dark; ' +
'`className` is the highlight.js language.',
},
},
layout: 'padded',
},
title: 'Components/Highlight',
}

export default meta

type Story = StoryObj<typeof Highlight>

const js = `// Initialise the client
import flagsmith from 'flagsmith'

flagsmith.init({
environmentID: 'YOUR_ENVIRONMENT_KEY',
onChange: () => {
const bannerSize = flagsmith.getValue('banner_size')
},
})`

const ts = `import { useFlags } from 'flagsmith/react'

type FlagName = 'banner_size' | 'my_feature'

const flags = useFlags<FlagName>(['banner_size'])
const size: number = flags.banner_size.value ?? 0`

const json = `{
"flags": [
{ "feature": "banner_size", "enabled": true, "value": 42 },
{ "feature": "my_feature", "enabled": false, "value": null }
]
}`

const yaml = `flags:
- feature: banner_size
enabled: true
value: 42`

// Mirrors the React SDK snippet in code-help: markup tags inside JavaScript.
const jsx = `export function HomePage() {
const flags = useFlags(['banner_size'])
return (
<Row className="banner">
<Flag name="banner_size" size={flags.banner_size.value} />
</Row>
)
}`

export const JavaScript: Story = {
args: { children: js, className: 'javascript', forceExpanded: true },
}

export const TypeScript: Story = {
args: { children: ts, className: 'typescript', forceExpanded: true },
}

export const Json: Story = {
args: { children: json, className: 'json', forceExpanded: true },
}

export const Yaml: Story = {
args: { children: yaml, className: 'yaml', forceExpanded: true },
}

export const Jsx: Story = {
args: { children: jsx, className: 'javascript', forceExpanded: true },
}

// Embedded variant: transparent, for code whose container owns the surface.
export const Embedded: Story = {
args: {
children: js,
className: 'javascript',
embedded: true,
forceExpanded: true,
},
}
Loading
Loading