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
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@
"prepare": "npm run panda",
"panda": "panda codegen",
"panda:watch": "panda codegen --watch",
"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 ../python-editor-v3-microbit run build && mkdir -p node_modules/@microbit-foundation && rm -rf node_modules/@microbit-foundation/python-editor-v3-microbit && ln -s ../../../python-editor-v3-microbit node_modules/@microbit-foundation/python-editor-v3-microbit && rm -rf styled-system && npm run panda",
"dev:unlink-theme": "rm -rf node_modules/@microbit-foundation/python-editor-v3-microbit && rm -rf styled-system && npm run panda",
"serve": "npx serve --no-clipboard -l 3000 -- build/",
"prestart": "npm run panda",
"start": "vite dev",
Expand Down
2 changes: 1 addition & 1 deletion src/common/GenericDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const GenericDialogFooter = ({
variant="link"
size="lg"
onPress={onCloseDontShowAgain}
css={{ color: "brand.500", mr: "auto" }}
css={{ color: "fg.link", mr: "auto" }}
>
<FormattedMessage id="dont-show-again" />
</Button>
Expand Down
2 changes: 1 addition & 1 deletion src/common/PostSaveDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const PostSaveDialogBody = ({
values={{
link: (chunks: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
onClick={handleShowTransferHexHelp}
href=""
cursor="pointer"
Expand Down
62 changes: 62 additions & 0 deletions src/deployment/default/panda-preset.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* (c) 2026, Micro:bit Educational Foundation and contributors
*
* SPDX-License-Identifier: MIT
*/
import {
droppedConditionTokens,
unknownSemanticTokens,
} from "@microbit/ui/preset-lint";

Check failure on line 9 in src/deployment/default/panda-preset.test.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find module '@microbit/ui/preset-lint' or its corresponding type declarations.
import { createRequire } from "node:module";
import { describe, expect, it } from "vitest";
import { appPreset } from "./panda-preset";

// Panda accepts an unknown `semanticTokens` key silently — the override
// never applies and nothing fails, so a rename in @microbit/ui would leave
// this app on the library's colours with a green typecheck. See the
// CSS-variable contract in @microbit/ui's README.

// This app's own semantic tokens, which the base preset does not define.
const introduces = [
"colors.sidebarHeaderBg",
"colors.sidebarTablistBg",
"colors.sidebarTabSelectedText",
"colors.sidebarTabSelectedBg",
];

it("app preset overrides only semantic tokens @microbit/ui defines", () => {
expect(unknownSemanticTokens(appPreset, { introduces })).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/python-editor-v3-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, { introduces })).toEqual([]);
});

it("keeps every condition the base preset's tokens carry", () => {
expect(droppedConditionTokens(brandPreset)).toEqual([]);
});
});
2 changes: 1 addition & 1 deletion src/documentation/api/ApiDocumentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ const ActiveLevel = ({
id="api-description"
values={{
link: (chunks: ReactNode) => (
<Link color="brand.500" onClick={handleReferenceLink} href="">
<Link color="fg.link" onClick={handleReferenceLink} href="">
{chunks}
</Link>
),
Expand Down
6 changes: 3 additions & 3 deletions src/documentation/common/DocumentationContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const DocumentationApiLinkMark = (
const [, setState] = useRouterState();
return (
<Link
color="brand.600"
color="fg.link"
onClick={(e) => {
e.preventDefault();
setState({
Expand All @@ -93,7 +93,7 @@ const DocumentationInternalLinkMark = (
const [state, setState] = useRouterState();
return (
<Link
color="brand.600"
color="fg.link"
onClick={(e) => {
e.preventDefault();
setState(
Expand All @@ -118,7 +118,7 @@ const DocumentationExternalLinkMark = (
) => {
return (
<Link
color="brand.600"
color="fg.link"
href={props.mark.href}
target="_blank"
rel="nofollow noopener"
Expand Down
2 changes: 1 addition & 1 deletion src/documentation/ideas/IdeasDocumentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ const ActiveLevel = ({
values={{
link: (chunks: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
href={microbitOrgMiciProjectsUrl(languageId)}
target="_blank"
rel="noopener"
Expand Down
2 changes: 1 addition & 1 deletion src/editor/ModuleOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const ModuleOverlay = ({ moduleData }: ModuleOverlayProps) => {
link: (chunks: ReactNode) => (
<Button
variant="link"
css={{ color: "brand.500" }}
css={{ color: "fg.link" }}
onPress={handleShowSettings}
>
{chunks}
Expand Down
10 changes: 5 additions & 5 deletions src/workbench/AboutDialog/AboutDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const AboutDialog = ({ isOpen, onClose, finalFocusRef }: AboutDialogProps) => {
<Link
rel="noopener noreferrer"
target="blank"
color="brand.500"
color="fg.link"
href="https://github.com/microbit-foundation/python-editor-v3/graphs/contributors"
>
{chunks}
Expand Down Expand Up @@ -213,7 +213,7 @@ const AboutDialog = ({ isOpen, onClose, finalFocusRef }: AboutDialogProps) => {
values={{
link: (chunks: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
href="https://micropython.org"
target="_blank"
rel="noopener"
Expand Down Expand Up @@ -276,7 +276,7 @@ const MicroPythonSection = () => {
values={{
linkV1: (chunks: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
href="https://github.com/bbcmicrobit/micropython"
target="_blank"
rel="noopener"
Expand All @@ -286,7 +286,7 @@ const MicroPythonSection = () => {
),
linkV2: (_: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
href="https://github.com/microbit-foundation/micropython-microbit-v2"
target="_blank"
rel="noopener"
Expand All @@ -299,7 +299,7 @@ const MicroPythonSection = () => {
</Text>
<Text fontSize="md">
<Link
color="brand.500"
color="fg.link"
href="https://ntoll.org/article/story-micropython-on-microbit/"
target="_blank"
rel="noopener"
Expand Down
2 changes: 1 addition & 1 deletion src/workbench/WelcomeDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const WelcomeDialog = ({ youtubeId, isOpen, onClose }: WelcomeDialogProps) => {
values={{
link: (chunks: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
target="_blank"
rel="noreferrer"
href={guideLink}
Expand Down
2 changes: 1 addition & 1 deletion src/workbench/connect-dialogs/ConnectDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const ConnectDialogFooter = ({
variant="link"
size="lg"
onPress={onNextDontShowAgain}
css={{ color: "brand.500", mr: "auto" }}
css={{ color: "fg.link", mr: "auto" }}
>
<FormattedMessage id="dont-show-again" />
</Button>
Expand Down
4 changes: 2 additions & 2 deletions src/workbench/connect-dialogs/FirmwareDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const FirmwareDialogBody = () => {
values={{
link: (chunks: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
display="inline-flex"
alignItems="center"
target="_blank"
Expand All @@ -86,7 +86,7 @@ const FirmwareDialogBody = () => {
</VStack>
</HStack>
<Link
color="brand.500"
color="fg.link"
display="inline-flex"
alignItems="center"
target="_blank"
Expand Down
10 changes: 3 additions & 7 deletions src/workbench/connect-dialogs/NotFoundDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,7 @@ const NotFoundDialogBody = ({
id="not-found-checklist-one"
values={{
link: (chunks: ReactNode) => (
<Link
color="brand.500"
onClick={handleReviewDevice}
href=""
>
<Link color="fg.link" onClick={handleReviewDevice} href="">
{chunks}
</Link>
),
Expand All @@ -109,7 +105,7 @@ const NotFoundDialogBody = ({
values={{
link: (chunks: ReactNode) => (
<Link
color="brand.500"
color="fg.link"
display="inline-flex"
alignItems="center"
target="_blank"
Expand All @@ -130,7 +126,7 @@ const NotFoundDialogBody = ({
</Text>
</VStack>
<Link
color="brand.500"
color="fg.link"
display="inline-flex"
alignItems="center"
target="_blank"
Expand Down
Loading