From 3eadebd950480b4c5e80f84ec5c418eff468ee2e Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Thu, 9 Oct 2025 10:09:51 +0100 Subject: [PATCH] Theme: Add `/theme-playground` route (#111974) * add basic theme-playground page * basic theme playground * generate schema * sort of include the schema * proper json schema * add base theme * bit of tidy up * don't use appEvents.emit * tidy up ThemeDemo * extract translations * add CODEOWNERS --- .github/CODEOWNERS | 1 + package.json | 4 +- packages/grafana-data/src/internal/index.ts | 1 + .../src/components/ThemeDemos/ThemeDemo.tsx | 52 +- packages/grafana-ui/src/internal/index.ts | 1 + project.json | 3 +- public/app/core/utils/ConfigProvider.tsx | 4 + .../app/features/theme-playground/README.md | 3 + .../theme-playground/ThemePlayground.tsx | 160 ++++++ .../theme-playground/schema.generated.json | 511 ++++++++++++++++++ public/app/routes/routes.tsx | 6 + public/locales/en-US/grafana.json | 4 + yarn.lock | 59 +- 13 files changed, 780 insertions(+), 29 deletions(-) create mode 100644 public/app/features/theme-playground/README.md create mode 100644 public/app/features/theme-playground/ThemePlayground.tsx create mode 100644 public/app/features/theme-playground/schema.generated.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dd7c1d87290..708740f5ce6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -949,6 +949,7 @@ playwright.storybook.config.ts @grafana/grafana-frontend-platform /public/app/features/serviceaccounts/ @grafana/identity-squad /public/app/features/teams/ @grafana/access-squad /public/app/features/templating/ @grafana/dashboards-squad +/public/app/features/theme-playground/ @grafana/grafana-frontend-platform /public/app/features/trails/ @grafana/observability-metrics /public/app/features/transformers/ @grafana/datapro /public/app/features/transformers/timeSeriesTable/ @grafana/dataviz-squad @grafana/app-o11y-visualizations diff --git a/package.json b/package.json index 3b6c04e0c01..e3614d04384 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,8 @@ "stats": "webpack --mode production --config scripts/webpack/webpack.prod.js --profile --json > compilation-stats.json", "storybook": "yarn workspace @grafana/ui storybook --ci", "storybook:build": "yarn workspace @grafana/ui storybook:build", - "themes-generate": "esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --platform=node --tsconfig=./scripts/cli/tsconfig.json | node", + "themes-schema": "typescript-json-schema ./tsconfig.json NewThemeOptions --include 'packages/grafana-data/src/themes/createTheme.ts' --out public/app/features/theme-playground/schema.generated.json", + "themes-generate": "yarn themes-schema && esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --platform=node --tsconfig=./scripts/cli/tsconfig.json | node", "themes:usage": "eslint . --ignore-pattern '*.test.ts*' --ignore-pattern '*.spec.ts*' --cache --plugin '@grafana' --rule '{ @grafana/theme-token-usage: \"error\" }'", "typecheck": "tsc --noEmit && yarn run packages:typecheck", "plugins:build-bundled": "echo 'bundled plugins are no longer supported'", @@ -255,6 +256,7 @@ "ts-jest": "29.4.0", "ts-node": "10.9.2", "typescript": "5.9.2", + "typescript-json-schema": "^0.65.1", "webpack": "5.101.0", "webpack-assets-manifest": "^5.1.0", "webpack-cli": "6.0.1", diff --git a/packages/grafana-data/src/internal/index.ts b/packages/grafana-data/src/internal/index.ts index 8fcb8da4e0d..e2dab753baa 100644 --- a/packages/grafana-data/src/internal/index.ts +++ b/packages/grafana-data/src/internal/index.ts @@ -93,6 +93,7 @@ export { DataTransformerID } from '../transformations/transformers/ids'; export { mergeTransformer } from '../transformations/transformers/merge'; export { getThemeById } from '../themes/registry'; +export * as experimentalThemeDefinitions from '../themes/themeDefinitions'; export { GrafanaEdition } from '../types/config'; export { SIPrefix } from '../valueFormats/symbolFormatters'; diff --git a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx index 6128326b5e8..36fccb70159 100644 --- a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx +++ b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx @@ -18,17 +18,20 @@ import { Icon } from '../Icon/Icon'; import { Input } from '../Input/Input'; import { BackgroundColor, BorderColor, Box, BoxShadow } from '../Layout/Box/Box'; import { Stack } from '../Layout/Stack/Stack'; +import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; import { Switch } from '../Switch/Switch'; import { Text, TextProps } from '../Text/Text'; interface DemoBoxProps { bg?: BackgroundColor; border?: BorderColor; + scrollable?: boolean; shadow?: BoxShadow; textColor?: TextProps['color']; } -const DemoBox = ({ bg, border, children, shadow }: React.PropsWithChildren) => { +const DemoBox = ({ bg, border, children, shadow, scrollable }: React.PropsWithChildren) => { + const MaybeScroll = scrollable ? ScrollContainer : React.Fragment; return ( - {children} + {children} ); }; @@ -121,7 +124,7 @@ export const ThemeDemo = () => { - + @@ -134,8 +137,8 @@ export const ThemeDemo = () => { - - + +
@@ -154,8 +157,8 @@ export const ThemeDemo = () => { - -
name
+ +
@@ -229,7 +232,7 @@ export const ThemeDemo = () => { - + {allButtonVariants.map((variant) => (
name