diff --git a/Makefile b/Makefile index 1feb0a44e36..7997ac53d45 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,13 @@ dev: @echo "Starting development servers..." @# Start both processes, with marimo in background @(trap 'kill %1; exit' INT; \ - marimo edit --no-token --headless /tmp & \ + uv run marimo edit --no-token --headless /tmp & \ + pnpm dev) +dev-sandbox: + @echo "Starting development servers..." + @# Start both processes, with marimo in background + @(trap 'kill %1; exit' INT; \ + uv run marimo edit /tmp/notebook.py --no-token --headless --sandbox & \ pnpm dev) ############# diff --git a/frontend/src/components/app-config/user-config-form.tsx b/frontend/src/components/app-config/user-config-form.tsx index f344fbe1559..5a3c6496900 100644 --- a/frontend/src/components/app-config/user-config-form.tsx +++ b/frontend/src/components/app-config/user-config-form.tsx @@ -13,6 +13,7 @@ import { PackageIcon, } from "lucide-react"; import React, { useId, useRef } from "react"; +import { useLocale } from "react-aria"; import { useForm } from "react-hook-form"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; @@ -118,6 +119,7 @@ export const UserConfigForm: React.FC = () => { ); const capabilities = useAtomValue(capabilitiesAtom); const marimoVersion = useAtomValue(marimoVersionAtom); + const { locale } = useLocale(); const { saveUserConfig } = useRequestClient(); // Create form @@ -1333,8 +1335,9 @@ export const UserConfigForm: React.FC = () => { ))} -
+
Version: {marimoVersion} + Locale: {locale}
diff --git a/frontend/src/core/i18n/local-provider.tsx b/frontend/src/core/i18n/local-provider.tsx new file mode 100644 index 00000000000..f77162dc433 --- /dev/null +++ b/frontend/src/core/i18n/local-provider.tsx @@ -0,0 +1,12 @@ +/* Copyright 2024 Marimo. All rights reserved. */ + +import type { ReactNode } from "react"; +import { I18nProvider } from "react-aria-components"; + +interface LocaleProviderProps { + children: ReactNode; +} + +export const LocaleProvider = ({ children }: LocaleProviderProps) => { + return {children}; +}; diff --git a/frontend/src/core/islands/components/web-components.tsx b/frontend/src/core/islands/components/web-components.tsx index ef0ae98e92e..db5075b227a 100644 --- a/frontend/src/core/islands/components/web-components.tsx +++ b/frontend/src/core/islands/components/web-components.tsx @@ -7,6 +7,7 @@ import { ErrorBoundary } from "@/components/editor/boundary/ErrorBoundary"; import { TooltipProvider } from "@/components/ui/tooltip"; import { notebookAtom } from "@/core/cells/cells"; import { UI_ELEMENT_REGISTRY } from "@/core/dom/uiregistry"; +import { LocaleProvider } from "@/core/i18n/local-provider"; import { renderHTML } from "@/plugins/core/RenderHTML"; import { invariant } from "@/utils/invariant"; import type { CellId } from "../../cells/ids"; @@ -80,16 +81,18 @@ export class MarimoIslandElement extends HTMLElement { this.root?.render( - - - {initialHtml} - - {editor} - + + + + {initialHtml} + + {editor} + + , ); diff --git a/frontend/src/mount.tsx b/frontend/src/mount.tsx index 59fe1db2b9e..8a0f2964e9a 100644 --- a/frontend/src/mount.tsx +++ b/frontend/src/mount.tsx @@ -26,6 +26,7 @@ import { parseConfigOverrides, parseUserConfig, } from "./core/config/config-schema"; +import { LocaleProvider } from "./core/i18n/local-provider"; import { MarimoApp, preloadPage } from "./core/MarimoApp"; import { type AppMode, initialModeAtom, viewStateAtom } from "./core/mode"; import { cleanupAuthQueryParams } from "./core/network/auth"; @@ -82,9 +83,11 @@ export function mount(options: unknown, el: Element): Error | undefined { root.render( - - - + + + + + , ); } catch (error) { diff --git a/frontend/src/plugins/core/registerReactComponent.tsx b/frontend/src/plugins/core/registerReactComponent.tsx index cb1f4d2f353..868a9671c57 100644 --- a/frontend/src/plugins/core/registerReactComponent.tsx +++ b/frontend/src/plugins/core/registerReactComponent.tsx @@ -29,6 +29,7 @@ import { createInputEvent, MarimoValueUpdateEvent } from "@/core/dom/events"; import { getUIElementObjectId } from "@/core/dom/ui-element"; import { UIElementRegistry } from "@/core/dom/uiregistry"; import { FUNCTIONS_REGISTRY } from "@/core/functions/FunctionRegistry"; +import { LocaleProvider } from "@/core/i18n/local-provider"; import { store } from "@/core/state/jotai"; import { type HTMLElementNotDerivedFromRef, @@ -363,16 +364,18 @@ export function registerReactComponent(plugin: IPlugin): void { invariant(this.root, "Root must be defined"); this.root.render( - { - return parseInitialValue(this, UIElementRegistry.INSTANCE); - }} - > - {this.getChildren()} - , + + { + return parseInitialValue(this, UIElementRegistry.INSTANCE); + }} + > + {this.getChildren()} + + , ); } diff --git a/marimo/_cli/envinfo.py b/marimo/_cli/envinfo.py index 15f06d98a6c..210e8873326 100644 --- a/marimo/_cli/envinfo.py +++ b/marimo/_cli/envinfo.py @@ -46,6 +46,16 @@ def get_experimental_flags() -> dict[str, Union[str, bool, dict[str, Any]]]: return {} +def get_default_locale() -> str: + try: + import locale + + default_locale, _ = locale.getdefaultlocale() + return default_locale or "--" + except Exception: + return "--" + + def get_system_info() -> dict[str, Union[str, bool, dict[str, Any]]]: os_version = platform.release() if platform.system() == "Windows" and is_win11(): @@ -61,6 +71,7 @@ def get_system_info() -> dict[str, Union[str, bool, dict[str, Any]]]: # e.g., x86 or arm "Processor": platform.processor(), "Python Version": platform.python_version(), + "Locale": get_default_locale(), } binaries = {