From 0788f79a6569c3aa40f362545b46caa1077347d9 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Wed, 13 Aug 2025 16:36:36 -0400 Subject: [PATCH 01/18] Add a mixin for borders --- src/sass/_mixins.scss | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sass/_mixins.scss b/src/sass/_mixins.scss index 65a07f6..fda48ef 100644 --- a/src/sass/_mixins.scss +++ b/src/sass/_mixins.scss @@ -32,6 +32,17 @@ } } +@mixin border($size) { + border-width: 1px; + border-style: solid; + border-radius: map.get(tokens.$border-radius, $size); + + border-color: map.get(tokens.$border-color, dark); + @include light-mode { + border-color: map.get(tokens.$border-color, light); + } +} + @mixin transition($property, $duration) { transition-property: $property; transition-duration: map.get(tokens.$duration, $duration); From cef5f57e26c60d6b5aaaf0d71706e490cfe6f910 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Wed, 13 Aug 2025 16:36:36 -0400 Subject: [PATCH 02/18] Add a Navigation component that auto-hides and stuff --- src/Navigation/Navigation.stories.tsx | 116 ++++++++++++++++++++++++++ src/Navigation/index.scss | 75 +++++++++++++++++ src/Navigation/index.tsx | 57 +++++++++++++ src/index.ts | 2 + 4 files changed, 250 insertions(+) create mode 100644 src/Navigation/Navigation.stories.tsx create mode 100644 src/Navigation/index.scss create mode 100644 src/Navigation/index.tsx diff --git a/src/Navigation/Navigation.stories.tsx b/src/Navigation/Navigation.stories.tsx new file mode 100644 index 0000000..5f17e64 --- /dev/null +++ b/src/Navigation/Navigation.stories.tsx @@ -0,0 +1,116 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; + +import Navigation from "."; +import { Placeholder } from "../Placeholder"; +import Header from "../Header"; +import ColorSchemeToggle from "../ColorSchemeToggle"; +import DetSysIcon from "../DetSysIcon"; + +const meta = { + title: "Molecules/Navigation", + component: Navigation, + argTypes: { + initialState: { + options: ["open", "closed"], + }, + elements: { type: "function" }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + initialState: undefined, + elements: [ + , + , + ], + }, + render: (props) => ( +
+ +
+ ), +}; + +export const InHeader: Story = { + args: { + initialState: undefined, + elements: [ + , + , + ], + }, + render: (props) => ( +
} + elements={[ + , + , + ]} + /> + ), +}; + +export const DefaultOpen: Story = { + args: { + initialState: "open", + elements: [ + , + , + ], + }, + render: (props) => ( + <> +
+ +
+ + ), +}; + +export const InHeaderOpen: Story = { + args: { + initialState: "open", + elements: [ + + Docs + , + + Flakes + , + + Orgs + , + , + , + ], + }, + render: (props) => ( +
} + elements={[ + , + , + ]} + /> + ), +}; diff --git a/src/Navigation/index.scss b/src/Navigation/index.scss new file mode 100644 index 0000000..6f6f870 --- /dev/null +++ b/src/Navigation/index.scss @@ -0,0 +1,75 @@ +@use "sass:map"; + +@use "../sass/mixins"; +@use "../sass/tokens"; +@use "../sass/functions"; + +@media screen and (width >= 1024px) { + .navigation { + height: 24px; // Matches the svg-icon height used by the expander in closed mode + padding: 4px; // Matches the svg-icon height used by the expander in closed mode + .navigation__expand { + display: none; + } + + .navigation__elements { + height: 24px; + display: flex; + flex-direction: row; + align-items: center; + gap: 1em; + } + } +} + +@media screen and (width < 1024px) { + .navigation { + position: relative; + + .navigation__expand { + @include mixins.svg-button; + } + + .navigation__elements { + display: flex; + flex-direction: column; + gap: map.get(tokens.$spacing, sm); + + max-width: 100vw; + + position: absolute; + transform-origin: 100% 0; + z-index: 10; + right: 0; + top: calc(100% + #{map.get(tokens.$spacing, xs)}); + + @include mixins.pad(base); + border-radius: map.get(tokens.$border-radius, base); + + background-color: map.get(tokens.$brand, very-black); + $offset: map.get(tokens.$spacing, xs); + border-style: solid; + border-width: 1px; + border-color: map.get(tokens.$brand, black); + @include mixins.light-mode { + border: none; + background-color: map.get(tokens.$brand, white); + box-shadow: + $offset $offset $offset 0px map.get(tokens.$brand, light), + -$offset $offset $offset 0px map.get(tokens.$brand, light); + } + } + + .navigation__element { + width: min(320px, 100vw); + + @media screen and (width < 650px) { + width: 268px; + } + } + } + + .navigation--closed .navigation__elements { + display: none; + } +} diff --git a/src/Navigation/index.tsx b/src/Navigation/index.tsx new file mode 100644 index 0000000..b9111a8 --- /dev/null +++ b/src/Navigation/index.tsx @@ -0,0 +1,57 @@ +import { useId, useState, type FC } from "react"; + +import "./index.scss"; +import React from "react"; +import clsx from "clsx"; +import { Bars3Icon } from "@heroicons/react/24/outline"; + +export interface NavigationProps { + initialState?: "open" | "closed"; + elements: React.ReactElement[]; +} + +const Navigation: FC = ({ + elements, + initialState = "closed", +}) => { + const navigationId = useId(); + + const [menuState, setMenuState] = useState(initialState === "open"); + + const toggleNavigation = () => { + setMenuState((prev) => !prev); + }; + + return ( + + ); +}; + +export default Navigation; diff --git a/src/index.ts b/src/index.ts index 5821ba8..0385827 100644 --- a/src/index.ts +++ b/src/index.ts @@ -86,3 +86,5 @@ export { } from "./LabeledTextInput"; export { type PageLayoutProps, default as PageLayout } from "./PageLayout"; + +export { type NavigationProps, default as Navigation } from "./Navigation"; From 29b4392a2759b896126c128db16f12251bececf2 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Thu, 14 Aug 2025 21:46:17 -0400 Subject: [PATCH 03/18] Make a more fully fleshed out PageLayout example --- src/PageLayout/PageLayout.stories.tsx | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/PageLayout/PageLayout.stories.tsx b/src/PageLayout/PageLayout.stories.tsx index cd17b03..412ebc6 100644 --- a/src/PageLayout/PageLayout.stories.tsx +++ b/src/PageLayout/PageLayout.stories.tsx @@ -2,6 +2,10 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import PageLayout from "."; import { Placeholder } from "../Placeholder"; +import Header from "../Header"; +import DetSysIcon from "../DetSysIcon"; +import ColorSchemeToggle from "../ColorSchemeToggle"; +import Navigation from "../Navigation"; const meta = { title: "Template/PageLayout", @@ -33,3 +37,30 @@ export const Default: Story = { content: , }, }; + +export const FleshedOut: Story = { + args: { + header: ( +
+ +

DetSys

+ + } + elements={[ + , + , + , + ]} + />, + ]} + /> + ), + content:
, + panes: [], + }, +}; From dc8b25c5a6f6ef3bf818185987996a852bbd8b56 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Thu, 11 Sep 2025 22:51:53 -0400 Subject: [PATCH 04/18] drop header inside Header, and set it in PageLayout --- src/Header/index.tsx | 4 ++-- src/PageLayout/PageLayout.stories.tsx | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Header/index.tsx b/src/Header/index.tsx index 06d3aa4..d608d03 100644 --- a/src/Header/index.tsx +++ b/src/Header/index.tsx @@ -10,7 +10,7 @@ export interface HeaderProps { const Header: FC = ({ logo, elements = [] }) => { return ( -
+
{!!logo &&
{logo}
} @@ -22,7 +22,7 @@ const Header: FC = ({ logo, elements = [] }) => {
)}
-
+
); }; diff --git a/src/PageLayout/PageLayout.stories.tsx b/src/PageLayout/PageLayout.stories.tsx index 412ebc6..9fff7e9 100644 --- a/src/PageLayout/PageLayout.stories.tsx +++ b/src/PageLayout/PageLayout.stories.tsx @@ -53,6 +53,15 @@ export const FleshedOut: Story = { + Docs + , + + Flakes + , + + Orgs + , , , ]} From f671601010913359a2696d0848529053b16f1f94 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Fri, 15 Aug 2025 17:40:22 -0400 Subject: [PATCH 05/18] pin...? --- package-lock.json | 2 +- package.json | 4 ++-- src/ColorProvider/index.tsx | 2 ++ src/hooks/useSystemColorScheme.ts | 13 +++++++++---- src/theme.ts | 6 ++++++ 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index c502941..9355a15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "vitest": "^3.2.4" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19" } }, "node_modules/@adobe/css-tools": { diff --git a/package.json b/package.json index 188afa3..ef5335d 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@vitest/coverage-v8": "^3.2.4" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19" }, "dependencies": { "@heroicons/react": "^2.2.0", @@ -63,4 +63,4 @@ "clsx": "^2.1.1", "react-icons": "^5.5.0" } -} +} \ No newline at end of file diff --git a/src/ColorProvider/index.tsx b/src/ColorProvider/index.tsx index 36e57a0..ecc2bac 100644 --- a/src/ColorProvider/index.tsx +++ b/src/ColorProvider/index.tsx @@ -90,6 +90,8 @@ function writeSchemeToLocalStorage(preference: ColorSchemePreference) { } } +("use client"); + // Helper component for const ColorProvider: React.FC> = ({ useLocalStorage = true, diff --git a/src/hooks/useSystemColorScheme.ts b/src/hooks/useSystemColorScheme.ts index ace382a..d3ecdbe 100644 --- a/src/hooks/useSystemColorScheme.ts +++ b/src/hooks/useSystemColorScheme.ts @@ -1,13 +1,18 @@ -import React from "react"; +import { useEffect, useState } from "react"; import type { ColorScheme } from "../ColorContext"; function darkModeMatcher(): MediaQueryList | undefined { - const media = window?.matchMedia?.("(prefers-color-scheme: dark)"); + if (typeof window === "undefined") { + return undefined; + } + + const media = window.matchMedia?.("(prefers-color-scheme: dark)"); if (!media) { return undefined; } return media; + } function getScheme(matcher: MediaQueryList | MediaQueryListEvent): ColorScheme { @@ -24,11 +29,11 @@ function querySystemColorScheme(): ColorScheme | undefined { } function useSystemColorScheme() { - const [systemColorScheme, setSystemColorScheme] = React.useState( + const [systemColorScheme, setSystemColorScheme] = useState( querySystemColorScheme, ); - React.useEffect(() => { + useEffect(() => { const media = darkModeMatcher(); if (!media) { diff --git a/src/theme.ts b/src/theme.ts index d79dcd9..540d871 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -6,6 +6,12 @@ export function themeForScheme(scheme: ColorScheme): string { export function applyTheme(root: Element, scheme: ColorScheme) { const classes = root.classList; + + if (classes === undefined) { + console.log("classList on the root is null. Assuming we're doing SSR.") + return; + } + const [next, previous]: [ColorScheme, ColorScheme] = scheme === "light" ? ["light", "dark"] : ["dark", "light"]; From d20aaeedce834af822a4495a910bc1f867f7c302 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Fri, 22 Aug 2025 15:07:02 -0400 Subject: [PATCH 06/18] Support server-side rendering --- src/ColorProvider/index.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ColorProvider/index.tsx b/src/ColorProvider/index.tsx index ecc2bac..f069350 100644 --- a/src/ColorProvider/index.tsx +++ b/src/ColorProvider/index.tsx @@ -90,16 +90,20 @@ function writeSchemeToLocalStorage(preference: ColorSchemePreference) { } } -("use client"); - // Helper component for const ColorProvider: React.FC> = ({ useLocalStorage = true, simulatedSystemColorScheme, preferredColorScheme, - root = document.body, + root, children, }) => { + if (!root) { + if (typeof document !== "undefined") { + root = document.body; + } + } + const actualSystemColorScheme = useSystemColorScheme(); const systemColorScheme = simulatedSystemColorScheme ?? actualSystemColorScheme; @@ -112,7 +116,9 @@ const ColorProvider: React.FC> = ({ ); // Apply the theme super early so we don't get a FOUC - applyTheme(root, scheme); + if (root) { + applyTheme(root, scheme); + } // Since we're pretty high up in the component tree, we want to be extremely // careful about re-rendering. Memoization ensures that the object only @@ -130,7 +136,10 @@ const ColorProvider: React.FC> = ({ // Switch body classes depending on the chosen scheme useEffect(() => { - applyTheme(root, scheme); + console.log("beep boop", root); + if (root) { + applyTheme(root, scheme); + } }, [scheme]); return ( From e5917660d7e49143fae08005f265fab4a3153593 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Fri, 22 Aug 2025 16:55:47 -0400 Subject: [PATCH 07/18] Add some icons and more tabs to the CTA --- src/ColorProvider/index.tsx | 1 - src/InstallCTA/InstallCTA.stories.tsx | 6 --- src/InstallCTA/index.scss | 8 ++++ src/InstallCTA/index.tsx | 60 ++++++++++++++------------- src/InstallCTA/types.ts | 5 ++- 5 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/ColorProvider/index.tsx b/src/ColorProvider/index.tsx index f069350..f8d9dba 100644 --- a/src/ColorProvider/index.tsx +++ b/src/ColorProvider/index.tsx @@ -136,7 +136,6 @@ const ColorProvider: React.FC> = ({ // Switch body classes depending on the chosen scheme useEffect(() => { - console.log("beep boop", root); if (root) { applyTheme(root, scheme); } diff --git a/src/InstallCTA/InstallCTA.stories.tsx b/src/InstallCTA/InstallCTA.stories.tsx index 92e0c82..cbd486a 100644 --- a/src/InstallCTA/InstallCTA.stories.tsx +++ b/src/InstallCTA/InstallCTA.stories.tsx @@ -23,12 +23,6 @@ export const MacOS: Story = { }, }; -export const WSL: Story = { - args: { - initialTab: InstallTarget.WSL, - }, -}; - export const Linux: Story = { args: { initialTab: InstallTarget.Linux, diff --git a/src/InstallCTA/index.scss b/src/InstallCTA/index.scss index 6aff8bd..8bb16d3 100644 --- a/src/InstallCTA/index.scss +++ b/src/InstallCTA/index.scss @@ -4,6 +4,14 @@ @use "../sass/mixins"; .install-cta { + .install-cta__header { + font-size: map.get(tokens.$font-size, lg); + color: map.get(tokens.$brand, light); + @include mixins.light-mode { + color: map.get(tokens.$brand, gray); + } + } + strong, p { color: map.get(tokens.$brand, white); diff --git a/src/InstallCTA/index.tsx b/src/InstallCTA/index.tsx index 186f3b2..94167d3 100644 --- a/src/InstallCTA/index.tsx +++ b/src/InstallCTA/index.tsx @@ -1,4 +1,6 @@ import { useState, type FC } from "react"; +import { FaApple, FaLinux, FaAws, FaGithub } from "react-icons/fa6"; +import { SiNixos } from "react-icons/si"; import TabSelector from "./TabSelector"; import { InstallTarget, detectInstallTarget } from "./types"; @@ -19,6 +21,22 @@ export interface InstallCTAProps { initialTab?: InstallTarget; } +const ctaTabs: [InstallTarget, React.FC][] = [ + [InstallTarget.MacOS, FaApple], + [InstallTarget.Linux, FaLinux], + [InstallTarget.AWS, FaAws], + [InstallTarget.GitHub, FaGithub], + [InstallTarget.NixOS, SiNixos], +]; + +const ctaComponents: Record = { + [InstallTarget.MacOS]: MacInstaller, + [InstallTarget.Linux]: InstallFromCurl, + [InstallTarget.AWS]: InstallFromCurl, + [InstallTarget.GitHub]: InstallFromCurl, + [InstallTarget.NixOS]: InstallFromCurl, +}; + /** * A call-to-action component for downloading Determinate Nix. * @@ -33,43 +51,27 @@ const InstallCTA: FC = ({ initialTab }) => { return detectInstallTarget(); }); - const wantsCurlInstall = - activeTab === InstallTarget.WSL || activeTab === InstallTarget.Linux; + const TabBody = ctaComponents[activeTab]; return (

