+>(({ className, ...props }, ref) => {
return (
->(({ className, type, ...props }, ref) => {
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
return (
->(({ className, type, ...props }, ref) => {
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
return (
->(({ className, type, ...props }, ref) => {
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
return (
& { priority?: boolean }>
+type LinkComponent = ComponentType
>
- const RegularLink = (props: ComponentProps<'a'>) =>
-const RegularImage = (props: ComponentProps<'img'>) =>
-export const TripleCard = (props: {cards: z.infer, imageComponent: typeof NextImage | typeof RegularImage, linkComponent: typeof NextLink | typeof RegularLink }) => {
+export const TripleCard = (props: { cards: TripleCardItem[]; imageComponent: ImageComponent; linkComponent: LinkComponent }) => {
return (
diff --git a/documentation-ui/src/custom/docs/index.ts b/documentation-ui/src/custom/docs/index.ts
index 24678f9..9adad2c 100644
--- a/documentation-ui/src/custom/docs/index.ts
+++ b/documentation-ui/src/custom/docs/index.ts
@@ -4,3 +4,4 @@ export { TripleCard as DocsTripleCard } from './components/triplecard'
export { HelpCard as DocsHelpCard } from './components/helpcard'
export * from './components/header'
export * from './components/page'
+export * from './components/gdpr'
diff --git a/documentation-ui/src/custom/docs/scripts/nav/index.tsx b/documentation-ui/src/custom/docs/scripts/nav/index.tsx
index a9e2c68..4d55140 100644
--- a/documentation-ui/src/custom/docs/scripts/nav/index.tsx
+++ b/documentation-ui/src/custom/docs/scripts/nav/index.tsx
@@ -1,6 +1,5 @@
import {createRoot} from "react-dom/client"
-import { ComponentProps } from "react";
import { NavBar } from "../../components/navmenu";
(() => {
diff --git a/documentation-ui/src/custom/theme-selector.tsx b/documentation-ui/src/custom/theme-selector.tsx
index 7434bf2..b5afd2c 100644
--- a/documentation-ui/src/custom/theme-selector.tsx
+++ b/documentation-ui/src/custom/theme-selector.tsx
@@ -1,39 +1,29 @@
'use client'
-import { ComputerIcon, MoonIcon, SunIcon } from "lucide-react";
-import React from "react";
-import { Button } from "@quantinuum/quantinuum-ui";
-import { getTheme, subscribeToTheme, setTheme } from "src/utils/darkMode";
+import { ComputerIcon, MoonIcon, SunIcon } from 'lucide-react'
+import React from 'react'
+import { Button } from '@quantinuum/quantinuum-ui'
+import { type useTheme } from './use-theme'
-export const useTheme = () => {
- const [theme, _setLocalTheme] = React.useState(typeof window !== "undefined" ? getTheme() : {mode: 'dark' as const, isDark: true});
-
- React.useEffect(() => {
- subscribeToTheme((theme) => _setLocalTheme(theme))
- }, [])
- return { theme, setMode: (_mode: typeof theme['mode']) => setTheme(_mode) }
-}
-
-export const ThemeSelector = React.forwardRef>(({theme, setMode}, ref) => {
+export const ThemeSelector = React.forwardRef>(({ theme, setMode }, ref) => {
const stateMap = {
- "light": {
+ light: {
icon: ,
},
- "dark": {
- icon:
+ dark: {
+ icon: ,
},
- "system": {
+ system: {
icon: ,
},
- } satisfies Record
+ } satisfies Record
return (
{
- if (theme.mode === "dark") setMode('light')
- if (theme.mode === "light") setMode("system")
- if (theme.mode === "system") setMode("dark")
+ if (theme.mode === 'dark') setMode('light')
+ if (theme.mode === 'light') setMode('system')
+ if (theme.mode === 'system') setMode('dark')
}} ref={ref}>
{stateMap[theme.mode].icon}
)
-
})
diff --git a/documentation-ui/src/custom/use-theme.ts b/documentation-ui/src/custom/use-theme.ts
new file mode 100644
index 0000000..4a1d146
--- /dev/null
+++ b/documentation-ui/src/custom/use-theme.ts
@@ -0,0 +1,19 @@
+'use client'
+
+import React from 'react'
+import { getTheme, setTheme, subscribeToTheme } from 'src/utils/darkMode'
+
+export const useTheme = () => {
+ const [theme, setLocalTheme] = React.useState(
+ typeof window !== 'undefined' ? getTheme() : { mode: 'dark' as const, isDark: true }
+ )
+
+ React.useEffect(() => {
+ return subscribeToTheme((nextTheme) => setLocalTheme(nextTheme))
+ }, [])
+
+ return {
+ theme,
+ setMode: (mode: typeof theme.mode) => setTheme(mode),
+ }
+}
diff --git a/documentation-ui/src/index.ts b/documentation-ui/src/index.ts
index 94944a0..ec1d4d4 100644
--- a/documentation-ui/src/index.ts
+++ b/documentation-ui/src/index.ts
@@ -1,5 +1,6 @@
export * from "./custom/slide-in";
export * from "./custom/theme-selector";
+export * from "./custom/use-theme";
export * from "./tailwindTheme";
export * from "./utils";
export * from './custom/docs'
diff --git a/documentation-ui/src/utils/darkMode.ts b/documentation-ui/src/utils/darkMode.ts
index 5942ab6..90b0134 100644
--- a/documentation-ui/src/utils/darkMode.ts
+++ b/documentation-ui/src/utils/darkMode.ts
@@ -1,5 +1,4 @@
-const modes = ["system", "dark", "light"] as const;
-type Mode = (typeof modes)[number];
+type Mode = "system" | "dark" | "light";
const isMode = (mode: string): mode is Mode => {
return ["system", "dark", "light"].includes(mode);
};
diff --git a/documentation-ui/stories/custom/theme-selector.stories.tsx b/documentation-ui/stories/custom/theme-selector.stories.tsx
index 43e711c..5f931f8 100644
--- a/documentation-ui/stories/custom/theme-selector.stories.tsx
+++ b/documentation-ui/stories/custom/theme-selector.stories.tsx
@@ -1,5 +1,6 @@
import { Meta, StoryObj } from "@storybook/react";
-import { ThemeSelector, useTheme } from "src/custom/theme-selector";
+import { ThemeSelector } from "src/custom/theme-selector";
+import { useTheme } from "src/custom/use-theme";
export function ThemeSelectorDemo() {
const { theme, setMode } = useTheme();
return ;
diff --git a/documentation-ui/tsconfig.json b/documentation-ui/tsconfig.json
index 455b176..50c68db 100644
--- a/documentation-ui/tsconfig.json
+++ b/documentation-ui/tsconfig.json
@@ -3,7 +3,6 @@
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["node_modules", "dist", "storybook-static", "sphinx-ui"],
"compilerOptions": {
- "baseUrl": "./",
"target": "es2016",
"strict": true,
"noImplicitAny": true,
@@ -12,10 +11,15 @@
"jsx": "react-jsx",
"module": "ESNext",
"declaration": true,
+ "types": ["vitest/globals"],
"sourceMap": true,
"outDir": "dist",
- "moduleResolution": "node",
+ "baseUrl": ".",
+ "moduleResolution": "bundler",
+ "paths": {
+ "src/*": ["./src/*"]
+ },
"allowSyntheticDefaultImports": true,
"emitDeclarationOnly": true
}
diff --git a/documentation-ui/vitest.config.mjs b/documentation-ui/vitest.config.mjs
new file mode 100644
index 0000000..ff860b7
--- /dev/null
+++ b/documentation-ui/vitest.config.mjs
@@ -0,0 +1,29 @@
+import react from '@vitejs/plugin-react'
+import tsconfigPaths from 'vite-tsconfig-paths'
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ plugins: [react(), tsconfigPaths()],
+
+ test: {
+ globals: true,
+ environment: 'jsdom',
+ testTimeout: 10000, // The default timeout is 5 seconds. In our case we have some complex UI tests that might take longer and may result in flaky tests thus we increase the maximum allowed time to 10 seconds.
+ server: {
+ // See https://vitest.dev/config/#server-deps-inline. This means we can import ESM in vitest tests.
+ deps: {
+ inline: ['@quantinuum/quantinuum-ui', '@quantinuum/documentation-ui'],
+ },
+ },
+ environmentOptions: {
+ jsdom: {
+ resources: 'usable',
+ },
+ },
+ include: [
+ 'src/**/*.{test,spec}.?(c|m)[jt]s?(x)', // By default vitest runs all .spec/.test files it finds. We don't want this because will try to run playwright tests as well so we specify here to run only tests files withing the .app folder
+ 'tests/contract/**/*.{test,spec}.?(c|m)[jt]s?(x)',
+ ],
+ setupFiles: ['setupTest.ts'],
+ },
+})
diff --git a/sphinx-ui/build-demo.sh b/sphinx-ui/build-demo.sh
old mode 100644
new mode 100755
diff --git a/sphinx-ui/build-dist.sh b/sphinx-ui/build-dist.sh
old mode 100644
new mode 100755
index e4e5a31..03251ea
--- a/sphinx-ui/build-dist.sh
+++ b/sphinx-ui/build-dist.sh
@@ -6,8 +6,8 @@ cd ./react
npm update @quantinuum/documentation-ui
npm install
npm run build
-cp ./build/injectNav.global.js ../quantinuum_sphinx/static/injectNav.global.js
-cp ./build/syncTheme.global.js ../quantinuum_sphinx/static/syncTheme.global.js
+cp ./build/injectNav.iife.js ../quantinuum_sphinx/static/injectNav.iife.js
+cp ./build/syncTheme.iife.js ../quantinuum_sphinx/static/syncTheme.iife.js
cp ./node_modules/@quantinuum/quantinuum-ui/dist/tokens.css ../quantinuum_sphinx/static/styles/quantinuum-ui-tokens.css
npx tailwindcss --postcss ./postcss.config.cjs -i ./index.css -o ../quantinuum_sphinx/static/styles/quantinuum-ui-tailwind.css
echo ✅ "Done. Added UI assets to dist."
diff --git a/sphinx-ui/quantinuum_sphinx/__init__.py b/sphinx-ui/quantinuum_sphinx/__init__.py
index 1a72867..c0ffa36 100644
--- a/sphinx-ui/quantinuum_sphinx/__init__.py
+++ b/sphinx-ui/quantinuum_sphinx/__init__.py
@@ -5,5 +5,5 @@
def setup(app: Sphinx):
app.add_html_theme("quantinuum_sphinx", str(Path(__file__).resolve().parent))
- app.add_js_file("injectNav.global.js")
- app.add_js_file("syncTheme.global.js")
+ app.add_js_file("injectNav.iife.js")
+ app.add_js_file("syncTheme.iife.js")
diff --git a/sphinx-ui/quantinuum_sphinx/page.html b/sphinx-ui/quantinuum_sphinx/page.html
index f24dadc..6a35369 100644
--- a/sphinx-ui/quantinuum_sphinx/page.html
+++ b/sphinx-ui/quantinuum_sphinx/page.html
@@ -6,7 +6,7 @@
-
+