diff --git a/package.json b/package.json index f9dd7fbba..b6265f9c7 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,10 @@ "ci": "npm run test && npm run lint && npm run build && npx prettier --check src", "deploy": "website-deploy-aws", "panda": "panda codegen", + "dev:link-ui": "rm -rf node_modules/@microbit/ui && ln -s ../../../ui/packages/ui node_modules/@microbit/ui && rm -rf styled-system && npm run panda", + "dev:link-ui-patterns": "rm -rf node_modules/@microbit/ui-patterns && ln -s ../../../ui/packages/ui-patterns node_modules/@microbit/ui-patterns && rm -rf styled-system && npm run panda", + "dev:link-theme": "npm --prefix ../ml-trainer-microbit run build && mkdir -p node_modules/@microbit-foundation && rm -rf node_modules/@microbit-foundation/ml-trainer-microbit && ln -s ../../../ml-trainer-microbit node_modules/@microbit-foundation/ml-trainer-microbit && rm -rf styled-system && npm run panda", + "dev:unlink-theme": "rm -rf node_modules/@microbit-foundation/ml-trainer-microbit && rm -rf styled-system && npm run panda", "predev": "npm run panda", "dev": "cross-env VITE_VERSION=$npm_package_version vite", "dev:apps": "cross-env VITE_BUILD_MODE=apps VITE_VERSION=$npm_package_version vite --host", diff --git a/src/compliance/NativeConsentDialog.tsx b/src/compliance/NativeConsentDialog.tsx index 576e6f5b1..757e3e537 100644 --- a/src/compliance/NativeConsentDialog.tsx +++ b/src/compliance/NativeConsentDialog.tsx @@ -57,6 +57,7 @@ export const NativeConsentDialog = ({ <> {" "} { values={{ link: (chunks: ReactNode) => ( diff --git a/src/components/BrokenFirmwareDialog.tsx b/src/components/BrokenFirmwareDialog.tsx index 826924717..49ad59d9f 100644 --- a/src/components/BrokenFirmwareDialog.tsx +++ b/src/components/BrokenFirmwareDialog.tsx @@ -54,7 +54,7 @@ const BrokenFirmwareDialog = ({ values={{ link: (chunks: ReactNode) => ( { {isNativePlatform() && tryAgain && isFindingDevice && ( - )} diff --git a/src/components/ErrorHandlerErrorView.tsx b/src/components/ErrorHandlerErrorView.tsx index d92f93a82..bdcc39c8b 100644 --- a/src/components/ErrorHandlerErrorView.tsx +++ b/src/components/ErrorHandlerErrorView.tsx @@ -30,7 +30,7 @@ const ErrorHandlerErrorView = ({ error }: ErrorHandlerErrorViewProps) => { values={{ link: (chunks: ReactNode) => ( ( saveHex(SaveType.Download)} diff --git a/src/components/NotFound.tsx b/src/components/NotFound.tsx index 043b1ad1c..d9c32ba1a 100644 --- a/src/components/NotFound.tsx +++ b/src/components/NotFound.tsx @@ -19,7 +19,7 @@ const NotFound = ({ href }: NotFoundProps) => { return ( diff --git a/src/components/UnsupportedMicrobitDialog.tsx b/src/components/UnsupportedMicrobitDialog.tsx index ea8d261ad..1992f9dee 100644 --- a/src/components/UnsupportedMicrobitDialog.tsx +++ b/src/components/UnsupportedMicrobitDialog.tsx @@ -51,7 +51,7 @@ const UnsupportedMicrobitDialog = ({ values={{ link: (chunks: ReactNode) => ( ( { + expect(unknownSemanticTokens(appPreset)).toEqual([]); +}); + +// A flat override of a { base, _onDark } token merges wholesale and +// silently drops the dark-surface flip — the same failure, one door over. +it("app preset keeps every condition the base preset's tokens carry", () => { + expect(droppedConditionTokens(appPreset)).toEqual([]); +}); + +// The private brand preset is optional — present only when linked +// (`npm run dev:link-theme`) or installed in a brand build, exactly as +// panda.config.ts treats it. Checked here rather than in its own repo so +// that repo stays free of a dependency on this library, and because the +// merge this guards against happens on this side. +const require = createRequire(import.meta.url); +let brandPreset: unknown; +try { + brandPreset = ( + require("@microbit-foundation/ml-trainer-microbit/panda-preset") as { + default: unknown; + } + ).default; +} catch { + brandPreset = undefined; +} + +describe.skipIf(!brandPreset)("private brand preset", () => { + it("overrides only semantic tokens @microbit/ui defines", () => { + expect(unknownSemanticTokens(brandPreset)).toEqual([]); + }); + + it("keeps every condition the base preset's tokens carry", () => { + expect(droppedConditionTokens(brandPreset)).toEqual([]); + }); +}); diff --git a/src/deployment/default/panda-preset.ts b/src/deployment/default/panda-preset.ts index e1ae00256..1fd478986 100644 --- a/src/deployment/default/panda-preset.ts +++ b/src/deployment/default/panda-preset.ts @@ -271,7 +271,7 @@ export const appPreset = definePreset({ // The native app's status-bar area (the ActionBar and the // full-screen dialog's safe-area gradient) follows the second // accent. - statusBarBg: { value: "{colors.brand2.500}" }, + surface: { statusBar: { value: "{colors.brand2.500}" } }, }, }, // This app's button vocabulary, merged into the core `button` recipe. @@ -309,8 +309,8 @@ export const appPreset = definePreset({ // pressed. Same tokens as `secondary` so the two can't drift. "secondary-disabled": { borderWidth: "2px", - borderColor: "button.secondaryBorder", - color: "button.secondaryText", + borderColor: "button.secondary.border", + color: "button.secondary.fg", bg: "transparent", opacity: "0.4", }, diff --git a/src/pages/OpenSharedProjectPage.tsx b/src/pages/OpenSharedProjectPage.tsx index 704406dc4..75af37187 100644 --- a/src/pages/OpenSharedProjectPage.tsx +++ b/src/pages/OpenSharedProjectPage.tsx @@ -99,7 +99,7 @@ const OpenSharedProjectPage = () => { values={{ link: (children: ReactNode) => (