- Get Determinate for {activeTab} +

+ Get Determinate for {activeTab} +

- {activeTab === InstallTarget.MacOS && } - {wantsCurlInstall && } +
    - null} - active={activeTab === InstallTarget.MacOS} - onClick={() => setActiveTab(InstallTarget.MacOS)} - /> - null} - active={activeTab === InstallTarget.WSL} - onClick={() => setActiveTab(InstallTarget.WSL)} - /> - null} - active={activeTab === InstallTarget.Linux} - onClick={() => setActiveTab(InstallTarget.Linux)} - /> - null} - href="https://docs.determinate.systems/guides/advanced-installation/#nixos" - external={true} - /> + {ctaTabs.map(([target, icon]) => ( + setActiveTab(target)} + /> + ))}
); diff --git a/src/InstallCTA/types.ts b/src/InstallCTA/types.ts index 6099ed8..4a45fba 100644 --- a/src/InstallCTA/types.ts +++ b/src/InstallCTA/types.ts @@ -3,9 +3,10 @@ */ export enum InstallTarget { MacOS = "macOS", - WSL = "Windows Subsystem for Linux (WSL)", Linux = "Linux", NixOS = "NixOS", + AWS = "AWS", + GitHub = "GitHub", } /** @@ -17,7 +18,7 @@ export function detectInstallTarget( userAgent = navigator.userAgent, ): InstallTarget { if (userAgent.includes("Windows")) { - return InstallTarget.WSL; + return InstallTarget.Linux; } if (userAgent.includes("Linux")) { From 6e93642a0066baf0323e5ee79d3d5bc2a990b2e0 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 10:32:35 -0400 Subject: [PATCH 08/18] CodeBlock/CodeFile: trim whitespace --- src/CodeBlock/index.tsx | 20 ++++++++++++-------- src/CodeFile/index.tsx | 23 ++++++++++++++--------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/CodeBlock/index.tsx b/src/CodeBlock/index.tsx index 5cd7635..a321696 100644 --- a/src/CodeBlock/index.tsx +++ b/src/CodeBlock/index.tsx @@ -21,13 +21,17 @@ const CodeBlock: FC = ({ code, title, allowCopy = true, -}) => ( -
-
- {title} {allowCopy && } -
- -
-); +}) => { + const trimmedCode = code.trim(); + + return ( +
+
+ {title} {allowCopy && } +
+ +
+ ); +}; export default CodeBlock; diff --git a/src/CodeFile/index.tsx b/src/CodeFile/index.tsx index 6caae06..e2b2800 100644 --- a/src/CodeFile/index.tsx +++ b/src/CodeFile/index.tsx @@ -43,14 +43,19 @@ const CodeFile: FC = ({ download = filename, allowCopy, allowDownload, -}) => ( -
-
- {filename} {allowCopy && }{" "} - {allowDownload && } -
- -
-); +}) => { + const trimmedCode = code.trim() + "\n"; + return ( +
+
+ {filename} {allowCopy && }{" "} + {allowDownload && ( + + )} +
+ +
+ ); +}; export default CodeFile; From 77d4d450a7306ed60943e6c6d9c78de1ab832883 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 10:32:35 -0400 Subject: [PATCH 09/18] Support highlighting nix --- src/hooks/useHighlight.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/hooks/useHighlight.ts b/src/hooks/useHighlight.ts index 3830e90..d0416b5 100644 --- a/src/hooks/useHighlight.ts +++ b/src/hooks/useHighlight.ts @@ -3,6 +3,7 @@ import { createJavaScriptRegexEngine } from "@shikijs/engine-javascript"; import langShell from "@shikijs/langs/shellscript"; import langTerraform from "@shikijs/langs/terraform"; import langYaml from "@shikijs/langs/yaml"; +import langNix from "@shikijs/langs/nix"; import themeGitHubDark from "@shikijs/themes/github-dark"; import themeGitHubLight from "@shikijs/themes/github-light"; import { useMemo } from "react"; @@ -11,10 +12,11 @@ import { useMemo } from "react"; * Languages understood by the UI system's highlighter. The `text` option prevents highlighting. */ export const highlightLanguages = [ + "nix", "shell", - "yaml", "terraform", "text", + "yaml", ] as const; export type HighlightLanguage = (typeof highlightLanguages)[number]; @@ -23,7 +25,12 @@ let shiki: ReturnType; function getShiki() { return (shiki ??= createHighlighterCoreSync({ themes: [themeGitHubLight, themeGitHubDark], - langs: [langShell, langTerraform, langYaml], + langs: [ + langNix, + langShell, + langTerraform, + langYaml, + ], engine: createJavaScriptRegexEngine(), })); } From 82f91049fe5a66b1b1bdc913ed786d80e095d525 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 10:32:35 -0400 Subject: [PATCH 10/18] Add a bunch of new tabs for the install CTA --- src/InstallCTA/FindAwsAMIs.tsx | 28 +++++++++++++++ src/InstallCTA/InstallCTA.stories.tsx | 20 +++++++++++ src/InstallCTA/InstallForNixOS.tsx | 46 +++++++++++++++++++++++++ src/InstallCTA/InstallFromCurl.tsx | 5 ++- src/InstallCTA/NavTab.tsx | 33 ------------------ src/InstallCTA/UseWithGitHubActions.tsx | 42 ++++++++++++++++++++++ src/InstallCTA/index.tsx | 13 ++++--- 7 files changed, 148 insertions(+), 39 deletions(-) create mode 100644 src/InstallCTA/FindAwsAMIs.tsx create mode 100644 src/InstallCTA/InstallForNixOS.tsx delete mode 100644 src/InstallCTA/NavTab.tsx create mode 100644 src/InstallCTA/UseWithGitHubActions.tsx diff --git a/src/InstallCTA/FindAwsAMIs.tsx b/src/InstallCTA/FindAwsAMIs.tsx new file mode 100644 index 0000000..ae62e3e --- /dev/null +++ b/src/InstallCTA/FindAwsAMIs.tsx @@ -0,0 +1,28 @@ +import type { FC } from "react"; +import CodeBlock from "../CodeBlock"; +import Link from "../Link"; +import GitHubButton from "../GitHubButton"; + +const code = `aws ec2 describe-images \\ + --owners 535002876703 \\ + --filters "Name=name,Values=determinate/nixos/epoch-1/*" \\ + "Name=architecture,Values=x86_64,arm64" \\ + --query "Images | sort_by(@, &CreationDate) | [-1]"`; + +const FindAwsAMIs: FC = () => { + return ( + <> +

+ Use NixOS with Determinate on AWS with our pre-published AMIs in every + region. +

+ +

+ See DeterminateSystems/nixos-amis on GitHub{" "} + +

+ + ); +}; + +export default FindAwsAMIs; diff --git a/src/InstallCTA/InstallCTA.stories.tsx b/src/InstallCTA/InstallCTA.stories.tsx index cbd486a..0c24908 100644 --- a/src/InstallCTA/InstallCTA.stories.tsx +++ b/src/InstallCTA/InstallCTA.stories.tsx @@ -28,3 +28,23 @@ export const Linux: Story = { initialTab: InstallTarget.Linux, }, }; + +export const AWS: Story = { + args: { + initialTab: InstallTarget.AWS, + }, +}; + +export const GitHub: Story = { + name: "GitHub", + args: { + initialTab: InstallTarget.GitHub, + }, +}; + +export const NixOS: Story = { + name: "NixOS", + args: { + initialTab: InstallTarget.NixOS, + }, +}; diff --git a/src/InstallCTA/InstallForNixOS.tsx b/src/InstallCTA/InstallForNixOS.tsx new file mode 100644 index 0000000..d2ee604 --- /dev/null +++ b/src/InstallCTA/InstallForNixOS.tsx @@ -0,0 +1,46 @@ +import type { FC } from "react"; +import CodeFile from "../CodeFile"; +import CodeBlock from "../CodeBlock"; +import Link from "../Link"; + +const code = ` +nixosConfigurations.workstation = nixpkgs.lib.nixosSystem { + modules = [ + # Load the Determinate module + determinate.nixosModules.default + ./configuration.nix + ]; +}; +`; + +const InstallForNixOS: FC = () => { + return ( + <> +

+ + + +

+ For more details, see{" "} + + Install on NixOS + + . +

+ + ); +}; + +export default InstallForNixOS; diff --git a/src/InstallCTA/InstallFromCurl.tsx b/src/InstallCTA/InstallFromCurl.tsx index 7a00817..594f67b 100644 --- a/src/InstallCTA/InstallFromCurl.tsx +++ b/src/InstallCTA/InstallFromCurl.tsx @@ -7,7 +7,10 @@ const installScript = const InstallFromCurl: FC = () => ( <> -

Use the Determinate Nix Installer CLI

+

+ Use the Determinate Nix Installer CLI for Linux, including Windows + Subsystem for Linx (WSL). +

= ({ - name, - icon: Icon, - href, - external = false, -}) => ( -
  • - - {name} - - -
  • -); - -export default NavTab; diff --git a/src/InstallCTA/UseWithGitHubActions.tsx b/src/InstallCTA/UseWithGitHubActions.tsx new file mode 100644 index 0000000..4b7ab9b --- /dev/null +++ b/src/InstallCTA/UseWithGitHubActions.tsx @@ -0,0 +1,42 @@ +import type { FC } from "react"; +import CodeBlock from "../CodeBlock"; +import Link from "../Link"; +import GitHubButton from "../GitHubButton"; +import CodeFile from "../CodeFile"; + +const code = ` +on: + push: +jobs: + tests: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v5 + - uses: DeterminateSystems/determinate-nix-action@v3 + - run: nix build .# + +`; + +const UseWithGitHubActions: FC = () => { + return ( + <> +

    Use Determinate Nix in GitHub Actions.

    + +

    + See our other{" "} + + GitHub Actions + + . +

    + + ); +}; + +export default UseWithGitHubActions; diff --git a/src/InstallCTA/index.tsx b/src/InstallCTA/index.tsx index 94167d3..a069cac 100644 --- a/src/InstallCTA/index.tsx +++ b/src/InstallCTA/index.tsx @@ -6,10 +6,13 @@ import TabSelector from "./TabSelector"; import { InstallTarget, detectInstallTarget } from "./types"; import InstallFromCurl from "./InstallFromCurl"; +import FindAwsAMIs from "./FindAwsAMIs"; +import UseWithGitHubActions from "./UseWithGitHubActions"; +import InstallForNixOS from "./InstallForNixOS"; + import MacInstaller from "../MacInstaller"; import "./index.scss"; -import NavTab from "./NavTab"; export { InstallTarget as CTAType } from "./types"; @@ -24,17 +27,17 @@ export interface InstallCTAProps { const ctaTabs: [InstallTarget, React.FC][] = [ [InstallTarget.MacOS, FaApple], [InstallTarget.Linux, FaLinux], + [InstallTarget.NixOS, SiNixos], [InstallTarget.AWS, FaAws], [InstallTarget.GitHub, FaGithub], - [InstallTarget.NixOS, SiNixos], ]; const ctaComponents: Record = { [InstallTarget.MacOS]: MacInstaller, [InstallTarget.Linux]: InstallFromCurl, - [InstallTarget.AWS]: InstallFromCurl, - [InstallTarget.GitHub]: InstallFromCurl, - [InstallTarget.NixOS]: InstallFromCurl, + [InstallTarget.AWS]: FindAwsAMIs, + [InstallTarget.GitHub]: UseWithGitHubActions, + [InstallTarget.NixOS]: InstallForNixOS, }; /** From 39333145f3fd7217b66d38c14177ad3188eb0c22 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 11:36:35 -0400 Subject: [PATCH 11/18] Make the cta look better --- package.json | 2 +- src/InstallCTA/FindAwsAMIs.tsx | 1 - src/InstallCTA/InstallForNixOS.tsx | 1 - src/InstallCTA/InstallFromCurl.tsx | 2 +- src/InstallCTA/UseWithGitHubActions.tsx | 2 -- src/InstallCTA/index.scss | 37 ++++++++++++++++++++----- src/InstallCTA/index.tsx | 2 +- src/hooks/useHighlight.ts | 7 +---- src/hooks/useSystemColorScheme.ts | 1 - src/sass/_mixins.scss | 15 ++++++++++ src/sass/_tokens.scss | 2 ++ 11 files changed, 51 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index ef5335d..0715e53 100644 --- a/package.json +++ b/package.json @@ -63,4 +63,4 @@ "clsx": "^2.1.1", "react-icons": "^5.5.0" } -} \ No newline at end of file +} diff --git a/src/InstallCTA/FindAwsAMIs.tsx b/src/InstallCTA/FindAwsAMIs.tsx index ae62e3e..7580cd9 100644 --- a/src/InstallCTA/FindAwsAMIs.tsx +++ b/src/InstallCTA/FindAwsAMIs.tsx @@ -1,6 +1,5 @@ import type { FC } from "react"; import CodeBlock from "../CodeBlock"; -import Link from "../Link"; import GitHubButton from "../GitHubButton"; const code = `aws ec2 describe-images \\ diff --git a/src/InstallCTA/InstallForNixOS.tsx b/src/InstallCTA/InstallForNixOS.tsx index d2ee604..c8e0022 100644 --- a/src/InstallCTA/InstallForNixOS.tsx +++ b/src/InstallCTA/InstallForNixOS.tsx @@ -1,5 +1,4 @@ import type { FC } from "react"; -import CodeFile from "../CodeFile"; import CodeBlock from "../CodeBlock"; import Link from "../Link"; diff --git a/src/InstallCTA/InstallFromCurl.tsx b/src/InstallCTA/InstallFromCurl.tsx index 594f67b..7b8c3cd 100644 --- a/src/InstallCTA/InstallFromCurl.tsx +++ b/src/InstallCTA/InstallFromCurl.tsx @@ -9,7 +9,7 @@ const InstallFromCurl: FC = () => ( <>

    Use the Determinate Nix Installer CLI for Linux, including Windows - Subsystem for Linx (WSL). + Subsystem for Linux (WSL).

    = ({ initialTab }) => { Get Determinate for {activeTab}

    -
    +
      diff --git a/src/hooks/useHighlight.ts b/src/hooks/useHighlight.ts index d0416b5..87cb2e0 100644 --- a/src/hooks/useHighlight.ts +++ b/src/hooks/useHighlight.ts @@ -25,12 +25,7 @@ let shiki: ReturnType; function getShiki() { return (shiki ??= createHighlighterCoreSync({ themes: [themeGitHubLight, themeGitHubDark], - langs: [ - langNix, - langShell, - langTerraform, - langYaml, - ], + langs: [langNix, langShell, langTerraform, langYaml], engine: createJavaScriptRegexEngine(), })); } diff --git a/src/hooks/useSystemColorScheme.ts b/src/hooks/useSystemColorScheme.ts index d3ecdbe..3a8ec52 100644 --- a/src/hooks/useSystemColorScheme.ts +++ b/src/hooks/useSystemColorScheme.ts @@ -12,7 +12,6 @@ function darkModeMatcher(): MediaQueryList | undefined { } return media; - } function getScheme(matcher: MediaQueryList | MediaQueryListEvent): ColorScheme { diff --git a/src/sass/_mixins.scss b/src/sass/_mixins.scss index fda48ef..f03cd29 100644 --- a/src/sass/_mixins.scss +++ b/src/sass/_mixins.scss @@ -43,6 +43,21 @@ } } +@mixin shadow { + box-shadow: + 0 0 #0000, + 0 0 #0000, + 0 1px 3px 0 rgba(0, 0, 0, 0.1), + 0 1px 2px -1px rgba(0, 0, 0, 0.1); + @include light-mode { + box-shadow: + 0 0 #0000, + 0 0 #0000, + 0 1px 3px 0 rgba(0, 0, 0, 0.1), + 0 1px 2px -1px rgba(0, 0, 0, 0.1); + } +} + @mixin transition($property, $duration) { transition-property: $property; transition-duration: map.get(tokens.$duration, $duration); diff --git a/src/sass/_tokens.scss b/src/sass/_tokens.scss index aa90a35..039b5b3 100644 --- a/src/sass/_tokens.scss +++ b/src/sass/_tokens.scss @@ -102,6 +102,8 @@ $spacing: ( xs: 0.25rem, sm: 0.5rem, base: 0.75rem, + lg: 0.75rem, + xl: 1rem, ); $breakpoints: ( From da97c1caf17323bb5cb45b8ab1f22d660ac92b06 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 12:55:08 -0400 Subject: [PATCH 12/18] Make the CodeBlock look nicer and subsume CodeFile --- src/CodeBlock/CodeBlock.stories.tsx | 58 +++++++++++++++++++ src/CodeBlock/index.scss | 32 ++++++++++- src/CodeBlock/index.tsx | 29 +++++++++- src/CodeFile/CodeFile.stories.tsx | 75 ------------------------- src/CodeFile/index.scss | 12 ---- src/CodeFile/index.tsx | 61 -------------------- src/InstallCTA/FindAwsAMIs.tsx | 7 ++- src/InstallCTA/InstallForNixOS.tsx | 2 + src/InstallCTA/InstallFromCurl.tsx | 1 + src/InstallCTA/UseWithGitHubActions.tsx | 7 ++- src/sass/_mixins.scss | 40 +++++++++++++ 11 files changed, 170 insertions(+), 154 deletions(-) delete mode 100644 src/CodeFile/CodeFile.stories.tsx delete mode 100644 src/CodeFile/index.scss delete mode 100644 src/CodeFile/index.tsx diff --git a/src/CodeBlock/CodeBlock.stories.tsx b/src/CodeBlock/CodeBlock.stories.tsx index d7ffe5b..e20d476 100644 --- a/src/CodeBlock/CodeBlock.stories.tsx +++ b/src/CodeBlock/CodeBlock.stories.tsx @@ -11,9 +11,16 @@ const meta = { control: "select", options: [...highlightLanguages], }, + kind: { + control: "select", + options: ["snippet", "file"], + }, code: { control: "text" }, allowCopy: { control: "boolean" }, }, + args: { + kind: "snippet", + }, } satisfies Meta; export default meta; @@ -55,3 +62,54 @@ jobs: allowCopy: true, }, }; +export const GithubCI: Story = { + args: { + language: "yaml", + code: `on: + pull_request: + workflow_dispatch: + push: + branches: + - main + +jobs: + nix-ci: + runs-on: ubuntu-latest + # Include this block to log in to FlakeHub and access private flakes + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/determinate-nix-action@v3 + - uses: DeterminateSystems/flakehub-cache-action@main + - uses: DeterminateSystems/nix-flake-checker-action@main + - run: nix flake check`, + title: ".github/workflows/nix-ci.yaml", + kind: "file", + allowCopy: true, + allowDownload: true, + }, +}; + +export const AWS: Story = { + args: { + language: "terraform", + code: `data "aws_ami" "detsys_nixos" { + owners = ["535002876703"] + most_recent = true + + filter { + name = "name" + values = ["determinate/nixos/epoch-1/*"] + } + + filter { + name = "architecture" + values = ["x86_64"] # or "ARM64" for Graviton + } +}`, + title: "aws_ami.tf", + kind: "file", + }, +}; diff --git a/src/CodeBlock/index.scss b/src/CodeBlock/index.scss index 3a49997..d6b5c7e 100644 --- a/src/CodeBlock/index.scss +++ b/src/CodeBlock/index.scss @@ -2,7 +2,37 @@ @use "../sass/mixins"; @use "../sass/tokens"; +@use "../sass/functions"; + +.code-block { + @include mixins.border(base); + + .highlight { + @include mixins.border-bottom(base); + @include mixins.pad(base); + } +} .code-block__heading { - @include mixins.pad-bottom(lg); + @include mixins.border-top(base); + + padding: map.get(tokens.$spacing, base) map.get(tokens.$spacing, lg); + text-align: center; + align-items: center; + justify-content: space-between; + display: flex; + + @include mixins.light-mode { + color: map.get(tokens.$brand, black); + } + + background: functions.lighten(map.get(tokens.$brand, black), 5%); + @include mixins.light-mode { + background: functions.darken(map.get(tokens.$brand, white), 5%); + } + background-repeat: no-repeat; + + .code-block__title--file { + font-family: map.get(tokens.$fonts, mono); + } } diff --git a/src/CodeBlock/index.tsx b/src/CodeBlock/index.tsx index a321696..1ed4ac5 100644 --- a/src/CodeBlock/index.tsx +++ b/src/CodeBlock/index.tsx @@ -5,12 +5,17 @@ import Highlight from "../Highlight"; import CopyButton from "../CopyButton"; import "./index.scss"; +import DownloadButton from "../DownloadButton"; +import clsx from "clsx"; export interface CodeBlockProps { language: HighlightLanguage; code: string; title: string; + downloadAs?: string; allowCopy?: boolean; + allowDownload?: boolean; + kind: "snippet" | "file"; } /** @@ -20,14 +25,36 @@ const CodeBlock: FC = ({ language, code, title, + downloadAs = title, + allowDownload = true, allowCopy = true, + kind = "snippet", }) => { const trimmedCode = code.trim(); + const isFile = kind === "file"; return (
      - {title} {allowCopy && } + + {title} + + {(allowCopy || allowDownload) && ( + + {allowCopy && } + {allowDownload && isFile && ( + + )} + + )}
      diff --git a/src/CodeFile/CodeFile.stories.tsx b/src/CodeFile/CodeFile.stories.tsx deleted file mode 100644 index a788384..0000000 --- a/src/CodeFile/CodeFile.stories.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - -import CodeFile from "./"; -import { highlightLanguages } from "../hooks/useHighlight"; - -const meta = { - title: "Molecules/CodeFile", - component: CodeFile, - argTypes: { - language: { - control: "select", - options: [...highlightLanguages], - }, - code: { control: "text" }, - filename: { control: "text" }, - allowCopy: { control: "boolean" }, - allowDownload: { control: "boolean" }, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const GithubCI: Story = { - args: { - language: "yaml", - code: `on: - pull_request: - workflow_dispatch: - push: - branches: - - main - -jobs: - nix-ci: - runs-on: ubuntu-latest - # Include this block to log in to FlakeHub and access private flakes - permissions: - id-token: write - contents: read - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/determinate-nix-action@v3 - - uses: DeterminateSystems/flakehub-cache-action@main - - uses: DeterminateSystems/nix-flake-checker-action@main - - run: nix flake check`, - filename: ".github/workflows/nix-ci.yaml", - download: "github-nix-ci.yaml", - allowCopy: true, - allowDownload: true, - }, -}; - -export const AWS: Story = { - args: { - language: "terraform", - code: `data "aws_ami" "detsys_nixos" { - owners = ["535002876703"] - most_recent = true - - filter { - name = "name" - values = ["determinate/nixos/epoch-1/*"] - } - - filter { - name = "architecture" - values = ["x86_64"] # or "ARM64" for Graviton - } -}`, - filename: "aws_ami.tf", - allowCopy: true, - allowDownload: true, - }, -}; diff --git a/src/CodeFile/index.scss b/src/CodeFile/index.scss deleted file mode 100644 index 26a9387..0000000 --- a/src/CodeFile/index.scss +++ /dev/null @@ -1,12 +0,0 @@ -@use "sass:map"; - -@use "../sass/tokens"; -@use "../sass/mixins"; - -.code-file__heading code { - font-family: map.get(tokens.$fonts, mono); - color: map.get(tokens.$brand, white); - @include mixins.light-mode { - color: map.get(tokens.$brand, black); - } -} diff --git a/src/CodeFile/index.tsx b/src/CodeFile/index.tsx deleted file mode 100644 index e2b2800..0000000 --- a/src/CodeFile/index.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { type FC } from "react"; - -import type { HighlightLanguage } from "../hooks/useHighlight"; -import CopyButton from "../CopyButton"; -import DownloadButton from "../DownloadButton"; -import Highlight from "../Highlight"; - -import "./index.scss"; - -export interface CodeFileProps { - language: HighlightLanguage; - code: string; - - /** - * The filename to use for displaying. - */ - filename: string; - - /** - * If an alternative download filename is required (for example, a user might - * download a dot-prefixed filename that is hidden by default on macOS and - * Linux). - * - * Defaults to the value of `filename` - */ - download?: string; - - /** - * Whether or not to allow copying. Defaults to true. - */ - allowCopy?: boolean; - - /** - * Whether or not to allow downloading. Defaults to true. - */ - allowDownload?: boolean; -} - -const CodeFile: FC = ({ - language, - code, - filename, - download = filename, - allowCopy, - allowDownload, -}) => { - const trimmedCode = code.trim() + "\n"; - return ( -
      -
      - {filename} {allowCopy && }{" "} - {allowDownload && ( - - )} -
      - -
      - ); -}; - -export default CodeFile; diff --git a/src/InstallCTA/FindAwsAMIs.tsx b/src/InstallCTA/FindAwsAMIs.tsx index 7580cd9..6c7094d 100644 --- a/src/InstallCTA/FindAwsAMIs.tsx +++ b/src/InstallCTA/FindAwsAMIs.tsx @@ -15,7 +15,12 @@ const FindAwsAMIs: FC = () => { Use NixOS with Determinate on AWS with our pre-published AMIs in every region.

      - +

      See DeterminateSystems/nixos-amis on GitHub{" "} diff --git a/src/InstallCTA/InstallForNixOS.tsx b/src/InstallCTA/InstallForNixOS.tsx index c8e0022..410c5c1 100644 --- a/src/InstallCTA/InstallForNixOS.tsx +++ b/src/InstallCTA/InstallForNixOS.tsx @@ -17,11 +17,13 @@ const InstallForNixOS: FC = () => { <>

      ( Subsystem for Linux (WSL).

      { return ( <>

      Use Determinate Nix in GitHub Actions.

      - diff --git a/src/sass/_mixins.scss b/src/sass/_mixins.scss index f03cd29..3a64cf3 100644 --- a/src/sass/_mixins.scss +++ b/src/sass/_mixins.scss @@ -43,6 +43,46 @@ } } +@mixin border-top($size) { + border-top-width: 1px; + border-top-style: solid; + border-left-style: solid; + border-right-style: solid; + border-left-width: 1px; + border-right-width: 1px; + border-top-left-radius: calc(map.get(tokens.$border-radius, $size) - 1px); + border-top-right-radius: calc(map.get(tokens.$border-radius, $size) - 1px); + + border-top-color: map.get(tokens.$border-color, dark); + border-left-color: map.get(tokens.$border-color, dark); + border-right-color: map.get(tokens.$border-color, dark); + @include light-mode { + border-top-color: map.get(tokens.$border-color, light); + border-left-color: map.get(tokens.$border-color, light); + border-right-color: map.get(tokens.$border-color, light); + } +} + +@mixin border-bottom($size) { + border-bottom-width: 1px; + border-bottom-style: solid; + border-left-style: solid; + border-right-style: solid; + border-left-width: 1px; + border-right-width: 1px; + border-bottom-left-radius: calc(map.get(tokens.$border-radius, $size) - 1px); + border-bottom-right-radius: calc(map.get(tokens.$border-radius, $size) - 1px); + + border-bottom-color: map.get(tokens.$border-color, dark); + border-left-color: map.get(tokens.$border-color, dark); + border-right-color: map.get(tokens.$border-color, dark); + @include light-mode { + border-bottom-color: map.get(tokens.$border-color, light); + border-left-color: map.get(tokens.$border-color, light); + border-right-color: map.get(tokens.$border-color, light); + } +} + @mixin shadow { box-shadow: 0 0 #0000, From f97eb8f39bf349c8474286cdc6134ba752fef2de Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 12:55:08 -0400 Subject: [PATCH 13/18] Tidy up --- src/CodeBlock/index.scss | 1 + src/InstallCTA/InstallForNixOS.tsx | 13 +++++---- src/InstallCTA/UseWithGitHubActions.tsx | 9 +----- src/InstallCTA/index.scss | 38 ++++++++++++++++--------- src/InstallCTA/index.tsx | 8 ++---- src/sass/_mixins.scss | 6 ++++ 6 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/CodeBlock/index.scss b/src/CodeBlock/index.scss index d6b5c7e..d1d463b 100644 --- a/src/CodeBlock/index.scss +++ b/src/CodeBlock/index.scss @@ -6,6 +6,7 @@ .code-block { @include mixins.border(base); + @include mixins.margin-y(xl); .highlight { @include mixins.border-bottom(base); diff --git a/src/InstallCTA/InstallForNixOS.tsx b/src/InstallCTA/InstallForNixOS.tsx index 410c5c1..8f98b3b 100644 --- a/src/InstallCTA/InstallForNixOS.tsx +++ b/src/InstallCTA/InstallForNixOS.tsx @@ -15,18 +15,21 @@ nixosConfigurations.workstation = nixpkgs.lib.nixosSystem { const InstallForNixOS: FC = () => { return ( <> -

      +

      Add Determinate as an input to your flake:

      +

      Then, include the Determinate NixOS module:

      diff --git a/src/InstallCTA/UseWithGitHubActions.tsx b/src/InstallCTA/UseWithGitHubActions.tsx index ccb5bec..f1a383c 100644 --- a/src/InstallCTA/UseWithGitHubActions.tsx +++ b/src/InstallCTA/UseWithGitHubActions.tsx @@ -19,14 +19,7 @@ const UseWithGitHubActions: FC = () => { return ( <>

      Use Determinate Nix in GitHub Actions.

      - +

      See our other{" "} diff --git a/src/InstallCTA/index.scss b/src/InstallCTA/index.scss index f00f406..9c4f7dc 100644 --- a/src/InstallCTA/index.scss +++ b/src/InstallCTA/index.scss @@ -2,12 +2,15 @@ @use "../sass/tokens"; @use "../sass/mixins"; +@use "../sass/functions"; .install-cta { @include mixins.border(base); @include mixins.pad(lg); @include mixins.shadow; + width: 100%; + .install-cta__header { font-weight: 600; font-size: map.get(tokens.$font-size, lg); @@ -30,21 +33,22 @@ } } +.install-cta__body { + margin: map.get(tokens.$spacing, xl) 0; + + p { + font-size: map.get(tokens.$font-size, base); + } +} + .install-cta__links { display: flex; flex-direction: row; + flex-wrap: wrap; gap: map.get(tokens.$spacing, base); list-style-type: none; - margin-top: map.get(tokens.$padding, lg); - padding: 0; -} - -.install-cta__body { - margin: map.get(tokens.$spacing, lg) 0; -} - -.install-cta__tab { + padding-top: map.get(tokens.$spacing, base); } .install-cta__link { @@ -56,6 +60,12 @@ border-top: 2px solid rgba($color: map.get(tokens.$colors, secondary), $alpha: 0); padding: map.get(tokens.$spacing, lg) map.get(tokens.$spacing, base); + @include mixins.transition(color, short); + + color: functions.lighten(map.get(tokens.$brand, black), 30%); + border-top: 2px solid + rgba($color: map.get(tokens.$colors, secondary), $alpha: 0); + padding: map.get(tokens.$spacing, lg) map.get(tokens.$spacing, xs); svg { padding-right: map.get(tokens.$padding, base); @@ -63,13 +73,15 @@ width: auto; } - &.install-cta__link--active { - border-top-color: map.get(tokens.$colors, primary); + &:hover { + color: map.get(tokens.$brand, very-black); + border-top-color: map.get(tokens.$colors, secondary); } - &:hover, + &.install-cta__link--active, &:focus { - border-top-color: map.get(tokens.$colors, secondary); + color: map.get(tokens.$brand, ocean-blue); + border-top-color: map.get(tokens.$brand, ocean-blue); } } diff --git a/src/InstallCTA/index.tsx b/src/InstallCTA/index.tsx index ab09a18..151ec93 100644 --- a/src/InstallCTA/index.tsx +++ b/src/InstallCTA/index.tsx @@ -58,11 +58,9 @@ const InstallCTA: FC = ({ initialTab }) => { return (

      -

      -

      - Get Determinate for {activeTab} -
      -

      +
      + Get Determinate for {activeTab} +
      diff --git a/src/sass/_mixins.scss b/src/sass/_mixins.scss index 3a64cf3..5626814 100644 --- a/src/sass/_mixins.scss +++ b/src/sass/_mixins.scss @@ -103,6 +103,12 @@ transition-duration: map.get(tokens.$duration, $duration); } +@mixin margin-y($size) { + $spacing: map.get(tokens.$spacing, $size); + + margin: $spacing 0; +} + @mixin pad($size) { $padding: map.get(tokens.$padding, $size); From 1ad8088a2ce505c3d794495ef167ebcb68b2a889 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 16:21:11 -0400 Subject: [PATCH 14/18] Make the AWS icon look better --- src/InstallCTA/index.scss | 7 +++++++ src/InstallCTA/index.tsx | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/InstallCTA/index.scss b/src/InstallCTA/index.scss index 9c4f7dc..cb22c89 100644 --- a/src/InstallCTA/index.scss +++ b/src/InstallCTA/index.scss @@ -45,6 +45,8 @@ display: flex; flex-direction: row; flex-wrap: wrap; + text-align: center; + align-items: center; gap: map.get(tokens.$spacing, base); list-style-type: none; @@ -53,6 +55,7 @@ .install-cta__link { display: flex; + text-align: center; align-items: center; text-wrap-mode: nowrap; @@ -73,6 +76,10 @@ width: auto; } + svg.install-cta__icon--apple { + height: 30px; + } + &:hover { color: map.get(tokens.$brand, very-black); border-top-color: map.get(tokens.$colors, secondary); diff --git a/src/InstallCTA/index.tsx b/src/InstallCTA/index.tsx index 151ec93..59093cd 100644 --- a/src/InstallCTA/index.tsx +++ b/src/InstallCTA/index.tsx @@ -28,7 +28,7 @@ const ctaTabs: [InstallTarget, React.FC][] = [ [InstallTarget.MacOS, FaApple], [InstallTarget.Linux, FaLinux], [InstallTarget.NixOS, SiNixos], - [InstallTarget.AWS, FaAws], + [InstallTarget.AWS, () => ], [InstallTarget.GitHub, FaGithub], ]; From 2111385d628da245301b6d8cc2df91a0273b08ff Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 16:29:50 -0400 Subject: [PATCH 15/18] knolling --- src/Highlight/index.scss | 6 ++--- src/InstallCTA/FindAwsAMIs.tsx | 9 ++++--- src/InstallCTA/index.scss | 44 +++++++++++++++++++++++----------- src/InstallCTA/index.tsx | 16 ++++++------- src/Link/index.scss | 2 ++ src/sass/_tokens.scss | 2 +- 6 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/Highlight/index.scss b/src/Highlight/index.scss index f639e31..8b0e470 100644 --- a/src/Highlight/index.scss +++ b/src/Highlight/index.scss @@ -4,16 +4,14 @@ @use "../sass/mixins"; // Default values taken from Shiki's 'classic' output type -$shiki-dark-bg: #24292e; -$shiki-light-bg: #fff; .highlight { text-wrap-mode: wrap; line-break: anywhere; - background-color: var(--shiki-dark-bg, map.get(tokens.$code, bg-dark)); + background-color: map.get(tokens.$code, bg-dark); @include mixins.light-mode { - background-color: var(--shiki-light-bg, map.get(tokens.$code, bg-light)); + background-color: map.get(tokens.$code, bg-light); } &.highlight--inline { diff --git a/src/InstallCTA/FindAwsAMIs.tsx b/src/InstallCTA/FindAwsAMIs.tsx index 6c7094d..d9506e2 100644 --- a/src/InstallCTA/FindAwsAMIs.tsx +++ b/src/InstallCTA/FindAwsAMIs.tsx @@ -1,6 +1,6 @@ import type { FC } from "react"; import CodeBlock from "../CodeBlock"; -import GitHubButton from "../GitHubButton"; +import Link from "../Link"; const code = `aws ec2 describe-images \\ --owners 535002876703 \\ @@ -22,8 +22,11 @@ const FindAwsAMIs: FC = () => { title={"Search for AMIs"} />

      - See DeterminateSystems/nixos-amis on GitHub{" "} - + See{" "} + + DeterminateSystems/nixos-amis on GitHub + + .

      ); diff --git a/src/InstallCTA/index.scss b/src/InstallCTA/index.scss index cb22c89..6e94eb9 100644 --- a/src/InstallCTA/index.scss +++ b/src/InstallCTA/index.scss @@ -6,12 +6,13 @@ .install-cta { @include mixins.border(base); - @include mixins.pad(lg); @include mixins.shadow; width: 100%; .install-cta__header { + @include mixins.pad(lg); + font-weight: 600; font-size: map.get(tokens.$font-size, lg); color: map.get(tokens.$brand, light); @@ -34,6 +35,7 @@ } .install-cta__body { + @include mixins.pad(lg); margin: map.get(tokens.$spacing, xl) 0; p { @@ -42,6 +44,7 @@ } .install-cta__links { + @include mixins.pad(lg); display: flex; flex-direction: row; flex-wrap: wrap; @@ -50,7 +53,11 @@ gap: map.get(tokens.$spacing, base); list-style-type: none; - padding-top: map.get(tokens.$spacing, base); + padding-bottom: map.get(tokens.$spacing, base); + border-bottom: 1px solid map.get(tokens.$border-color, dark); + @include mixins.light-mode { + border-bottom: 1px solid map.get(tokens.$border-color, light); + } } .install-cta__link { @@ -59,14 +66,14 @@ align-items: center; text-wrap-mode: nowrap; - @include mixins.transition(border-top-color, shortish); - border-top: 2px solid - rgba($color: map.get(tokens.$colors, secondary), $alpha: 0); - padding: map.get(tokens.$spacing, lg) map.get(tokens.$spacing, base); - @include mixins.transition(color, short); + @include mixins.transition(border-bottom-color, shortish); + @include mixins.transition(color, shortish); - color: functions.lighten(map.get(tokens.$brand, black), 30%); - border-top: 2px solid + color: functions.darken(map.get(tokens.$brand, white), 15%); + @include mixins.light-mode { + color: functions.lighten(map.get(tokens.$brand, black), 30%); + } + border-bottom: 2px solid rgba($color: map.get(tokens.$colors, secondary), $alpha: 0); padding: map.get(tokens.$spacing, lg) map.get(tokens.$spacing, xs); @@ -76,19 +83,28 @@ width: auto; } - svg.install-cta__icon--apple { + svg.install-cta__icon--aws { height: 30px; + margin-top: 5px; } &:hover { - color: map.get(tokens.$brand, very-black); - border-top-color: map.get(tokens.$colors, secondary); + color: map.get(tokens.$brand, white); + border-bottom-color: map.get(tokens.$colors, secondary); + @include mixins.light-mode { + color: map.get(tokens.$brand, very-black); + } } &.install-cta__link--active, &:focus { - color: map.get(tokens.$brand, ocean-blue); - border-top-color: map.get(tokens.$brand, ocean-blue); + color: map.get(tokens.$brand, sky-blue); + border-bottom-color: map.get(tokens.$brand, sky-blue); + + @include mixins.light-mode { + color: map.get(tokens.$brand, ocean-blue); + border-bottom-color: map.get(tokens.$brand, ocean-blue); + } } } diff --git a/src/InstallCTA/index.tsx b/src/InstallCTA/index.tsx index 59093cd..7a92c81 100644 --- a/src/InstallCTA/index.tsx +++ b/src/InstallCTA/index.tsx @@ -27,8 +27,8 @@ export interface InstallCTAProps { const ctaTabs: [InstallTarget, React.FC][] = [ [InstallTarget.MacOS, FaApple], [InstallTarget.Linux, FaLinux], - [InstallTarget.NixOS, SiNixos], - [InstallTarget.AWS, () => ], + [InstallTarget.NixOS, () => ], + [InstallTarget.AWS, () => ], [InstallTarget.GitHub, FaGithub], ]; @@ -58,12 +58,6 @@ const InstallCTA: FC = ({ initialTab }) => { return (
      -
      - Get Determinate for {activeTab} -
      -
      - -
        {ctaTabs.map(([target, icon]) => ( = ({ initialTab }) => { /> ))}
      +
      + Get Determinate for {activeTab} +
      +
      + +
      ); }; diff --git a/src/Link/index.scss b/src/Link/index.scss index b57d28e..71cd5f2 100644 --- a/src/Link/index.scss +++ b/src/Link/index.scss @@ -5,6 +5,8 @@ .link { color: map.get(tokens.$brand, orange); + text-decoration: underline; + text-underline-offset: 0.15em; @include mixins.transition(color, short); &:hover { diff --git a/src/sass/_tokens.scss b/src/sass/_tokens.scss index 039b5b3..94489c2 100644 --- a/src/sass/_tokens.scss +++ b/src/sass/_tokens.scss @@ -41,7 +41,7 @@ $colors: ( $code: ( // Default values taken from Shiki's 'classic' output type - bg-dark: #24292e, + bg-dark: #231f20, bg-light: #fff ); From 033f2f8e2b0b8c4f70c90a2a91999769ef8b5de6 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 17:18:40 -0400 Subject: [PATCH 16/18] Make the icons more consistent --- src/InstallCTA/TabSelector.tsx | 5 +++-- src/InstallCTA/index.scss | 5 ----- src/InstallCTA/index.tsx | 16 ++++++++-------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/InstallCTA/TabSelector.tsx b/src/InstallCTA/TabSelector.tsx index 4998f43..4380a96 100644 --- a/src/InstallCTA/TabSelector.tsx +++ b/src/InstallCTA/TabSelector.tsx @@ -1,10 +1,11 @@ import { useCallback, type FC, type MouseEvent } from "react"; import type { InstallTarget } from "./types"; +import type { IconBaseProps } from "react-icons"; export interface TabSelectorProps { name: InstallTarget; - icon: FC; + icon: FC; active: boolean; onClick: () => void; } @@ -34,7 +35,7 @@ const TabSelector: FC = ({ } onClick={handleClick} > - {name} + {name} ); diff --git a/src/InstallCTA/index.scss b/src/InstallCTA/index.scss index 6e94eb9..4ed939a 100644 --- a/src/InstallCTA/index.scss +++ b/src/InstallCTA/index.scss @@ -83,11 +83,6 @@ width: auto; } - svg.install-cta__icon--aws { - height: 30px; - margin-top: 5px; - } - &:hover { color: map.get(tokens.$brand, white); border-bottom-color: map.get(tokens.$colors, secondary); diff --git a/src/InstallCTA/index.tsx b/src/InstallCTA/index.tsx index 7a92c81..3f4eae0 100644 --- a/src/InstallCTA/index.tsx +++ b/src/InstallCTA/index.tsx @@ -1,6 +1,5 @@ import { useState, type FC } from "react"; -import { FaApple, FaLinux, FaAws, FaGithub } from "react-icons/fa6"; -import { SiNixos } from "react-icons/si"; +import { SiGithub, SiLinux, SiApple, SiNixos, SiAmazon } from "react-icons/si"; import TabSelector from "./TabSelector"; import { InstallTarget, detectInstallTarget } from "./types"; @@ -13,6 +12,7 @@ import InstallForNixOS from "./InstallForNixOS"; import MacInstaller from "../MacInstaller"; import "./index.scss"; +import type { IconBaseProps } from "react-icons"; export { InstallTarget as CTAType } from "./types"; @@ -24,12 +24,12 @@ export interface InstallCTAProps { initialTab?: InstallTarget; } -const ctaTabs: [InstallTarget, React.FC][] = [ - [InstallTarget.MacOS, FaApple], - [InstallTarget.Linux, FaLinux], - [InstallTarget.NixOS, () => ], - [InstallTarget.AWS, () => ], - [InstallTarget.GitHub, FaGithub], +const ctaTabs: [InstallTarget, React.FC][] = [ + [InstallTarget.MacOS, SiApple], + [InstallTarget.Linux, SiLinux], + [InstallTarget.NixOS, SiNixos], + [InstallTarget.AWS, SiAmazon], + [InstallTarget.GitHub, SiGithub], ]; const ctaComponents: Record = { From 5ee1512a9aea7f03a768bd68564c40c27a579445 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 17:25:32 -0400 Subject: [PATCH 17/18] Clean up the MacInstaller icon to match --- src/MacInstaller/index.scss | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/MacInstaller/index.scss b/src/MacInstaller/index.scss index ae3693b..d1e5881 100644 --- a/src/MacInstaller/index.scss +++ b/src/MacInstaller/index.scss @@ -10,13 +10,25 @@ min-width: 15em; align-items: center; + justify-content: center; background-color: map.get(tokens.$brand, black); - border: 1px solid map.get(tokens.$brand, magenta); + @include mixins.light-mode { + background-color: map.get(tokens.$brand, light); + } + color: map.get(tokens.$brand, white); + @include mixins.light-mode { + color: map.get(tokens.$brand, black); + } + + border: 1px solid map.get(tokens.$brand, magenta); + text-decoration: none; font-family: map.get(tokens.$fonts, sans); + font-size: map.get(tokens.$font-size, base); + font-weight: 500; padding: 1rem; border-radius: 0.5rem; @@ -25,14 +37,22 @@ &:hover, &:focus { + background-color: color.scale( map.get(tokens.$brand, magenta), $blackness: 50% ); + @include mixins.light-mode { + background-color: color.scale( + map.get(tokens.$brand, magenta), + $lightness: 80% + ); + } } } .mac-installer__pkg { flex: 3.5rem 3.5rem auto; margin-right: 1rem; + width: 45px; } From 4a0338d7f0562ec0d4f5ed797e73a381f9bca088 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 26 Aug 2025 17:36:44 -0400 Subject: [PATCH 18/18] Make the cta widget support a version --- src/InstallCTA/FindAwsAMIs.tsx | 3 +- src/InstallCTA/InstallCTA.stories.tsx | 70 +++++++++++++++++++++---- src/InstallCTA/InstallForNixOS.tsx | 5 +- src/InstallCTA/InstallFromCurl.tsx | 14 +++-- src/InstallCTA/UseWithGitHubActions.tsx | 8 +-- src/InstallCTA/index.scss | 5 -- src/InstallCTA/index.tsx | 24 ++++++--- src/MacInstaller/index.scss | 9 ++-- src/MacInstaller/index.tsx | 35 ++++++++----- 9 files changed, 124 insertions(+), 49 deletions(-) diff --git a/src/InstallCTA/FindAwsAMIs.tsx b/src/InstallCTA/FindAwsAMIs.tsx index d9506e2..557ac3a 100644 --- a/src/InstallCTA/FindAwsAMIs.tsx +++ b/src/InstallCTA/FindAwsAMIs.tsx @@ -1,6 +1,7 @@ import type { FC } from "react"; import CodeBlock from "../CodeBlock"; import Link from "../Link"; +import type { TabProps } from "."; const code = `aws ec2 describe-images \\ --owners 535002876703 \\ @@ -8,7 +9,7 @@ const code = `aws ec2 describe-images \\ "Name=architecture,Values=x86_64,arm64" \\ --query "Images | sort_by(@, &CreationDate) | [-1]"`; -const FindAwsAMIs: FC = () => { +const FindAwsAMIs: FC = (_: TabProps) => { return ( <>

      diff --git a/src/InstallCTA/InstallCTA.stories.tsx b/src/InstallCTA/InstallCTA.stories.tsx index 0c24908..1910150 100644 --- a/src/InstallCTA/InstallCTA.stories.tsx +++ b/src/InstallCTA/InstallCTA.stories.tsx @@ -6,7 +6,21 @@ import { InstallTarget } from "./types"; const meta = { title: "Composite/InstallCTA", component: InstallCTA, - argTypes: {}, + argTypes: { + initialTab: { + type: "string", + options: [ + InstallTarget.AWS, + InstallTarget.GitHub, + InstallTarget.Linux, + InstallTarget.MacOS, + InstallTarget.NixOS, + ], + }, + version: { + type: "string", + }, + }, } satisfies Meta; export default meta; @@ -16,35 +30,73 @@ export const Default: Story = { args: {}, }; -export const MacOS: Story = { - name: "macOS", +export const MacOSLatest: Story = { + name: "macOS Tagged", + args: { + initialTab: InstallTarget.MacOS, + }, +}; + +export const LinuxLatest: Story = { + args: { + initialTab: InstallTarget.Linux, + }, +}; + +export const AWSLatest: Story = { + args: { + initialTab: InstallTarget.AWS, + }, +}; + +export const GitHubLatest: Story = { + name: "GitHub Latest", + args: { + initialTab: InstallTarget.GitHub, + }, +}; + +export const NixOSLatest: Story = { + name: "NixOS Latest", + args: { + initialTab: InstallTarget.NixOS, + }, +}; + +export const MacOSTagged: Story = { + name: "macOS Tagged", args: { initialTab: InstallTarget.MacOS, + version: "3.8.6", }, }; -export const Linux: Story = { +export const LinuxTagged: Story = { args: { initialTab: InstallTarget.Linux, + version: "3.8.6", }, }; -export const AWS: Story = { +export const AWSTagged: Story = { args: { initialTab: InstallTarget.AWS, + version: "3.8.6", }, }; -export const GitHub: Story = { - name: "GitHub", +export const GitHubTagged: Story = { + name: "GitHub Tagged", args: { initialTab: InstallTarget.GitHub, + version: "3.8.6", }, }; -export const NixOS: Story = { - name: "NixOS", +export const NixOSTagged: Story = { + name: "NixOS Tagged", args: { initialTab: InstallTarget.NixOS, + version: "3.8.6", }, }; diff --git a/src/InstallCTA/InstallForNixOS.tsx b/src/InstallCTA/InstallForNixOS.tsx index 8f98b3b..848f898 100644 --- a/src/InstallCTA/InstallForNixOS.tsx +++ b/src/InstallCTA/InstallForNixOS.tsx @@ -1,6 +1,7 @@ import type { FC } from "react"; import CodeBlock from "../CodeBlock"; import Link from "../Link"; +import type { TabProps } from "."; const code = ` nixosConfigurations.workstation = nixpkgs.lib.nixosSystem { @@ -12,14 +13,14 @@ nixosConfigurations.workstation = nixpkgs.lib.nixosSystem { }; `; -const InstallForNixOS: FC = () => { +const InstallForNixOS: FC = ({ version }: TabProps) => { return ( <>

      Add Determinate as an input to your flake:

      diff --git a/src/InstallCTA/InstallFromCurl.tsx b/src/InstallCTA/InstallFromCurl.tsx index 0ef66e3..a163d3f 100644 --- a/src/InstallCTA/InstallFromCurl.tsx +++ b/src/InstallCTA/InstallFromCurl.tsx @@ -1,11 +1,17 @@ import { type FC } from "react"; import CodeBlock from "../CodeBlock"; +import type { TabProps } from "."; -const installScript = - "curl -fsSL https://install.determinate.systems/nix | sh -s -- install --determinate"; +const installScript = (version: string | undefined) => { + if (typeof version === "undefined") { + return "curl -fsSL https://install.determinate.systems/nix | sh -s -- install --determinate"; + } else { + return `curl -fsSL https://install.determinate.systems/nix/tag/v${version} | sh -s -- install --determinate`; + } +}; -const InstallFromCurl: FC = () => ( +const InstallFromCurl: FC = ({ version }: TabProps) => ( <>

      Use the Determinate Nix Installer CLI for Linux, including Windows @@ -14,7 +20,7 @@ const InstallFromCurl: FC = () => ( diff --git a/src/InstallCTA/UseWithGitHubActions.tsx b/src/InstallCTA/UseWithGitHubActions.tsx index f1a383c..2319249 100644 --- a/src/InstallCTA/UseWithGitHubActions.tsx +++ b/src/InstallCTA/UseWithGitHubActions.tsx @@ -1,8 +1,10 @@ import type { FC } from "react"; import Link from "../Link"; import CodeBlock from "../CodeBlock"; +import type { TabProps } from "."; -const code = ` +const UseWithGitHubActions: FC = ({ version }: TabProps) => { + const code = ` on: push: jobs: @@ -10,12 +12,10 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v5 - - uses: DeterminateSystems/determinate-nix-action@v3 + - uses: DeterminateSystems/determinate-nix-action@v${version || "3"} - run: nix build .# `; - -const UseWithGitHubActions: FC = () => { return ( <>

      Use Determinate Nix in GitHub Actions.

      diff --git a/src/InstallCTA/index.scss b/src/InstallCTA/index.scss index 4ed939a..ae2a4e6 100644 --- a/src/InstallCTA/index.scss +++ b/src/InstallCTA/index.scss @@ -53,11 +53,6 @@ gap: map.get(tokens.$spacing, base); list-style-type: none; - padding-bottom: map.get(tokens.$spacing, base); - border-bottom: 1px solid map.get(tokens.$border-color, dark); - @include mixins.light-mode { - border-bottom: 1px solid map.get(tokens.$border-color, light); - } } .install-cta__link { diff --git a/src/InstallCTA/index.tsx b/src/InstallCTA/index.tsx index 3f4eae0..1c17e17 100644 --- a/src/InstallCTA/index.tsx +++ b/src/InstallCTA/index.tsx @@ -22,6 +22,18 @@ export interface InstallCTAProps { * This is only applicable for the initial render. */ initialTab?: InstallTarget; + + /** + * Version of Determinate to pin to, when possible + */ + version?: string; +} + +export interface TabProps { + /** + * Version of Determinate to pin to, when possible + */ + version?: string; } const ctaTabs: [InstallTarget, React.FC][] = [ @@ -32,7 +44,7 @@ const ctaTabs: [InstallTarget, React.FC][] = [ [InstallTarget.GitHub, SiGithub], ]; -const ctaComponents: Record = { +const ctaComponents: Record> = { [InstallTarget.MacOS]: MacInstaller, [InstallTarget.Linux]: InstallFromCurl, [InstallTarget.AWS]: FindAwsAMIs, @@ -45,7 +57,7 @@ const ctaComponents: Record = { * * Due to the numerous options available, */ -const InstallCTA: FC = ({ initialTab }) => { +const InstallCTA: FC = ({ initialTab, version }) => { const [activeTab, setActiveTab] = useState(() => { if (initialTab) { return initialTab; @@ -58,6 +70,9 @@ const InstallCTA: FC = ({ initialTab }) => { return (
      +
      + Get Determinate{version && ` v${version}`} +
        {ctaTabs.map(([target, icon]) => ( = ({ initialTab }) => { /> ))}
      -
      - Get Determinate for {activeTab} -
      - +
      ); diff --git a/src/MacInstaller/index.scss b/src/MacInstaller/index.scss index d1e5881..db14d8e 100644 --- a/src/MacInstaller/index.scss +++ b/src/MacInstaller/index.scss @@ -37,16 +37,15 @@ &:hover, &:focus { - background-color: color.scale( map.get(tokens.$brand, magenta), $blackness: 50% ); @include mixins.light-mode { - background-color: color.scale( - map.get(tokens.$brand, magenta), - $lightness: 80% - ); + background-color: color.scale( + map.get(tokens.$brand, magenta), + $lightness: 80% + ); } } } diff --git a/src/MacInstaller/index.tsx b/src/MacInstaller/index.tsx index 2ecc7cc..79df065 100644 --- a/src/MacInstaller/index.tsx +++ b/src/MacInstaller/index.tsx @@ -4,21 +4,30 @@ import url from "./macPackageData"; import "./index.scss"; +export interface MacInstallerProps { + version?: string; +} + /** * A call to action for downloading the Determinate Nix universal Mac installer. */ -const MacInstaller: FC = () => ( - - Package icon representing the graphical installer - Download Determinate Nix - -); +const MacInstaller: FC = ({ + version, +}: MacInstallerProps) => { + const urlPath = version ? `tag/v${version}` : `stable`; + return ( + + Package icon representing the graphical installer + Download Determinate Nix{version && ` v${version}`} + + ); +}; export default MacInstaller;