refactor: remove MUI and Emotion (#27821)

> 🤖 This PR was modified by Coder Agents on behalf of Jake Howell.

Until we meet again.

## Stack

- #27636
- #27718 
- #27719 
- #27722
- #27723
- #27724
- #27728
- #27730
- #27732
- #27762
- #27763
- #27786
- #27787
- #27788
- #27789
- #27790
- #27791 
- #27817 
- #27820
- #28009

## Final removal (`c39b664`)

Removes the last of MUI and Emotion now that every surface has been
migrated:

- **Dependencies**: drops `@mui/material` and
`@emotion/{cache,css,react,styled}` from `package.json` /
`pnpm-lock.yaml`, and deletes the `@types/emotion.d.ts` and
`@types/mui.d.ts` module augmentations.
- **Theming**: replaces the Emotion `CacheProvider`, MUI `ThemeProvider`
/ `StyledEngineProvider`, and `CssBaseline` in `ThemeProvider` with a
lightweight `theme/context.tsx` that exposes `ThemeContextProvider` and
a `useTheme` hook.
- **Global styles**: moves the base `body` styles (background, text
color, font, antialiasing) that `CssBaseline` previously provided into
`index.css`, and drops the temporary MUI modal/popover scrollbar-gutter
workaround.
- **Cleanup**: removes the MUI → shadcn / Emotion → Tailwind migration
guidance from `site/AGENTS.md`, updates the Storybook `preview.tsx`, and
adjusts assorted components (`Command`, `Slider`, `Switch`, `Tabs`,
`SyntaxHighlighter`, timing charts) and theme files to consume the new
context instead of MUI/Emotion.
This commit is contained in:
Jake Howell
2026-08-17 17:04:48 +10:00
committed by GitHub
parent 521c383f6b
commit ea8ba0c678
56 changed files with 198 additions and 1305 deletions
-3
View File
@@ -78,9 +78,6 @@ updates:
xterm:
patterns:
- "@xterm*"
mui:
patterns:
- "@mui*"
react:
patterns:
- "react"
-4
View File
@@ -72,10 +72,6 @@
// We discourage people from various older libraries that
// are no longer recommended/being migrated from.
"typescript.preferences.autoImportSpecifierExcludeRegexes": [
// discourage people from using MUI components
"^@mui(?:/.*)?$",
// discourage people from using Emotion CSS
"^@emotion(?:/.*)?$",
// we prefer people use `lodash/foo` over `lodash`
"^lodash$"
]
-64
View File
@@ -61,70 +61,6 @@
"parseDiffFromFile"
]
},
"@mui/material/Alert": "Use components/Alert/Alert instead.",
"@mui/material/AlertTitle": "Use components/Alert/Alert instead.",
// "@mui/material/Autocomplete": "Use shadcn/ui Combobox instead.",
"@mui/material/Avatar": "Use components/Avatar/Avatar instead.",
"@mui/material/Box": "Use a <div> with Tailwind classes instead.",
"@mui/material/Button": "Use components/Button/Button instead.",
// "@mui/material/Card": "Use shadcn/ui Card component instead.",
// "@mui/material/CardActionArea": "Use shadcn/ui Card component instead.",
// "@mui/material/CardContent": "Use shadcn/ui Card component instead.",
// "@mui/material/Checkbox": "Use shadcn/ui Checkbox component instead.",
"@mui/material/Chip": "Use components/Badge or Tailwind styles instead.",
// "@mui/material/CircularProgress": "Use components/Spinner/Spinner instead.",
// "@mui/material/Collapse": "Use shadcn/ui Collapsible instead.",
// "@mui/material/CssBaseline": "Use Tailwind CSS base styles instead.",
// "@mui/material/Dialog": "Use shadcn/ui Dialog component instead.",
// "@mui/material/DialogActions": "Use shadcn/ui Dialog component instead.",
// "@mui/material/DialogContent": "Use shadcn/ui Dialog component instead.",
// "@mui/material/DialogContentText": "Use shadcn/ui Dialog component instead.",
// "@mui/material/DialogTitle": "Use shadcn/ui Dialog component instead.",
// "@mui/material/Divider": "Use shadcn/ui Separator or <hr> with Tailwind instead.",
// "@mui/material/Drawer": "Use shadcn/ui Sheet component instead.",
// "@mui/material/FormControl": "Use native form elements with Tailwind instead.",
// "@mui/material/FormControlLabel": "Use shadcn/ui Label with form components instead.",
"@mui/material/FormGroup": "Use a <div> with Tailwind classes instead.",
// "@mui/material/FormHelperText": "Use a <p> with Tailwind classes instead.",
"@mui/material/FormLabel": "Use shadcn/ui Label component instead.",
"@mui/material/Grid": "Use Tailwind grid utilities instead.",
"@mui/material/IconButton": "Use components/Button/Button with variant='icon' instead.",
// "@mui/material/InputAdornment": "Use Tailwind positioning in input wrapper instead.",
// "@mui/material/InputBase": "Use shadcn/ui Input component instead.",
"@mui/material/LinearProgress": "Use a progress bar with Tailwind instead.",
// "@mui/material/Link": "Use React Router Link or native <a> tags instead.",
// "@mui/material/List": "Use native <ul> with Tailwind instead.",
// "@mui/material/ListItem": "Use native <li> with Tailwind instead.",
"@mui/material/ListItemIcon": "Use lucide-react icons in list items instead.",
// "@mui/material/ListItemText": "Use native elements with Tailwind instead.",
// "@mui/material/Menu": "Use shadcn/ui DropdownMenu instead.",
// "@mui/material/MenuItem": "Use shadcn/ui DropdownMenu components instead.",
// "@mui/material/MenuList": "Use shadcn/ui DropdownMenu components instead.",
"@mui/material/Paper": "Use a <div> with Tailwind shadow/border classes instead.",
"@mui/material/Popover": "Use components/Popover/Popover instead.",
// "@mui/material/Radio": "Use shadcn/ui RadioGroup instead.",
// "@mui/material/RadioGroup": "Use shadcn/ui RadioGroup instead.",
// "@mui/material/Select": "Use shadcn/ui Select component instead.",
"@mui/material/Skeleton": "Use shadcn/ui Skeleton component instead.",
// "@mui/material/Snackbar": "Use components/GlobalSnackbar instead.",
// "@mui/material/Stack": "Use Tailwind flex utilities instead (e.g., <div className='flex flex-col gap-4'>).",
// "@mui/material/styles": "Use Tailwind CSS instead.",
"@mui/material/SvgIcon": "Use lucide-react icons instead.",
"@mui/material/Switch": "Use shadcn/ui Switch component instead.",
"@mui/material/Table": "Import from components/Table/Table instead.",
"@mui/material/TableRow": "Import from components/Table/Table instead.",
// "@mui/material/TextField": "Use shadcn/ui Input component instead.",
// "@mui/material/ToggleButton": "Use shadcn/ui Toggle or custom component instead.",
// "@mui/material/ToggleButtonGroup": "Use shadcn/ui Toggle or custom component instead.",
"@mui/material/Tooltip": "Use components/Tooltip/Tooltip instead.",
"@mui/material/Typography": "Use native HTML elements instead. Eg: <span>, <p>, <h1>, etc.",
"@mui/material/useMediaQuery": "Use Tailwind responsive classes or custom hook instead.",
// "@mui/system": "Use Tailwind CSS instead.",
"@mui/utils": "Use native alternatives or utility libraries instead.",
// "@emotion/css": "Use Tailwind CSS instead.",
// "@emotion/react": "Use Tailwind CSS instead.",
"@emotion/styled": "Use Tailwind CSS instead.",
// "@emotion/cache": "Use Tailwind CSS instead.",
// "#/components/Stack/Stack": "Use Tailwind flex utilities instead (e.g., <div className='flex flex-col gap-4'>).",
"lodash": "Use lodash/<name> instead."
}
+4 -9
View File
@@ -182,14 +182,6 @@ Components should be atomic, reusable and free of business logic. Modules are
similar to components except that they can be more complex and can contain
business logic specific to the product.
### MUI
The codebase is currently using MUI v5. Please see the
[official documentation](https://mui.com/material-ui/getting-started/). In
general, favor building a custom component via MUI instead of plain React/HTML,
as MUI's suite of components is thoroughly battle-tested and accessible right
out of the box.
### Structure
Each component and module gets its own folder. Module folders may group multiple
@@ -246,7 +238,10 @@ new conventions, but all new components should follow these guidelines.
## Styling
We use [Emotion](https://emotion.sh/) to handle CSS styles.
We use [Tailwind CSS](https://tailwindcss.com/) to handle CSS styles. Reusable UI
primitives come from [shadcn/ui](https://ui.shadcn.com/) components in
`site/src/components`. Use the `cn` helper from `#/utils/cn` to compose and
conditionally apply classes.
## Forms
+10 -20
View File
@@ -1,11 +1,5 @@
import "../src/index.css";
import "../src/theme/globalFonts";
import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
import CssBaseline from "@mui/material/CssBaseline";
import {
ThemeProvider as MuiThemeProvider,
StyledEngineProvider,
} from "@mui/material/styles";
import { DecoratorHelpers } from "@storybook/addon-themes";
import type { Decorator, Parameters } from "@storybook/react-vite";
import { StrictMode } from "react";
@@ -14,6 +8,7 @@ import { withRouter } from "storybook-addon-remix-react-router";
import { TooltipProvider } from "../src/components/Tooltip/Tooltip";
import themes, { baseModeFor, isConcreteThemeName } from "../src/theme";
import { AppearanceProvider } from "../src/theme/appearance";
import { ThemeContextProvider } from "../src/theme/context";
DecoratorHelpers.initializeThemeState(Object.keys(themes), "dark");
@@ -112,20 +107,15 @@ const withTheme: Decorator = (Story, context) => {
return (
<StrictMode>
<StyledEngineProvider injectFirst>
<MuiThemeProvider theme={themes[concreteName]}>
<EmotionThemeProvider theme={themes[concreteName]}>
<AppearanceProvider
externalImages={themes[concreteName].externalImages}
>
<TooltipProvider delayDuration={100}>
<CssBaseline />
<Story />
</TooltipProvider>
</AppearanceProvider>
</EmotionThemeProvider>
</MuiThemeProvider>
</StyledEngineProvider>
<ThemeContextProvider theme={themes[concreteName]}>
<AppearanceProvider
externalImages={themes[concreteName].externalImages}
>
<TooltipProvider delayDuration={100}>
<Story />
</TooltipProvider>
</AppearanceProvider>
</ThemeContextProvider>
</StrictMode>
);
};
+1 -20
View File
@@ -80,7 +80,6 @@ Debug logs and pprof dumps use the same job name and commit SHA convention.
## Components
- MUI components are deprecated - migrate away from these when encountered
- Use shadcn/ui components first - check `site/src/components` for existing implementations.
- Do not use shadcn CLI - manually add components to maintain consistency
- The modules folder should contain components with business logic specific to the codebase.
@@ -103,9 +102,8 @@ Debug logs and pprof dumps use the same job name and commit SHA convention.
## Styling
- Emotion CSS is deprecated. Use Tailwind CSS instead.
- Use Tailwind CSS for styling.
- Use custom Tailwind classes in tailwind.config.js.
- Tailwind CSS reset is currently not used to maintain compatibility with MUI
- Responsive design - use Tailwind's responsive prefixes (sm:, md:, lg:, xl:)
- Do not use `dark:` prefix for dark mode
@@ -279,23 +277,6 @@ Debug logs and pprof dumps use the same job name and commit SHA convention.
audit the diff against FE1 to FE10 and fix every FAIL before creating
the PR
## Migration (MUI → shadcn) (Emotion → Tailwind)
### Migration Strategy
- Identify MUI components in current feature
- Find shadcn equivalent in existing components
- Create wrapper if needed for missing functionality
- Update tests to reflect new component structure
- Remove MUI imports once migration complete
### Migration Guidelines
- Use Tailwind classes for all new styling
- Replace Emotion `css` prop with Tailwind classes
- Leverage custom color tokens: `content-primary`, `surface-secondary`, etc.
- Use `className` with `clsx` for conditional styling
## React Rules
### 1. Purity & Immutability
-4
View File
@@ -42,9 +42,6 @@
"@dnd-kit/utilities": "3.2.2",
"@emoji-mart/data": "1.2.1",
"@emoji-mart/react": "1.1.1",
"@emotion/cache": "11.14.0",
"@emotion/react": "11.14.0",
"@emotion/styled": "11.14.1",
"@fontsource-variable/geist": "5.3.0",
"@fontsource-variable/geist-mono": "5.2.7",
"@fontsource/fira-code": "5.2.7",
@@ -54,7 +51,6 @@
"@lexical/react": "0.44.0",
"@lexical/utils": "0.48.0",
"@monaco-editor/react": "4.7.0",
"@mui/material": "5.18.0",
"@novnc/novnc": "^1.5.0",
"@pierre/diffs": "1.3.3",
"@pierre/trees": "1.0.0-beta.4",
+6 -450
View File
@@ -47,15 +47,6 @@ importers:
'@emoji-mart/react':
specifier: 1.1.1
version: 1.1.1(emoji-mart@5.6.0)(react@19.2.8)
'@emotion/cache':
specifier: 11.14.0
version: 11.14.0
'@emotion/react':
specifier: 11.14.0
version: 11.14.0(@types/react@19.2.18)(react@19.2.8)
'@emotion/styled':
specifier: 11.14.1
version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)
'@fontsource-variable/geist':
specifier: 5.3.0
version: 5.3.0
@@ -83,9 +74,6 @@ importers:
'@monaco-editor/react':
specifier: 4.7.0
version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
'@mui/material':
specifier: 5.18.0
version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
'@novnc/novnc':
specifier: ^1.5.0
version: 1.5.0
@@ -509,10 +497,6 @@ packages:
resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==, tarball: https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz}
engines: {node: '>=6.9.0'}
'@babel/helper-module-imports@7.27.1':
resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==, tarball: https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz}
engines: {node: '>=6.9.0'}
'@babel/helper-module-imports@7.29.7':
resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==, tarball: https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz}
engines: {node: '>=6.9.0'}
@@ -752,60 +736,12 @@ packages:
emoji-mart: ^5.2
react: ^16.8 || ^17 || ^18
'@emotion/babel-plugin@11.13.5':
resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==, tarball: https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz}
'@emotion/cache@11.14.0':
resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==, tarball: https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz}
'@emotion/hash@0.9.2':
resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==, tarball: https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz}
'@emotion/is-prop-valid@1.4.0':
resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==, tarball: https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz}
'@emotion/memoize@0.9.0':
resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==, tarball: https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz}
'@emotion/react@11.14.0':
resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==, tarball: https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz}
peerDependencies:
'@types/react': '*'
react: '>=16.8.0'
peerDependenciesMeta:
'@types/react':
optional: true
'@emotion/serialize@1.3.3':
resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==, tarball: https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz}
'@emotion/sheet@1.4.0':
resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==, tarball: https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz}
'@emotion/styled@11.14.1':
resolution: {integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==, tarball: https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz}
peerDependencies:
'@emotion/react': ^11.0.0-rc.0
'@types/react': '*'
react: '>=16.8.0'
peerDependenciesMeta:
'@types/react':
optional: true
'@emotion/unitless@0.10.0':
resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==, tarball: https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz}
'@emotion/use-insertion-effect-with-fallbacks@1.2.0':
resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==, tarball: https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz}
peerDependencies:
react: '>=16.8.0'
'@emotion/utils@1.4.2':
resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==, tarball: https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz}
'@emotion/weak-memoize@0.4.0':
resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==, tarball: https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz}
'@esbuild/aix-ppc64@0.25.12':
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz}
engines: {node: '>=18'}
@@ -1199,83 +1135,6 @@ packages:
resolution: {integrity: sha512-SSnyl/4ni/2ViHKkiZb8eajA/eN1DNFaHjhGiLUdZvDz6PKF4COSf/17xqSz64nOo2Ia29SA6B2KNCsyCbVmaQ==, tarball: https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.35.9.tgz}
engines: {node: '>=18'}
'@mui/core-downloads-tracker@5.18.0':
resolution: {integrity: sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==, tarball: https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz}
'@mui/material@5.18.0':
resolution: {integrity: sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==, tarball: https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
'@emotion/styled': ^11.3.0
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/react':
optional: true
'@emotion/styled':
optional: true
'@types/react':
optional: true
'@mui/private-theming@5.17.1':
resolution: {integrity: sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==, tarball: https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz}
engines: {node: '>=12.0.0'}
peerDependencies:
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
'@mui/styled-engine@5.18.0':
resolution: {integrity: sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==, tarball: https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.4.1
'@emotion/styled': ^11.3.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/react':
optional: true
'@emotion/styled':
optional: true
'@mui/system@5.18.0':
resolution: {integrity: sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==, tarball: https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
'@emotion/styled': ^11.3.0
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/react':
optional: true
'@emotion/styled':
optional: true
'@types/react':
optional: true
'@mui/types@7.2.24':
resolution: {integrity: sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==, tarball: https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz}
peerDependencies:
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
'@mui/utils@5.17.1':
resolution: {integrity: sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==, tarball: https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz}
engines: {node: '>=12.0.0'}
peerDependencies:
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
'@napi-rs/wasm-runtime@1.0.7':
resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==, tarball: https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz}
@@ -1463,9 +1322,6 @@ packages:
'@polka/url@1.0.0-next.29':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==, tarball: https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz}
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==, tarball: https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz}
'@preact/signals-core@1.14.2':
resolution: {integrity: sha512-RZHdBj9ZF4n40Rp4jS052EHHjBWf96P9oNdXPfhQTovCuWY9iQn3Gq+gOTJSgBO9A/JBuPfMOWsSX/lIU9Pc/A==, tarball: https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.2.tgz}
@@ -2765,12 +2621,6 @@ packages:
'@types/novnc__novnc@1.5.0':
resolution: {integrity: sha512-9DrDJK1hUT6Cbp4t03IsU/DsR6ndnIrDgZVrzITvspldHQ7n81F3wUDfq89zmPM3wg4GErH11IQa0QuTgLMf+w==, tarball: https://registry.npmjs.org/@types/novnc__novnc/-/novnc__novnc-1.5.0.tgz}
'@types/parse-json@4.0.2':
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==, tarball: https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz}
'@types/prop-types@15.7.15':
resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==, tarball: https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz}
'@types/qs@6.9.7':
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==, tarball: https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz}
@@ -2795,11 +2645,6 @@ packages:
'@types/react-syntax-highlighter@15.5.13':
resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==, tarball: https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz}
'@types/react-transition-group@4.4.12':
resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==, tarball: https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz}
peerDependencies:
'@types/react': '*'
'@types/react-virtualized-auto-sizer@1.0.8':
resolution: {integrity: sha512-keJpNyhiwfl2+N12G1ocCVA5ZDBArbPLe/S90X3kt7fam9naeHdaYYWbpe2sHczp70JWJ+2QLhBE8kLvLuVNjA==, tarball: https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.8.tgz}
deprecated: This is a stub types definition. react-virtualized-auto-sizer provides its own type definitions, so you do not need this installed.
@@ -3057,10 +2902,6 @@ packages:
axios@1.18.1:
resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==, tarball: https://registry.npmjs.org/axios/-/axios-1.18.1.tgz}
babel-plugin-macros@3.1.0:
resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==, tarball: https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz}
engines: {node: '>=10', npm: '>=6'}
babel-plugin-react-compiler@1.0.0:
resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==, tarball: https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz}
@@ -3142,10 +2983,6 @@ packages:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==, tarball: https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz}
engines: {node: '>= 0.4'}
callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, tarball: https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz}
engines: {node: '>=6'}
camelcase-css@2.0.1:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==, tarball: https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz}
engines: {node: '>= 6'}
@@ -3303,9 +3140,6 @@ packages:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, tarball: https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz}
engines: {node: '>= 0.6'}
convert-source-map@1.9.0:
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, tarball: https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz}
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, tarball: https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz}
@@ -3329,10 +3163,6 @@ packages:
cose-base@2.2.0:
resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==, tarball: https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz}
cosmiconfig@7.1.0:
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==, tarball: https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz}
engines: {node: '>=10'}
cpu-features@0.0.10:
resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==, tarball: https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz}
engines: {node: '>=10.0.0'}
@@ -3369,9 +3199,6 @@ packages:
resolution: {integrity: sha512-OytmFH+13/QXONJcC75QNdMtKpceNk3u8ThBjyyYjkEcy/ekBwR1mMAuNvi3gdBPW3N5TlCzQ0WZw8H0lN/bDw==, tarball: https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.3.tgz}
engines: {node: '>=20'}
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==, tarball: https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, tarball: https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz}
@@ -3727,9 +3554,6 @@ packages:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==, tarball: https://registry.npmjs.org/entities/-/entities-6.0.1.tgz}
engines: {node: '>=0.12'}
error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, tarball: https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz}
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, tarball: https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz}
engines: {node: '>= 0.4'}
@@ -3764,10 +3588,6 @@ packages:
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, tarball: https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz}
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, tarball: https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz}
engines: {node: '>=10'}
escape-string-regexp@5.0.0:
resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==, tarball: https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz}
engines: {node: '>=12'}
@@ -3854,9 +3674,6 @@ packages:
resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==, tarball: https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz}
engines: {node: '>= 0.8'}
find-root@1.1.0:
resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==, tarball: https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz}
follow-redirects@1.16.0:
resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==, tarball: https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz}
engines: {node: '>=4.0'}
@@ -4107,10 +3924,6 @@ packages:
immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==, tarball: https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz}
import-fresh@3.3.1:
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==, tarball: https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz}
engines: {node: '>=6'}
indent-string@4.0.0:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, tarball: https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz}
engines: {node: '>=8'}
@@ -4155,9 +3968,6 @@ packages:
is-array-buffer@3.0.2:
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==, tarball: https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz}
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, tarball: https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz}
is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==, tarball: https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz}
@@ -4342,9 +4152,6 @@ packages:
engines: {node: '>=6'}
hasBin: true
json-parse-even-better-errors@2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, tarball: https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz}
json-rpc-2.0@1.7.1:
resolution: {integrity: sha512-JqZjhjAanbpkXIzFE7u8mE/iFblawwlXtONaCvRqI+pyABVz7B4M1EUNpyVW+dZjqgQ2L5HFmZCmOCgUKm00hg==, tarball: https://registry.npmjs.org/json-rpc-2.0/-/json-rpc-2.0-1.7.1.tgz}
@@ -4929,20 +4736,12 @@ packages:
pako@1.0.11:
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==, tarball: https://registry.npmjs.org/pako/-/pako-1.0.11.tgz}
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, tarball: https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz}
engines: {node: '>=6'}
parse-entities@2.0.0:
resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==, tarball: https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz}
parse-entities@4.0.2:
resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==, tarball: https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz}
parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, tarball: https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz}
engines: {node: '>=8'}
parse5@7.3.0:
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==, tarball: https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz}
@@ -4983,10 +4782,6 @@ packages:
path-to-regexp@6.3.0:
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==, tarball: https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz}
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, tarball: https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz}
engines: {node: '>=8'}
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, tarball: https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz}
@@ -5259,9 +5054,6 @@ packages:
react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, tarball: https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz}
react-is@19.1.1:
resolution: {integrity: sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==, tarball: https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz}
react-markdown@9.1.0:
resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==, tarball: https://registry.npmjs.org/react-markdown/-/react-markdown-9.1.0.tgz}
peerDependencies:
@@ -5453,10 +5245,6 @@ packages:
resize-observer-polyfill@1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==, tarball: https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz}
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, tarball: https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz}
engines: {node: '>=4'}
resolve@1.22.11:
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==, tarball: https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz}
engines: {node: '>= 0.4'}
@@ -5621,10 +5409,6 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, tarball: https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz}
engines: {node: '>=0.10.0'}
source-map@0.5.7:
resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==, tarball: https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz}
engines: {node: '>=0.10.0'}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, tarball: https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz}
engines: {node: '>=0.10.0'}
@@ -5748,9 +5532,6 @@ packages:
style-to-object@1.0.9:
resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==, tarball: https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz}
stylis@4.2.0:
resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==, tarball: https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz}
stylis@4.3.6:
resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==, tarball: https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz}
@@ -6496,13 +6277,6 @@ snapshots:
'@babel/helper-globals@7.29.7': {}
'@babel/helper-module-imports@7.27.1':
dependencies:
'@babel/traverse': 7.29.7
'@babel/types': 7.29.7
transitivePeerDependencies:
- supports-color
'@babel/helper-module-imports@7.29.7':
dependencies:
'@babel/traverse': 7.29.7
@@ -6727,88 +6501,13 @@ snapshots:
emoji-mart: 5.6.0
react: 19.2.8
'@emotion/babel-plugin@11.13.5':
dependencies:
'@babel/helper-module-imports': 7.27.1
'@babel/runtime': 7.26.10
'@emotion/hash': 0.9.2
'@emotion/memoize': 0.9.0
'@emotion/serialize': 1.3.3
babel-plugin-macros: 3.1.0
convert-source-map: 1.9.0
escape-string-regexp: 4.0.0
find-root: 1.1.0
source-map: 0.5.7
stylis: 4.2.0
transitivePeerDependencies:
- supports-color
'@emotion/cache@11.14.0':
dependencies:
'@emotion/memoize': 0.9.0
'@emotion/sheet': 1.4.0
'@emotion/utils': 1.4.2
'@emotion/weak-memoize': 0.4.0
stylis: 4.2.0
'@emotion/hash@0.9.2': {}
'@emotion/is-prop-valid@1.4.0':
dependencies:
'@emotion/memoize': 0.9.0
optional: true
'@emotion/memoize@0.9.0': {}
'@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8)':
dependencies:
'@babel/runtime': 7.26.10
'@emotion/babel-plugin': 11.13.5
'@emotion/cache': 11.14.0
'@emotion/serialize': 1.3.3
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.8)
'@emotion/utils': 1.4.2
'@emotion/weak-memoize': 0.4.0
hoist-non-react-statics: 3.3.2
react: 19.2.8
optionalDependencies:
'@types/react': 19.2.18
transitivePeerDependencies:
- supports-color
'@emotion/serialize@1.3.3':
dependencies:
'@emotion/hash': 0.9.2
'@emotion/memoize': 0.9.0
'@emotion/unitless': 0.10.0
'@emotion/utils': 1.4.2
csstype: 3.2.3
'@emotion/sheet@1.4.0': {}
'@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)':
dependencies:
'@babel/runtime': 7.26.10
'@emotion/babel-plugin': 11.13.5
'@emotion/is-prop-valid': 1.4.0
'@emotion/react': 11.14.0(@types/react@19.2.18)(react@19.2.8)
'@emotion/serialize': 1.3.3
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.8)
'@emotion/utils': 1.4.2
react: 19.2.8
optionalDependencies:
'@types/react': 19.2.18
transitivePeerDependencies:
- supports-color
'@emotion/unitless@0.10.0': {}
'@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.8)':
dependencies:
react: 19.2.8
'@emotion/utils@1.4.2': {}
'@emotion/weak-memoize@0.4.0': {}
'@emotion/memoize@0.9.0':
optional: true
'@esbuild/aix-ppc64@0.25.12':
optional: true
@@ -7223,82 +6922,6 @@ snapshots:
outvariant: 1.4.3
strict-event-emitter: 0.5.1
'@mui/core-downloads-tracker@5.18.0': {}
'@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/core-downloads-tracker': 5.18.0
'@mui/system': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)
'@mui/types': 7.2.24(@types/react@19.2.18)
'@mui/utils': 5.17.1(@types/react@19.2.18)(react@19.2.8)
'@popperjs/core': 2.11.8
'@types/react-transition-group': 4.4.12(@types/react@19.2.18)
clsx: 2.1.1
csstype: 3.1.3
prop-types: 15.8.1
react: 19.2.8
react-dom: 19.2.8(react@19.2.8)
react-is: 19.1.1
react-transition-group: 4.4.5(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
optionalDependencies:
'@emotion/react': 11.14.0(@types/react@19.2.18)(react@19.2.8)
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)
'@types/react': 19.2.18
'@mui/private-theming@5.17.1(@types/react@19.2.18)(react@19.2.8)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/utils': 5.17.1(@types/react@19.2.18)(react@19.2.8)
prop-types: 15.8.1
react: 19.2.8
optionalDependencies:
'@types/react': 19.2.18
'@mui/styled-engine@5.18.0(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(react@19.2.8)':
dependencies:
'@babel/runtime': 7.26.10
'@emotion/cache': 11.14.0
'@emotion/serialize': 1.3.3
csstype: 3.1.3
prop-types: 15.8.1
react: 19.2.8
optionalDependencies:
'@emotion/react': 11.14.0(@types/react@19.2.18)(react@19.2.8)
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)
'@mui/system@5.18.0(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/private-theming': 5.17.1(@types/react@19.2.18)(react@19.2.8)
'@mui/styled-engine': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8))(react@19.2.8)
'@mui/types': 7.2.24(@types/react@19.2.18)
'@mui/utils': 5.17.1(@types/react@19.2.18)(react@19.2.8)
clsx: 2.1.1
csstype: 3.1.3
prop-types: 15.8.1
react: 19.2.8
optionalDependencies:
'@emotion/react': 11.14.0(@types/react@19.2.18)(react@19.2.8)
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)
'@types/react': 19.2.18
'@mui/types@7.2.24(@types/react@19.2.18)':
optionalDependencies:
'@types/react': 19.2.18
'@mui/utils@5.17.1(@types/react@19.2.18)(react@19.2.8)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/types': 7.2.24(@types/react@19.2.18)
'@types/prop-types': 15.7.15
clsx: 2.1.1
prop-types: 15.8.1
react: 19.2.8
react-is: 19.1.1
optionalDependencies:
'@types/react': 19.2.18
'@napi-rs/wasm-runtime@1.0.7':
dependencies:
'@emnapi/core': 1.11.3
@@ -7436,8 +7059,6 @@ snapshots:
'@polka/url@1.0.0-next.29': {}
'@popperjs/core@2.11.8': {}
'@preact/signals-core@1.14.2': {}
'@protobufjs/aspromise@1.1.2': {}
@@ -8810,10 +8431,6 @@ snapshots:
'@types/novnc__novnc@1.5.0': {}
'@types/parse-json@4.0.2': {}
'@types/prop-types@15.7.15': {}
'@types/qs@6.9.7': {}
'@types/range-parser@1.2.4': {}
@@ -8835,10 +8452,6 @@ snapshots:
dependencies:
'@types/react': 19.2.18
'@types/react-transition-group@4.4.12(@types/react@19.2.18)':
dependencies:
'@types/react': 19.2.18
'@types/react-virtualized-auto-sizer@1.0.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
dependencies:
react-virtualized-auto-sizer: 1.0.26(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
@@ -9122,12 +8735,6 @@ snapshots:
- debug
- supports-color
babel-plugin-macros@3.1.0:
dependencies:
'@babel/runtime': 7.26.10
cosmiconfig: 7.1.0
resolve: 1.22.12
babel-plugin-react-compiler@1.0.0:
dependencies:
'@babel/types': 7.28.5
@@ -9231,8 +8838,6 @@ snapshots:
call-bind-apply-helpers: 1.0.2
get-intrinsic: 1.3.0
callsites@3.1.0: {}
camelcase-css@2.0.1: {}
caniuse-lite@1.0.30001806: {}
@@ -9378,8 +8983,6 @@ snapshots:
content-type@1.0.5: {}
convert-source-map@1.9.0: {}
convert-source-map@2.0.0: {}
cookie-signature@1.0.7: {}
@@ -9398,14 +9001,6 @@ snapshots:
dependencies:
layout-base: 2.0.1
cosmiconfig@7.1.0:
dependencies:
'@types/parse-json': 4.0.2
import-fresh: 3.3.1
parse-json: 5.2.0
path-type: 4.0.0
yaml: 2.8.3
cpu-features@0.0.10:
dependencies:
buildcheck: 0.0.6
@@ -9441,8 +9036,6 @@ snapshots:
'@csstools/css-syntax-patches-for-csstree': 1.0.20
css-tree: 3.1.0
csstype@3.1.3: {}
csstype@3.2.3: {}
cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1):
@@ -9760,7 +9353,7 @@ snapshots:
dom-helpers@5.2.1:
dependencies:
'@babel/runtime': 7.26.10
csstype: 3.1.3
csstype: 3.2.3
dompurify@3.4.0:
optionalDependencies:
@@ -9806,10 +9399,6 @@ snapshots:
entities@6.0.1: {}
error-ex@1.3.2:
dependencies:
is-arrayish: 0.2.1
es-define-property@1.0.1: {}
es-errors@1.3.0: {}
@@ -9872,8 +9461,6 @@ snapshots:
escape-html@1.0.3: {}
escape-string-regexp@4.0.0: {}
escape-string-regexp@5.0.0: {}
esm-env@1.2.2: {}
@@ -9985,8 +9572,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
find-root@1.1.0: {}
follow-redirects@1.16.0: {}
for-each@0.3.4:
@@ -10301,11 +9886,6 @@ snapshots:
immediate@3.0.6: {}
import-fresh@3.3.1:
dependencies:
parent-module: 1.0.1
resolve-from: 4.0.0
indent-string@4.0.0: {}
inherits@2.0.4: {}
@@ -10349,8 +9929,6 @@ snapshots:
get-intrinsic: 1.3.0
is-typed-array: 1.1.15
is-arrayish@0.2.1: {}
is-bigint@1.0.4:
dependencies:
has-bigints: 1.0.2
@@ -10527,8 +10105,6 @@ snapshots:
jsesc@3.1.0: {}
json-parse-even-better-errors@2.3.1: {}
json-rpc-2.0@1.7.1: {}
json5@2.2.3: {}
@@ -11320,10 +10896,6 @@ snapshots:
pako@1.0.11: {}
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
parse-entities@2.0.0:
dependencies:
character-entities: 1.2.4
@@ -11343,13 +10915,6 @@ snapshots:
is-decimal: 2.0.1
is-hexadecimal: 2.0.1
parse-json@5.2.0:
dependencies:
'@babel/code-frame': 7.29.7
error-ex: 1.3.2
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
parse5@7.3.0:
dependencies:
entities: 6.0.1
@@ -11381,8 +10946,6 @@ snapshots:
path-to-regexp@6.3.0: {}
path-type@4.0.0: {}
pathe@2.0.3: {}
pathval@2.0.1: {}
@@ -11694,8 +11257,6 @@ snapshots:
react-is@18.3.1: {}
react-is@19.1.1: {}
react-markdown@9.1.0(@types/react@19.2.18)(react@19.2.8):
dependencies:
'@types/hast': 3.0.4
@@ -11948,8 +11509,6 @@ snapshots:
resize-observer-polyfill@1.5.1: {}
resolve-from@4.0.0: {}
resolve@1.22.11:
dependencies:
is-core-module: 2.16.1
@@ -12160,8 +11719,6 @@ snapshots:
source-map-js@1.2.1: {}
source-map@0.5.7: {}
source-map@0.6.1: {}
source-map@0.7.4: {}
@@ -12310,8 +11867,6 @@ snapshots:
dependencies:
inline-style-parser: 0.2.4
stylis@4.2.0: {}
stylis@4.3.6: {}
sucrase@3.35.1:
@@ -12862,7 +12417,8 @@ snapshots:
yallist@3.1.1: {}
yaml@2.8.3: {}
yaml@2.8.3:
optional: true
yargs-parser@21.1.1: {}
-5
View File
@@ -1,5 +0,0 @@
import type { Theme as CoderTheme } from "#/theme";
declare module "@emotion/react" {
interface Theme extends CoderTheme {}
}
-19
View File
@@ -1,19 +0,0 @@
import type { PaletteColor, PaletteColorOptions } from "@mui/material/styles";
declare module "@mui/material/styles" {
interface Palette {
neutral: PaletteColor;
dots: string;
}
interface PaletteOptions {
neutral?: PaletteColorOptions;
dots?: string;
}
}
declare module "@mui/material/Checkbox" {
interface CheckboxPropsSizeOverrides {
xsmall: true;
}
}
+1 -4
View File
@@ -40,10 +40,7 @@ export const CommandList: React.FC<
> = ({ className, ...props }) => {
return (
<CommandPrimitive.List
className={cn(
"max-h-96 overflow-y-auto overflow-x-hidden border-0 border-t border-solid border-border",
className,
)}
className={cn("max-h-96 overflow-y-auto overflow-x-hidden", className)}
{...props}
/>
);
@@ -70,7 +70,7 @@ export const DropdownMenuRadioItem: React.FC<
{...props}
>
{children}
<span className="absolute top-3.5 right-2 flex h-3.5 w-3.5 items-center justify-center">
<span className="absolute top-2.75 right-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<CheckIcon className="size-4" />
</DropdownMenuPrimitive.ItemIndicator>
+18 -12
View File
@@ -7,31 +7,37 @@ import { cn } from "#/utils/cn";
export const Slider: React.FC<
React.ComponentPropsWithRef<typeof SliderPrimitive.Root>
> = ({ className, ...props }) => {
> = ({ className, defaultValue, value, min = 0, max = 100, ...props }) => {
const thumbCount = Array.isArray(value)
? value.length
: Array.isArray(defaultValue)
? defaultValue.length
: 1;
return (
<SliderPrimitive.Root
className={cn(
"relative flex w-full items-center h-1.5",
"relative flex w-full touch-none select-none items-center h-1.5",
className,
"touch-none select-none",
)}
defaultValue={defaultValue}
value={value}
min={min}
max={max}
{...props}
>
<SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-surface-secondary data-[disabled]:opacity-40">
<SliderPrimitive.Range className="absolute h-full bg-content-primary" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb
className="block size-4 rounded-full border border-solid border-surface-invert-secondary bg-surface-primary shadow transition-colors
{Array.from({ length: thumbCount }, (_, index) => (
<SliderPrimitive.Thumb
key={`slider-thumb-${index}`}
className="block size-4 rounded-full border border-solid border-surface-invert-secondary bg-surface-primary shadow transition-colors
focus-visible:outline-none hover:border-content-primary
focus-visible:ring-0 focus-visible:ring-content-primary focus-visible:ring-offset-surface-primary
disabled:pointer-events-none data-[disabled]:opacity-100 data-[disabled]:border-border"
/>
<SliderPrimitive.Thumb
className="block size-4 rounded-full border border-solid border-surface-invert-secondary bg-surface-primary shadow transition-colors
focus-visible:outline-none hover:border-content-primary
focus-visible:ring-0 focus-visible:ring-content-primary focus-visible:ring-offset-surface-primary
disabled:pointer-events-none data-[disabled]:opacity-100 data-[disabled]:border-border"
/>
/>
))}
</SliderPrimitive.Root>
);
};
+3 -4
View File
@@ -29,13 +29,12 @@ const switchVariants = cva(
);
const thumbVariants = cva(
"pointer-events-none block rounded-full bg-surface-primary shadow-lg ring-0 transition-transform",
"pointer-events-none block rounded-full bg-surface-primary shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0",
{
variants: {
size: {
default:
"size-4 data-[state=checked]:translate-x-2.5 data-[state=unchecked]:-translate-x-1.5",
sm: "size-3 data-[state=checked]:translate-x-1.5 data-[state=unchecked]:-translate-x-1.5",
default: "size-4 data-[state=checked]:translate-x-4",
sm: "size-3 data-[state=checked]:translate-x-3",
},
},
defaultVariants: {
@@ -1,8 +1,8 @@
import { useTheme } from "@emotion/react";
import Editor, { DiffEditor, loader } from "@monaco-editor/react";
import type * as Monaco from "monaco-editor";
import * as monaco from "monaco-editor";
import { type ComponentProps, type FC, useCallback } from "react";
import { useTheme } from "#/theme/context";
import { useCoderTheme } from "./coderTheme";
loader.config({ monaco });
@@ -1,6 +1,7 @@
import { useTheme } from "@emotion/react";
import { useMonaco } from "@monaco-editor/react";
import { useEffect, useState } from "react";
import { useTheme } from "#/theme/context";
export const useCoderTheme = (): { isLoading: boolean; name: string } => {
const [isLoading, setIsLoading] = useState(true);
const monaco = useMonaco();
+7 -34
View File
@@ -1,16 +1,3 @@
import createCache from "@emotion/cache";
/** @deprecated Emotion is deprecated. Migrate to Tailwind CSS. */
import {
CacheProvider,
ThemeProvider as EmotionThemeProvider,
} from "@emotion/react";
/** @deprecated MUI CssBaseline is deprecated. Migrate to shadcn/ui components and Tailwind CSS. */
import CssBaseline from "@mui/material/CssBaseline";
/** @deprecated MUI components are deprecated. Migrate to shadcn/ui components and Tailwind CSS. */
import {
ThemeProvider as MuiThemeProvider,
StyledEngineProvider,
} from "@mui/material/styles";
import {
type FC,
type PropsWithChildren,
@@ -22,6 +9,7 @@ import { appearanceSettings } from "#/api/queries/users";
import { useEmbeddedMetadata } from "#/hooks/useEmbeddedMetadata";
import themes, { baseModeFor, CONCRETE_THEMES, type Theme } from "#/theme";
import { AppearanceProvider } from "#/theme/appearance";
import { ThemeContextProvider } from "#/theme/context";
import {
migrateLegacyPreference,
resolveActiveThemeName,
@@ -58,19 +46,9 @@ export const ThemeProvider: FC<PropsWithChildren> = ({ children }) => {
const theme = themes[concreteName];
return (
<StyledEngineProvider injectFirst>
<ThemeOverride theme={theme}>{children}</ThemeOverride>
</StyledEngineProvider>
);
return <ThemeOverride theme={theme}>{children}</ThemeOverride>;
};
// This is being added to allow Tailwind classes to be used with MUI components. https://mui.com/material-ui/integrations/interoperability/#tailwind-css
const cache = createCache({
key: "css",
prepend: true,
});
interface ThemeOverrideProps {
theme: Theme;
children?: ReactNode;
@@ -78,15 +56,10 @@ interface ThemeOverrideProps {
export const ThemeOverride: FC<ThemeOverrideProps> = ({ theme, children }) => {
return (
<CacheProvider value={cache}>
<MuiThemeProvider theme={theme}>
<EmotionThemeProvider theme={theme}>
<CssBaseline enableColorScheme />
<AppearanceProvider externalImages={theme.externalImages}>
{children}
</AppearanceProvider>
</EmotionThemeProvider>
</MuiThemeProvider>
</CacheProvider>
<ThemeContextProvider theme={theme}>
<AppearanceProvider externalImages={theme.externalImages}>
{children}
</AppearanceProvider>
</ThemeContextProvider>
);
};
+16 -11
View File
@@ -369,6 +369,10 @@
@apply h-full;
}
body {
@apply bg-surface-primary text-content-primary font-sans antialiased;
}
button,
input {
@apply font-sans;
@@ -423,17 +427,18 @@
}
}
/*
This is a temporary fix for MUI Modals/Popovers until they are removed.
When html has scrollbar-gutter: stable, the browser reserves space for the scrollbar.
MUI Modals/Popovers, when locking body scroll, add `overflow: hidden` and `padding-right`
to the body to compensate for the scrollbar they are hiding. This added padding-right
conflicts with the already reserved gutter space, causing a layout shift.
This rule overrides MUI's added padding-right on the body specifically when MUI
is likely to have set both overflow:hidden and padding-right.
*/
body[style*="overflow: hidden"][style*="padding-right"] {
padding-right: 0px;
h2 {
font-size: 1.5em;
font-weight: bold;
}
h3,
p {
margin-block: 1em;
}
h4 {
margin-block: 1.33em;
}
}
@@ -1,4 +1,3 @@
import { type Theme, useTheme } from "@emotion/react";
import { ExternalLinkIcon } from "lucide-react";
import { type FC, useState } from "react";
import { Link } from "react-router";
@@ -7,6 +6,8 @@ import {
TooltipContent,
TooltipTrigger,
} from "#/components/Tooltip/Tooltip";
import type { Theme } from "#/theme";
import { useTheme } from "#/theme/context";
import { Bar } from "./Chart/Bar";
import {
Chart,
@@ -1,10 +1,11 @@
import { type Theme, useTheme } from "@emotion/react";
import { type FC, useState } from "react";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "#/components/Tooltip/Tooltip";
import type { Theme } from "#/theme";
import { useTheme } from "#/theme/context";
import { Bar } from "./Chart/Bar";
import {
Chart,
@@ -1,4 +1,3 @@
import { useTheme } from "@emotion/react";
import {
File as FileViewer,
type SupportedLanguages,
@@ -11,6 +10,7 @@ import {
type UrlTransform,
} from "streamdown";
import { ScrollArea } from "#/components/ScrollArea/ScrollArea";
import { useTheme } from "#/theme/context";
import { cn } from "#/utils/cn";
import { MarkdownImage } from "./MarkdownImage";
@@ -1,9 +1,9 @@
import { useTheme } from "@emotion/react";
import type { FileDiffMetadata } from "@pierre/diffs";
import { FileDiff } from "@pierre/diffs/react";
import type React from "react";
import type * as TypesGen from "#/api/typesGenerated";
import { ScrollArea } from "#/components/ScrollArea/ScrollArea";
import { useTheme } from "#/theme/context";
import { getPathBasename } from "../../../utils/path";
import { DiffFileHeader } from "./DiffFileHeader";
import {
@@ -1,7 +1,7 @@
import { useTheme } from "@emotion/react";
import { File as FileViewer } from "@pierre/diffs/react";
import type React from "react";
import { ScrollArea } from "#/components/ScrollArea/ScrollArea";
import { useTheme } from "#/theme/context";
import { getPathBasename } from "../../../utils/path";
import { asRecord, asString } from "../runtimeTypeUtils";
import { ToolCall } from "./ToolCall";
@@ -1,8 +1,8 @@
import { useTheme } from "@emotion/react";
import { File as FileViewer } from "@pierre/diffs/react";
import { type ComponentPropsWithRef, type FC, memo } from "react";
import type * as TypesGen from "#/api/typesGenerated";
import { ScrollArea } from "#/components/ScrollArea/ScrollArea";
import { useTheme } from "#/theme/context";
import { cn } from "#/utils/cn";
import { AdvisorTool, type AdvisorToolResultType } from "./AdvisorTool";
import {
@@ -1,9 +1,9 @@
import { useTheme } from "@emotion/react";
import type { FileDiffMetadata } from "@pierre/diffs";
import { FileDiff } from "@pierre/diffs/react";
import type React from "react";
import type * as TypesGen from "#/api/typesGenerated";
import { ScrollArea } from "#/components/ScrollArea/ScrollArea";
import { useTheme } from "#/theme/context";
import { getPathBasename } from "../../../utils/path";
import { DiffFileHeader } from "./DiffFileHeader";
import {
@@ -1,4 +1,3 @@
import { useTheme } from "@emotion/react";
import type {
CodeViewHandle,
CodeViewItem,
@@ -22,6 +21,7 @@ import {
} from "react";
import { ErrorAlert } from "#/components/Alert/ErrorAlert";
import { Skeleton } from "#/components/Skeleton/Skeleton";
import { useTheme } from "#/theme/context";
import { cn } from "#/utils/cn";
import { countChangedLines } from "../../utils/countChangedLines";
import { changeColor, changeLabel } from "../../utils/diffColors";
@@ -1,4 +1,3 @@
import { useTheme } from "@emotion/react";
import { useFormik } from "formik";
import { type FC, useState } from "react";
import { SliderPicker, TwitterPicker } from "react-color";
@@ -15,6 +14,7 @@ import {
import { Label } from "#/components/Label/Label";
import { Textarea } from "#/components/Textarea/Textarea";
import { AnnouncementBannerView } from "#/modules/dashboard/AnnouncementBanners/AnnouncementBannerView";
import { useTheme } from "#/theme/context";
import { cn } from "#/utils/cn";
import { getFormHelpers } from "#/utils/formUtils";
@@ -1,4 +1,3 @@
import { useTheme } from "@emotion/react";
import { PlusIcon, RotateCwIcon } from "lucide-react";
import type { FC } from "react";
import Confetti from "react-confetti";
@@ -20,6 +19,7 @@ import {
TooltipTrigger,
} from "#/components/Tooltip/Tooltip";
import { useWindowSize } from "#/hooks/useWindowSize";
import { useTheme } from "#/theme/context";
import { AIGovernanceUsersConsumption } from "./AIGovernanceUsersConsumptionChart";
import { LicenseCard } from "./LicenseCard";
import { LicenseSeatConsumptionChart } from "./LicenseSeatConsumptionChart";
@@ -67,7 +67,7 @@ export const ModuleCard: React.FC<ModuleCardProps> = ({
{official && (
<>
{" "}
<BadgeCheckIcon className="size-4 text-highlight-sky align-middle" />
<BadgeCheckIcon className="size-4 text-highlight-sky align-middle inline-block" />
</>
)}
</h3>
@@ -1,8 +1,8 @@
import { useTheme } from "@emotion/react";
import Editor, { loader } from "@monaco-editor/react";
import * as monaco from "monaco-editor";
import { type FC, useEffect } from "react";
import { MONOSPACE_FONT_FAMILY } from "#/theme/constants";
import { useTheme } from "#/theme/context";
loader.config({ monaco });
@@ -31,15 +31,6 @@ import TemplateVersionEditorPage, {
const { API } = apiModule;
// For some reason this component in Jest is throwing a MUI style warning so,
// since we don't need it for this test, we can mock it out
vi.mock(
"modules/templates/TemplateResourcesTable/TemplateResourcesTable",
() => ({
TemplateResourcesTable: () => <div></div>,
}),
);
// Monaco is a large and complicated codebase that slows tests down and we don't
// need to test.
vi.mock("#/pages/TemplateVersionEditorPage/MonacoEditor", () => ({
+1 -2
View File
@@ -8,8 +8,7 @@ import {
import type { ExternalImageModeStyles } from "#/theme/externalImages";
/**
* Publishes *user* appearance values derived from the active site theme so
* components can consume them without depending on Emotion's `useTheme`.
* Publishes *user* appearance values derived from the active site theme.
*
* This is the client-side, theme-derived appearance surface (for example, how
* external images should be tinted for the active theme). It is intentionally
-7
View File
@@ -1,12 +1,9 @@
import type { TerminalFontName } from "#/api/typesGenerated";
export const borderRadius = 8;
const MONOSPACE_DEFAULT_FONT = "Geist Mono Variable";
const TERMINAL_SYMBOL_FONT = "'Coder Terminal Symbols'";
export const MONOSPACE_FONT_FAMILY =
"'Geist Mono Variable', 'IBM Plex Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'Liberation Mono', 'Monaco', 'Courier New', Courier, monospace";
export const BODY_FONT_FAMILY = `"Geist Variable", system-ui, sans-serif`;
const withTerminalSymbolFallback = (fontFamily: string) =>
fontFamily.replace(", monospace", `, ${TERMINAL_SYMBOL_FONT}, monospace`);
@@ -42,7 +39,3 @@ export const navHeight = 62;
export const containerWidth = 1380;
export const containerWidthMedium = 1080;
export const sidePadding = 24;
// MUI does not have aligned heights for buttons and inputs so we have to "hack" it a little bit
export const BUTTON_LG_HEIGHT = 40;
export const BUTTON_MD_HEIGHT = 36;
+26
View File
@@ -0,0 +1,26 @@
import { createContext, type FC, type ReactNode, useContext } from "react";
import type { Theme } from "#/theme";
const ThemeContext = createContext<Theme | undefined>(undefined);
interface ThemeContextProviderProps {
theme: Theme;
children: ReactNode;
}
export const ThemeContextProvider: FC<ThemeContextProviderProps> = ({
theme,
children,
}) => {
return (
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
);
};
export const useTheme = (): Theme => {
const theme = useContext(ThemeContext);
if (theme === undefined) {
throw new Error("useTheme must be used within a ThemeContextProvider");
}
return theme;
};
+2 -2
View File
@@ -2,11 +2,11 @@ import { forDarkThemes } from "../externalImages";
import branding from "./branding";
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import palette from "./palette";
import roles from "./roles";
export default {
...muiTheme,
palette,
externalImages: forDarkThemes,
experimental,
branding,
+3 -3
View File
@@ -1,5 +1,5 @@
import type * as monaco from "monaco-editor";
import muiTheme from "./mui";
import palette from "./palette";
export default {
base: "vs-dark",
@@ -31,7 +31,7 @@ export default {
},
],
colors: {
"editor.foreground": muiTheme.palette.text.primary,
"editor.background": muiTheme.palette.background.paper,
"editor.foreground": palette.text.primary,
"editor.background": palette.background.paper,
},
} satisfies monaco.editor.IStandaloneThemeData as monaco.editor.IStandaloneThemeData;
-84
View File
@@ -1,84 +0,0 @@
/**
* @deprecated MUI dark theme is deprecated. Migrate to Tailwind CSS theme system.
* This file provides MUI theme configuration for legacy compatibility only.
*/
/** @deprecated MUI createTheme is deprecated. Migrate to Tailwind CSS theme system. */
import { createTheme } from "@mui/material/styles";
import { BODY_FONT_FAMILY, borderRadius } from "../constants";
import { components } from "../mui";
import tw from "../tailwindColors";
const muiTheme = createTheme({
palette: {
mode: "dark",
primary: {
main: tw.sky[500],
contrastText: tw.white,
light: tw.sky[400],
dark: tw.sky[600],
},
secondary: {
main: tw.zinc[500],
contrastText: tw.zinc[200],
dark: tw.zinc[400],
},
background: {
default: tw.zinc[950],
paper: tw.zinc[900],
},
text: {
primary: tw.zinc[50],
secondary: tw.zinc[400],
disabled: tw.zinc[500],
},
divider: tw.zinc[700],
warning: {
light: tw.amber[500],
main: tw.amber[800],
dark: tw.amber[950],
},
success: {
main: tw.green[500],
dark: tw.green[600],
},
info: {
light: tw.blue[400],
main: tw.blue[600],
dark: tw.blue[950],
contrastText: tw.zinc[200],
},
error: {
light: tw.red[400],
main: tw.red[500],
dark: tw.red[950],
contrastText: tw.zinc[200],
},
action: {
hover: tw.zinc[800],
},
neutral: {
main: tw.zinc[50],
},
dots: tw.zinc[500],
},
typography: {
fontFamily: BODY_FONT_FAMILY,
body1: {
fontSize: "1rem" /* 16px at default scaling */,
lineHeight: "160%",
},
body2: {
fontSize: "0.875rem" /* 14px at default scaling */,
lineHeight: "160%",
},
},
shape: {
borderRadius,
},
components,
});
export default muiTheme;
+21
View File
@@ -0,0 +1,21 @@
import type { Palette } from "../palette";
import tw from "../tailwindColors";
const palette: Palette = {
mode: "dark",
primary: {
main: tw.sky[500],
},
secondary: {
main: tw.zinc[500],
},
background: {
default: tw.zinc[950],
paper: tw.zinc[900],
},
text: {
primary: tw.zinc[50],
},
};
export default palette;
+2 -2
View File
@@ -1,12 +1,12 @@
import palette from "../dark/palette";
import { forDarkThemes } from "../externalImages";
import branding from "./branding";
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import roles from "./roles";
export default {
...muiTheme,
palette,
externalImages: forDarkThemes,
experimental,
branding,
-12
View File
@@ -1,12 +0,0 @@
/**
* @deprecated MUI theme is deprecated. Migrate to Tailwind CSS theme system.
*
* MUI components are deprecated and the colorblind-friendly palette is
* expressed through `roles.ts` and the CSS variables in
* `site/src/index.css`, both of which drive the Tailwind-rendered UI that
* the diff panel and semantic roles use. We re-export the base dark MUI
* theme so `palette.mode === "dark"` stays correct for any remaining
* legacy MUI component that inspects it (for example, the Shiki theme
* selector in `DiffViewer.tsx`).
*/
export { default } from "../dark/mui";
+2 -2
View File
@@ -1,12 +1,12 @@
import palette from "../dark/palette";
import { forDarkThemes } from "../externalImages";
import branding from "./branding";
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import roles from "./roles";
export default {
...muiTheme,
palette,
externalImages: forDarkThemes,
experimental,
branding,
-9
View File
@@ -1,9 +0,0 @@
/**
* @deprecated MUI theme is deprecated. Migrate to Tailwind CSS theme system.
*
* The colorblind-friendly palette is expressed through `roles.ts` and the
* CSS variables in `site/src/index.css`. We re-export the base dark MUI
* theme so `palette.mode === "dark"` stays correct for any remaining
* legacy MUI component that inspects it.
*/
export { default } from "../dark/mui";
+4 -5
View File
@@ -1,5 +1,3 @@
/** @deprecated MUI Theme type is deprecated. Migrate to Tailwind CSS theme system. */
import type { Theme as MuiTheme } from "@mui/material/styles";
import type * as monaco from "monaco-editor";
import type { Branding } from "./branding";
import dark from "./dark";
@@ -10,11 +8,12 @@ import type { ExternalImageModeStyles } from "./externalImages";
import light from "./light";
import lightProtanDeuter from "./lightProtanDeuter";
import lightTritan from "./lightTritan";
import type { Palette } from "./palette";
import type { Roles } from "./roles";
export interface Theme extends Omit<MuiTheme, "palette"> {
/** @deprecated prefer `theme.roles` when possible */
palette: MuiTheme["palette"];
export interface Theme {
/** @deprecated prefer roles or CSS variables when possible */
palette: Palette;
/** Sets of colors that can be used based on the role that a UI element serves
* for the user.
+2 -2
View File
@@ -2,11 +2,11 @@ import { forLightThemes } from "../externalImages";
import branding from "./branding";
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import palette from "./palette";
import roles from "./roles";
export default {
...muiTheme,
palette,
externalImages: forLightThemes,
experimental,
branding,
+3 -3
View File
@@ -1,5 +1,5 @@
import type * as monaco from "monaco-editor";
import muiTheme from "./mui";
import palette from "./palette";
export default {
base: "vs",
@@ -31,7 +31,7 @@ export default {
},
],
colors: {
"editor.foreground": muiTheme.palette.text.primary,
"editor.background": muiTheme.palette.background.paper,
"editor.foreground": palette.text.primary,
"editor.background": palette.background.paper,
},
} satisfies monaco.editor.IStandaloneThemeData as monaco.editor.IStandaloneThemeData;
-185
View File
@@ -1,185 +0,0 @@
/**
* @deprecated MUI light theme is deprecated. Migrate to Tailwind CSS theme system.
* This file provides MUI theme configuration for legacy compatibility only.
*/
/** @deprecated MUI createTheme is deprecated. Migrate to Tailwind CSS theme system. */
import { createTheme } from "@mui/material/styles";
import { BODY_FONT_FAMILY, borderRadius } from "../constants";
import { components } from "../mui";
import tw from "../tailwindColors";
// biome-ignore lint/suspicious/noExplicitAny: needed for MUI overrides
type MuiStyle = any;
const muiTheme = createTheme({
palette: {
mode: "light",
primary: {
main: tw.sky[600],
contrastText: tw.sky[50],
light: tw.sky[400],
dark: tw.sky[500],
},
secondary: {
main: tw.zinc[500],
contrastText: tw.zinc[800],
dark: tw.zinc[600],
},
background: {
default: tw.zinc[50],
paper: tw.zinc[100],
},
text: {
primary: tw.zinc[950],
secondary: tw.zinc[600],
disabled: tw.zinc[500],
},
divider: tw.zinc[200],
warning: {
light: tw.amber[400],
main: tw.amber[800],
dark: tw.amber[950],
},
success: {
main: tw.green[500],
dark: tw.green[600],
},
info: {
light: tw.blue[400],
main: tw.blue[600],
dark: tw.blue[950],
contrastText: tw.zinc[200],
},
error: {
light: tw.red[400],
main: tw.red[500],
dark: tw.red[950],
contrastText: tw.zinc[800],
},
action: {
hover: tw.zinc[100],
},
neutral: {
main: tw.zinc[950],
},
dots: tw.zinc[400],
},
typography: {
fontFamily: BODY_FONT_FAMILY,
body1: {
fontSize: "1rem" /* 16px at default scaling */,
lineHeight: "160%",
},
body2: {
fontSize: "0.875rem" /* 14px at default scaling */,
lineHeight: "160%",
},
},
shape: {
borderRadius,
},
components: {
...components,
MuiCssBaseline: {
styleOverrides: (theme) => `
html, body, #root, #storybook-root {
height: 100%;
}
button, input {
font-family: ${BODY_FONT_FAMILY};
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 100px ${theme.palette.background.default} inset !important;
}
::placeholder {
color: ${theme.palette.text.disabled};
}
`,
},
MuiAvatar: {
styleOverrides: {
root: components.MuiAvatar.styleOverrides.root,
colorDefault: {
backgroundColor: tw.zinc[700],
},
},
},
MuiChip: {
styleOverrides: {
root: {
backgroundColor: tw.zinc[400],
},
},
},
MuiInputBase: {
...components.MuiInputBase,
styleOverrides: {
...components.MuiInputBase.styleOverrides,
["colorPrimary" as MuiStyle]: {
// Same as button
"& .MuiOutlinedInput-notchedOutline": {
borderColor: tw.zinc[300],
},
// The default outlined input color is white, which seemed jarring.
"&:hover:not(.Mui-error):not(.Mui-focused) .MuiOutlinedInput-notchedOutline":
{
borderColor: tw.zinc[500],
},
},
},
},
MuiCheckbox: {
styleOverrides: {
root: {
/**
* Adds focus styling to checkboxes (which doesn't exist normally, for
* some reason?).
*
* The checkbox component is a root span with a checkbox input inside
* it. MUI does not allow you to use selectors like (& input) to
* target the inner checkbox (even though you can use & td to style
* tables). Tried every combination of selector possible (including
* lots of !important), and the main issue seems to be that the
* styling just never gets processed for it to get injected into the
* CSSOM.
*
* Had to settle for adding styling to the span itself (which does
* make the styling more obvious, even if there's not much room for
* customization).
*/
"&.Mui-focusVisible": {
boxShadow: `0 0 0 2px ${tw.blue[600]}`,
},
"&.Mui-disabled": {
color: tw.zinc[500],
},
},
},
},
MuiTooltip: {
styleOverrides: {
tooltip: ({ theme }) => ({
lineHeight: "150%",
borderRadius: 4,
background: theme.palette.background.paper,
color: theme.palette.secondary.contrastText,
border: `1px solid ${theme.palette.divider}`,
padding: "8px 16px",
boxShadow: "0 1px 4px #0001",
}),
},
},
},
});
export default muiTheme;
+21
View File
@@ -0,0 +1,21 @@
import type { Palette } from "../palette";
import tw from "../tailwindColors";
const palette: Palette = {
mode: "light",
primary: {
main: tw.sky[600],
},
secondary: {
main: tw.zinc[500],
},
background: {
default: tw.zinc[50],
paper: tw.zinc[100],
},
text: {
primary: tw.zinc[950],
},
};
export default palette;
+2 -2
View File
@@ -1,12 +1,12 @@
import { forLightThemes } from "../externalImages";
import palette from "../light/palette";
import branding from "./branding";
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import roles from "./roles";
export default {
...muiTheme,
palette,
externalImages: forLightThemes,
experimental,
branding,
-10
View File
@@ -1,10 +0,0 @@
/**
* @deprecated MUI theme is deprecated. Migrate to Tailwind CSS theme system.
*
* The colorblind-friendly palette is expressed through `roles.ts` and the
* CSS variables in `site/src/index.css`. We re-export the base light MUI
* theme so `palette.mode === "light"` stays correct for any remaining
* legacy MUI component that inspects it, including the Shiki theme
* selector in `DiffViewer.tsx`.
*/
export { default } from "../light/mui";
+2 -2
View File
@@ -1,12 +1,12 @@
import { forLightThemes } from "../externalImages";
import palette from "../light/palette";
import branding from "./branding";
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import roles from "./roles";
export default {
...muiTheme,
palette,
externalImages: forLightThemes,
experimental,
branding,
-8
View File
@@ -1,8 +0,0 @@
/**
* @deprecated MUI theme is deprecated. Migrate to Tailwind CSS theme system.
*
* Re-exports the base light MUI theme so `palette.mode === "light"` stays
* correct for legacy MUI components. Colorblind palette overrides live in
* `roles.ts` and the CSS variables block in `site/src/index.css`.
*/
export { default } from "../light/mui";
-222
View File
@@ -1,222 +0,0 @@
/**
* @deprecated MUI theme configuration is deprecated. Migrate to Tailwind CSS theme system.
* This file provides MUI theme overrides for legacy compatibility only.
*/
/** @deprecated MUI ThemeOptions is deprecated. Migrate to Tailwind CSS theme system. */
import type { ThemeOptions } from "@mui/material/styles";
import { BUTTON_LG_HEIGHT, BUTTON_MD_HEIGHT } from "./constants";
import tw from "./tailwindColors";
// biome-ignore lint/suspicious/noExplicitAny: needed for MUI overrides
type MuiStyle = any;
export const components = {
MuiAvatar: {
styleOverrides: {
root: {
width: 36,
height: 36,
fontSize: 18,
"& .MuiSvgIcon-root": {
width: "50%",
},
},
colorDefault: ({ theme }) => ({
backgroundColor: theme.palette.primary.light,
}),
},
},
MuiLink: {
defaultProps: {
underline: "hover",
},
},
MuiSkeleton: {
styleOverrides: {
root: ({ theme }) => ({
backgroundColor: theme.palette.divider,
}),
},
},
MuiLinearProgress: {
styleOverrides: {
root: {
borderRadius: 999,
},
},
},
MuiMenu: {
defaultProps: {
anchorOrigin: {
vertical: "bottom",
horizontal: "right",
},
transformOrigin: {
vertical: "top",
horizontal: "right",
},
},
styleOverrides: {
paper: {
marginTop: 8,
borderRadius: 4,
padding: "4px 0",
minWidth: 160,
},
root: {
// It should be the same as the menu padding
"& .MuiDivider-root": {
marginTop: "4px !important",
marginBottom: "4px !important",
},
},
},
},
MuiMenuItem: {
styleOverrides: {
root: {
gap: 12,
"& .MuiSvgIcon-root": {
fontSize: 20,
},
},
},
},
MuiSnackbar: {
styleOverrides: {
anchorOriginBottomRight: {
bottom: `${24 + 36}px !important`, // 36 is the bottom bar height
},
},
},
MuiSnackbarContent: {
styleOverrides: {
root: {
borderRadius: "4px !important",
},
},
},
MuiTextField: {
defaultProps: {
InputLabelProps: {
shrink: true,
},
},
},
MuiInputBase: {
defaultProps: {
color: "primary",
},
styleOverrides: {
root: {
height: BUTTON_LG_HEIGHT,
},
sizeSmall: {
height: BUTTON_MD_HEIGHT,
fontSize: 14,
},
multiline: {
height: "auto",
},
["colorPrimary" as MuiStyle]: {
// Same as button
"& .MuiOutlinedInput-notchedOutline": {
borderColor: tw.zinc[600],
},
// The default outlined input color is white, which seemed jarring.
"&:hover:not(.Mui-error):not(.Mui-focused) .MuiOutlinedInput-notchedOutline":
{
borderColor: tw.zinc[500],
},
},
},
},
MuiFormHelperText: {
defaultProps: {
sx: {
marginLeft: 0,
marginTop: 1,
"&::first-letter": {
// Server errors are returned in all lowercase. To display them as
// field errors in the UI, we capitalize the first letter.
textTransform: "uppercase",
},
},
},
},
MuiRadio: {
defaultProps: {
disableRipple: true,
},
},
MuiCheckbox: {
styleOverrides: {
root: {
/**
* Adds focus styling to checkboxes (which doesn't exist normally, for
* some reason?).
*
* The checkbox component is a root span with a checkbox input inside
* it. MUI does not allow you to use selectors like (& input) to
* target the inner checkbox (even though you can use & td to style
* tables). Tried every combination of selector possible (including
* lots of !important), and the main issue seems to be that the
* styling just never gets processed for it to get injected into the
* CSSOM.
*
* Had to settle for adding styling to the span itself (which does
* make the styling more obvious, even if there's not much room for
* customization).
*/
"&.Mui-focusVisible": {
boxShadow: `0 0 0 2px ${tw.blue[400]}`,
},
"&.Mui-disabled": {
color: tw.zinc[500],
},
"& .MuiSvgIcon-fontSizeXsmall": {
fontSize: "1rem",
},
},
},
},
MuiAutocomplete: {
styleOverrides: {
root: {
// Not sure why but since the input has padding we don't need it here
"& .MuiInputBase-root": {
padding: "0px 0px 0px 8px",
},
},
},
},
MuiList: {
defaultProps: {
disablePadding: true,
},
},
MuiTabs: {
defaultProps: {
textColor: "primary",
indicatorColor: "primary",
},
},
MuiTooltip: {
styleOverrides: {
tooltip: ({ theme }) => ({
lineHeight: "150%",
borderRadius: 4,
background: theme.palette.divider,
padding: "8px 16px",
}),
arrow: ({ theme }) => ({
color: theme.palette.divider,
}),
},
},
} satisfies ThemeOptions["components"];
+20
View File
@@ -0,0 +1,20 @@
/**
* Minimal palette used by remaining non-Tailwind consumers (Monaco, charts,
* confetti, color pickers). Prefer semantic CSS variables and roles when possible.
*/
export interface Palette {
mode: "dark" | "light";
primary: {
main: string;
};
secondary: {
main: string;
};
background: {
default: string;
paper: string;
};
text: {
primary: string;
};
}
-3
View File
@@ -1,8 +1,5 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
corePlugins: {
preflight: false,
},
darkMode: ["selector"],
content: [
"./index.html",
-1
View File
@@ -5,7 +5,6 @@
"incremental": true,
"isolatedModules": true,
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
"lib": ["dom", "esnext"],
"module": "preserve",
"moduleResolution": "bundler",
+3 -52
View File
@@ -62,8 +62,6 @@ export default defineConfig({
},
codeSplitting: {
groups: [
{ name: "mui", test: /@mui/ },
{ name: "emotion", test: /@emotion/ },
{ name: "monaco", test: /monaco-editor/ },
{ name: "xterm", test: /@xterm/ },
{ name: "emoji-mart", test: /emoji-mart/ },
@@ -157,58 +155,11 @@ export default defineConfig({
},
allowedHosts: [".coder", ".dev.coder.com"],
},
// Pre-bundle deps that Vite tends to discover late (deep MUI
// imports, Emotion). Without this, Vite re-optimizes mid-session
// which returns 504 "Outdated Optimize Dep" for every previously
// served chunk, cascading into dynamic import failures.
// Pre-bundle deps that Vite tends to discover late. Without this, Vite
// re-optimizes mid-session which returns 504 "Outdated Optimize Dep" for
// every previously served chunk, cascading into dynamic import failures.
optimizeDeps: {
include: [
"@emotion/cache",
"@emotion/css",
"@emotion/react",
"@emotion/react/jsx-runtime",
"@emotion/styled",
"@mui/material/Autocomplete",
"@mui/material/Card",
"@mui/material/CardActionArea",
"@mui/material/CardContent",
"@mui/material/Checkbox",
"@mui/material/Collapse",
"@mui/material/CssBaseline",
"@mui/material/Dialog",
"@mui/material/DialogActions",
"@mui/material/DialogContent",
"@mui/material/DialogContentText",
"@mui/material/DialogTitle",
"@mui/material/Divider",
"@mui/material/Drawer",
"@mui/material/FormControl",
"@mui/material/FormControlLabel",
"@mui/material/FormGroup",
"@mui/material/FormHelperText",
"@mui/material/FormLabel",
"@mui/material/InputAdornment",
"@mui/material/InputBase",
"@mui/material/Link",
"@mui/material/List",
"@mui/material/ListItem",
"@mui/material/ListItemText",
"@mui/material/Menu",
"@mui/material/MenuItem",
"@mui/material/MenuList",
"@mui/material/Radio",
"@mui/material/RadioGroup",
"@mui/material/Select",
"@mui/material/Skeleton",
"@mui/material/Snackbar",
"@mui/material/Stack",
"@mui/material/TableRow",
"@mui/material/TextField",
"@mui/material/ToggleButton",
"@mui/material/ToggleButtonGroup",
"@mui/material/styles",
"@mui/system/createTheme",
"@mui/system/useTheme",
// Discovered at runtime without this entry, triggering
// a mid-run dep re-optimization that breaks imports.
"@tanstack/react-query-devtools",