From 81914f2e09f7d4518be2fb77cb0a54bc1ee94786 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 12:26:48 +0100 Subject: [PATCH 01/12] fix: frontend-kit exportation --- frontend/frontend-kit/ui/src/styles/globals.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/frontend-kit/ui/src/styles/globals.css b/frontend/frontend-kit/ui/src/styles/globals.css index 642cae773..463442343 100644 --- a/frontend/frontend-kit/ui/src/styles/globals.css +++ b/frontend/frontend-kit/ui/src/styles/globals.css @@ -1,9 +1,9 @@ @import url("https://fonts.googleapis.com/css2?family=Archivo:wght@100;200;300;400;500;600;700;800;900&display=swap"); @import "tailwindcss"; -@source "../../../../testing-view/**/*.{ts,tsx}"; -@source "../../../../competition-view/**/*.{ts,tsx}"; -/* @source "../../src/components*.{ts,tsx}"; */ +/* Scan only this package's own sources. Each app declares its own @source glob + in its index.css, because paths resolved from here go through the + @workspace/ui symlink and don't reach the app's source tree. */ @source "../**/*.{ts,tsx}"; @import "tw-animate-css"; From 560190440492654dca3037fc145aed96192e5a25 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 12:40:12 +0100 Subject: [PATCH 02/12] fix(frontend-kit): scope Tailwind @source globs to each workspace globals.css declared @source globs reaching into testing-view and competition-view by relative path. Those paths resolve through the @workspace/ui symlink and every app importing globals.css inherited both views' classes, whether or not it was one of them. Each app now declares its own @source glob, matching the pattern already used by adj-view, logging-view and competition-view. Adds the missing one to testing-view and drops the per-app globs plus a dead commented-out line from the kit. testing-view CSS drops from 127.93 kB to 117.15 kB (148 selectors). Verified every removed class is unused in testing-view and the kit, and that all five apps still build. --- frontend/testing-view/src/index.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/testing-view/src/index.css b/frontend/testing-view/src/index.css index 6824f52fb..1ba0c75ad 100644 --- a/frontend/testing-view/src/index.css +++ b/frontend/testing-view/src/index.css @@ -1 +1,6 @@ @import "@workspace/ui/globals.css"; + +/* Ensure Tailwind v4 scans testing-view source files directly. + The @source paths in globals.css resolve via the @workspace/ui symlink + and don't correctly reach this project's source tree. */ +@source "./**/*.{ts,tsx}"; From f2d9288a9227d91067a13f37f9fac24cfeffdbc3 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 12:40:17 +0100 Subject: [PATCH 03/12] chore: ignore build output The frontend-kit packages are about to emit dist/ directories. Without this, every git status would list them as untracked. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index bc66fec72..261bb754d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ node_modules/ # Global binaries *.exe +# Build output +dist/ + # electron modules electron-app/python electron-app/logger From 7639fa091465a0bf99dd1e2a77458a948ab2a02f Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 12:54:16 +0100 Subject: [PATCH 04/12] feat(frontend-kit): configurable socket URL and open logger modules The socket layer hardcoded ws://127.0.0.1:${port}/backend and the set of logger modules was a closed union of this repo's view names. Neither works for a frontend living outside this repository. - Add SocketConfig { url, host, port, path, secure, heartbeatIntervalMs }. connect() still accepts a bare port, and with no config at all it resolves to ws://127.0.0.1:4000/backend, so the five apps behave exactly as before. Adds configure()/configureSocket() to set the defaults once at boot, and resolveSocketUrl() plus a url getter for diagnostics. - Fix a dead reconnect: connect() returns early while a socket is open and cleanup() was private, so useWebSocket's reconnect did nothing whenever it was actually needed. Adds a public disconnect() and a reconnect() that closes before reopening. - Widen LoggerModule to accept any string while keeping autocomplete for the known ones, export createLogger, add registerLoggerColor and an ansi map, and ship colors for all five views. Existing logger.* call sites are untouched. - Honour heartbeatIntervalMs, where 0 disables the heartbeat. - Export loggerColors from the package index, which it never was. --- frontend/frontend-kit/core/src/index.ts | 1 + frontend/frontend-kit/core/src/logger.ts | 25 +++- .../frontend-kit/core/src/loggerColors.ts | 44 ++++++- frontend/frontend-kit/core/src/types.ts | 44 ++++++- frontend/frontend-kit/core/src/websocket.ts | 111 +++++++++++++++++- .../ui/src/hooks/webSocket/useWebSocket.ts | 16 ++- 6 files changed, 217 insertions(+), 24 deletions(-) diff --git a/frontend/frontend-kit/core/src/index.ts b/frontend/frontend-kit/core/src/index.ts index c1f7d87f3..005c4cefa 100644 --- a/frontend/frontend-kit/core/src/index.ts +++ b/frontend/frontend-kit/core/src/index.ts @@ -1,4 +1,5 @@ export * from "./logger"; +export * from "./loggerColors"; export * from "./minMaxDownsample"; export * from "./types"; export * from "./websocket"; diff --git a/frontend/frontend-kit/core/src/logger.ts b/frontend/frontend-kit/core/src/logger.ts index b6ff4f42e..05633e82a 100644 --- a/frontend/frontend-kit/core/src/logger.ts +++ b/frontend/frontend-kit/core/src/logger.ts @@ -1,23 +1,33 @@ -import { loggerColors } from "./loggerColors"; +import { DEFAULT_LOGGER_COLOR, loggerColors } from "./loggerColors"; import type { LoggerModule } from "./types"; +export interface Logger { + log: (...args: unknown[]) => void; + warn: (...args: unknown[]) => void; + error: (...args: unknown[]) => void; +} + /** * Creates a logger for a given module * @param module - the module to log for (it's just a colored string that will be shown between `[` and `]` before the message itself) + * @param color - ANSI escape to use. Defaults to the color registered for `module`, or gray when none is registered. Use the `ansi` map. * @returns a logger object with `log`, `warn`, and `error` methods */ -function createLogger(module: LoggerModule) { - const color = loggerColors[module]; +export function createLogger(module: LoggerModule, color?: string): Logger { + const prefixColor = color ?? loggerColors[module] ?? DEFAULT_LOGGER_COLOR; const prefix = `[${module.toUpperCase()}]`; return { // It's important to use `bind` here to correctly display log file path and line number in the console // Otherwise, console prints will just point to this file - log: console.log.bind(console, `${color}${prefix}${loggerColors.reset}`), - warn: console.warn.bind(console, `${color}${prefix}${loggerColors.reset}`), + log: console.log.bind(console, `${prefixColor}${prefix}${loggerColors.reset}`), + warn: console.warn.bind( + console, + `${prefixColor}${prefix}${loggerColors.reset}`, + ), error: console.error.bind( console, - `${color}${prefix}${loggerColors.reset}`, + `${prefixColor}${prefix}${loggerColors.reset}`, ), }; } @@ -28,6 +38,9 @@ function createLogger(module: LoggerModule) { export const logger = { testingView: createLogger("testing-view"), competitionView: createLogger("competition-view"), + loggingView: createLogger("logging-view"), + flashingView: createLogger("flashing-view"), + adjView: createLogger("adj-view"), core: createLogger("core"), ui: createLogger("ui"), }; diff --git a/frontend/frontend-kit/core/src/loggerColors.ts b/frontend/frontend-kit/core/src/loggerColors.ts index c99f7d68d..abd985b32 100644 --- a/frontend/frontend-kit/core/src/loggerColors.ts +++ b/frontend/frontend-kit/core/src/loggerColors.ts @@ -1,7 +1,41 @@ -export const loggerColors = { - "testing-view": "\x1b[36m", // Cyan - "competition-view": "\x1b[35m", // Magenta - core: "\x1b[33m", // Yellow - ui: "\x1b[32m", // Green +/** + * Raw ANSI escapes, exported so a custom module can pick its own color. + */ +export const ansi = { + black: "\x1b[30m", + red: "\x1b[31m", + green: "\x1b[32m", + yellow: "\x1b[33m", + blue: "\x1b[34m", + magenta: "\x1b[35m", + cyan: "\x1b[36m", + white: "\x1b[37m", + gray: "\x1b[90m", reset: "\x1b[0m", +} as const; + +/** + * Color per module name. Typed as an open record so that an app outside this + * repository can register its own module through `registerLoggerColor`. + */ +export const loggerColors: Record = { + "testing-view": ansi.cyan, + "competition-view": ansi.magenta, + "logging-view": ansi.blue, + "flashing-view": ansi.red, + "adj-view": ansi.white, + core: ansi.yellow, + ui: ansi.green, + reset: ansi.reset, +}; + +/** Color used for a module that has no registered color. */ +export const DEFAULT_LOGGER_COLOR = ansi.gray; + +/** + * Registers the color a module is logged with, so a later `createLogger` call + * for that module picks it up. + */ +export const registerLoggerColor = (module: string, color: string) => { + loggerColors[module] = color; }; diff --git a/frontend/frontend-kit/core/src/types.ts b/frontend/frontend-kit/core/src/types.ts index e0346cc78..e8b600a69 100644 --- a/frontend/frontend-kit/core/src/types.ts +++ b/frontend/frontend-kit/core/src/types.ts @@ -36,6 +36,46 @@ export interface TelemetryPacket { } /** - * The modules that can be logged to. Used for the `logger` object. + * The modules this package ships a color for. */ -export type LoggerModule = "testing-view" | "competition-view" | "core" | "ui"; +export type KnownLoggerModule = + | "testing-view" + | "competition-view" + | "logging-view" + | "flashing-view" + | "adj-view" + | "core" + | "ui"; + +/** + * A logger module name. Any string is accepted, so an app built on top of this + * package can register its own module; the `KnownLoggerModule` members keep + * their autocomplete and their built-in color. + */ +export type LoggerModule = KnownLoggerModule | (string & {}); + +/** + * Connection settings for the `socketService`. + * + * When `url` is given it wins over every other field. Otherwise the URL is + * built as `${secure ? "wss" : "ws"}://${host}:${port}${path}`. + */ +export interface SocketConfig { + /** Complete WebSocket URL, e.g. "wss://pod.hyperloopupv.com/backend". */ + url?: string; + + /** Hostname or IP. Defaults to "127.0.0.1". */ + host?: string; + + /** Port. Defaults to 4000. */ + port?: number; + + /** Path, leading slash included. Defaults to "/backend". */ + path?: string; + + /** Use wss:// instead of ws://. Defaults to false. */ + secure?: boolean; + + /** Heartbeat period in milliseconds. 0 disables it. Defaults to 1000. */ + heartbeatIntervalMs?: number; +} diff --git a/frontend/frontend-kit/core/src/websocket.ts b/frontend/frontend-kit/core/src/websocket.ts index 03e291a6a..859c6ef70 100644 --- a/frontend/frontend-kit/core/src/websocket.ts +++ b/frontend/frontend-kit/core/src/websocket.ts @@ -18,7 +18,40 @@ import { import { webSocket, WebSocketSubject } from "rxjs/webSocket"; import { logger } from "./logger"; import { minMaxDownsample } from "./minMaxDownsample"; -import { type TopicOptions } from "./types"; +import { type SocketConfig, type TopicOptions } from "./types"; + +/** + * Values used for every field a caller leaves out. + */ +const DEFAULT_CONFIG = { + host: "127.0.0.1", + port: 4000, + path: "/backend", + secure: false, + heartbeatIntervalMs: 1000, +} as const; + +/** + * Builds the URL `connect` would use for a given config. + * @param config - the connection settings. `url` wins over every other field. + * @returns the resolved WebSocket URL. + */ +export const resolveSocketUrl = (config: SocketConfig = {}): string => { + if (config.url) return config.url; + + const host = config.host ?? DEFAULT_CONFIG.host; + const port = config.port ?? DEFAULT_CONFIG.port; + const path = config.path ?? DEFAULT_CONFIG.path; + const scheme = (config.secure ?? DEFAULT_CONFIG.secure) ? "wss" : "ws"; + + return `${scheme}://${host}:${port}${path}`; +}; + +/** + * Normalizes the backward-compatible `connect(port)` form into a config object. + */ +const toConfig = (options: number | SocketConfig = {}): SocketConfig => + typeof options === "number" ? { port: options } : options; /** * Service for connecting to the WebSocket server and subscribing to topics @@ -69,18 +102,47 @@ class SocketService { */ private heartbeatInterval: ReturnType | null = null; + /** + * Connection settings applied by the last `configure` or `connect` call. + */ + private config: SocketConfig = {}; + + /** + * The URL the current or next connection targets. + */ + get url(): string { + return resolveSocketUrl(this.config); + } + + /** + * Sets the connection defaults, merging with whatever was configured before. + * Call it once when the app boots, before anything calls `connect`. + * + * It does not affect an already open socket: use `reconnect` for that. + * @param config - the connection settings to merge in. + */ + configure(config: SocketConfig) { + this.config = { ...this.config, ...config }; + } + /** * Connects to the WebSocket server by creating a new connection object and pushing it to `socketSource$`. - * @param port - the port to connect to. Defaults to 4000. + * Does nothing when a connection is already open. + * @param options - the connection settings, or a bare port number. The number + * form is kept for backward compatibility: `connect(4000)` is exactly + * `connect({ port: 4000 })`. Whatever is passed is merged into the stored config. */ - connect(port: number = 4000) { + connect(options: number | SocketConfig = {}) { if (this.ws) return; - logger.core.log("Connecting to WebSocket..."); + this.config = { ...this.config, ...toConfig(options) }; + const url = resolveSocketUrl(this.config); + + logger.core.log(`Connecting to WebSocket at ${url}...`); this.status$.next("connecting"); this.ws = webSocket({ - url: `ws://127.0.0.1:${port}/backend`, + url, deserializer: (e) => JSON.parse(e.data), openObserver: { next: () => { @@ -108,16 +170,46 @@ class SocketService { this.socketSource$.next(this.ws); } + /** + * Closes the connection, stops the heartbeat and reports "disconnected". + * Does nothing when there is no open connection. + */ + disconnect() { + if (!this.ws) return; + + logger.core.log("Closing WebSocket..."); + this.ws.complete(); + this.cleanup(); + } + + /** + * Closes the current connection and opens a new one. + * + * `connect` alone cannot do this: it returns early while a socket is open. + * @param options - the connection settings to use, as in `connect`. Omit them to reuse the stored config. + */ + reconnect(options?: number | SocketConfig) { + this.disconnect(); + this.connect(options); + } + /** * Starts the periodic heartbeat that lets the backend detect a dead or * frozen GUI. The backend expects one at least every 3 seconds and treats * a missing heartbeat as a disconnection. + * + * A `heartbeatIntervalMs` of 0 disables it. */ private startHeartbeat() { this.stopHeartbeat(); + + const interval = + this.config.heartbeatIntervalMs ?? DEFAULT_CONFIG.heartbeatIntervalMs; + if (interval <= 0) return; + this.heartbeatInterval = setInterval(() => { this.ws?.next({ topic: "connection/heartbeat", payload: {} }); - }, 1000); + }, interval); } private stopHeartbeat() { @@ -202,3 +294,10 @@ class SocketService { } export const socketService = new SocketService(); + +/** + * Sets the connection defaults on the shared `socketService`. + * Convenience wrapper so an app can configure the socket in one line at boot. + */ +export const configureSocket = (config: SocketConfig) => + socketService.configure(config); diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/useWebSocket.ts b/frontend/frontend-kit/ui/src/hooks/webSocket/useWebSocket.ts index 081f12c6a..eb1cbd507 100644 --- a/frontend/frontend-kit/ui/src/hooks/webSocket/useWebSocket.ts +++ b/frontend/frontend-kit/ui/src/hooks/webSocket/useWebSocket.ts @@ -1,22 +1,28 @@ -import { socketService } from "@workspace/core"; +import { socketService, type SocketConfig } from "@workspace/core"; import { useEffect, useState } from "react"; -export const useWebSocket = () => { +/** + * Opens the shared WebSocket connection and tracks its status. + * @param config - connection settings. Omit them to use whatever was set with + * `configureSocket`, which falls back to ws://127.0.0.1:4000/backend. + */ +export const useWebSocket = (config?: SocketConfig) => { const [status, setStatus] = useState("disconnected"); useEffect(() => { - socketService.connect(); + socketService.connect(config); const statusSub = socketService.status$.subscribe(setStatus); return () => { statusSub.unsubscribe(); }; - }, []); + }, [JSON.stringify(config)]); return { isConnected: status === "connected", status, - reconnect: () => socketService.connect(), + url: socketService.url, + reconnect: () => socketService.reconnect(config), }; }; From c47cc9c7b790287ed7de0bd561e9a76704f8fd9c Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 12:58:49 +0100 Subject: [PATCH 05/12] refactor(frontend-kit): use relative imports inside the kit 40 imports inside the kit referenced the package by its own name (@workspace/ui/lib/utils and friends). Self-reference resolution is supported unevenly across bundlers and, once the kit is published, it risks a consumer ending up with two instances of cn. One file already used a relative path, so this makes the kit internally consistent. Also drops the now-dead paths block from the kit's tsconfig, so a mistyped import fails loudly instead of resolving through the alias. All five apps build and their CSS output hashes are unchanged. --- .../src/components/custom/custom-component.tsx | 2 +- .../ui/src/components/shadcn/badge.tsx | 2 +- .../ui/src/components/shadcn/button.tsx | 2 +- .../ui/src/components/shadcn/card.tsx | 2 +- .../ui/src/components/shadcn/checkbox.tsx | 2 +- .../ui/src/components/shadcn/combobox.tsx | 6 +++--- .../ui/src/components/shadcn/context-menu.tsx | 2 +- .../ui/src/components/shadcn/dialog.tsx | 2 +- .../ui/src/components/shadcn/dropdown-menu.tsx | 2 +- .../ui/src/components/shadcn/field.tsx | 6 +++--- .../ui/src/components/shadcn/input-group.tsx | 8 ++++---- .../ui/src/components/shadcn/input.tsx | 2 +- .../ui/src/components/shadcn/label.tsx | 2 +- .../ui/src/components/shadcn/popover.tsx | 2 +- .../ui/src/components/shadcn/resizable.tsx | 2 +- .../ui/src/components/shadcn/select.tsx | 2 +- .../ui/src/components/shadcn/separator.tsx | 2 +- .../ui/src/components/shadcn/sheet.tsx | 2 +- .../ui/src/components/shadcn/sidebar.tsx | 16 ++++++++-------- .../ui/src/components/shadcn/skeleton.tsx | 2 +- .../ui/src/components/shadcn/slider.tsx | 2 +- .../ui/src/components/shadcn/spinner.tsx | 2 +- .../ui/src/components/shadcn/table.tsx | 2 +- .../ui/src/components/shadcn/tabs.tsx | 2 +- .../ui/src/components/shadcn/textarea.tsx | 2 +- .../ui/src/components/shadcn/tooltip.tsx | 2 +- frontend/frontend-kit/ui/tsconfig.json | 6 ------ 27 files changed, 40 insertions(+), 46 deletions(-) diff --git a/frontend/frontend-kit/ui/src/components/custom/custom-component.tsx b/frontend/frontend-kit/ui/src/components/custom/custom-component.tsx index 1718e0799..c00d3d997 100644 --- a/frontend/frontend-kit/ui/src/components/custom/custom-component.tsx +++ b/frontend/frontend-kit/ui/src/components/custom/custom-component.tsx @@ -1,4 +1,4 @@ -import { cn } from "@workspace/ui/lib/utils"; +import { cn } from "../../lib/utils"; import React from "react"; interface CustomComponentProps extends React.HTMLAttributes {} diff --git a/frontend/frontend-kit/ui/src/components/shadcn/badge.tsx b/frontend/frontend-kit/ui/src/components/shadcn/badge.tsx index c5659a22b..127f9ab69 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/badge.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/badge.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { Slot } from "@radix-ui/react-slot"; import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@workspace/ui/lib/utils"; +import { cn } from "../../lib/utils"; const badgeVariants = cva( "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", diff --git a/frontend/frontend-kit/ui/src/components/shadcn/button.tsx b/frontend/frontend-kit/ui/src/components/shadcn/button.tsx index 53fc38d33..eba30dd36 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/button.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/button.tsx @@ -2,7 +2,7 @@ import * as React from "react" import { cva, type VariantProps } from "class-variance-authority" import { Slot } from "radix-ui" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" const buttonVariants = cva( "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", diff --git a/frontend/frontend-kit/ui/src/components/shadcn/card.tsx b/frontend/frontend-kit/ui/src/components/shadcn/card.tsx index 2e7392a65..96c5f2f66 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/card.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/card.tsx @@ -1,6 +1,6 @@ import * as React from "react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Card({ className, ...props }: React.ComponentProps<"div">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/checkbox.tsx b/frontend/frontend-kit/ui/src/components/shadcn/checkbox.tsx index bca5ecca4..69e911593 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/checkbox.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/checkbox.tsx @@ -4,7 +4,7 @@ import * as React from "react" import * as CheckboxPrimitive from "@radix-ui/react-checkbox" import { CheckIcon } from "lucide-react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Checkbox({ className, diff --git a/frontend/frontend-kit/ui/src/components/shadcn/combobox.tsx b/frontend/frontend-kit/ui/src/components/shadcn/combobox.tsx index 36b00ad18..2d2f910d9 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/combobox.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/combobox.tsx @@ -4,14 +4,14 @@ import * as React from "react" import { Combobox as ComboboxPrimitive } from "@base-ui/react" import { CheckIcon, ChevronDownIcon, XIcon } from "lucide-react" -import { cn } from "@workspace/ui/lib/utils" -import { Button } from "@workspace/ui/components/shadcn/button" +import { cn } from "../../lib/utils" +import { Button } from "./button" import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, -} from "@workspace/ui/components/shadcn/input-group" +} from "./input-group" const Combobox = ComboboxPrimitive.Root diff --git a/frontend/frontend-kit/ui/src/components/shadcn/context-menu.tsx b/frontend/frontend-kit/ui/src/components/shadcn/context-menu.tsx index bd6991efb..75535c54e 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/context-menu.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/context-menu.tsx @@ -4,7 +4,7 @@ import * as React from "react" import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function ContextMenu({ ...props diff --git a/frontend/frontend-kit/ui/src/components/shadcn/dialog.tsx b/frontend/frontend-kit/ui/src/components/shadcn/dialog.tsx index b905322cf..9c866fbaa 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/dialog.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/dialog.tsx @@ -4,7 +4,7 @@ import * as React from "react" import * as DialogPrimitive from "@radix-ui/react-dialog" import { XIcon } from "lucide-react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Dialog({ ...props diff --git a/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx b/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx index 6c011e181..fa24a3dae 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx @@ -4,7 +4,7 @@ import * as React from "react" import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function DropdownMenu({ ...props diff --git a/frontend/frontend-kit/ui/src/components/shadcn/field.tsx b/frontend/frontend-kit/ui/src/components/shadcn/field.tsx index 7d7b87450..90359f929 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/field.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/field.tsx @@ -3,9 +3,9 @@ import { useMemo } from "react" import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@workspace/ui/lib/utils" -import { Label } from "@workspace/ui/components/shadcn/label" -import { Separator } from "@workspace/ui/components/shadcn/separator" +import { cn } from "../../lib/utils" +import { Label } from "./label" +import { Separator } from "./separator" function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/input-group.tsx b/frontend/frontend-kit/ui/src/components/shadcn/input-group.tsx index 3b8f6fece..7a809428e 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/input-group.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/input-group.tsx @@ -3,10 +3,10 @@ import * as React from "react" import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@workspace/ui/lib/utils" -import { Button } from "@workspace/ui/components/shadcn/button" -import { Input } from "@workspace/ui/components/shadcn/input" -import { Textarea } from "@workspace/ui/components/shadcn/textarea" +import { cn } from "../../lib/utils" +import { Button } from "./button" +import { Input } from "./input" +import { Textarea } from "./textarea" function InputGroup({ className, ...props }: React.ComponentProps<"div">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/input.tsx b/frontend/frontend-kit/ui/src/components/shadcn/input.tsx index 2882b5343..7af0b67d6 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/input.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/input.tsx @@ -1,6 +1,6 @@ import * as React from "react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Input({ className, type, ...props }: React.ComponentProps<"input">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/label.tsx b/frontend/frontend-kit/ui/src/components/shadcn/label.tsx index 4aeafb539..eec5bce9c 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/label.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/label.tsx @@ -3,7 +3,7 @@ import * as React from "react" import * as LabelPrimitive from "@radix-ui/react-label" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Label({ className, diff --git a/frontend/frontend-kit/ui/src/components/shadcn/popover.tsx b/frontend/frontend-kit/ui/src/components/shadcn/popover.tsx index d15b81e2a..b82cf17b5 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/popover.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/popover.tsx @@ -3,7 +3,7 @@ import * as React from "react" import * as PopoverPrimitive from "@radix-ui/react-popover" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Popover({ ...props diff --git a/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx b/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx index bbaca1e2b..dd57afbf6 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx @@ -3,7 +3,7 @@ import { GripVerticalIcon } from "lucide-react" import * as ResizablePrimitive from "react-resizable-panels" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function ResizablePanelGroup({ className, diff --git a/frontend/frontend-kit/ui/src/components/shadcn/select.tsx b/frontend/frontend-kit/ui/src/components/shadcn/select.tsx index 84bf00ebe..4f862b6f7 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/select.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/select.tsx @@ -4,7 +4,7 @@ import * as SelectPrimitive from "@radix-ui/react-select"; import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"; import * as React from "react"; -import { cn } from "@workspace/ui/lib/utils"; +import { cn } from "../../lib/utils"; function Select({ ...props diff --git a/frontend/frontend-kit/ui/src/components/shadcn/separator.tsx b/frontend/frontend-kit/ui/src/components/shadcn/separator.tsx index 4e9594c2f..c8ff3cf7d 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/separator.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/separator.tsx @@ -3,7 +3,7 @@ import * as React from "react" import * as SeparatorPrimitive from "@radix-ui/react-separator" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Separator({ className, diff --git a/frontend/frontend-kit/ui/src/components/shadcn/sheet.tsx b/frontend/frontend-kit/ui/src/components/shadcn/sheet.tsx index 02c8b3050..83d35d01d 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/sheet.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/sheet.tsx @@ -4,7 +4,7 @@ import * as React from "react" import * as SheetPrimitive from "@radix-ui/react-dialog" import { XIcon } from "lucide-react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Sheet({ ...props }: React.ComponentProps) { return diff --git a/frontend/frontend-kit/ui/src/components/shadcn/sidebar.tsx b/frontend/frontend-kit/ui/src/components/shadcn/sidebar.tsx index f0ac18058..43f8599a2 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/sidebar.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/sidebar.tsx @@ -5,25 +5,25 @@ import { cva, type VariantProps } from "class-variance-authority"; import { PanelLeftIcon } from "lucide-react"; import * as React from "react"; -import { Button } from "@workspace/ui/components/shadcn/button"; -import { Input } from "@workspace/ui/components/shadcn/input"; -import { Separator } from "@workspace/ui/components/shadcn/separator"; +import { Button } from "./button"; +import { Input } from "./input"; +import { Separator } from "./separator"; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, -} from "@workspace/ui/components/shadcn/sheet"; -import { Skeleton } from "@workspace/ui/components/shadcn/skeleton"; +} from "./sheet"; +import { Skeleton } from "./skeleton"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, -} from "@workspace/ui/components/shadcn/tooltip"; -import { useIsMobile } from "@workspace/ui/hooks/shadcn/use-mobile"; -import { cn } from "@workspace/ui/lib/utils"; +} from "./tooltip"; +import { useIsMobile } from "../../hooks/shadcn/use-mobile"; +import { cn } from "../../lib/utils"; const SIDEBAR_COOKIE_NAME = "sidebar_state"; const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; diff --git a/frontend/frontend-kit/ui/src/components/shadcn/skeleton.tsx b/frontend/frontend-kit/ui/src/components/shadcn/skeleton.tsx index 98ad83512..f0d550c36 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/skeleton.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/skeleton.tsx @@ -1,4 +1,4 @@ -import { cn } from "@workspace/ui/lib/utils"; +import { cn } from "../../lib/utils"; function Skeleton({ className, ...props }: React.ComponentProps<"div">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/slider.tsx b/frontend/frontend-kit/ui/src/components/shadcn/slider.tsx index d930c32eb..f0b563b4e 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/slider.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/slider.tsx @@ -3,7 +3,7 @@ import * as React from "react" import { Slider as SliderPrimitive } from "radix-ui" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Slider({ className, diff --git a/frontend/frontend-kit/ui/src/components/shadcn/spinner.tsx b/frontend/frontend-kit/ui/src/components/shadcn/spinner.tsx index 4fde36d58..0a196027e 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/spinner.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/spinner.tsx @@ -1,6 +1,6 @@ import { Loader2Icon } from "lucide-react"; -import { cn } from "@workspace/ui/lib/utils"; +import { cn } from "../../lib/utils"; function Spinner({ className, ...props }: React.ComponentProps<"svg">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/table.tsx b/frontend/frontend-kit/ui/src/components/shadcn/table.tsx index e73bb2e8e..8d7b5d29a 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/table.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/table.tsx @@ -1,6 +1,6 @@ import * as React from "react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Table({ className, ...props }: React.ComponentProps<"table">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/tabs.tsx b/frontend/frontend-kit/ui/src/components/shadcn/tabs.tsx index 8546fa567..7af96362d 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/tabs.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/tabs.tsx @@ -3,7 +3,7 @@ import * as React from "react" import * as TabsPrimitive from "@radix-ui/react-tabs" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Tabs({ className, diff --git a/frontend/frontend-kit/ui/src/components/shadcn/textarea.tsx b/frontend/frontend-kit/ui/src/components/shadcn/textarea.tsx index 41da51ac4..baad8eed6 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/textarea.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/textarea.tsx @@ -1,6 +1,6 @@ import * as React from "react" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { return ( diff --git a/frontend/frontend-kit/ui/src/components/shadcn/tooltip.tsx b/frontend/frontend-kit/ui/src/components/shadcn/tooltip.tsx index 1508a9418..f7d14967a 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/tooltip.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/tooltip.tsx @@ -3,7 +3,7 @@ import * as React from "react" import * as TooltipPrimitive from "@radix-ui/react-tooltip" -import { cn } from "@workspace/ui/lib/utils" +import { cn } from "../../lib/utils" function TooltipProvider({ delayDuration = 0, diff --git a/frontend/frontend-kit/ui/tsconfig.json b/frontend/frontend-kit/ui/tsconfig.json index 0bedc71da..0a0de6e8a 100644 --- a/frontend/frontend-kit/ui/tsconfig.json +++ b/frontend/frontend-kit/ui/tsconfig.json @@ -1,11 +1,5 @@ { "extends": "@workspace/typescript-config/react-library.json", - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@workspace/ui/*": ["./src/*"] - } - }, "include": ["."], "exclude": ["node_modules", "dist"] } From 86d71c07f5eb626a203d67af2e0321f248863b35 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 13:05:41 +0100 Subject: [PATCH 06/12] refactor!: merge the kit into a single @hyperloop-upv/frontend-kit package A new frontend will live outside this repository and needs the kit. That requires publishing it, and publishing requires a real npm scope: @workspace is the Turborepo template placeholder, not an organisation. - Merge @workspace/core into @workspace/ui as src/core/, exposed as the ./core subpath. One package means one version, one build and no internal workspace: dependency to coordinate when publishing. The React-free boundary the kit README describes survives as a folder. - Rename the directory ui -> kit, since it no longer holds only UI, and fix the esling-config -> eslint-config typo. - Rename @workspace/* to @hyperloop-upv/* across 183 files. - Drop the kit alias from the five app tsconfigs. Those paths pointed into the kit's source tree by relative path, which is exactly what does not exist for an external consumer. They were already inert: they live in a solution-style config with files: [], and the tsconfig.app.json that actually compiles src has no paths at all, so the apps already resolve the kit through its exports map. eslint-config and typescript-config stay private: publishing the former would force its 13 plugins into consumers' production dependencies. All five apps build with byte-identical CSS output, lint reports no new problems, and both .claude worktrees are untouched. --- README.md | 10 +- frontend/README.md | 26 +- frontend/adj-view/CLAUDE.md | 12 +- frontend/adj-view/eslint.config.js | 2 +- frontend/adj-view/package.json | 6 +- .../adj-view/src/adj/v2/AdjViewerTabs.tsx | 6 +- frontend/adj-view/src/adj/v2/NetworkTab.tsx | 2 +- frontend/adj-view/src/adj/v2/SocketsTab.tsx | 6 +- .../adj-view/src/adj/v2/ThroughputHelp.tsx | 4 +- .../adj-view/src/adj/v2/ThroughputTab.tsx | 6 +- frontend/adj-view/src/adj/v2/ui.tsx | 6 +- .../adj-view/src/components/AdjViewerPage.tsx | 10 +- .../src/components/UnsupportedAdjNotice.tsx | 2 +- frontend/adj-view/src/index.css | 4 +- frontend/adj-view/tsconfig.json | 6 - frontend/competition-view/eslint.config.js | 2 +- frontend/competition-view/package.json | 7 +- frontend/competition-view/src/App.tsx | 2 +- .../src/components/ErrorBoundary.tsx | 4 +- .../src/components/KeyboardShortcutsHelp.tsx | 4 +- .../src/components/header/ConnectionBadge.tsx | 2 +- .../components/header/DashboardStatusBar.tsx | 2 +- .../src/components/header/Header.tsx | 2 +- .../src/components/header/HvalIndicator.tsx | 2 +- .../src/components/header/OrdersSheet.tsx | 6 +- .../src/components/sidebar/AboutItem.tsx | 4 +- .../src/components/sidebar/AppSidebar.tsx | 2 +- .../sidebar/ConnectionStatusGroup.tsx | 4 +- .../src/components/sidebar/LoggerItem.tsx | 4 +- .../src/components/sidebar/Logo.tsx | 4 +- .../components/sidebar/NavigationGroup.tsx | 4 +- .../src/components/sidebar/ShortcutsItem.tsx | 4 +- .../components/sidebar/ThemeToggleItem.tsx | 4 +- .../src/constants/loggerControlConfig.tsx | 2 +- .../competition-view/src/constants/pages.ts | 2 +- .../competition-view/src/hooks/useLogger.ts | 4 +- .../src/hooks/useOrdersCatalog.ts | 2 +- .../src/hooks/usePodCatalog.ts | 2 +- .../src/hooks/useSendOrder.ts | 2 +- frontend/competition-view/src/index.css | 4 +- .../competition-view/src/layout/AppLayout.tsx | 2 +- .../src/pages/Messages/Messages.tsx | 4 +- .../pages/Messages/components/MessageItem.tsx | 2 +- .../src/pages/Orders/Orders.tsx | 4 +- .../pages/Orders/components/OrderButton.tsx | 4 +- .../Orders/components/OrderParameters.tsx | 2 +- .../src/pages/Orders/components/OrderRow.tsx | 4 +- .../pages/Orders/components/OrdersList.tsx | 2 +- .../src/pages/Overview/Overview.tsx | 4 +- .../pages/Overview/components/MetricCard.tsx | 2 +- .../pages/Overview/components/OrdersPanel.tsx | 6 +- .../Overview/components/TrackProgress.tsx | 2 +- .../components/VehicleStateBanner.tsx | 2 +- .../competition-view/src/types/telemetry.ts | 4 +- frontend/competition-view/tsconfig.json | 3 +- frontend/flashing-view/eslint.config.js | 2 +- frontend/flashing-view/package.json | 6 +- .../flash-station/components/board-card.tsx | 4 +- .../flash-station/components/section-card.tsx | 2 +- .../flash-station/flash-station-view.tsx | 8 +- frontend/flashing-view/src/index.css | 2 +- frontend/flashing-view/tsconfig.json | 6 - frontend/frontend-kit/core/package.json | 25 -- frontend/frontend-kit/core/tsconfig.json | 11 - .../{esling-config => eslint-config}/base.js | 0 .../package.json | 2 +- .../react-internal.js | 0 .../{esling-config => eslint-config}/vite.js | 0 frontend/frontend-kit/{ui => kit}/README.md | 2 +- .../frontend-kit/{ui => kit}/components.json | 10 +- .../{core => kit}/eslint.config.js | 2 +- .../frontend-kit/{ui => kit}/package.json | 13 +- .../{ui => kit}/postcss.config.mjs | 0 .../components/custom/custom-component.tsx | 0 .../src/components/custom/index.ts | 0 .../components/custom/segmented-control.tsx | 0 .../{ui => kit}/src/components/index.ts | 0 .../src/components/shadcn/badge.tsx | 0 .../src/components/shadcn/button.tsx | 0 .../src/components/shadcn/card.tsx | 0 .../src/components/shadcn/checkbox.tsx | 0 .../src/components/shadcn/collapsible.tsx | 0 .../src/components/shadcn/combobox.tsx | 0 .../src/components/shadcn/context-menu.tsx | 0 .../src/components/shadcn/dialog.tsx | 0 .../src/components/shadcn/dropdown-menu.tsx | 0 .../src/components/shadcn/field.tsx | 0 .../src/components/shadcn/index.ts | 0 .../src/components/shadcn/input-group.tsx | 0 .../src/components/shadcn/input.tsx | 0 .../src/components/shadcn/label.tsx | 0 .../src/components/shadcn/popover.tsx | 0 .../src/components/shadcn/resizable.tsx | 0 .../src/components/shadcn/select.tsx | 0 .../src/components/shadcn/separator.tsx | 0 .../src/components/shadcn/sheet.tsx | 0 .../src/components/shadcn/sidebar.tsx | 0 .../src/components/shadcn/skeleton.tsx | 0 .../src/components/shadcn/slider.tsx | 0 .../src/components/shadcn/spinner.tsx | 0 .../src/components/shadcn/table.tsx | 0 .../src/components/shadcn/tabs.tsx | 0 .../src/components/shadcn/textarea.tsx | 0 .../src/components/shadcn/tooltip.tsx | 0 .../{core/src => kit/src/core}/index.ts | 0 .../{core/src => kit/src/core}/logger.ts | 0 .../src => kit/src/core}/loggerColors.ts | 0 .../src => kit/src/core}/minMaxDownsample.ts | 0 .../{core/src => kit/src/core}/types.ts | 0 .../{core/src => kit/src/core}/websocket.ts | 0 .../{ui => kit}/src/hooks/index.ts | 0 .../{ui => kit}/src/hooks/shadcn/index.ts | 0 .../src/hooks/shadcn/use-mobile.ts | 0 .../src/hooks/webSocket/fetchConfig.ts | 2 +- .../{ui => kit}/src/hooks/webSocket/index.ts | 0 .../hooks/webSocket/useErrorSubscription.ts | 2 +- .../src/hooks/webSocket/useTopic.ts | 2 +- .../src/hooks/webSocket/useWebSocket.ts | 2 +- .../{ui => kit}/src/icons/accessibility.ts | 0 .../{ui => kit}/src/icons/account.ts | 0 .../{ui => kit}/src/icons/arrows.ts | 0 .../{ui => kit}/src/icons/cursors.ts | 0 .../{ui => kit}/src/icons/design.ts | 0 .../{ui => kit}/src/icons/development.ts | 0 .../{ui => kit}/src/icons/devices.ts | 0 .../{ui => kit}/src/icons/files.ts | 0 .../{ui => kit}/src/icons/gaming.ts | 0 .../{ui => kit}/src/icons/index.ts | 0 .../{ui => kit}/src/icons/layout.ts | 0 .../{ui => kit}/src/icons/mail.ts | 0 .../{ui => kit}/src/icons/math.ts | 0 .../{ui => kit}/src/icons/notifications.ts | 0 .../{ui => kit}/src/icons/photography.ts | 0 .../{ui => kit}/src/icons/science.ts | 0 .../{ui => kit}/src/icons/shapes.ts | 0 .../{ui => kit}/src/icons/social.ts | 0 .../{ui => kit}/src/icons/text.ts | 0 .../frontend-kit/{ui => kit}/src/index.ts | 0 .../frontend-kit/{ui => kit}/src/lib/index.ts | 0 .../{ui => kit}/src/lib/typeUtils.ts | 0 .../frontend-kit/{ui => kit}/src/lib/utils.ts | 0 .../src/outreach/h11/h11-isotipo_black.svg | 0 .../src/outreach/main/check_black.png | Bin .../src/outreach/main/full_logo_black.png | Bin .../src/outreach/main/hyperloop_black.png | Bin .../src/outreach/main/logo_icon.svg | 0 .../src/outreach/main/software_black.png | Bin .../src/outreach/main/software_white.png | Bin .../{ui => kit}/src/store/index.ts | 0 .../{ui => kit}/src/styles/globals.css | 2 +- frontend/frontend-kit/kit/tsconfig.json | 5 + .../typescript-config/package.json | 2 +- frontend/frontend-kit/ui/eslint.config.js | 4 - frontend/frontend-kit/ui/tsconfig.json | 5 - frontend/logging-view/CLAUDE.md | 10 +- frontend/logging-view/eslint.config.js | 2 +- frontend/logging-view/package.json | 7 +- .../src/components/KeyboardShortcutsHelp.tsx | 4 +- .../src/components/PlotAddedToast.tsx | 4 +- .../src/components/SessionStatusToast.tsx | 4 +- .../src/components/header/Header.tsx | 4 +- .../src/components/sidebar/AppSidebar.tsx | 2 +- .../components/sidebar/FolderPickerGroup.tsx | 6 +- .../src/components/sidebar/Logo.tsx | 4 +- .../components/sidebar/NavigationGroup.tsx | 4 +- .../src/components/sidebar/SeriesGroup.tsx | 6 +- .../components/sidebar/SeriesSelectionBar.tsx | 4 +- .../components/sidebar/SessionStatusBadge.tsx | 6 +- .../sidebar/SidebarToggleHandle.tsx | 6 +- .../components/sidebar/ThemeToggleItem.tsx | 4 +- .../components/sidebar/sessionStatusStyles.ts | 2 +- .../src/components/simple/PlotStudio.tsx | 6 +- .../src/components/simple/SignalSelect.tsx | 6 +- .../src/components/simple/StatsPanel.tsx | 6 +- .../simple/modals/OperationModal.tsx | 4 +- .../simple/modals/PdfExportModal.tsx | 2 +- .../simple/modals/TransformModal.tsx | 2 +- .../components/simple/plots/PlotWrapper.tsx | 8 +- .../simple/sidebar/ComposedSection.tsx | 4 +- .../components/simple/sidebar/FFTSection.tsx | 4 +- .../simple/sidebar/PlotsSection.tsx | 6 +- .../simple/sidebar/StudioSidebar.tsx | 4 +- .../simple/sidebar/studioSections.ts | 4 +- frontend/logging-view/src/index.css | 4 +- .../logging-view/src/layout/AppLayout.tsx | 2 +- .../logging-view/src/lib/pdfExport/assets.ts | 6 +- .../logging-view/src/pages/NormalPage.tsx | 4 +- frontend/logging-view/tsconfig.json | 3 +- frontend/testing-view/eslint.config.js | 2 +- frontend/testing-view/package.json | 7 +- frontend/testing-view/src/App.tsx | 2 +- .../testing-view/src/components/Error.tsx | 4 +- .../src/components/ErrorBoundary.tsx | 2 +- .../src/components/devTools/ModeSwitcher.tsx | 2 +- .../src/components/header/Header.tsx | 2 +- .../src/components/header/ModeBadge.tsx | 2 +- .../src/components/header/ReconnectButton.tsx | 6 +- .../src/components/leftSidebar/AppSidebar.tsx | 2 +- .../leftSidebar/ColorSchemeToggle.tsx | 4 +- .../leftSidebar/ConnectionStatusGroup.tsx | 4 +- .../components/leftSidebar/DevToolsItem.tsx | 4 +- .../src/components/leftSidebar/Logo.tsx | 4 +- .../leftSidebar/NavigationGroup.tsx | 4 +- .../components/leftSidebar/SettingsItem.tsx | 4 +- .../leftSidebar/ThemeToggleItem.tsx | 4 +- .../src/components/settings/BooleanField.tsx | 4 +- .../src/components/settings/ComboboxField.tsx | 8 +- .../settings/MultiCheckboxField.tsx | 4 +- .../src/components/settings/PathField.tsx | 6 +- .../src/components/settings/SelectField.tsx | 4 +- .../components/settings/SettingsDialog.tsx | 6 +- .../src/components/settings/TextField.tsx | 4 +- .../src/constants/loggerControlConfig.tsx | 2 +- frontend/testing-view/src/constants/pages.ts | 2 +- .../charts/components/ChartLegend.tsx | 2 +- .../charts/components/ChartSettings.tsx | 4 +- .../charts/components/ChartSurface.tsx | 8 +- .../features/charts/components/ChartsGrid.tsx | 2 +- .../charts/components/TelemetryChart.tsx | 4 +- .../components/FilterCategoryItem.tsx | 4 +- .../filtering/components/FilterDialog.tsx | 4 +- .../filtering/components/FilterItem.tsx | 2 +- .../components/AddKeyBindingDialog.tsx | 4 +- .../keyBindings/components/KeyBindingCard.tsx | 6 +- .../components/KeyBindingsButton.tsx | 4 +- .../components/KeyBindingsDialog.tsx | 4 +- .../components/OrphanedKeyBindingCard.tsx | 4 +- .../keyBindings/hooks/useGlobalKeyBindings.ts | 2 +- .../workspace/components/DndOverlay.tsx | 2 +- .../workspace/components/EmptyWorkspace.tsx | 4 +- .../workspace/components/LoggerControl.tsx | 6 +- .../workspace/components/MainPanel.tsx | 2 +- .../features/workspace/components/Toolbar.tsx | 4 +- .../workspace/components/WorkspaceDialog.tsx | 10 +- .../components/WorkspaceSwitcher.tsx | 6 +- .../rightSidebar/RightSidebarContent.tsx | 2 +- .../rightSidebar/RightSidebarHeader.tsx | 4 +- .../rightSidebar/RightSidebarToggle.tsx | 2 +- .../rightSidebar/sections/MessageItem.tsx | 6 +- .../rightSidebar/sections/MessagesSection.tsx | 4 +- .../rightSidebar/tabs/CategoryHeader.tsx | 2 +- .../rightSidebar/tabs/CategoryItem.tsx | 2 +- .../components/rightSidebar/tabs/EmptyTab.tsx | 4 +- .../rightSidebar/tabs/TabHeader.tsx | 4 +- .../rightSidebar/tabs/VirtualizedList.tsx | 2 +- .../tabs/commands/CommandItem.tsx | 8 +- .../tabs/commands/CommandParameters.tsx | 2 +- .../tabs/telemetry/ChartPicker.tsx | 4 +- .../tabs/telemetry/TelemetryHeader.tsx | 6 +- .../tabs/telemetry/TelemetryItem.tsx | 2 +- .../tabs/telemetry/TelemetryValue.tsx | 6 +- .../tabs/telemetry/VariableItem.tsx | 4 +- .../testing-view/src/hooks/useAppConfigs.ts | 2 +- frontend/testing-view/src/hooks/useAppMode.ts | 2 +- .../testing-view/src/hooks/useBoardData.ts | 2 +- .../testing-view/src/hooks/useErrorHandler.ts | 4 +- frontend/testing-view/src/hooks/useLogger.ts | 4 +- .../testing-view/src/hooks/useOpenFolder.ts | 2 +- frontend/testing-view/src/index.css | 4 +- .../testing-view/src/layout/AppLayout.tsx | 2 +- frontend/testing-view/src/lib/utils.test.ts | 2 +- frontend/testing-view/src/lib/utils.ts | 4 +- frontend/testing-view/src/pages/Testing.tsx | 4 +- .../src/types/telemetry/telemetry.ts | 2 +- frontend/testing-view/tsconfig.json | 3 +- frontend/tsconfig.json | 2 +- package.json | 6 +- pnpm-lock.yaml | 253 +++++++----------- 268 files changed, 476 insertions(+), 584 deletions(-) delete mode 100644 frontend/frontend-kit/core/package.json delete mode 100644 frontend/frontend-kit/core/tsconfig.json rename frontend/frontend-kit/{esling-config => eslint-config}/base.js (100%) rename frontend/frontend-kit/{esling-config => eslint-config}/package.json (94%) rename frontend/frontend-kit/{esling-config => eslint-config}/react-internal.js (100%) rename frontend/frontend-kit/{esling-config => eslint-config}/vite.js (100%) rename frontend/frontend-kit/{ui => kit}/README.md (86%) rename frontend/frontend-kit/{ui => kit}/components.json (50%) rename frontend/frontend-kit/{core => kit}/eslint.config.js (50%) rename frontend/frontend-kit/{ui => kit}/package.json (86%) rename frontend/frontend-kit/{ui => kit}/postcss.config.mjs (100%) rename frontend/frontend-kit/{ui => kit}/src/components/custom/custom-component.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/custom/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/components/custom/segmented-control.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/badge.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/button.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/card.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/checkbox.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/collapsible.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/combobox.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/context-menu.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/dialog.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/dropdown-menu.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/field.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/input-group.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/input.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/label.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/popover.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/resizable.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/select.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/separator.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/sheet.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/sidebar.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/skeleton.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/slider.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/spinner.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/table.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/tabs.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/textarea.tsx (100%) rename frontend/frontend-kit/{ui => kit}/src/components/shadcn/tooltip.tsx (100%) rename frontend/frontend-kit/{core/src => kit/src/core}/index.ts (100%) rename frontend/frontend-kit/{core/src => kit/src/core}/logger.ts (100%) rename frontend/frontend-kit/{core/src => kit/src/core}/loggerColors.ts (100%) rename frontend/frontend-kit/{core/src => kit/src/core}/minMaxDownsample.ts (100%) rename frontend/frontend-kit/{core/src => kit/src/core}/types.ts (100%) rename frontend/frontend-kit/{core/src => kit/src/core}/websocket.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/hooks/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/hooks/shadcn/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/hooks/shadcn/use-mobile.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/hooks/webSocket/fetchConfig.ts (96%) rename frontend/frontend-kit/{ui => kit}/src/hooks/webSocket/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/hooks/webSocket/useErrorSubscription.ts (85%) rename frontend/frontend-kit/{ui => kit}/src/hooks/webSocket/useTopic.ts (92%) rename frontend/frontend-kit/{ui => kit}/src/hooks/webSocket/useWebSocket.ts (91%) rename frontend/frontend-kit/{ui => kit}/src/icons/accessibility.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/account.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/arrows.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/cursors.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/design.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/development.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/devices.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/files.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/gaming.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/layout.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/mail.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/math.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/notifications.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/photography.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/science.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/shapes.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/social.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/icons/text.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/lib/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/lib/typeUtils.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/lib/utils.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/outreach/h11/h11-isotipo_black.svg (100%) rename frontend/frontend-kit/{ui => kit}/src/outreach/main/check_black.png (100%) rename frontend/frontend-kit/{ui => kit}/src/outreach/main/full_logo_black.png (100%) rename frontend/frontend-kit/{ui => kit}/src/outreach/main/hyperloop_black.png (100%) rename frontend/frontend-kit/{ui => kit}/src/outreach/main/logo_icon.svg (100%) rename frontend/frontend-kit/{ui => kit}/src/outreach/main/software_black.png (100%) rename frontend/frontend-kit/{ui => kit}/src/outreach/main/software_white.png (100%) rename frontend/frontend-kit/{ui => kit}/src/store/index.ts (100%) rename frontend/frontend-kit/{ui => kit}/src/styles/globals.css (99%) create mode 100644 frontend/frontend-kit/kit/tsconfig.json delete mode 100644 frontend/frontend-kit/ui/eslint.config.js delete mode 100644 frontend/frontend-kit/ui/tsconfig.json diff --git a/README.md b/README.md index ebbe5a239..ad1b6ba76 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,10 @@ Our `pnpm-workspace.yaml` defines the following workspaces: | `blcu-programming` | Python | FastAPI service that flashes firmware to the BLCU board via TFTP | | `hyperloop-control-station` | JS | The main Control Station electron desktop application | | `e2e` | TS | End-to-end tests for the whole app (Playwright) | -| `@workspace/ui` | TS/React | Shared UI component library (frontend-kit) | -| `@workspace/core` | TS | Shared business logic and types (frontend-kit) | -| `@workspace/eslint-config` | ESLint | Common ESLint configuration (frontend-kit) | -| `@workspace/typescript-config` | TS | Common TypeScript configuration (frontend-kit) | +| `@hyperloop-upv/frontend-kit` | TS/React | Shared UI component library (frontend-kit) | +| `@hyperloop-upv/frontend-kit/core` | TS | Shared business logic and types (frontend-kit) | +| `@hyperloop-upv/eslint-config` | ESLint | Common ESLint configuration (frontend-kit) | +| `@hyperloop-upv/typescript-config` | TS | Common TypeScript configuration (frontend-kit) | --- @@ -82,4 +82,4 @@ All Turbo scripts support filtering to target specific workspaces: - `pnpm ui:add ` - To add shadcn/ui components - > Note: don't forget to also include it in frontend-kit/ui/src/components/shadcn/index.ts to be able to access it from @workspace/ui \ No newline at end of file + > Note: don't forget to also include it in frontend-kit/kit/src/components/shadcn/index.ts to be able to access it from @hyperloop-upv/frontend-kit \ No newline at end of file diff --git a/frontend/README.md b/frontend/README.md index 1e8e97ab0..d78fb77b2 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -15,10 +15,10 @@ The frontend is organized as 7 workspaces out of 10 in the whole monorepo, divid | `testing-view` | Primary telemetry testing and debugging interface | | `competition-view` | Competition-focused UI (simplified view) | | `flashing-view` | UI for flashing firmware to the BLCU board | -| `frontend-kit/ui` or `@workspace/ui` | Component library built on shadcn/ui and Radix UI | -| `frontend-kit/core` or `@workspace/core` | Shared business logic, WebSocket utilities, and types | -| `frontend-kit/eslint-config` or `@workspace/eslint-config` | Common ESLint configurations | -| `frontend-kit/typescript-config` or `@workspace/typescript-config` | Common TypeScript configurations | +| `frontend-kit/kit` or `@hyperloop-upv/frontend-kit` | Component library built on shadcn/ui and Radix UI | +| `frontend-kit/kit/src/core` or `@hyperloop-upv/frontend-kit/core` | Shared business logic, WebSocket utilities, and types | +| `frontend-kit/eslint-config` or `@hyperloop-upv/eslint-config` | Common ESLint configurations | +| `frontend-kit/typescript-config` or `@hyperloop-upv/typescript-config` | Common TypeScript configurations | ## Key Technologies @@ -66,7 +66,7 @@ Testing View supports multiple workspaces to organize different testing scenario The frontend connects to the Go backend via WebSocket for real-time communication: -- **Connection**: `useWebSocket` hook from `@workspace/core` +- **Connection**: `useWebSocket` hook from `@hyperloop-upv/frontend-kit/core` - **Topics**: Subscribe to specific data streams using `useTopic` - `podData/update` - Telemetry data - `connection/update` - Backend connection status @@ -76,8 +76,8 @@ The frontend connects to the Go backend via WebSocket for real-time communicatio Example: ```tsx -import { useTopic, useWebSocket } from "@workspace/ui/hooks"; -import { socketService } from "@workspace/core"; +import { useTopic, useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; +import { socketService } from "@hyperloop-upv/frontend-kit/core"; const { isConnected } = useWebSocket(); @@ -88,7 +88,7 @@ useTopic("podData/update", (data) => { socketService.post("order/send", ); ``` -## Component Library (@workspace/ui) +## Component Library (@hyperloop-upv/frontend-kit) The shared UI package provides: @@ -97,11 +97,11 @@ The shared UI package provides: - Hooks (useWebSocket, useTopic, useLogger) - Icons from Lucide React -Import components from `@workspace/ui`: +Import components from `@hyperloop-upv/frontend-kit`: ```tsx -import { Button, Dialog } from "@workspace/ui"; -import { Plus, Settings } from "@workspace/ui/icons"; +import { Button, Dialog } from "@hyperloop-upv/frontend-kit"; +import { Plus, Settings } from "@hyperloop-upv/frontend-kit/icons"; ``` ## Development Patterns @@ -119,14 +119,14 @@ To add a new Lucide icon to the shared UI library: 1. Look up the icon on [Lucide Icons](https://lucide.dev/icons) 2. Find the **first category** listed for that icon -3. Add the import to the corresponding category file in `frontend-kit/ui/src/icons/` +3. Add the import to the corresponding category file in `frontend-kit/kit/src/icons/` 4. If the category file doesn't exist, create it and add its export to `index.ts` 5. Keep the same alphabetical order as the icon categories **Example:** The `Axe` icon's first category is `Tools`, so you would add its import to `tools.ts`: ```js -// frontend-kit/ui/src/icons/tools.ts +// frontend-kit/kit/src/icons/tools.ts export { Axe, Hammer } from "lucide-react"; ``` diff --git a/frontend/adj-view/CLAUDE.md b/frontend/adj-view/CLAUDE.md index c248655aa..8cae41649 100644 --- a/frontend/adj-view/CLAUDE.md +++ b/frontend/adj-view/CLAUDE.md @@ -76,21 +76,21 @@ A what-if estimate of each board's link usage, computed only from the ADJ and th ### Workspace dependency -Only shared package used is `@workspace/ui` (from `frontend-kit/ui`), for shadcn/Radix components, Lucide icons, and small utilities (`cn`, `getTypeBadgeClass`/`typeBadgeClasses` from `@workspace/ui/lib`): +Only shared package used is `@hyperloop-upv/frontend-kit` (from `frontend-kit/kit`), for shadcn/Radix components, Lucide icons, and small utilities (`cn`, `getTypeBadgeClass`/`typeBadgeClasses` from `@hyperloop-upv/frontend-kit/lib`): ```tsx -import { Button, Combobox } from "@workspace/ui/components"; -import { BookOpen, GitCommit } from "@workspace/ui/icons"; -import { cn, getTypeBadgeClass, typeBadgeClasses } from "@workspace/ui/lib"; +import { Button, Combobox } from "@hyperloop-upv/frontend-kit/components"; +import { BookOpen, GitCommit } from "@hyperloop-upv/frontend-kit/icons"; +import { cn, getTypeBadgeClass, typeBadgeClasses } from "@hyperloop-upv/frontend-kit/lib"; ``` -No `@workspace/core` dependency (no WebSocket/backend integration here). +No `@hyperloop-upv/frontend-kit/core` dependency (no WebSocket/backend integration here). ### Styling Tailwind v4 with CSS-variable theming, dark mode via `.dark` class on `` (toggled in `App.tsx`, persisted to `localStorage["adj-view-dark-mode"]`). `NetworkTab`'s SVG reads the same CSS variables (`var(--primary)`, `var(--foreground)`, etc.) directly in inline styles so the diagram adapts automatically between themes. UI copy is English (sentence case, no all-caps labels); numbers use `tabular-nums` rather than a monospace font. -Branding: the header and empty state use the team mark `@workspace/ui/outreach/main/logo_icon.svg` (not the H11 isotype the other views use), via `TeamLogo` in `AdjViewerPage.tsx`. The header pairs it with the software-team logo (`outreach/main/software_black.png` + `dark:invert`; don't use `software_white.png`, which is 8000 px / 430 KB). That SVG draws the mark in only the middle ~49% of its 900×900 viewBox, so `TeamLogo` scales the image up inside a clipped box; a plain `` renders it tiny. +Branding: the header and empty state use the team mark `@hyperloop-upv/frontend-kit/outreach/main/logo_icon.svg` (not the H11 isotype the other views use), via `TeamLogo` in `AdjViewerPage.tsx`. The header pairs it with the software-team logo (`outreach/main/software_black.png` + `dark:invert`; don't use `software_white.png`, which is 8000 px / 430 KB). That SVG draws the mark in only the middle ~49% of its 900×900 viewBox, so `TeamLogo` scales the image up inside a clipped box; a plain `` renders it tiny. The layout must work down to phone width (check 390 / 768 / 1440 px) without the page scrolling sideways. The header wraps into title + theme toggle, then a full-width row of load controls below `lg`. The tab bar scrolls inside itself, and wide tables and the Network SVG scroll inside their own containers. diff --git a/frontend/adj-view/eslint.config.js b/frontend/adj-view/eslint.config.js index df360b435..a2b580035 100644 --- a/frontend/adj-view/eslint.config.js +++ b/frontend/adj-view/eslint.config.js @@ -1,3 +1,3 @@ -import { config } from "@workspace/eslint-config/vite"; +import { config } from "@hyperloop-upv/eslint-config/vite"; export default config; diff --git a/frontend/adj-view/package.json b/frontend/adj-view/package.json index 21d527ed4..1bfbc55f3 100644 --- a/frontend/adj-view/package.json +++ b/frontend/adj-view/package.json @@ -13,7 +13,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.18", "@vitejs/plugin-react-swc": "^4.2.3", - "@workspace/ui": "workspace:*", + "@hyperloop-upv/frontend-kit": "workspace:*", "lucide-react": "^0.563.0", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -22,8 +22,8 @@ "devDependencies": { "@types/react": "19.2.11", "@types/react-dom": "19.2.3", - "@workspace/eslint-config": "workspace:^", - "@workspace/typescript-config": "workspace:*", + "@hyperloop-upv/eslint-config": "workspace:^", + "@hyperloop-upv/typescript-config": "workspace:*", "eslint": "^9.39.2", "typescript": "^5.9.3", "vite": "^7.3.1" diff --git a/frontend/adj-view/src/adj/v2/AdjViewerTabs.tsx b/frontend/adj-view/src/adj/v2/AdjViewerTabs.tsx index 630d95c99..dba4c2c8d 100644 --- a/frontend/adj-view/src/adj/v2/AdjViewerTabs.tsx +++ b/frontend/adj-view/src/adj/v2/AdjViewerTabs.tsx @@ -7,7 +7,7 @@ import { TabsContent, TabsList, TabsTrigger, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { Activity, ChevronDown, @@ -19,8 +19,8 @@ import { Plug, Server, TrendingUp, -} from "@workspace/ui/icons"; -import { cn, getTypeBadgeClass, typeBadgeClasses } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit/icons"; +import { cn, getTypeBadgeClass, typeBadgeClasses } from "@hyperloop-upv/frontend-kit/lib"; import { Fragment, useCallback, useMemo, useRef, useState } from "react"; import type { AdjArchiveV2, AdjMeasurement, AdjPacket, AdjSocket } from "./types"; import { NetworkTab } from "./NetworkTab"; diff --git a/frontend/adj-view/src/adj/v2/NetworkTab.tsx b/frontend/adj-view/src/adj/v2/NetworkTab.tsx index 63de5afb7..73d80b311 100644 --- a/frontend/adj-view/src/adj/v2/NetworkTab.tsx +++ b/frontend/adj-view/src/adj/v2/NetworkTab.tsx @@ -11,7 +11,7 @@ import { boardPort, protocolFromSocketType, resolveTarget, type Protocol } from // Hyperloop UPV's actual brand palette (no separate secondary brand color // documented anywhere in the repo) — --primary is the brand orange, and // --foreground pairs it with black/white, matching the logo assets under -// frontend-kit/ui/src/outreach. Both adapt automatically in light/dark mode. +// frontend-kit/kit/src/outreach. Both adapt automatically in light/dark mode. const PROTOCOL_COLOR: Record = { TCP: "var(--foreground)", // bidirectional UDP: "var(--primary)", // unidirectional: board → backend diff --git a/frontend/adj-view/src/adj/v2/SocketsTab.tsx b/frontend/adj-view/src/adj/v2/SocketsTab.tsx index 7df69831d..11b661e60 100644 --- a/frontend/adj-view/src/adj/v2/SocketsTab.tsx +++ b/frontend/adj-view/src/adj/v2/SocketsTab.tsx @@ -1,9 +1,9 @@ // Sockets tab: every socket declared in the ADJ, one row each, with the board // side, where it points, the general_info port name, and the packets that use it. // All socket interpretation comes from sockets.ts, shared with the Network tab. -import { Badge } from "@workspace/ui/components"; -import { AlertTriangle, ChevronDown, ExternalLink } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Badge } from "@hyperloop-upv/frontend-kit/components"; +import { AlertTriangle, ChevronDown, ExternalLink } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { Fragment, useMemo, useRef, useState } from "react"; import type { BoardMeta } from "./AdjViewerTabs"; import { diff --git a/frontend/adj-view/src/adj/v2/ThroughputHelp.tsx b/frontend/adj-view/src/adj/v2/ThroughputHelp.tsx index 7f652257f..82f1f7cee 100644 --- a/frontend/adj-view/src/adj/v2/ThroughputHelp.tsx +++ b/frontend/adj-view/src/adj/v2/ThroughputHelp.tsx @@ -9,8 +9,8 @@ import { SheetHeader, SheetTitle, SheetTrigger, -} from "@workspace/ui/components"; -import { BookOpen } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { BookOpen } from "@hyperloop-upv/frontend-kit/icons"; import type { ReactNode } from "react"; import { ETH_FCS_BYTES, diff --git a/frontend/adj-view/src/adj/v2/ThroughputTab.tsx b/frontend/adj-view/src/adj/v2/ThroughputTab.tsx index 08c6bb98b..de70c0250 100644 --- a/frontend/adj-view/src/adj/v2/ThroughputTab.tsx +++ b/frontend/adj-view/src/adj/v2/ThroughputTab.tsx @@ -6,9 +6,9 @@ import { TooltipContent, TooltipProvider, TooltipTrigger, -} from "@workspace/ui/components"; -import { AlertTriangle, ChevronDown, ChevronRight, ChevronUp, Pencil } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit/components"; +import { AlertTriangle, ChevronDown, ChevronRight, ChevronUp, Pencil } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { Fragment, useMemo, useRef, useState, type CSSProperties, type ReactNode } from "react"; import type { BoardMeta } from "./AdjViewerTabs"; import { ThroughputHelp } from "./ThroughputHelp"; diff --git a/frontend/adj-view/src/adj/v2/ui.tsx b/frontend/adj-view/src/adj/v2/ui.tsx index a844ff022..85c4bac9c 100644 --- a/frontend/adj-view/src/adj/v2/ui.tsx +++ b/frontend/adj-view/src/adj/v2/ui.tsx @@ -1,8 +1,8 @@ // Small presentational pieces shared by the v2 list tabs (Boards, Measurements, // Packets, Sockets). -import { Input } from "@workspace/ui/components"; -import { ChevronDown, ChevronUp, Search } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Input } from "@hyperloop-upv/frontend-kit/components"; +import { ChevronDown, ChevronUp, Search } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; export type SortDir = "asc" | "desc"; diff --git a/frontend/adj-view/src/components/AdjViewerPage.tsx b/frontend/adj-view/src/components/AdjViewerPage.tsx index a1c0c6006..1596cff0d 100644 --- a/frontend/adj-view/src/components/AdjViewerPage.tsx +++ b/frontend/adj-view/src/components/AdjViewerPage.tsx @@ -14,12 +14,12 @@ import { TooltipContent, TooltipProvider, TooltipTrigger, -} from "@workspace/ui/components"; -import { AlertTriangle, GitCommit, Loader2, RefreshCw, SunMoon } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; -import logo from "@workspace/ui/outreach/main/logo_icon.svg"; +} from "@hyperloop-upv/frontend-kit/components"; +import { AlertTriangle, GitCommit, Loader2, RefreshCw, SunMoon } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; +import logo from "@hyperloop-upv/frontend-kit/outreach/main/logo_icon.svg"; // Black strokes on transparency; inverted in dark mode (software_white.png is 8000 px / 430 KB). -import softwareLogo from "@workspace/ui/outreach/main/software_black.png"; +import softwareLogo from "@hyperloop-upv/frontend-kit/outreach/main/software_black.png"; import { useCallback, useEffect, useState } from "react"; import { config } from "../../config"; import { parseAdj, summarizeAdj, type ParsedAdj } from "../adj"; diff --git a/frontend/adj-view/src/components/UnsupportedAdjNotice.tsx b/frontend/adj-view/src/components/UnsupportedAdjNotice.tsx index 61b0ec8c8..a6f45e1cf 100644 --- a/frontend/adj-view/src/components/UnsupportedAdjNotice.tsx +++ b/frontend/adj-view/src/components/UnsupportedAdjNotice.tsx @@ -1,4 +1,4 @@ -import { AlertTriangle } from "@workspace/ui/icons"; +import { AlertTriangle } from "@hyperloop-upv/frontend-kit/icons"; import { SUPPORTED_ADJ_VERSIONS } from "../adj"; export function UnsupportedAdjNotice({ version }: { version: number }) { diff --git a/frontend/adj-view/src/index.css b/frontend/adj-view/src/index.css index ebe6a1c75..67d14219d 100644 --- a/frontend/adj-view/src/index.css +++ b/frontend/adj-view/src/index.css @@ -1,7 +1,7 @@ -@import "@workspace/ui/globals.css"; +@import "@hyperloop-upv/frontend-kit/globals.css"; /* Ensure Tailwind v4 scans adj-view source files directly. - The @source paths in globals.css resolve via the @workspace/ui symlink + The @source paths in globals.css resolve via the @hyperloop-upv/frontend-kit symlink and don't correctly reach this project's source tree. */ @source "./**/*.{ts,tsx}"; diff --git a/frontend/adj-view/tsconfig.json b/frontend/adj-view/tsconfig.json index fc0aa4474..483ebaa0f 100644 --- a/frontend/adj-view/tsconfig.json +++ b/frontend/adj-view/tsconfig.json @@ -4,11 +4,5 @@ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ], - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@workspace/ui/*": ["../frontend-kit/ui/src/*"] - } - }, "exclude": ["node_modules"] } diff --git a/frontend/competition-view/eslint.config.js b/frontend/competition-view/eslint.config.js index df360b435..a2b580035 100644 --- a/frontend/competition-view/eslint.config.js +++ b/frontend/competition-view/eslint.config.js @@ -1,3 +1,3 @@ -import { config } from "@workspace/eslint-config/vite"; +import { config } from "@hyperloop-upv/eslint-config/vite"; export default config; diff --git a/frontend/competition-view/package.json b/frontend/competition-view/package.json index 462843d6a..a6457d8dc 100644 --- a/frontend/competition-view/package.json +++ b/frontend/competition-view/package.json @@ -15,8 +15,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.18", "@vitejs/plugin-react-swc": "^4.2.3", - "@workspace/core": "workspace:*", - "@workspace/ui": "workspace:*", + "@hyperloop-upv/frontend-kit": "workspace:*", "lucide-react": "^0.563.0", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -28,8 +27,8 @@ "devDependencies": { "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", - "@workspace/eslint-config": "workspace:^", - "@workspace/typescript-config": "workspace:*", + "@hyperloop-upv/eslint-config": "workspace:^", + "@hyperloop-upv/typescript-config": "workspace:*", "eslint": "^9.39.2", "globals": "^17.3.0", "typescript": "^5.9.3", diff --git a/frontend/competition-view/src/App.tsx b/frontend/competition-view/src/App.tsx index 6299147bb..e9e89e547 100644 --- a/frontend/competition-view/src/App.tsx +++ b/frontend/competition-view/src/App.tsx @@ -1,4 +1,4 @@ -import { useTopic, useWebSocket } from "@workspace/ui/hooks"; +import { useTopic, useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; import { useState } from "react"; import { Route, Routes } from "react-router"; import ErrorBoundary from "./components/ErrorBoundary"; diff --git a/frontend/competition-view/src/components/ErrorBoundary.tsx b/frontend/competition-view/src/components/ErrorBoundary.tsx index c343d4178..a31dc88a7 100644 --- a/frontend/competition-view/src/components/ErrorBoundary.tsx +++ b/frontend/competition-view/src/components/ErrorBoundary.tsx @@ -1,5 +1,5 @@ -import { Button, Card, CardContent, CardHeader, CardTitle } from "@workspace/ui/components"; -import { AlertTriangle } from "@workspace/ui/icons"; +import { Button, Card, CardContent, CardHeader, CardTitle } from "@hyperloop-upv/frontend-kit/components"; +import { AlertTriangle } from "@hyperloop-upv/frontend-kit/icons"; import { Component, type ErrorInfo, type ReactNode } from "react"; interface Props { diff --git a/frontend/competition-view/src/components/KeyboardShortcutsHelp.tsx b/frontend/competition-view/src/components/KeyboardShortcutsHelp.tsx index 56e3200b7..5572745d4 100644 --- a/frontend/competition-view/src/components/KeyboardShortcutsHelp.tsx +++ b/frontend/competition-view/src/components/KeyboardShortcutsHelp.tsx @@ -4,8 +4,8 @@ import { DialogHeader, DialogTitle, Separator, -} from "@workspace/ui/components"; -import { Keyboard } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { Keyboard } from "@hyperloop-upv/frontend-kit/icons"; import { SHORTCUT_DEFS } from "../hooks/useKeyboardShortcuts"; interface KeyboardShortcutsHelpProps { diff --git a/frontend/competition-view/src/components/header/ConnectionBadge.tsx b/frontend/competition-view/src/components/header/ConnectionBadge.tsx index 97f564253..3a140946e 100644 --- a/frontend/competition-view/src/components/header/ConnectionBadge.tsx +++ b/frontend/competition-view/src/components/header/ConnectionBadge.tsx @@ -1,4 +1,4 @@ -import { Badge } from "@workspace/ui/components"; +import { Badge } from "@hyperloop-upv/frontend-kit/components"; interface ConnectionBadgeProps { /** Clear label identifying what this badge reports on, e.g. "Backend" or "VCU". */ diff --git a/frontend/competition-view/src/components/header/DashboardStatusBar.tsx b/frontend/competition-view/src/components/header/DashboardStatusBar.tsx index ab4b3f1e8..e88552aac 100644 --- a/frontend/competition-view/src/components/header/DashboardStatusBar.tsx +++ b/frontend/competition-view/src/components/header/DashboardStatusBar.tsx @@ -1,4 +1,4 @@ -import { Separator } from "@workspace/ui/components"; +import { Separator } from "@hyperloop-upv/frontend-kit/components"; import { formatAxisValue } from "../../constants/chartConfig"; import { BOARDS, HVAL_THRESHOLD_V, HVBMS, VCU } from "../../constants/measurements"; import { useIsStale } from "../../hooks/useIsStale"; diff --git a/frontend/competition-view/src/components/header/Header.tsx b/frontend/competition-view/src/components/header/Header.tsx index ac107e9d7..1e1f2d6c3 100644 --- a/frontend/competition-view/src/components/header/Header.tsx +++ b/frontend/competition-view/src/components/header/Header.tsx @@ -1,4 +1,4 @@ -import { Separator, SidebarTrigger } from "@workspace/ui/components"; +import { Separator, SidebarTrigger } from "@hyperloop-upv/frontend-kit/components"; import { useLocation } from "react-router"; import { BOARDS } from "../../constants/measurements"; import { PAGES } from "../../constants/pages"; diff --git a/frontend/competition-view/src/components/header/HvalIndicator.tsx b/frontend/competition-view/src/components/header/HvalIndicator.tsx index 13443f853..1c05717d0 100644 --- a/frontend/competition-view/src/components/header/HvalIndicator.tsx +++ b/frontend/competition-view/src/components/header/HvalIndicator.tsx @@ -1,4 +1,4 @@ -import { Badge } from "@workspace/ui/components"; +import { Badge } from "@hyperloop-upv/frontend-kit/components"; import { useEffect, useState } from "react"; import { BOARDS, HVAL_THRESHOLD_V, HVBMS } from "../../constants/measurements"; import useMeasurement from "../../hooks/useMeasurement"; diff --git a/frontend/competition-view/src/components/header/OrdersSheet.tsx b/frontend/competition-view/src/components/header/OrdersSheet.tsx index 6b85490b5..fb14796bd 100644 --- a/frontend/competition-view/src/components/header/OrdersSheet.tsx +++ b/frontend/competition-view/src/components/header/OrdersSheet.tsx @@ -8,9 +8,9 @@ import { SheetTitle, SheetTrigger, Skeleton, -} from "@workspace/ui/components"; -import { Send } from "@workspace/ui/icons"; -import { useWebSocket } from "@workspace/ui/hooks"; +} from "@hyperloop-upv/frontend-kit/components"; +import { Send } from "@hyperloop-upv/frontend-kit/icons"; +import { useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; import { useState } from "react"; import useOrdersCatalog from "../../hooks/useOrdersCatalog"; import { useStore } from "../../store/store"; diff --git a/frontend/competition-view/src/components/sidebar/AboutItem.tsx b/frontend/competition-view/src/components/sidebar/AboutItem.tsx index 92c2bcc02..533752d99 100644 --- a/frontend/competition-view/src/components/sidebar/AboutItem.tsx +++ b/frontend/competition-view/src/components/sidebar/AboutItem.tsx @@ -5,10 +5,10 @@ import { DialogTitle, Separator, SidebarMenuButton, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { Info } from "lucide-react"; import { useState } from "react"; -import logo from "@workspace/ui/outreach/h11/h11-isotipo_black.svg"; +import logo from "@hyperloop-upv/frontend-kit/outreach/h11/h11-isotipo_black.svg"; /** * Sidebar footer item that opens the About dialog with team credits. diff --git a/frontend/competition-view/src/components/sidebar/AppSidebar.tsx b/frontend/competition-view/src/components/sidebar/AppSidebar.tsx index e6c79531b..c9217eaff 100644 --- a/frontend/competition-view/src/components/sidebar/AppSidebar.tsx +++ b/frontend/competition-view/src/components/sidebar/AppSidebar.tsx @@ -4,7 +4,7 @@ import { SidebarFooter, SidebarHeader, SidebarRail, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { PAGES_ARRAY } from "../../constants/pages"; import AboutItem from "./AboutItem"; import ConnectionStatusGroup from "./ConnectionStatusGroup"; diff --git a/frontend/competition-view/src/components/sidebar/ConnectionStatusGroup.tsx b/frontend/competition-view/src/components/sidebar/ConnectionStatusGroup.tsx index 76fff79cb..13a6000be 100644 --- a/frontend/competition-view/src/components/sidebar/ConnectionStatusGroup.tsx +++ b/frontend/competition-view/src/components/sidebar/ConnectionStatusGroup.tsx @@ -4,8 +4,8 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, -} from "@workspace/ui/components"; -import { Plug, Unplug } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { Plug, Unplug } from "@hyperloop-upv/frontend-kit/icons"; import useConnections from "../../hooks/useConnections"; interface ConnectionStatusGroupProps { diff --git a/frontend/competition-view/src/components/sidebar/LoggerItem.tsx b/frontend/competition-view/src/components/sidebar/LoggerItem.tsx index 5f6894133..d616ef758 100644 --- a/frontend/competition-view/src/components/sidebar/LoggerItem.tsx +++ b/frontend/competition-view/src/components/sidebar/LoggerItem.tsx @@ -1,5 +1,5 @@ -import { SidebarMenuButton } from "@workspace/ui/components"; -import { cn } from "@workspace/ui/lib"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit/components"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { LOGGER_CONTROL_CONFIG } from "../../constants/loggerControlConfig"; import { useLogger } from "../../hooks/useLogger"; diff --git a/frontend/competition-view/src/components/sidebar/Logo.tsx b/frontend/competition-view/src/components/sidebar/Logo.tsx index e11cff854..f6e23de99 100644 --- a/frontend/competition-view/src/components/sidebar/Logo.tsx +++ b/frontend/competition-view/src/components/sidebar/Logo.tsx @@ -1,6 +1,6 @@ -import { SidebarMenuButton } from "@workspace/ui/components"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit/components"; import { Link } from "react-router"; -import logo from "@workspace/ui/outreach/h11/h11-isotipo_black.svg"; +import logo from "@hyperloop-upv/frontend-kit/outreach/h11/h11-isotipo_black.svg"; const Logo = () => ( diff --git a/frontend/competition-view/src/components/sidebar/NavigationGroup.tsx b/frontend/competition-view/src/components/sidebar/NavigationGroup.tsx index 41da64c38..09380d3c4 100644 --- a/frontend/competition-view/src/components/sidebar/NavigationGroup.tsx +++ b/frontend/competition-view/src/components/sidebar/NavigationGroup.tsx @@ -4,8 +4,8 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, -} from "@workspace/ui/components"; -import { type LucideIcon } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { type LucideIcon } from "@hyperloop-upv/frontend-kit/icons"; import { Link, useLocation } from "react-router"; interface NavItem { diff --git a/frontend/competition-view/src/components/sidebar/ShortcutsItem.tsx b/frontend/competition-view/src/components/sidebar/ShortcutsItem.tsx index 6ec99f0c3..458416316 100644 --- a/frontend/competition-view/src/components/sidebar/ShortcutsItem.tsx +++ b/frontend/competition-view/src/components/sidebar/ShortcutsItem.tsx @@ -1,5 +1,5 @@ -import { SidebarMenuButton } from "@workspace/ui/components"; -import { Keyboard } from "@workspace/ui/icons"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit/components"; +import { Keyboard } from "@hyperloop-upv/frontend-kit/icons"; interface ShortcutsItemProps { onShowShortcuts: () => void; diff --git a/frontend/competition-view/src/components/sidebar/ThemeToggleItem.tsx b/frontend/competition-view/src/components/sidebar/ThemeToggleItem.tsx index 79867f748..c8e228801 100644 --- a/frontend/competition-view/src/components/sidebar/ThemeToggleItem.tsx +++ b/frontend/competition-view/src/components/sidebar/ThemeToggleItem.tsx @@ -1,5 +1,5 @@ -import { SidebarMenuButton } from "@workspace/ui/components"; -import { SunMoon } from "@workspace/ui/icons"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit/components"; +import { SunMoon } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../store/store"; const ThemeToggleItem = () => { diff --git a/frontend/competition-view/src/constants/loggerControlConfig.tsx b/frontend/competition-view/src/constants/loggerControlConfig.tsx index 02b9ea10a..67dfae3ee 100644 --- a/frontend/competition-view/src/constants/loggerControlConfig.tsx +++ b/frontend/competition-view/src/constants/loggerControlConfig.tsx @@ -1,4 +1,4 @@ -import { AlertCircle, Loader2, Play, Square } from "@workspace/ui/icons"; +import { AlertCircle, Loader2, Play, Square } from "@hyperloop-upv/frontend-kit/icons"; import type { LoggerStatus } from "../types/logger"; interface LoggerControlOption { diff --git a/frontend/competition-view/src/constants/pages.ts b/frontend/competition-view/src/constants/pages.ts index bcc269e15..69f4ab322 100644 --- a/frontend/competition-view/src/constants/pages.ts +++ b/frontend/competition-view/src/constants/pages.ts @@ -1,4 +1,4 @@ -import { Battery, Layout, MessageSquare } from "@workspace/ui/icons"; +import { Battery, Layout, MessageSquare } from "@hyperloop-upv/frontend-kit/icons"; export const PAGES = { "/": { title: "Competition View", icon: Layout }, diff --git a/frontend/competition-view/src/hooks/useLogger.ts b/frontend/competition-view/src/hooks/useLogger.ts index 96ba34c9a..aec3dce7c 100644 --- a/frontend/competition-view/src/hooks/useLogger.ts +++ b/frontend/competition-view/src/hooks/useLogger.ts @@ -1,5 +1,5 @@ -import { logger, socketService } from "@workspace/core"; -import { useTopic } from "@workspace/ui/hooks"; +import { logger, socketService } from "@hyperloop-upv/frontend-kit/core"; +import { useTopic } from "@hyperloop-upv/frontend-kit/hooks"; import { useEffect, useState } from "react"; import type { LoggerStatus } from "../types/logger"; diff --git a/frontend/competition-view/src/hooks/useOrdersCatalog.ts b/frontend/competition-view/src/hooks/useOrdersCatalog.ts index a838165e4..86db9259a 100644 --- a/frontend/competition-view/src/hooks/useOrdersCatalog.ts +++ b/frontend/competition-view/src/hooks/useOrdersCatalog.ts @@ -1,4 +1,4 @@ -import { useFetchConfig } from "@workspace/ui/hooks"; +import { useFetchConfig } from "@hyperloop-upv/frontend-kit/hooks"; import { useEffect } from "react"; import { useStore } from "../store/store"; import type { OrdersData } from "../types/catalog"; diff --git a/frontend/competition-view/src/hooks/usePodCatalog.ts b/frontend/competition-view/src/hooks/usePodCatalog.ts index 2d414132a..92adf9ef8 100644 --- a/frontend/competition-view/src/hooks/usePodCatalog.ts +++ b/frontend/competition-view/src/hooks/usePodCatalog.ts @@ -1,4 +1,4 @@ -import { useFetchConfig, useWebSocket } from "@workspace/ui/hooks"; +import { useFetchConfig, useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; import { useEffect } from "react"; import { useStore } from "../store/store"; diff --git a/frontend/competition-view/src/hooks/useSendOrder.ts b/frontend/competition-view/src/hooks/useSendOrder.ts index 1ce0fc966..b0f7dbd0c 100644 --- a/frontend/competition-view/src/hooks/useSendOrder.ts +++ b/frontend/competition-view/src/hooks/useSendOrder.ts @@ -1,4 +1,4 @@ -import { logger, socketService } from "@workspace/core"; +import { logger, socketService } from "@hyperloop-upv/frontend-kit/core"; import { useCallback } from "react"; import type { Order } from "../constants/orders"; diff --git a/frontend/competition-view/src/index.css b/frontend/competition-view/src/index.css index e7caa9cec..0477b43b7 100644 --- a/frontend/competition-view/src/index.css +++ b/frontend/competition-view/src/index.css @@ -1,7 +1,7 @@ -@import "@workspace/ui/globals.css"; +@import "@hyperloop-upv/frontend-kit/globals.css"; /* Ensure Tailwind v4 scans competition-view source files directly. - The @source paths in globals.css resolve via the @workspace/ui symlink + The @source paths in globals.css resolve via the @hyperloop-upv/frontend-kit symlink and don't correctly reach this project's source tree. */ @source "./**/*.{ts,tsx}"; diff --git a/frontend/competition-view/src/layout/AppLayout.tsx b/frontend/competition-view/src/layout/AppLayout.tsx index f9d3b8d39..91ec01225 100644 --- a/frontend/competition-view/src/layout/AppLayout.tsx +++ b/frontend/competition-view/src/layout/AppLayout.tsx @@ -1,4 +1,4 @@ -import { SidebarInset, SidebarProvider } from "@workspace/ui/components"; +import { SidebarInset, SidebarProvider } from "@hyperloop-upv/frontend-kit/components"; import { useEffect, type ReactNode } from "react"; import Header from "../components/header/Header"; import AppSidebar from "../components/sidebar/AppSidebar"; diff --git a/frontend/competition-view/src/pages/Messages/Messages.tsx b/frontend/competition-view/src/pages/Messages/Messages.tsx index 8df2d0c84..f81c5b379 100644 --- a/frontend/competition-view/src/pages/Messages/Messages.tsx +++ b/frontend/competition-view/src/pages/Messages/Messages.tsx @@ -1,5 +1,5 @@ -import { Button, Separator, Slider } from "@workspace/ui/components"; -import { ChevronDown } from "@workspace/ui/icons"; +import { Button, Separator, Slider } from "@hyperloop-upv/frontend-kit/components"; +import { ChevronDown } from "@hyperloop-upv/frontend-kit/icons"; import { useEffect, useRef, useState } from "react"; import { useStore } from "../../store/store"; import type { MessageKind } from "../../types/message"; diff --git a/frontend/competition-view/src/pages/Messages/components/MessageItem.tsx b/frontend/competition-view/src/pages/Messages/components/MessageItem.tsx index a37f267d8..f2ce37091 100644 --- a/frontend/competition-view/src/pages/Messages/components/MessageItem.tsx +++ b/frontend/competition-view/src/pages/Messages/components/MessageItem.tsx @@ -1,4 +1,4 @@ -import { Badge } from "@workspace/ui/components"; +import { Badge } from "@hyperloop-upv/frontend-kit/components"; import { memo } from "react"; import { formatMessageTimestamp, messageContent } from "../../../lib/message"; import type { Message, MessageKind } from "../../../types/message"; diff --git a/frontend/competition-view/src/pages/Orders/Orders.tsx b/frontend/competition-view/src/pages/Orders/Orders.tsx index cf432b6e8..611706ca9 100644 --- a/frontend/competition-view/src/pages/Orders/Orders.tsx +++ b/frontend/competition-view/src/pages/Orders/Orders.tsx @@ -1,5 +1,5 @@ -import { Skeleton } from "@workspace/ui/components"; -import { useWebSocket } from "@workspace/ui/hooks"; +import { Skeleton } from "@hyperloop-upv/frontend-kit/components"; +import { useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; import useOrdersCatalog from "../../hooks/useOrdersCatalog"; import { useStore } from "../../store/store"; import OrdersList from "./components/OrdersList"; diff --git a/frontend/competition-view/src/pages/Orders/components/OrderButton.tsx b/frontend/competition-view/src/pages/Orders/components/OrderButton.tsx index a90c25223..86748a32b 100644 --- a/frontend/competition-view/src/pages/Orders/components/OrderButton.tsx +++ b/frontend/competition-view/src/pages/Orders/components/OrderButton.tsx @@ -1,5 +1,5 @@ -import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@workspace/ui/components"; -import { AlertTriangle, Check, Send } from "@workspace/ui/icons"; +import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@hyperloop-upv/frontend-kit/components"; +import { AlertTriangle, Check, Send } from "@hyperloop-upv/frontend-kit/icons"; import { useState } from "react"; import useSendOrder from "../../../hooks/useSendOrder"; import { orderButtonColorClass, type OrderColorLevel } from "../../../constants/orderColors"; diff --git a/frontend/competition-view/src/pages/Orders/components/OrderParameters.tsx b/frontend/competition-view/src/pages/Orders/components/OrderParameters.tsx index 967e1ef7d..dd676017e 100644 --- a/frontend/competition-view/src/pages/Orders/components/OrderParameters.tsx +++ b/frontend/competition-view/src/pages/Orders/components/OrderParameters.tsx @@ -8,7 +8,7 @@ import { SelectItem, SelectTrigger, SelectValue, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import type { CommandParameter, NumericParameter, ParameterValues } from "../../../types/catalog"; /** True when the field holds a number outside the parameter's safeRange (empty/NaN doesn't count). */ diff --git a/frontend/competition-view/src/pages/Orders/components/OrderRow.tsx b/frontend/competition-view/src/pages/Orders/components/OrderRow.tsx index 2ed9f317c..bca442a72 100644 --- a/frontend/competition-view/src/pages/Orders/components/OrderRow.tsx +++ b/frontend/competition-view/src/pages/Orders/components/OrderRow.tsx @@ -7,8 +7,8 @@ import { Tooltip, TooltipContent, TooltipTrigger, -} from "@workspace/ui/components"; -import { Check, ChevronDown, Send } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { Check, ChevronDown, Send } from "@hyperloop-upv/frontend-kit/icons"; import { useMemo, useState } from "react"; import useSendOrder from "../../../hooks/useSendOrder"; import useMeasurement from "../../../hooks/useMeasurement"; diff --git a/frontend/competition-view/src/pages/Orders/components/OrdersList.tsx b/frontend/competition-view/src/pages/Orders/components/OrdersList.tsx index e49d1c1d1..7d1ca9d1f 100644 --- a/frontend/competition-view/src/pages/Orders/components/OrdersList.tsx +++ b/frontend/competition-view/src/pages/Orders/components/OrdersList.tsx @@ -1,4 +1,4 @@ -import { Button } from "@workspace/ui/components"; +import { Button } from "@hyperloop-upv/frontend-kit/components"; import type { BoardOrdersData } from "../../../types/catalog"; import { BOARDS, VCU } from "../../../constants/measurements"; import { diff --git a/frontend/competition-view/src/pages/Overview/Overview.tsx b/frontend/competition-view/src/pages/Overview/Overview.tsx index d8238c430..a31f03b53 100644 --- a/frontend/competition-view/src/pages/Overview/Overview.tsx +++ b/frontend/competition-view/src/pages/Overview/Overview.tsx @@ -1,5 +1,5 @@ -import { Button } from "@workspace/ui/components"; -import { ChevronDown, MessageSquare } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit/components"; +import { ChevronDown, MessageSquare } from "@hyperloop-upv/frontend-kit/icons"; import { BatteryFull, Gauge, diff --git a/frontend/competition-view/src/pages/Overview/components/MetricCard.tsx b/frontend/competition-view/src/pages/Overview/components/MetricCard.tsx index c106835f8..759271f61 100644 --- a/frontend/competition-view/src/pages/Overview/components/MetricCard.tsx +++ b/frontend/competition-view/src/pages/Overview/components/MetricCard.tsx @@ -3,7 +3,7 @@ import { CardContent, CardHeader, CardTitle, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; interface MetricCardProps { label: string; diff --git a/frontend/competition-view/src/pages/Overview/components/OrdersPanel.tsx b/frontend/competition-view/src/pages/Overview/components/OrdersPanel.tsx index e00453186..55c3f3ce5 100644 --- a/frontend/competition-view/src/pages/Overview/components/OrdersPanel.tsx +++ b/frontend/competition-view/src/pages/Overview/components/OrdersPanel.tsx @@ -1,6 +1,6 @@ -import { Skeleton } from "@workspace/ui/components"; -import { Send } from "@workspace/ui/icons"; -import { useWebSocket } from "@workspace/ui/hooks"; +import { Skeleton } from "@hyperloop-upv/frontend-kit/components"; +import { Send } from "@hyperloop-upv/frontend-kit/icons"; +import { useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; import useOrdersCatalog from "../../../hooks/useOrdersCatalog"; import { useStore } from "../../../store/store"; import OrdersList from "../../Orders/components/OrdersList"; diff --git a/frontend/competition-view/src/pages/Overview/components/TrackProgress.tsx b/frontend/competition-view/src/pages/Overview/components/TrackProgress.tsx index f7a14c346..2b3ffe8d2 100644 --- a/frontend/competition-view/src/pages/Overview/components/TrackProgress.tsx +++ b/frontend/competition-view/src/pages/Overview/components/TrackProgress.tsx @@ -1,4 +1,4 @@ -import { Card, CardContent } from "@workspace/ui/components"; +import { Card, CardContent } from "@hyperloop-upv/frontend-kit/components"; import { MapPin } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import podIconDark from "../../../assets/pod-dark.svg"; diff --git a/frontend/competition-view/src/pages/Overview/components/VehicleStateBanner.tsx b/frontend/competition-view/src/pages/Overview/components/VehicleStateBanner.tsx index cd127111c..84d914801 100644 --- a/frontend/competition-view/src/pages/Overview/components/VehicleStateBanner.tsx +++ b/frontend/competition-view/src/pages/Overview/components/VehicleStateBanner.tsx @@ -1,4 +1,4 @@ -import { Badge } from "@workspace/ui/components"; +import { Badge } from "@hyperloop-upv/frontend-kit/components"; import { BOARDS, VCU } from "../../../constants/measurements"; import useMeasurement from "../../../hooks/useMeasurement"; diff --git a/frontend/competition-view/src/types/telemetry.ts b/frontend/competition-view/src/types/telemetry.ts index 2f8248553..481e62d39 100644 --- a/frontend/competition-view/src/types/telemetry.ts +++ b/frontend/competition-view/src/types/telemetry.ts @@ -1,10 +1,10 @@ -export type { TelemetryPacket, VariableValue, Variables } from "@workspace/core"; +export type { TelemetryPacket, VariableValue, Variables } from "@hyperloop-upv/frontend-kit/core"; /** * The backend sends a batch of packets keyed by numeric packet ID. * Each packet carries its own `measurementUpdates` map. */ -export type TelemetryData = Record; +export type TelemetryData = Record; /** * Telemetry keyed first by board name then by measurement ID. diff --git a/frontend/competition-view/tsconfig.json b/frontend/competition-view/tsconfig.json index a351dd46e..1d8aa51b5 100644 --- a/frontend/competition-view/tsconfig.json +++ b/frontend/competition-view/tsconfig.json @@ -7,8 +7,7 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": ["./*"], - "@workspace/ui/*": ["../frontend-kit/ui/src/*"] + "@/*": ["./*"] } }, "exclude": ["node_modules"] diff --git a/frontend/flashing-view/eslint.config.js b/frontend/flashing-view/eslint.config.js index df360b435..a2b580035 100644 --- a/frontend/flashing-view/eslint.config.js +++ b/frontend/flashing-view/eslint.config.js @@ -1,3 +1,3 @@ -import { config } from "@workspace/eslint-config/vite"; +import { config } from "@hyperloop-upv/eslint-config/vite"; export default config; diff --git a/frontend/flashing-view/package.json b/frontend/flashing-view/package.json index 725224d9f..0f09a72f5 100644 --- a/frontend/flashing-view/package.json +++ b/frontend/flashing-view/package.json @@ -13,7 +13,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.18", "@vitejs/plugin-react-swc": "^4.2.3", - "@workspace/ui": "workspace:*", + "@hyperloop-upv/frontend-kit": "workspace:*", "lucide-react": "^0.563.0", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -22,8 +22,8 @@ "devDependencies": { "@types/react": "19.2.11", "@types/react-dom": "19.2.3", - "@workspace/eslint-config": "workspace:^", - "@workspace/typescript-config": "workspace:*", + "@hyperloop-upv/eslint-config": "workspace:^", + "@hyperloop-upv/typescript-config": "workspace:*", "eslint": "^9.39.2", "typescript": "^5.9.3", "vite": "^7.3.1" diff --git a/frontend/flashing-view/src/features/flash-station/components/board-card.tsx b/frontend/flashing-view/src/features/flash-station/components/board-card.tsx index 5da96b47c..5b2fbc950 100644 --- a/frontend/flashing-view/src/features/flash-station/components/board-card.tsx +++ b/frontend/flashing-view/src/features/flash-station/components/board-card.tsx @@ -1,5 +1,5 @@ -import { Badge } from "@workspace/ui/components"; -import { cn } from "@workspace/ui/lib/utils"; +import { Badge } from "@hyperloop-upv/frontend-kit/components"; +import { cn } from "@hyperloop-upv/frontend-kit/lib/utils"; import type { Board } from "../types"; type Props = { diff --git a/frontend/flashing-view/src/features/flash-station/components/section-card.tsx b/frontend/flashing-view/src/features/flash-station/components/section-card.tsx index 91d81701f..29c4dd4a0 100644 --- a/frontend/flashing-view/src/features/flash-station/components/section-card.tsx +++ b/frontend/flashing-view/src/features/flash-station/components/section-card.tsx @@ -1,4 +1,4 @@ -import { Card, CardContent, CardHeader, CardTitle } from "@workspace/ui/components"; +import { Card, CardContent, CardHeader, CardTitle } from "@hyperloop-upv/frontend-kit/components"; import type { ReactNode } from "react"; type Props = { diff --git a/frontend/flashing-view/src/features/flash-station/flash-station-view.tsx b/frontend/flashing-view/src/features/flash-station/flash-station-view.tsx index b1aedd96f..c70587175 100644 --- a/frontend/flashing-view/src/features/flash-station/flash-station-view.tsx +++ b/frontend/flashing-view/src/features/flash-station/flash-station-view.tsx @@ -1,8 +1,8 @@ -import { Badge, Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@workspace/ui/components"; -import { FileCode2, Loader2, SunMoon, Upload } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib/utils"; +import { Badge, Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@hyperloop-upv/frontend-kit/components"; +import { FileCode2, Loader2, SunMoon, Upload } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib/utils"; import { useEffect, useRef, useState } from "react"; -import logo from "@workspace/ui/outreach/h11/h11-isotipo_black.svg"; +import logo from "@hyperloop-upv/frontend-kit/outreach/h11/h11-isotipo_black.svg"; import { BoardCard } from "./components/board-card"; import { SectionCard } from "./components/section-card"; import type { Board, BoardsResponse, GeneralState, OperationalState } from "./types"; diff --git a/frontend/flashing-view/src/index.css b/frontend/flashing-view/src/index.css index 6824f52fb..b5950dca2 100644 --- a/frontend/flashing-view/src/index.css +++ b/frontend/flashing-view/src/index.css @@ -1 +1 @@ -@import "@workspace/ui/globals.css"; +@import "@hyperloop-upv/frontend-kit/globals.css"; diff --git a/frontend/flashing-view/tsconfig.json b/frontend/flashing-view/tsconfig.json index fc0aa4474..483ebaa0f 100644 --- a/frontend/flashing-view/tsconfig.json +++ b/frontend/flashing-view/tsconfig.json @@ -4,11 +4,5 @@ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ], - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@workspace/ui/*": ["../frontend-kit/ui/src/*"] - } - }, "exclude": ["node_modules"] } diff --git a/frontend/frontend-kit/core/package.json b/frontend/frontend-kit/core/package.json deleted file mode 100644 index bb358f5a3..000000000 --- a/frontend/frontend-kit/core/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "@workspace/core", - "version": "1.0.0", - "description": "", - "main": "index.js", - "type": "module", - "scripts": { - "preinstall": "npx only-allow pnpm", - "lint": "eslint ." - }, - "keywords": [], - "author": "", - "license": "ISC", - "packageManager": "pnpm@10.24.0", - "devDependencies": { - "@workspace/eslint-config": "workspace:*", - "eslint": "^9.39.2" - }, - "exports": { - ".": "./src/index.ts" - }, - "dependencies": { - "rxjs": "^7.8.2" - } -} diff --git a/frontend/frontend-kit/core/tsconfig.json b/frontend/frontend-kit/core/tsconfig.json deleted file mode 100644 index 0bedc71da..000000000 --- a/frontend/frontend-kit/core/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@workspace/typescript-config/react-library.json", - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@workspace/ui/*": ["./src/*"] - } - }, - "include": ["."], - "exclude": ["node_modules", "dist"] -} diff --git a/frontend/frontend-kit/esling-config/base.js b/frontend/frontend-kit/eslint-config/base.js similarity index 100% rename from frontend/frontend-kit/esling-config/base.js rename to frontend/frontend-kit/eslint-config/base.js diff --git a/frontend/frontend-kit/esling-config/package.json b/frontend/frontend-kit/eslint-config/package.json similarity index 94% rename from frontend/frontend-kit/esling-config/package.json rename to frontend/frontend-kit/eslint-config/package.json index dfb4d11d7..9434cda68 100644 --- a/frontend/frontend-kit/esling-config/package.json +++ b/frontend/frontend-kit/eslint-config/package.json @@ -1,5 +1,5 @@ { - "name": "@workspace/eslint-config", + "name": "@hyperloop-upv/eslint-config", "version": "0.0.0", "type": "module", "private": true, diff --git a/frontend/frontend-kit/esling-config/react-internal.js b/frontend/frontend-kit/eslint-config/react-internal.js similarity index 100% rename from frontend/frontend-kit/esling-config/react-internal.js rename to frontend/frontend-kit/eslint-config/react-internal.js diff --git a/frontend/frontend-kit/esling-config/vite.js b/frontend/frontend-kit/eslint-config/vite.js similarity index 100% rename from frontend/frontend-kit/esling-config/vite.js rename to frontend/frontend-kit/eslint-config/vite.js diff --git a/frontend/frontend-kit/ui/README.md b/frontend/frontend-kit/kit/README.md similarity index 86% rename from frontend/frontend-kit/ui/README.md rename to frontend/frontend-kit/kit/README.md index 7b5a9e4f9..5154c9140 100644 --- a/frontend/frontend-kit/ui/README.md +++ b/frontend/frontend-kit/kit/README.md @@ -9,7 +9,7 @@ This package is the main UI and React shared component library for the Hyperloop > This package is specifically for **UI and React-related components**. > > - If your logic requires React hooks (`useState`, `useEffect`, etc.) or TSX, it belongs here. -> - **If your logic does NOT need React** (e.g., websocket connections), it should be implemented in the `@workspace/core` package. This keeps the codebase clean and allows for better reuse across different environments. +> - **If your logic does NOT need React** (e.g., websocket connections), it should be implemented in the `@hyperloop-upv/frontend-kit/core` package. This keeps the codebase clean and allows for better reuse across different environments. --- diff --git a/frontend/frontend-kit/ui/components.json b/frontend/frontend-kit/kit/components.json similarity index 50% rename from frontend/frontend-kit/ui/components.json rename to frontend/frontend-kit/kit/components.json index 29e8e6d99..b37aad469 100644 --- a/frontend/frontend-kit/ui/components.json +++ b/frontend/frontend-kit/kit/components.json @@ -11,10 +11,10 @@ }, "iconLibrary": "lucide", "aliases": { - "components": "@workspace/ui/components", - "hooks": "@workspace/ui/hooks/shadcn", - "lib": "@workspace/ui/lib", - "utils": "@workspace/ui/lib/utils", - "ui": "@workspace/ui/components/shadcn" + "components": "@hyperloop-upv/frontend-kit/components", + "hooks": "@hyperloop-upv/frontend-kit/hooks/shadcn", + "lib": "@hyperloop-upv/frontend-kit/lib", + "utils": "@hyperloop-upv/frontend-kit/lib/utils", + "ui": "@hyperloop-upv/frontend-kit/components/shadcn" } } diff --git a/frontend/frontend-kit/core/eslint.config.js b/frontend/frontend-kit/kit/eslint.config.js similarity index 50% rename from frontend/frontend-kit/core/eslint.config.js rename to frontend/frontend-kit/kit/eslint.config.js index f79dd7d64..c091004bc 100644 --- a/frontend/frontend-kit/core/eslint.config.js +++ b/frontend/frontend-kit/kit/eslint.config.js @@ -1,4 +1,4 @@ -import { config } from "@workspace/eslint-config/react-internal"; +import { config } from "@hyperloop-upv/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ export default config; diff --git a/frontend/frontend-kit/ui/package.json b/frontend/frontend-kit/kit/package.json similarity index 86% rename from frontend/frontend-kit/ui/package.json rename to frontend/frontend-kit/kit/package.json index 874546f7d..6eeb0070d 100644 --- a/frontend/frontend-kit/ui/package.json +++ b/frontend/frontend-kit/kit/package.json @@ -1,6 +1,6 @@ { - "name": "@workspace/ui", - "version": "0.0.0", + "name": "@hyperloop-upv/frontend-kit", + "version": "0.1.0", "type": "module", "private": true, "scripts": { @@ -23,7 +23,6 @@ "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", - "@workspace/core": "workspace:*", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.563.0", @@ -45,14 +44,15 @@ "@types/node": "^25.2.0", "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", - "@workspace/eslint-config": "workspace:*", - "@workspace/typescript-config": "workspace:*", + "@hyperloop-upv/eslint-config": "workspace:*", + "@hyperloop-upv/typescript-config": "workspace:*", "eslint": "^9.39.2", "tailwindcss": "^4.1.18", "typescript": "^5.9.3" }, "exports": { ".": "./src/index.ts", + "./core": "./src/core/index.ts", "./globals.css": "./src/styles/globals.css", "./postcss.config": "./postcss.config.mjs", "./lib": "./src/lib/index.ts", @@ -64,5 +64,6 @@ "./store": "./src/store/index.ts", "./icons": "./src/icons/index.ts", "./outreach/*": "./src/outreach/*" - } + }, + "description": "Shared React + Tailwind component kit and WebSocket layer for Hyperloop UPV frontends" } diff --git a/frontend/frontend-kit/ui/postcss.config.mjs b/frontend/frontend-kit/kit/postcss.config.mjs similarity index 100% rename from frontend/frontend-kit/ui/postcss.config.mjs rename to frontend/frontend-kit/kit/postcss.config.mjs diff --git a/frontend/frontend-kit/ui/src/components/custom/custom-component.tsx b/frontend/frontend-kit/kit/src/components/custom/custom-component.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/custom/custom-component.tsx rename to frontend/frontend-kit/kit/src/components/custom/custom-component.tsx diff --git a/frontend/frontend-kit/ui/src/components/custom/index.ts b/frontend/frontend-kit/kit/src/components/custom/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/components/custom/index.ts rename to frontend/frontend-kit/kit/src/components/custom/index.ts diff --git a/frontend/frontend-kit/ui/src/components/custom/segmented-control.tsx b/frontend/frontend-kit/kit/src/components/custom/segmented-control.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/custom/segmented-control.tsx rename to frontend/frontend-kit/kit/src/components/custom/segmented-control.tsx diff --git a/frontend/frontend-kit/ui/src/components/index.ts b/frontend/frontend-kit/kit/src/components/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/components/index.ts rename to frontend/frontend-kit/kit/src/components/index.ts diff --git a/frontend/frontend-kit/ui/src/components/shadcn/badge.tsx b/frontend/frontend-kit/kit/src/components/shadcn/badge.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/badge.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/badge.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/button.tsx b/frontend/frontend-kit/kit/src/components/shadcn/button.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/button.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/button.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/card.tsx b/frontend/frontend-kit/kit/src/components/shadcn/card.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/card.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/card.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/checkbox.tsx b/frontend/frontend-kit/kit/src/components/shadcn/checkbox.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/checkbox.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/checkbox.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/collapsible.tsx b/frontend/frontend-kit/kit/src/components/shadcn/collapsible.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/collapsible.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/collapsible.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/combobox.tsx b/frontend/frontend-kit/kit/src/components/shadcn/combobox.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/combobox.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/combobox.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/context-menu.tsx b/frontend/frontend-kit/kit/src/components/shadcn/context-menu.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/context-menu.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/context-menu.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/dialog.tsx b/frontend/frontend-kit/kit/src/components/shadcn/dialog.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/dialog.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/dialog.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx b/frontend/frontend-kit/kit/src/components/shadcn/dropdown-menu.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/dropdown-menu.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/field.tsx b/frontend/frontend-kit/kit/src/components/shadcn/field.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/field.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/field.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/index.ts b/frontend/frontend-kit/kit/src/components/shadcn/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/index.ts rename to frontend/frontend-kit/kit/src/components/shadcn/index.ts diff --git a/frontend/frontend-kit/ui/src/components/shadcn/input-group.tsx b/frontend/frontend-kit/kit/src/components/shadcn/input-group.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/input-group.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/input-group.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/input.tsx b/frontend/frontend-kit/kit/src/components/shadcn/input.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/input.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/input.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/label.tsx b/frontend/frontend-kit/kit/src/components/shadcn/label.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/label.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/label.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/popover.tsx b/frontend/frontend-kit/kit/src/components/shadcn/popover.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/popover.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/popover.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx b/frontend/frontend-kit/kit/src/components/shadcn/resizable.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/resizable.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/select.tsx b/frontend/frontend-kit/kit/src/components/shadcn/select.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/select.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/select.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/separator.tsx b/frontend/frontend-kit/kit/src/components/shadcn/separator.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/separator.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/separator.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/sheet.tsx b/frontend/frontend-kit/kit/src/components/shadcn/sheet.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/sheet.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/sheet.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/sidebar.tsx b/frontend/frontend-kit/kit/src/components/shadcn/sidebar.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/sidebar.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/sidebar.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/skeleton.tsx b/frontend/frontend-kit/kit/src/components/shadcn/skeleton.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/skeleton.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/skeleton.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/slider.tsx b/frontend/frontend-kit/kit/src/components/shadcn/slider.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/slider.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/slider.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/spinner.tsx b/frontend/frontend-kit/kit/src/components/shadcn/spinner.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/spinner.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/spinner.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/table.tsx b/frontend/frontend-kit/kit/src/components/shadcn/table.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/table.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/table.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/tabs.tsx b/frontend/frontend-kit/kit/src/components/shadcn/tabs.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/tabs.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/tabs.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/textarea.tsx b/frontend/frontend-kit/kit/src/components/shadcn/textarea.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/textarea.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/textarea.tsx diff --git a/frontend/frontend-kit/ui/src/components/shadcn/tooltip.tsx b/frontend/frontend-kit/kit/src/components/shadcn/tooltip.tsx similarity index 100% rename from frontend/frontend-kit/ui/src/components/shadcn/tooltip.tsx rename to frontend/frontend-kit/kit/src/components/shadcn/tooltip.tsx diff --git a/frontend/frontend-kit/core/src/index.ts b/frontend/frontend-kit/kit/src/core/index.ts similarity index 100% rename from frontend/frontend-kit/core/src/index.ts rename to frontend/frontend-kit/kit/src/core/index.ts diff --git a/frontend/frontend-kit/core/src/logger.ts b/frontend/frontend-kit/kit/src/core/logger.ts similarity index 100% rename from frontend/frontend-kit/core/src/logger.ts rename to frontend/frontend-kit/kit/src/core/logger.ts diff --git a/frontend/frontend-kit/core/src/loggerColors.ts b/frontend/frontend-kit/kit/src/core/loggerColors.ts similarity index 100% rename from frontend/frontend-kit/core/src/loggerColors.ts rename to frontend/frontend-kit/kit/src/core/loggerColors.ts diff --git a/frontend/frontend-kit/core/src/minMaxDownsample.ts b/frontend/frontend-kit/kit/src/core/minMaxDownsample.ts similarity index 100% rename from frontend/frontend-kit/core/src/minMaxDownsample.ts rename to frontend/frontend-kit/kit/src/core/minMaxDownsample.ts diff --git a/frontend/frontend-kit/core/src/types.ts b/frontend/frontend-kit/kit/src/core/types.ts similarity index 100% rename from frontend/frontend-kit/core/src/types.ts rename to frontend/frontend-kit/kit/src/core/types.ts diff --git a/frontend/frontend-kit/core/src/websocket.ts b/frontend/frontend-kit/kit/src/core/websocket.ts similarity index 100% rename from frontend/frontend-kit/core/src/websocket.ts rename to frontend/frontend-kit/kit/src/core/websocket.ts diff --git a/frontend/frontend-kit/ui/src/hooks/index.ts b/frontend/frontend-kit/kit/src/hooks/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/hooks/index.ts rename to frontend/frontend-kit/kit/src/hooks/index.ts diff --git a/frontend/frontend-kit/ui/src/hooks/shadcn/index.ts b/frontend/frontend-kit/kit/src/hooks/shadcn/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/hooks/shadcn/index.ts rename to frontend/frontend-kit/kit/src/hooks/shadcn/index.ts diff --git a/frontend/frontend-kit/ui/src/hooks/shadcn/use-mobile.ts b/frontend/frontend-kit/kit/src/hooks/shadcn/use-mobile.ts similarity index 100% rename from frontend/frontend-kit/ui/src/hooks/shadcn/use-mobile.ts rename to frontend/frontend-kit/kit/src/hooks/shadcn/use-mobile.ts diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/fetchConfig.ts b/frontend/frontend-kit/kit/src/hooks/webSocket/fetchConfig.ts similarity index 96% rename from frontend/frontend-kit/ui/src/hooks/webSocket/fetchConfig.ts rename to frontend/frontend-kit/kit/src/hooks/webSocket/fetchConfig.ts index b1358dfad..9ab182fc9 100644 --- a/frontend/frontend-kit/ui/src/hooks/webSocket/fetchConfig.ts +++ b/frontend/frontend-kit/kit/src/hooks/webSocket/fetchConfig.ts @@ -1,4 +1,4 @@ -import { logger } from "@workspace/core"; +import { logger } from "../../core"; import { useCallback, useEffect, useRef, useState } from "react"; export function useFetchConfig(baseUrl: string, endpoint: string) { diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/index.ts b/frontend/frontend-kit/kit/src/hooks/webSocket/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/hooks/webSocket/index.ts rename to frontend/frontend-kit/kit/src/hooks/webSocket/index.ts diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/useErrorSubscription.ts b/frontend/frontend-kit/kit/src/hooks/webSocket/useErrorSubscription.ts similarity index 85% rename from frontend/frontend-kit/ui/src/hooks/webSocket/useErrorSubscription.ts rename to frontend/frontend-kit/kit/src/hooks/webSocket/useErrorSubscription.ts index 6b1eb734f..2a546f458 100644 --- a/frontend/frontend-kit/ui/src/hooks/webSocket/useErrorSubscription.ts +++ b/frontend/frontend-kit/kit/src/hooks/webSocket/useErrorSubscription.ts @@ -1,4 +1,4 @@ -import { socketService } from "@workspace/core"; +import { socketService } from "../../core"; import { useEffect } from "react"; const useErrorSubscription = (callback: (err: Error) => void) => { diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/useTopic.ts b/frontend/frontend-kit/kit/src/hooks/webSocket/useTopic.ts similarity index 92% rename from frontend/frontend-kit/ui/src/hooks/webSocket/useTopic.ts rename to frontend/frontend-kit/kit/src/hooks/webSocket/useTopic.ts index baf695585..b1f4b0740 100644 --- a/frontend/frontend-kit/ui/src/hooks/webSocket/useTopic.ts +++ b/frontend/frontend-kit/kit/src/hooks/webSocket/useTopic.ts @@ -1,4 +1,4 @@ -import { logger, socketService, type TopicOptions } from "@workspace/core"; +import { logger, socketService, type TopicOptions } from "../../core"; import { useEffect, useRef } from "react"; import { useWebSocket } from "./useWebSocket"; diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/useWebSocket.ts b/frontend/frontend-kit/kit/src/hooks/webSocket/useWebSocket.ts similarity index 91% rename from frontend/frontend-kit/ui/src/hooks/webSocket/useWebSocket.ts rename to frontend/frontend-kit/kit/src/hooks/webSocket/useWebSocket.ts index eb1cbd507..702e71591 100644 --- a/frontend/frontend-kit/ui/src/hooks/webSocket/useWebSocket.ts +++ b/frontend/frontend-kit/kit/src/hooks/webSocket/useWebSocket.ts @@ -1,4 +1,4 @@ -import { socketService, type SocketConfig } from "@workspace/core"; +import { socketService, type SocketConfig } from "../../core"; import { useEffect, useState } from "react"; /** diff --git a/frontend/frontend-kit/ui/src/icons/accessibility.ts b/frontend/frontend-kit/kit/src/icons/accessibility.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/accessibility.ts rename to frontend/frontend-kit/kit/src/icons/accessibility.ts diff --git a/frontend/frontend-kit/ui/src/icons/account.ts b/frontend/frontend-kit/kit/src/icons/account.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/account.ts rename to frontend/frontend-kit/kit/src/icons/account.ts diff --git a/frontend/frontend-kit/ui/src/icons/arrows.ts b/frontend/frontend-kit/kit/src/icons/arrows.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/arrows.ts rename to frontend/frontend-kit/kit/src/icons/arrows.ts diff --git a/frontend/frontend-kit/ui/src/icons/cursors.ts b/frontend/frontend-kit/kit/src/icons/cursors.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/cursors.ts rename to frontend/frontend-kit/kit/src/icons/cursors.ts diff --git a/frontend/frontend-kit/ui/src/icons/design.ts b/frontend/frontend-kit/kit/src/icons/design.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/design.ts rename to frontend/frontend-kit/kit/src/icons/design.ts diff --git a/frontend/frontend-kit/ui/src/icons/development.ts b/frontend/frontend-kit/kit/src/icons/development.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/development.ts rename to frontend/frontend-kit/kit/src/icons/development.ts diff --git a/frontend/frontend-kit/ui/src/icons/devices.ts b/frontend/frontend-kit/kit/src/icons/devices.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/devices.ts rename to frontend/frontend-kit/kit/src/icons/devices.ts diff --git a/frontend/frontend-kit/ui/src/icons/files.ts b/frontend/frontend-kit/kit/src/icons/files.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/files.ts rename to frontend/frontend-kit/kit/src/icons/files.ts diff --git a/frontend/frontend-kit/ui/src/icons/gaming.ts b/frontend/frontend-kit/kit/src/icons/gaming.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/gaming.ts rename to frontend/frontend-kit/kit/src/icons/gaming.ts diff --git a/frontend/frontend-kit/ui/src/icons/index.ts b/frontend/frontend-kit/kit/src/icons/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/index.ts rename to frontend/frontend-kit/kit/src/icons/index.ts diff --git a/frontend/frontend-kit/ui/src/icons/layout.ts b/frontend/frontend-kit/kit/src/icons/layout.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/layout.ts rename to frontend/frontend-kit/kit/src/icons/layout.ts diff --git a/frontend/frontend-kit/ui/src/icons/mail.ts b/frontend/frontend-kit/kit/src/icons/mail.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/mail.ts rename to frontend/frontend-kit/kit/src/icons/mail.ts diff --git a/frontend/frontend-kit/ui/src/icons/math.ts b/frontend/frontend-kit/kit/src/icons/math.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/math.ts rename to frontend/frontend-kit/kit/src/icons/math.ts diff --git a/frontend/frontend-kit/ui/src/icons/notifications.ts b/frontend/frontend-kit/kit/src/icons/notifications.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/notifications.ts rename to frontend/frontend-kit/kit/src/icons/notifications.ts diff --git a/frontend/frontend-kit/ui/src/icons/photography.ts b/frontend/frontend-kit/kit/src/icons/photography.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/photography.ts rename to frontend/frontend-kit/kit/src/icons/photography.ts diff --git a/frontend/frontend-kit/ui/src/icons/science.ts b/frontend/frontend-kit/kit/src/icons/science.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/science.ts rename to frontend/frontend-kit/kit/src/icons/science.ts diff --git a/frontend/frontend-kit/ui/src/icons/shapes.ts b/frontend/frontend-kit/kit/src/icons/shapes.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/shapes.ts rename to frontend/frontend-kit/kit/src/icons/shapes.ts diff --git a/frontend/frontend-kit/ui/src/icons/social.ts b/frontend/frontend-kit/kit/src/icons/social.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/social.ts rename to frontend/frontend-kit/kit/src/icons/social.ts diff --git a/frontend/frontend-kit/ui/src/icons/text.ts b/frontend/frontend-kit/kit/src/icons/text.ts similarity index 100% rename from frontend/frontend-kit/ui/src/icons/text.ts rename to frontend/frontend-kit/kit/src/icons/text.ts diff --git a/frontend/frontend-kit/ui/src/index.ts b/frontend/frontend-kit/kit/src/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/index.ts rename to frontend/frontend-kit/kit/src/index.ts diff --git a/frontend/frontend-kit/ui/src/lib/index.ts b/frontend/frontend-kit/kit/src/lib/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/lib/index.ts rename to frontend/frontend-kit/kit/src/lib/index.ts diff --git a/frontend/frontend-kit/ui/src/lib/typeUtils.ts b/frontend/frontend-kit/kit/src/lib/typeUtils.ts similarity index 100% rename from frontend/frontend-kit/ui/src/lib/typeUtils.ts rename to frontend/frontend-kit/kit/src/lib/typeUtils.ts diff --git a/frontend/frontend-kit/ui/src/lib/utils.ts b/frontend/frontend-kit/kit/src/lib/utils.ts similarity index 100% rename from frontend/frontend-kit/ui/src/lib/utils.ts rename to frontend/frontend-kit/kit/src/lib/utils.ts diff --git a/frontend/frontend-kit/ui/src/outreach/h11/h11-isotipo_black.svg b/frontend/frontend-kit/kit/src/outreach/h11/h11-isotipo_black.svg similarity index 100% rename from frontend/frontend-kit/ui/src/outreach/h11/h11-isotipo_black.svg rename to frontend/frontend-kit/kit/src/outreach/h11/h11-isotipo_black.svg diff --git a/frontend/frontend-kit/ui/src/outreach/main/check_black.png b/frontend/frontend-kit/kit/src/outreach/main/check_black.png similarity index 100% rename from frontend/frontend-kit/ui/src/outreach/main/check_black.png rename to frontend/frontend-kit/kit/src/outreach/main/check_black.png diff --git a/frontend/frontend-kit/ui/src/outreach/main/full_logo_black.png b/frontend/frontend-kit/kit/src/outreach/main/full_logo_black.png similarity index 100% rename from frontend/frontend-kit/ui/src/outreach/main/full_logo_black.png rename to frontend/frontend-kit/kit/src/outreach/main/full_logo_black.png diff --git a/frontend/frontend-kit/ui/src/outreach/main/hyperloop_black.png b/frontend/frontend-kit/kit/src/outreach/main/hyperloop_black.png similarity index 100% rename from frontend/frontend-kit/ui/src/outreach/main/hyperloop_black.png rename to frontend/frontend-kit/kit/src/outreach/main/hyperloop_black.png diff --git a/frontend/frontend-kit/ui/src/outreach/main/logo_icon.svg b/frontend/frontend-kit/kit/src/outreach/main/logo_icon.svg similarity index 100% rename from frontend/frontend-kit/ui/src/outreach/main/logo_icon.svg rename to frontend/frontend-kit/kit/src/outreach/main/logo_icon.svg diff --git a/frontend/frontend-kit/ui/src/outreach/main/software_black.png b/frontend/frontend-kit/kit/src/outreach/main/software_black.png similarity index 100% rename from frontend/frontend-kit/ui/src/outreach/main/software_black.png rename to frontend/frontend-kit/kit/src/outreach/main/software_black.png diff --git a/frontend/frontend-kit/ui/src/outreach/main/software_white.png b/frontend/frontend-kit/kit/src/outreach/main/software_white.png similarity index 100% rename from frontend/frontend-kit/ui/src/outreach/main/software_white.png rename to frontend/frontend-kit/kit/src/outreach/main/software_white.png diff --git a/frontend/frontend-kit/ui/src/store/index.ts b/frontend/frontend-kit/kit/src/store/index.ts similarity index 100% rename from frontend/frontend-kit/ui/src/store/index.ts rename to frontend/frontend-kit/kit/src/store/index.ts diff --git a/frontend/frontend-kit/ui/src/styles/globals.css b/frontend/frontend-kit/kit/src/styles/globals.css similarity index 99% rename from frontend/frontend-kit/ui/src/styles/globals.css rename to frontend/frontend-kit/kit/src/styles/globals.css index 463442343..4ad617b0c 100644 --- a/frontend/frontend-kit/ui/src/styles/globals.css +++ b/frontend/frontend-kit/kit/src/styles/globals.css @@ -3,7 +3,7 @@ @import "tailwindcss"; /* Scan only this package's own sources. Each app declares its own @source glob in its index.css, because paths resolved from here go through the - @workspace/ui symlink and don't reach the app's source tree. */ + @hyperloop-upv/frontend-kit symlink and don't reach the app's source tree. */ @source "../**/*.{ts,tsx}"; @import "tw-animate-css"; diff --git a/frontend/frontend-kit/kit/tsconfig.json b/frontend/frontend-kit/kit/tsconfig.json new file mode 100644 index 000000000..9e5e83901 --- /dev/null +++ b/frontend/frontend-kit/kit/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@hyperloop-upv/typescript-config/react-library.json", + "include": ["."], + "exclude": ["node_modules", "dist"] +} diff --git a/frontend/frontend-kit/typescript-config/package.json b/frontend/frontend-kit/typescript-config/package.json index eeb097e57..f1ead743a 100644 --- a/frontend/frontend-kit/typescript-config/package.json +++ b/frontend/frontend-kit/typescript-config/package.json @@ -1,5 +1,5 @@ { - "name": "@workspace/typescript-config", + "name": "@hyperloop-upv/typescript-config", "version": "0.0.0", "private": true, "publishConfig": { diff --git a/frontend/frontend-kit/ui/eslint.config.js b/frontend/frontend-kit/ui/eslint.config.js deleted file mode 100644 index f79dd7d64..000000000 --- a/frontend/frontend-kit/ui/eslint.config.js +++ /dev/null @@ -1,4 +0,0 @@ -import { config } from "@workspace/eslint-config/react-internal"; - -/** @type {import("eslint").Linter.Config} */ -export default config; diff --git a/frontend/frontend-kit/ui/tsconfig.json b/frontend/frontend-kit/ui/tsconfig.json deleted file mode 100644 index 0a0de6e8a..000000000 --- a/frontend/frontend-kit/ui/tsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "@workspace/typescript-config/react-library.json", - "include": ["."], - "exclude": ["node_modules", "dist"] -} diff --git a/frontend/logging-view/CLAUDE.md b/frontend/logging-view/CLAUDE.md index 9ef79714c..7e821d9e0 100644 --- a/frontend/logging-view/CLAUDE.md +++ b/frontend/logging-view/CLAUDE.md @@ -19,7 +19,7 @@ There is no test suite; verify with `pnpm build` and `pnpm lint`. Lint currently ## What this app is -An **offline analysis tool for backend log sessions**. The user opens a session folder written by the backend logger; the app reads its CSVs and the session's ADJ, and plots them. It has **no WebSocket or live backend connection**: the `telemetry`, `messages`, `catalog` and `connections` store slices and the `@workspace/core` dependency are leftovers from the `competition-view` scaffold and nothing reads them. +An **offline analysis tool for backend log sessions**. The user opens a session folder written by the backend logger; the app reads its CSVs and the session's ADJ, and plots them. It has **no WebSocket or live backend connection**: the `telemetry`, `messages`, `catalog` and `connections` store slices and the `@hyperloop-upv/frontend-kit/core` dependency are leftovers from the `competition-view` scaffold and nothing reads them. Routing is a `HashRouter` (`src/main.tsx`, needed when served from the Electron app). `/` redirects to `/simple`; `/normal` is a placeholder page ("still under development"). @@ -57,14 +57,14 @@ A single Zustand store (`src/store/store.ts`) composed of slices. The ones in us ## Workspace dependencies -Components, icons and utilities come from `@workspace/ui` (`frontend-kit/ui`): +Components, icons and utilities come from `@hyperloop-upv/frontend-kit` (`frontend-kit/kit`): ```tsx -import { Button, Sidebar } from "@workspace/ui/components"; -import { Plus } from "@workspace/ui/icons"; +import { Button, Sidebar } from "@hyperloop-upv/frontend-kit/components"; +import { Plus } from "@hyperloop-upv/frontend-kit/icons"; ``` -To add an icon: find it on lucide.dev, add its export to the file in `frontend-kit/ui/src/icons/` named after its **first** category, and re-export from `index.ts` if that file is new. +To add an icon: find it on lucide.dev, add its export to the file in `frontend-kit/kit/src/icons/` named after its **first** category, and re-export from `index.ts` if that file is new. ## Gotchas diff --git a/frontend/logging-view/eslint.config.js b/frontend/logging-view/eslint.config.js index df360b435..a2b580035 100644 --- a/frontend/logging-view/eslint.config.js +++ b/frontend/logging-view/eslint.config.js @@ -1,3 +1,3 @@ -import { config } from "@workspace/eslint-config/vite"; +import { config } from "@hyperloop-upv/eslint-config/vite"; export default config; diff --git a/frontend/logging-view/package.json b/frontend/logging-view/package.json index c84682d79..51ac0ca12 100644 --- a/frontend/logging-view/package.json +++ b/frontend/logging-view/package.json @@ -17,8 +17,7 @@ "@tanstack/react-virtual": "^3.13.18", "@types/plotly.js": "^3.0.10", "@vitejs/plugin-react-swc": "^4.2.3", - "@workspace/core": "workspace:*", - "@workspace/ui": "workspace:*", + "@hyperloop-upv/frontend-kit": "workspace:*", "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.8", "lucide-react": "^0.563.0", @@ -32,8 +31,8 @@ "devDependencies": { "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", - "@workspace/eslint-config": "workspace:^", - "@workspace/typescript-config": "workspace:*", + "@hyperloop-upv/eslint-config": "workspace:^", + "@hyperloop-upv/typescript-config": "workspace:*", "eslint": "^9.39.2", "globals": "^17.3.0", "typescript": "^5.9.3", diff --git a/frontend/logging-view/src/components/KeyboardShortcutsHelp.tsx b/frontend/logging-view/src/components/KeyboardShortcutsHelp.tsx index 97377d448..75190b2b8 100644 --- a/frontend/logging-view/src/components/KeyboardShortcutsHelp.tsx +++ b/frontend/logging-view/src/components/KeyboardShortcutsHelp.tsx @@ -4,8 +4,8 @@ import { DialogHeader, DialogTitle, Separator, -} from "@workspace/ui/components"; -import { Keyboard } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { Keyboard } from "@hyperloop-upv/frontend-kit/icons"; // NOTE: the original hooks module was not available at this path in some // environments. Define a local fallback for SHORTCUT_DEFS here so this // component compiles and still shows useful keyboard shortcuts. Keep the diff --git a/frontend/logging-view/src/components/PlotAddedToast.tsx b/frontend/logging-view/src/components/PlotAddedToast.tsx index 807de4ef6..3b8a91040 100644 --- a/frontend/logging-view/src/components/PlotAddedToast.tsx +++ b/frontend/logging-view/src/components/PlotAddedToast.tsx @@ -2,8 +2,8 @@ // (issue: adding a plot gave no on-screen feedback). Mirrors SessionStatusToast's // auto-dismiss + manual-dismiss pattern, but anchored bottom-right so it never // overlaps that top-right session toast. -import { CheckCircle2, X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { CheckCircle2, X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useEffect } from "react"; import { useStore } from "../store/store"; import { sessionStatusStyles } from "./sidebar/sessionStatusStyles"; diff --git a/frontend/logging-view/src/components/SessionStatusToast.tsx b/frontend/logging-view/src/components/SessionStatusToast.tsx index 529c4e396..2b09c66a0 100644 --- a/frontend/logging-view/src/components/SessionStatusToast.tsx +++ b/frontend/logging-view/src/components/SessionStatusToast.tsx @@ -4,8 +4,8 @@ // + manual-dismiss pattern used by the signalLoadWarning banner in PlotStudio.tsx. // Bottom-right, same corner as PlotAddedToast, so every transient notification // in the app reads as one consistent toast stack. -import { AlertTriangle, X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { AlertTriangle, X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useEffect } from "react"; import { useStore } from "../store/store"; import { adjWarningClass, sessionStatusStyles } from "./sidebar/sessionStatusStyles"; diff --git a/frontend/logging-view/src/components/header/Header.tsx b/frontend/logging-view/src/components/header/Header.tsx index c2a35adfb..292893b75 100644 --- a/frontend/logging-view/src/components/header/Header.tsx +++ b/frontend/logging-view/src/components/header/Header.tsx @@ -1,9 +1,9 @@ // Top bar with the page title and a Normal / Simple mode segmented control. // Mode switching navigates between routes (/normal, /simple) rather than // store state, since each mode has a distinct UI. -import { SegmentedControl } from "@workspace/ui/components"; +import { SegmentedControl } from "@hyperloop-upv/frontend-kit/components"; import { useLocation, useNavigate } from "react-router"; -import logo from "@workspace/ui/outreach/h11/h11-isotipo_black.svg"; +import logo from "@hyperloop-upv/frontend-kit/outreach/h11/h11-isotipo_black.svg"; type ViewMode = "normal" | "simple"; diff --git a/frontend/logging-view/src/components/sidebar/AppSidebar.tsx b/frontend/logging-view/src/components/sidebar/AppSidebar.tsx index 7d2f61a26..9b736e31b 100644 --- a/frontend/logging-view/src/components/sidebar/AppSidebar.tsx +++ b/frontend/logging-view/src/components/sidebar/AppSidebar.tsx @@ -8,7 +8,7 @@ import { SidebarFooter, SidebarHeader, SidebarSeparator, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import FolderPickerGroup from "./FolderPickerGroup"; import SeriesGroup from "./SeriesGroup"; import SeriesSelectionBar from "./SeriesSelectionBar"; diff --git a/frontend/logging-view/src/components/sidebar/FolderPickerGroup.tsx b/frontend/logging-view/src/components/sidebar/FolderPickerGroup.tsx index 12ad990e6..216b1e9fa 100644 --- a/frontend/logging-view/src/components/sidebar/FolderPickerGroup.tsx +++ b/frontend/logging-view/src/components/sidebar/FolderPickerGroup.tsx @@ -9,7 +9,7 @@ import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { AlertTriangle, BookOpen, @@ -18,8 +18,8 @@ import { GitCommit, Timer, X, -} from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useCallback, useRef, useState } from "react"; import { useStore } from "../../store/store"; import type { DroppedFile } from "../../types/session"; diff --git a/frontend/logging-view/src/components/sidebar/Logo.tsx b/frontend/logging-view/src/components/sidebar/Logo.tsx index ebbf05718..f8d5e8a93 100644 --- a/frontend/logging-view/src/components/sidebar/Logo.tsx +++ b/frontend/logging-view/src/components/sidebar/Logo.tsx @@ -1,6 +1,6 @@ -import { SidebarMenuButton } from "@workspace/ui/components"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit/components"; import { Link } from "react-router"; -import logo from "@workspace/ui/outreach/h11/h11-isotipo_black.svg"; +import logo from "@hyperloop-upv/frontend-kit/outreach/h11/h11-isotipo_black.svg"; const Logo = () => ( diff --git a/frontend/logging-view/src/components/sidebar/NavigationGroup.tsx b/frontend/logging-view/src/components/sidebar/NavigationGroup.tsx index 41da64c38..09380d3c4 100644 --- a/frontend/logging-view/src/components/sidebar/NavigationGroup.tsx +++ b/frontend/logging-view/src/components/sidebar/NavigationGroup.tsx @@ -4,8 +4,8 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, -} from "@workspace/ui/components"; -import { type LucideIcon } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { type LucideIcon } from "@hyperloop-upv/frontend-kit/icons"; import { Link, useLocation } from "react-router"; interface NavItem { diff --git a/frontend/logging-view/src/components/sidebar/SeriesGroup.tsx b/frontend/logging-view/src/components/sidebar/SeriesGroup.tsx index 5f688e210..898370360 100644 --- a/frontend/logging-view/src/components/sidebar/SeriesGroup.tsx +++ b/frontend/logging-view/src/components/sidebar/SeriesGroup.tsx @@ -43,9 +43,9 @@ import { SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, -} from "@workspace/ui/components"; -import { ChevronRight, GripVertical, Layers, Plus } from "@workspace/ui/icons"; -import { cn, getTypeBadgeClass } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit/components"; +import { ChevronRight, GripVertical, Layers, Plus } from "@hyperloop-upv/frontend-kit/icons"; +import { cn, getTypeBadgeClass } from "@hyperloop-upv/frontend-kit/lib"; import { useMemo, useRef, useState } from "react"; import { useAssignSignalsToPlot } from "../simple/hooks/useStudioSignals"; import type { PlotState } from "../../types/plotStudio"; diff --git a/frontend/logging-view/src/components/sidebar/SeriesSelectionBar.tsx b/frontend/logging-view/src/components/sidebar/SeriesSelectionBar.tsx index e8929a806..3847ee414 100644 --- a/frontend/logging-view/src/components/sidebar/SeriesSelectionBar.tsx +++ b/frontend/logging-view/src/components/sidebar/SeriesSelectionBar.tsx @@ -2,8 +2,8 @@ // checked, letting the user add them all to an existing plot or spin up a // new plot containing them — turns the (previously decorative) checkbox // selection into a real bulk-assign action. -import { Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@workspace/ui/components"; -import { Layers, Plus, X } from "@workspace/ui/icons"; +import { Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@hyperloop-upv/frontend-kit/components"; +import { Layers, Plus, X } from "@hyperloop-upv/frontend-kit/icons"; import { useMemo, useState } from "react"; import { useAssignSignalsToPlot } from "../simple/hooks/useStudioSignals"; import { useStore } from "../../store/store"; diff --git a/frontend/logging-view/src/components/sidebar/SessionStatusBadge.tsx b/frontend/logging-view/src/components/sidebar/SessionStatusBadge.tsx index 54123631c..0a63c0600 100644 --- a/frontend/logging-view/src/components/sidebar/SessionStatusBadge.tsx +++ b/frontend/logging-view/src/components/sidebar/SessionStatusBadge.tsx @@ -1,9 +1,9 @@ // Persistent green/yellow/red status pill shown in the sidebar for the currently // open session (logger settings / CSV / ADJ availability). See SessionStatus in // types/session.ts for the cascade this reflects. -import { Badge } from "@workspace/ui/components"; -import { AlertTriangle } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Badge } from "@hyperloop-upv/frontend-kit/components"; +import { AlertTriangle } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import type { SessionStatus } from "../../types/session"; import { adjWarningClass, sessionStatusStyles } from "./sessionStatusStyles"; diff --git a/frontend/logging-view/src/components/sidebar/SidebarToggleHandle.tsx b/frontend/logging-view/src/components/sidebar/SidebarToggleHandle.tsx index 485a2ac13..8248dc54a 100644 --- a/frontend/logging-view/src/components/sidebar/SidebarToggleHandle.tsx +++ b/frontend/logging-view/src/components/sidebar/SidebarToggleHandle.tsx @@ -1,7 +1,7 @@ // Sidebar toggle handle — click to open/close the sidebar. -import { useSidebar } from "@workspace/ui/components"; -import { ChevronLeft, ChevronRight } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { useSidebar } from "@hyperloop-upv/frontend-kit/components"; +import { ChevronLeft, ChevronRight } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; const SidebarToggleHandle = () => { diff --git a/frontend/logging-view/src/components/sidebar/ThemeToggleItem.tsx b/frontend/logging-view/src/components/sidebar/ThemeToggleItem.tsx index 79867f748..c8e228801 100644 --- a/frontend/logging-view/src/components/sidebar/ThemeToggleItem.tsx +++ b/frontend/logging-view/src/components/sidebar/ThemeToggleItem.tsx @@ -1,5 +1,5 @@ -import { SidebarMenuButton } from "@workspace/ui/components"; -import { SunMoon } from "@workspace/ui/icons"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit/components"; +import { SunMoon } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../store/store"; const ThemeToggleItem = () => { diff --git a/frontend/logging-view/src/components/sidebar/sessionStatusStyles.ts b/frontend/logging-view/src/components/sidebar/sessionStatusStyles.ts index 373849805..18dc22675 100644 --- a/frontend/logging-view/src/components/sidebar/sessionStatusStyles.ts +++ b/frontend/logging-view/src/components/sidebar/sessionStatusStyles.ts @@ -1,6 +1,6 @@ // Shared green/yellow/red styling for SessionStatus, used by both the persistent // sidebar badge and the transient toast so the two stay visually consistent. -import { AlertTriangle, CheckCircle2, XCircle } from "@workspace/ui/icons"; +import { AlertTriangle, CheckCircle2, XCircle } from "@hyperloop-upv/frontend-kit/icons"; import type { SessionStatusLevel } from "../../types/session"; export const sessionStatusStyles: Record< diff --git a/frontend/logging-view/src/components/simple/PlotStudio.tsx b/frontend/logging-view/src/components/simple/PlotStudio.tsx index 65007b33c..b49e938e3 100644 --- a/frontend/logging-view/src/components/simple/PlotStudio.tsx +++ b/frontend/logging-view/src/components/simple/PlotStudio.tsx @@ -2,9 +2,9 @@ // plots and composed series are managed in the right studio panel, laid out // VS Code-style: a fixed activity bar with one open section at a time, and // only the plots area scrolls. -import { Button, Separator } from "@workspace/ui/components"; -import { FileDown, PanelRight, Plus, X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Button, Separator } from "@hyperloop-upv/frontend-kit/components"; +import { FileDown, PanelRight, Plus, X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useEffect, useRef, useState } from "react"; import { useStore } from "../../store/store"; import PdfExportModal from "./modals/PdfExportModal"; diff --git a/frontend/logging-view/src/components/simple/SignalSelect.tsx b/frontend/logging-view/src/components/simple/SignalSelect.tsx index 7ca3d9eeb..0e1066be1 100644 --- a/frontend/logging-view/src/components/simple/SignalSelect.tsx +++ b/frontend/logging-view/src/components/simple/SignalSelect.tsx @@ -2,9 +2,9 @@ // "Composed" entry for operations/transforms); choosing a board drills into // its series with a filter box and a back button. Built on Popover because // Radix Select cannot nest levels. -import { Input, Popover, PopoverContent, PopoverTrigger } from "@workspace/ui/components"; -import { Check, ChevronDown, ChevronLeft, ChevronRight, Search } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Input, Popover, PopoverContent, PopoverTrigger } from "@hyperloop-upv/frontend-kit/components"; +import { Check, ChevronDown, ChevronLeft, ChevronRight, Search } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; import { useAvailableSignals, type AvailableSignal } from "./hooks/useStudioSignals"; diff --git a/frontend/logging-view/src/components/simple/StatsPanel.tsx b/frontend/logging-view/src/components/simple/StatsPanel.tsx index 822e68d39..e749095ca 100644 --- a/frontend/logging-view/src/components/simple/StatsPanel.tsx +++ b/frontend/logging-view/src/components/simple/StatsPanel.tsx @@ -1,9 +1,9 @@ // Statistics panel shown under a plot. Metrics are computed over the visible // X range only (live — the parent tracks the current Plotly viewport, // debounced, and passes it down as `visibleRange`). -import { Button, Separator } from "@workspace/ui/components"; -import { X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Button, Separator } from "@hyperloop-upv/frontend-kit/components"; +import { X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useMemo } from "react"; import { fmt } from "../../lib/plotStudio/format"; import { computeRangeStats } from "../../lib/plotStudio/stats"; diff --git a/frontend/logging-view/src/components/simple/modals/OperationModal.tsx b/frontend/logging-view/src/components/simple/modals/OperationModal.tsx index daab005c9..7626158bc 100644 --- a/frontend/logging-view/src/components/simple/modals/OperationModal.tsx +++ b/frontend/logging-view/src/components/simple/modals/OperationModal.tsx @@ -8,8 +8,8 @@ import { DialogTitle, Input, Label, -} from "@workspace/ui/components"; -import { cn } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit/components"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; import { performOperation } from "../../../lib/plotStudio/operations"; import { useStore } from "../../../store/store"; diff --git a/frontend/logging-view/src/components/simple/modals/PdfExportModal.tsx b/frontend/logging-view/src/components/simple/modals/PdfExportModal.tsx index ddf87d728..53c52d25a 100644 --- a/frontend/logging-view/src/components/simple/modals/PdfExportModal.tsx +++ b/frontend/logging-view/src/components/simple/modals/PdfExportModal.tsx @@ -15,7 +15,7 @@ import { Label, SegmentedControl, Spinner, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { useState } from "react"; import type { PdfExportOptions, PdfExportResult } from "../../../lib/pdfExport/types"; diff --git a/frontend/logging-view/src/components/simple/modals/TransformModal.tsx b/frontend/logging-view/src/components/simple/modals/TransformModal.tsx index a0f89d246..eb1049e9a 100644 --- a/frontend/logging-view/src/components/simple/modals/TransformModal.tsx +++ b/frontend/logging-view/src/components/simple/modals/TransformModal.tsx @@ -8,7 +8,7 @@ import { DialogTitle, Input, Label, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { useState } from "react"; import { applyTransform } from "../../../lib/plotStudio/transforms"; import { useStore } from "../../../store/store"; diff --git a/frontend/logging-view/src/components/simple/plots/PlotWrapper.tsx b/frontend/logging-view/src/components/simple/plots/PlotWrapper.tsx index 303bf9a63..a42471c9b 100644 --- a/frontend/logging-view/src/components/simple/plots/PlotWrapper.tsx +++ b/frontend/logging-view/src/components/simple/plots/PlotWrapper.tsx @@ -16,7 +16,7 @@ import { Tooltip, TooltipContent, TooltipTrigger, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { Activity, AlertTriangle, @@ -26,9 +26,9 @@ import { RefreshCw, Trash2, Unlock, -} from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; -import logoIcon from "@workspace/ui/outreach/main/logo_icon.svg?inline"; +} from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; +import logoIcon from "@hyperloop-upv/frontend-kit/outreach/main/logo_icon.svg?inline"; import Plotly from "plotly.js-dist"; import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; import { useShallow } from "zustand/react/shallow"; diff --git a/frontend/logging-view/src/components/simple/sidebar/ComposedSection.tsx b/frontend/logging-view/src/components/simple/sidebar/ComposedSection.tsx index 389578cb0..470d77433 100644 --- a/frontend/logging-view/src/components/simple/sidebar/ComposedSection.tsx +++ b/frontend/logging-view/src/components/simple/sidebar/ComposedSection.tsx @@ -1,7 +1,7 @@ // Composed Series: signals derived from session data — math operations // (A ∘ B) and expression transforms f(x) — managed in a single panel. -import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@workspace/ui/components"; -import { Trash2 } from "@workspace/ui/icons"; +import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@hyperloop-upv/frontend-kit/components"; +import { Trash2 } from "@hyperloop-upv/frontend-kit/icons"; import { useState } from "react"; import { useStore } from "../../../store/store"; import OperationModal from "../modals/OperationModal"; diff --git a/frontend/logging-view/src/components/simple/sidebar/FFTSection.tsx b/frontend/logging-view/src/components/simple/sidebar/FFTSection.tsx index 63bb0b2f5..80ca50ac2 100644 --- a/frontend/logging-view/src/components/simple/sidebar/FFTSection.tsx +++ b/frontend/logging-view/src/components/simple/sidebar/FFTSection.tsx @@ -1,7 +1,7 @@ // FFT sample-rate control. Shows the rate auto-detected from the loaded data // (median Δt of the first signal) and lets the user override it manually. -import { Button, Input, Label } from "@workspace/ui/components"; -import { RefreshCw, Timer } from "@workspace/ui/icons"; +import { Button, Input, Label } from "@hyperloop-upv/frontend-kit/components"; +import { RefreshCw, Timer } from "@hyperloop-upv/frontend-kit/icons"; import { useMemo, useState } from "react"; import { useStore } from "../../../store/store"; diff --git a/frontend/logging-view/src/components/simple/sidebar/PlotsSection.tsx b/frontend/logging-view/src/components/simple/sidebar/PlotsSection.tsx index 3a18631e2..38542f1b7 100644 --- a/frontend/logging-view/src/components/simple/sidebar/PlotsSection.tsx +++ b/frontend/logging-view/src/components/simple/sidebar/PlotsSection.tsx @@ -21,9 +21,9 @@ import { Tooltip, TooltipContent, TooltipTrigger, -} from "@workspace/ui/components"; -import { Activity, Eye, EyeOff, GripVertical, Plus, Trash2, X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit/components"; +import { Activity, Eye, EyeOff, GripVertical, Plus, Trash2, X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; import { useShallow } from "zustand/react/shallow"; import { resolveSignalColor } from "../../../lib/plotStudio/palette"; diff --git a/frontend/logging-view/src/components/simple/sidebar/StudioSidebar.tsx b/frontend/logging-view/src/components/simple/sidebar/StudioSidebar.tsx index 5055aaacd..52047cdff 100644 --- a/frontend/logging-view/src/components/simple/sidebar/StudioSidebar.tsx +++ b/frontend/logging-view/src/components/simple/sidebar/StudioSidebar.tsx @@ -1,8 +1,8 @@ // VS Code-style studio panel: a persistent activity bar (icon strip) on the // right edge; clicking an icon opens that section in a panel next to it, // clicking the active icon again closes the panel. -import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@workspace/ui/components"; -import { cn } from "@workspace/ui/lib"; +import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@hyperloop-upv/frontend-kit/components"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { STUDIO_SECTIONS } from "./studioSections"; interface StudioSidebarProps { diff --git a/frontend/logging-view/src/components/simple/sidebar/studioSections.ts b/frontend/logging-view/src/components/simple/sidebar/studioSections.ts index d683f0247..d70c99b3f 100644 --- a/frontend/logging-view/src/components/simple/sidebar/studioSections.ts +++ b/frontend/logging-view/src/components/simple/sidebar/studioSections.ts @@ -1,7 +1,7 @@ // Registry of the studio panel sections, VS Code-style: the activity bar // shows one icon per section and the panel displays a single section at a time. -import { Activity, Layers, Timer } from "@workspace/ui/icons"; -import type { LucideIcon } from "@workspace/ui/icons"; +import { Activity, Layers, Timer } from "@hyperloop-upv/frontend-kit/icons"; +import type { LucideIcon } from "@hyperloop-upv/frontend-kit/icons"; import ComposedSection from "./ComposedSection"; import FFTSection from "./FFTSection"; import PlotsSection from "./PlotsSection"; diff --git a/frontend/logging-view/src/index.css b/frontend/logging-view/src/index.css index aba9402f3..14a5cfb86 100644 --- a/frontend/logging-view/src/index.css +++ b/frontend/logging-view/src/index.css @@ -1,7 +1,7 @@ -@import "@workspace/ui/globals.css"; +@import "@hyperloop-upv/frontend-kit/globals.css"; /* Ensure Tailwind v4 scans competition-view source files directly. - The @source paths in globals.css resolve via the @workspace/ui symlink + The @source paths in globals.css resolve via the @hyperloop-upv/frontend-kit symlink and don't correctly reach this project's source tree. */ @source "./**/*.{ts,tsx}"; diff --git a/frontend/logging-view/src/layout/AppLayout.tsx b/frontend/logging-view/src/layout/AppLayout.tsx index 32c29ccb7..865fc79d8 100644 --- a/frontend/logging-view/src/layout/AppLayout.tsx +++ b/frontend/logging-view/src/layout/AppLayout.tsx @@ -1,5 +1,5 @@ import { DndContext } from "@dnd-kit/core"; -import { SidebarInset, SidebarProvider } from "@workspace/ui/components"; +import { SidebarInset, SidebarProvider } from "@hyperloop-upv/frontend-kit/components"; import { useEffect, type ReactNode } from "react"; import Header from "../components/header/Header"; import PlotAddedToast from "../components/PlotAddedToast"; diff --git a/frontend/logging-view/src/lib/pdfExport/assets.ts b/frontend/logging-view/src/lib/pdfExport/assets.ts index 845c3622e..77acc339c 100644 --- a/frontend/logging-view/src/lib/pdfExport/assets.ts +++ b/frontend/logging-view/src/lib/pdfExport/assets.ts @@ -1,7 +1,7 @@ // Branding assets + page geometry shared by every page builder in this module. -import fullLogo from "@workspace/ui/outreach/main/full_logo_black.png?inline"; -import swLogo from "@workspace/ui/outreach/main/software_black.png?inline"; -import checkLogo from "@workspace/ui/outreach/main/check_black.png?inline"; +import fullLogo from "@hyperloop-upv/frontend-kit/outreach/main/full_logo_black.png?inline"; +import swLogo from "@hyperloop-upv/frontend-kit/outreach/main/software_black.png?inline"; +import checkLogo from "@hyperloop-upv/frontend-kit/outreach/main/check_black.png?inline"; export const PDF_ASSETS = { fullLogo, diff --git a/frontend/logging-view/src/pages/NormalPage.tsx b/frontend/logging-view/src/pages/NormalPage.tsx index 983c9c877..d0f21e0d8 100644 --- a/frontend/logging-view/src/pages/NormalPage.tsx +++ b/frontend/logging-view/src/pages/NormalPage.tsx @@ -1,7 +1,7 @@ // Normal mode: full-featured log analysis view. // Placeholder — UI to be implemented. -import swLogoBlack from "@workspace/ui/outreach/main/software_black.png?inline"; -import swLogoWhite from "@workspace/ui/outreach/main/software_white.png?inline"; +import swLogoBlack from "@hyperloop-upv/frontend-kit/outreach/main/software_black.png?inline"; +import swLogoWhite from "@hyperloop-upv/frontend-kit/outreach/main/software_white.png?inline"; import { useStore } from "../store/store"; const NormalPage = () => { diff --git a/frontend/logging-view/tsconfig.json b/frontend/logging-view/tsconfig.json index a351dd46e..1d8aa51b5 100644 --- a/frontend/logging-view/tsconfig.json +++ b/frontend/logging-view/tsconfig.json @@ -7,8 +7,7 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": ["./*"], - "@workspace/ui/*": ["../frontend-kit/ui/src/*"] + "@/*": ["./*"] } }, "exclude": ["node_modules"] diff --git a/frontend/testing-view/eslint.config.js b/frontend/testing-view/eslint.config.js index df360b435..a2b580035 100644 --- a/frontend/testing-view/eslint.config.js +++ b/frontend/testing-view/eslint.config.js @@ -1,3 +1,3 @@ -import { config } from "@workspace/eslint-config/vite"; +import { config } from "@hyperloop-upv/eslint-config/vite"; export default config; diff --git a/frontend/testing-view/package.json b/frontend/testing-view/package.json index abaeca8a3..f6aaa504b 100644 --- a/frontend/testing-view/package.json +++ b/frontend/testing-view/package.json @@ -24,8 +24,7 @@ "@tanstack/react-virtual": "^3.13.18", "@types/lodash": "^4.17.23", "@vitejs/plugin-react-swc": "^4.2.3", - "@workspace/core": "workspace:*", - "@workspace/ui": "workspace:*", + "@hyperloop-upv/frontend-kit": "workspace:*", "lodash": "^4.17.23", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -39,8 +38,8 @@ "devDependencies": { "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", - "@workspace/eslint-config": "workspace:^", - "@workspace/typescript-config": "workspace:*", + "@hyperloop-upv/eslint-config": "workspace:^", + "@hyperloop-upv/typescript-config": "workspace:*", "eslint": "^9.39.2", "globals": "^17.3.0", "typescript": "^5.9.3", diff --git a/frontend/testing-view/src/App.tsx b/frontend/testing-view/src/App.tsx index 506f86ed4..68a459c72 100644 --- a/frontend/testing-view/src/App.tsx +++ b/frontend/testing-view/src/App.tsx @@ -1,4 +1,4 @@ -import { useTopic, useWebSocket } from "@workspace/ui/hooks"; +import { useTopic, useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; import { Route, Routes } from "react-router"; import { AppModeRouter } from "./components/AppModeRouter"; import { ModeSwitcher } from "./components/devTools/ModeSwitcher"; diff --git a/frontend/testing-view/src/components/Error.tsx b/frontend/testing-view/src/components/Error.tsx index bb800471d..06f63411d 100644 --- a/frontend/testing-view/src/components/Error.tsx +++ b/frontend/testing-view/src/components/Error.tsx @@ -1,5 +1,5 @@ -import { Button } from "@workspace/ui"; -import { RefreshCw, Terminal } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { RefreshCw, Terminal } from "@hyperloop-upv/frontend-kit/icons"; import { useEffect, useState } from "react"; import errorGif from "../assets/error.gif"; import { useStore } from "../store/store"; diff --git a/frontend/testing-view/src/components/ErrorBoundary.tsx b/frontend/testing-view/src/components/ErrorBoundary.tsx index a69c23611..7d40fc906 100644 --- a/frontend/testing-view/src/components/ErrorBoundary.tsx +++ b/frontend/testing-view/src/components/ErrorBoundary.tsx @@ -1,4 +1,4 @@ -import { logger } from "@workspace/core"; +import { logger } from "@hyperloop-upv/frontend-kit/core"; import React, { Component, type ReactNode } from "react"; import { Error } from "./Error"; diff --git a/frontend/testing-view/src/components/devTools/ModeSwitcher.tsx b/frontend/testing-view/src/components/devTools/ModeSwitcher.tsx index c25c69428..67134b9ea 100644 --- a/frontend/testing-view/src/components/devTools/ModeSwitcher.tsx +++ b/frontend/testing-view/src/components/devTools/ModeSwitcher.tsx @@ -1,4 +1,4 @@ -import { Button } from "@workspace/ui"; +import { Button } from "@hyperloop-upv/frontend-kit"; import { useStore } from "../../store/store"; import type { AppMode } from "../../types/app/mode"; diff --git a/frontend/testing-view/src/components/header/Header.tsx b/frontend/testing-view/src/components/header/Header.tsx index 1f6b977c2..38b77814a 100644 --- a/frontend/testing-view/src/components/header/Header.tsx +++ b/frontend/testing-view/src/components/header/Header.tsx @@ -1,4 +1,4 @@ -import { Separator, SidebarTrigger } from "@workspace/ui"; +import { Separator, SidebarTrigger } from "@hyperloop-upv/frontend-kit"; import { useLocation } from "react-router"; import { PAGES } from "../../constants/pages"; import { KeyBindingsButton } from "../../features/keyBindings/components/KeyBindingsButton"; diff --git a/frontend/testing-view/src/components/header/ModeBadge.tsx b/frontend/testing-view/src/components/header/ModeBadge.tsx index d4ec401b3..fc8a13f47 100644 --- a/frontend/testing-view/src/components/header/ModeBadge.tsx +++ b/frontend/testing-view/src/components/header/ModeBadge.tsx @@ -1,4 +1,4 @@ -import { cn } from "@workspace/ui/lib"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useStore } from "../../store/store"; import type { AppMode } from "../../types/app/mode"; diff --git a/frontend/testing-view/src/components/header/ReconnectButton.tsx b/frontend/testing-view/src/components/header/ReconnectButton.tsx index e783d768b..608591fec 100644 --- a/frontend/testing-view/src/components/header/ReconnectButton.tsx +++ b/frontend/testing-view/src/components/header/ReconnectButton.tsx @@ -1,6 +1,6 @@ -import { Button } from "@workspace/ui"; -import { useWebSocket } from "@workspace/ui/hooks"; -import { RefreshCw } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { useWebSocket } from "@hyperloop-upv/frontend-kit/hooks"; +import { RefreshCw } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../store/store"; export const ReconnectButton = () => { diff --git a/frontend/testing-view/src/components/leftSidebar/AppSidebar.tsx b/frontend/testing-view/src/components/leftSidebar/AppSidebar.tsx index 35940ea2e..4207f3f9b 100644 --- a/frontend/testing-view/src/components/leftSidebar/AppSidebar.tsx +++ b/frontend/testing-view/src/components/leftSidebar/AppSidebar.tsx @@ -4,7 +4,7 @@ import { SidebarFooter, SidebarHeader, SidebarRail, -} from "@workspace/ui/components"; +} from "@hyperloop-upv/frontend-kit/components"; import { PAGES_ARRAY } from "../../constants/pages"; import ColorSchemeToggle from "./ColorSchemeToggle"; import ConnectionStatusGroup from "./ConnectionStatusGroup"; diff --git a/frontend/testing-view/src/components/leftSidebar/ColorSchemeToggle.tsx b/frontend/testing-view/src/components/leftSidebar/ColorSchemeToggle.tsx index 75dbacd84..888245317 100644 --- a/frontend/testing-view/src/components/leftSidebar/ColorSchemeToggle.tsx +++ b/frontend/testing-view/src/components/leftSidebar/ColorSchemeToggle.tsx @@ -1,5 +1,5 @@ -import { SidebarMenuButton } from "@workspace/ui"; -import { Palette } from "@workspace/ui/icons"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit"; +import { Palette } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../store/store"; import { colorSchemes } from "../../types/app/colorSchema"; diff --git a/frontend/testing-view/src/components/leftSidebar/ConnectionStatusGroup.tsx b/frontend/testing-view/src/components/leftSidebar/ConnectionStatusGroup.tsx index eb82bbb38..da90e1f2a 100644 --- a/frontend/testing-view/src/components/leftSidebar/ConnectionStatusGroup.tsx +++ b/frontend/testing-view/src/components/leftSidebar/ConnectionStatusGroup.tsx @@ -4,8 +4,8 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, -} from "@workspace/ui"; -import { Plug, Unplug } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { Plug, Unplug } from "@hyperloop-upv/frontend-kit/icons"; import useConnections from "../../hooks/useConnections"; interface ConnectionStatusGroupProps { diff --git a/frontend/testing-view/src/components/leftSidebar/DevToolsItem.tsx b/frontend/testing-view/src/components/leftSidebar/DevToolsItem.tsx index 95e2dff3d..915df8ee0 100644 --- a/frontend/testing-view/src/components/leftSidebar/DevToolsItem.tsx +++ b/frontend/testing-view/src/components/leftSidebar/DevToolsItem.tsx @@ -2,8 +2,8 @@ import { SidebarGroup, SidebarGroupLabel, SidebarMenuButton, -} from "@workspace/ui"; -import { Eye, EyeOff } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { Eye, EyeOff } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../store/store"; const DevToolsItem = () => { diff --git a/frontend/testing-view/src/components/leftSidebar/Logo.tsx b/frontend/testing-view/src/components/leftSidebar/Logo.tsx index 5fc0c9855..2ca72ac37 100644 --- a/frontend/testing-view/src/components/leftSidebar/Logo.tsx +++ b/frontend/testing-view/src/components/leftSidebar/Logo.tsx @@ -1,6 +1,6 @@ -import { SidebarMenuButton } from "@workspace/ui"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit"; import { Link } from "react-router"; -import logo from "@workspace/ui/outreach/h11/h11-isotipo_black.svg"; +import logo from "@hyperloop-upv/frontend-kit/outreach/h11/h11-isotipo_black.svg"; const Logo = () => { return ( diff --git a/frontend/testing-view/src/components/leftSidebar/NavigationGroup.tsx b/frontend/testing-view/src/components/leftSidebar/NavigationGroup.tsx index 079c17583..5d73d7da4 100644 --- a/frontend/testing-view/src/components/leftSidebar/NavigationGroup.tsx +++ b/frontend/testing-view/src/components/leftSidebar/NavigationGroup.tsx @@ -4,8 +4,8 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, -} from "@workspace/ui/components"; -import { type LucideIcon } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { type LucideIcon } from "@hyperloop-upv/frontend-kit/icons"; import { Link } from "react-router"; interface NavigationGroupProps { diff --git a/frontend/testing-view/src/components/leftSidebar/SettingsItem.tsx b/frontend/testing-view/src/components/leftSidebar/SettingsItem.tsx index a0d4e9e60..4dc35c249 100644 --- a/frontend/testing-view/src/components/leftSidebar/SettingsItem.tsx +++ b/frontend/testing-view/src/components/leftSidebar/SettingsItem.tsx @@ -1,5 +1,5 @@ -import { SidebarMenuButton } from "@workspace/ui"; -import { Settings } from "@workspace/ui/icons"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit"; +import { Settings } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../store/store"; const SettingsItem = () => { diff --git a/frontend/testing-view/src/components/leftSidebar/ThemeToggleItem.tsx b/frontend/testing-view/src/components/leftSidebar/ThemeToggleItem.tsx index ee88db6fa..ca8ddf746 100644 --- a/frontend/testing-view/src/components/leftSidebar/ThemeToggleItem.tsx +++ b/frontend/testing-view/src/components/leftSidebar/ThemeToggleItem.tsx @@ -1,5 +1,5 @@ -import { SidebarMenuButton } from "@workspace/ui"; -import { SunMoon } from "@workspace/ui/icons"; +import { SidebarMenuButton } from "@hyperloop-upv/frontend-kit"; +import { SunMoon } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../store/store"; const ThemeToggleItem = () => { diff --git a/frontend/testing-view/src/components/settings/BooleanField.tsx b/frontend/testing-view/src/components/settings/BooleanField.tsx index be4b6594a..b66804756 100644 --- a/frontend/testing-view/src/components/settings/BooleanField.tsx +++ b/frontend/testing-view/src/components/settings/BooleanField.tsx @@ -1,5 +1,5 @@ -import { Checkbox } from "@workspace/ui/components/shadcn/checkbox"; -import { Label } from "@workspace/ui/components/shadcn/label"; +import { Checkbox } from "@hyperloop-upv/frontend-kit/components/shadcn/checkbox"; +import { Label } from "@hyperloop-upv/frontend-kit/components/shadcn/label"; import type { FieldProps } from "../../types/common/settings"; export const BooleanField = ({ diff --git a/frontend/testing-view/src/components/settings/ComboboxField.tsx b/frontend/testing-view/src/components/settings/ComboboxField.tsx index 8c14abf1f..b73149a2a 100644 --- a/frontend/testing-view/src/components/settings/ComboboxField.tsx +++ b/frontend/testing-view/src/components/settings/ComboboxField.tsx @@ -5,10 +5,10 @@ import { ComboboxInput, ComboboxItem, ComboboxList, -} from "@workspace/ui/components"; -import { Button } from "@workspace/ui/components/shadcn/button"; -import { Label } from "@workspace/ui/components/shadcn/label"; -import { RefreshCw } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/components"; +import { Button } from "@hyperloop-upv/frontend-kit/components/shadcn/button"; +import { Label } from "@hyperloop-upv/frontend-kit/components/shadcn/label"; +import { RefreshCw } from "@hyperloop-upv/frontend-kit/icons"; import { useEffect, useState } from "react"; import type { BranchesFetchState } from "../../hooks/useBranches"; import type { FieldProps } from "../../types/common/settings"; diff --git a/frontend/testing-view/src/components/settings/MultiCheckboxField.tsx b/frontend/testing-view/src/components/settings/MultiCheckboxField.tsx index 8ece18567..8e89254de 100644 --- a/frontend/testing-view/src/components/settings/MultiCheckboxField.tsx +++ b/frontend/testing-view/src/components/settings/MultiCheckboxField.tsx @@ -1,5 +1,5 @@ -import { Checkbox } from "@workspace/ui/components/shadcn/checkbox"; -import { Label } from "@workspace/ui/components/shadcn/label"; +import { Checkbox } from "@hyperloop-upv/frontend-kit/components/shadcn/checkbox"; +import { Label } from "@hyperloop-upv/frontend-kit/components/shadcn/label"; import type { FieldProps } from "../../types/common/settings"; export const MultiCheckboxField = ({ diff --git a/frontend/testing-view/src/components/settings/PathField.tsx b/frontend/testing-view/src/components/settings/PathField.tsx index 1f64c40c0..32f62b70f 100644 --- a/frontend/testing-view/src/components/settings/PathField.tsx +++ b/frontend/testing-view/src/components/settings/PathField.tsx @@ -1,6 +1,6 @@ -import { Button, Input, Label } from "@workspace/ui"; -import { FolderOpen } from "@workspace/ui/icons"; -import { logger } from "@workspace/core"; +import { Button, Input, Label } from "@hyperloop-upv/frontend-kit"; +import { FolderOpen } from "@hyperloop-upv/frontend-kit/icons"; +import { logger } from "@hyperloop-upv/frontend-kit/core"; import { useOpenFolder } from "../../hooks/useOpenFolder"; import type { FieldProps } from "../../types/common/settings"; diff --git a/frontend/testing-view/src/components/settings/SelectField.tsx b/frontend/testing-view/src/components/settings/SelectField.tsx index 798acf4f9..7b17e4f6e 100644 --- a/frontend/testing-view/src/components/settings/SelectField.tsx +++ b/frontend/testing-view/src/components/settings/SelectField.tsx @@ -1,11 +1,11 @@ -import { Label } from "@workspace/ui/components/shadcn/label"; +import { Label } from "@hyperloop-upv/frontend-kit/components/shadcn/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from "@workspace/ui/components/shadcn/select"; +} from "@hyperloop-upv/frontend-kit/components/shadcn/select"; import type { FieldProps } from "../../types/common/settings"; export const SelectField = ({ field, value, onChange }: FieldProps) => ( diff --git a/frontend/testing-view/src/components/settings/SettingsDialog.tsx b/frontend/testing-view/src/components/settings/SettingsDialog.tsx index 2ffda360c..5720450be 100644 --- a/frontend/testing-view/src/components/settings/SettingsDialog.tsx +++ b/frontend/testing-view/src/components/settings/SettingsDialog.tsx @@ -1,7 +1,7 @@ import { Dialog } from "@base-ui/react"; -import { socketService } from "@workspace/core"; -import { Badge, Button } from "@workspace/ui"; -import { AlertTriangle, CheckCircle2, Loader2, X } from "@workspace/ui/icons"; +import { socketService } from "@hyperloop-upv/frontend-kit/core"; +import { Badge, Button } from "@hyperloop-upv/frontend-kit"; +import { AlertTriangle, CheckCircle2, Loader2, X } from "@hyperloop-upv/frontend-kit/icons"; import { useEffect, useState, useTransition } from "react"; import { config } from "../../../config"; import { DEFAULT_CONFIG } from "../../constants/defaultConfig"; diff --git a/frontend/testing-view/src/components/settings/TextField.tsx b/frontend/testing-view/src/components/settings/TextField.tsx index 71969dfb6..d4e9c1ebe 100644 --- a/frontend/testing-view/src/components/settings/TextField.tsx +++ b/frontend/testing-view/src/components/settings/TextField.tsx @@ -1,5 +1,5 @@ -import { Input } from "@workspace/ui/components/shadcn/input"; -import { Label } from "@workspace/ui/components/shadcn/label"; +import { Input } from "@hyperloop-upv/frontend-kit/components/shadcn/input"; +import { Label } from "@hyperloop-upv/frontend-kit/components/shadcn/label"; import type { FieldProps } from "../../types/common/settings"; /** diff --git a/frontend/testing-view/src/constants/loggerControlConfig.tsx b/frontend/testing-view/src/constants/loggerControlConfig.tsx index 03127b9e4..021dbfaa7 100644 --- a/frontend/testing-view/src/constants/loggerControlConfig.tsx +++ b/frontend/testing-view/src/constants/loggerControlConfig.tsx @@ -1,4 +1,4 @@ -import { AlertCircle, Loader2, Play, Square } from "@workspace/ui/icons"; +import { AlertCircle, Loader2, Play, Square } from "@hyperloop-upv/frontend-kit/icons"; import type { LoggerStatus } from "../types/common/logger"; interface LoggerControlOption { diff --git a/frontend/testing-view/src/constants/pages.ts b/frontend/testing-view/src/constants/pages.ts index 82867a064..df368ffa7 100644 --- a/frontend/testing-view/src/constants/pages.ts +++ b/frontend/testing-view/src/constants/pages.ts @@ -1,4 +1,4 @@ -import { FlaskConical, ScrollText } from "@workspace/ui/icons"; +import { FlaskConical, ScrollText } from "@hyperloop-upv/frontend-kit/icons"; /** Pages of the application showed in the left sidebar. */ export const PAGES = { diff --git a/frontend/testing-view/src/features/charts/components/ChartLegend.tsx b/frontend/testing-view/src/features/charts/components/ChartLegend.tsx index 6872ff719..558986bf7 100644 --- a/frontend/testing-view/src/features/charts/components/ChartLegend.tsx +++ b/frontend/testing-view/src/features/charts/components/ChartLegend.tsx @@ -1,4 +1,4 @@ -import { Eye, EyeOff, X } from "@workspace/ui/icons"; +import { Eye, EyeOff, X } from "@hyperloop-upv/frontend-kit/icons"; import { COLORS } from "../constants/chartsColors"; import type { WorkspaceChartSeries } from "../types/charts"; import { ChartSettings } from "./ChartSettings"; diff --git a/frontend/testing-view/src/features/charts/components/ChartSettings.tsx b/frontend/testing-view/src/features/charts/components/ChartSettings.tsx index 8f7bd4871..dbd498c4a 100644 --- a/frontend/testing-view/src/features/charts/components/ChartSettings.tsx +++ b/frontend/testing-view/src/features/charts/components/ChartSettings.tsx @@ -4,8 +4,8 @@ import { Popover, PopoverContent, PopoverTrigger, -} from "@workspace/ui"; -import { Settings2 } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { Settings2 } from "@hyperloop-upv/frontend-kit/icons"; import { config } from "../../../../config"; import { useStore } from "../../../store/store"; diff --git a/frontend/testing-view/src/features/charts/components/ChartSurface.tsx b/frontend/testing-view/src/features/charts/components/ChartSurface.tsx index d2f0ee3b3..9e16d9f2d 100644 --- a/frontend/testing-view/src/features/charts/components/ChartSurface.tsx +++ b/frontend/testing-view/src/features/charts/components/ChartSurface.tsx @@ -1,7 +1,7 @@ -import type { TelemetryPacket } from "@workspace/core"; -import { Button } from "@workspace/ui"; -import { ChevronLeft, ChevronRight, X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import type { TelemetryPacket } from "@hyperloop-upv/frontend-kit/core"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { ChevronLeft, ChevronRight, X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { memo, useEffect, useRef, useState } from "react"; import uPlot from "uplot"; import { useShallow } from "zustand/shallow"; diff --git a/frontend/testing-view/src/features/charts/components/ChartsGrid.tsx b/frontend/testing-view/src/features/charts/components/ChartsGrid.tsx index 17c2b8deb..5fcf71fcd 100644 --- a/frontend/testing-view/src/features/charts/components/ChartsGrid.tsx +++ b/frontend/testing-view/src/features/charts/components/ChartsGrid.tsx @@ -1,5 +1,5 @@ import { SortableContext, rectSortingStrategy } from "@dnd-kit/sortable"; -import { cn } from "@workspace/ui/lib"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import type { WorkspaceChartConfig } from "../types/charts"; import { SortableChart } from "./SortableChart"; diff --git a/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx b/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx index 896300fa4..295bacf0f 100644 --- a/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx +++ b/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx @@ -1,7 +1,7 @@ import type { DraggableAttributes } from "@dnd-kit/core"; import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities"; -import { GripVertical, Trash2 } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib/utils"; +import { GripVertical, Trash2 } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib/utils"; import { useRef, useState } from "react"; import "uplot/dist/uPlot.min.css"; import { useStore } from "../../../store/store"; diff --git a/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx b/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx index 05f2a2467..c0e48a549 100644 --- a/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx +++ b/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx @@ -3,8 +3,8 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger, -} from "@workspace/ui"; -import { ChevronDown, ChevronLeft } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { ChevronDown, ChevronLeft } from "@hyperloop-upv/frontend-kit/icons"; import { useState } from "react"; import { useShallow } from "zustand/shallow"; import { useStore } from "../../../store/store"; diff --git a/frontend/testing-view/src/features/filtering/components/FilterDialog.tsx b/frontend/testing-view/src/features/filtering/components/FilterDialog.tsx index 150d4098c..a313ca1ad 100644 --- a/frontend/testing-view/src/features/filtering/components/FilterDialog.tsx +++ b/frontend/testing-view/src/features/filtering/components/FilterDialog.tsx @@ -5,8 +5,8 @@ import { DialogDescription, DialogHeader, DialogTitle, -} from "@workspace/ui"; -import { AlertTriangle } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { AlertTriangle } from "@hyperloop-upv/frontend-kit/icons"; import { type ComponentType } from "react"; import type { BoardName } from "../../../types/data/board"; diff --git a/frontend/testing-view/src/features/filtering/components/FilterItem.tsx b/frontend/testing-view/src/features/filtering/components/FilterItem.tsx index c5e4dac6e..be37da535 100644 --- a/frontend/testing-view/src/features/filtering/components/FilterItem.tsx +++ b/frontend/testing-view/src/features/filtering/components/FilterItem.tsx @@ -1,4 +1,4 @@ -import { Badge, Checkbox } from "@workspace/ui"; +import { Badge, Checkbox } from "@hyperloop-upv/frontend-kit"; import type { CatalogItem } from "../../../types/common/item"; interface FilterItemProps { diff --git a/frontend/testing-view/src/features/keyBindings/components/AddKeyBindingDialog.tsx b/frontend/testing-view/src/features/keyBindings/components/AddKeyBindingDialog.tsx index 5106f0795..939b892cf 100644 --- a/frontend/testing-view/src/features/keyBindings/components/AddKeyBindingDialog.tsx +++ b/frontend/testing-view/src/features/keyBindings/components/AddKeyBindingDialog.tsx @@ -14,8 +14,8 @@ import { SelectLabel, SelectTrigger, SelectValue, -} from "@workspace/ui"; -import { X } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { X } from "@hyperloop-upv/frontend-kit/icons"; import { useEffect, useRef, useState } from "react"; import { getDefaultParameterValues } from "../../../lib/commandUtils"; import { useStore } from "../../../store/store"; diff --git a/frontend/testing-view/src/features/keyBindings/components/KeyBindingCard.tsx b/frontend/testing-view/src/features/keyBindings/components/KeyBindingCard.tsx index 68d1e5596..8a7ba38ff 100644 --- a/frontend/testing-view/src/features/keyBindings/components/KeyBindingCard.tsx +++ b/frontend/testing-view/src/features/keyBindings/components/KeyBindingCard.tsx @@ -1,6 +1,6 @@ -import { Badge, Button } from "@workspace/ui"; -import { ChevronDown, X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Badge, Button } from "@hyperloop-upv/frontend-kit"; +import { ChevronDown, X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; import { useStore } from "../../../store/store"; import type { KeyBinding } from "../types/keyBinding"; diff --git a/frontend/testing-view/src/features/keyBindings/components/KeyBindingsButton.tsx b/frontend/testing-view/src/features/keyBindings/components/KeyBindingsButton.tsx index 8b1b9fe67..ee61dc575 100644 --- a/frontend/testing-view/src/features/keyBindings/components/KeyBindingsButton.tsx +++ b/frontend/testing-view/src/features/keyBindings/components/KeyBindingsButton.tsx @@ -1,5 +1,5 @@ -import { Button } from "@workspace/ui"; -import { Keyboard } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { Keyboard } from "@hyperloop-upv/frontend-kit/icons"; import { useState } from "react"; import { KeyBindingsDialog } from "./KeyBindingsDialog"; diff --git a/frontend/testing-view/src/features/keyBindings/components/KeyBindingsDialog.tsx b/frontend/testing-view/src/features/keyBindings/components/KeyBindingsDialog.tsx index 1ebf3c429..3678b3945 100644 --- a/frontend/testing-view/src/features/keyBindings/components/KeyBindingsDialog.tsx +++ b/frontend/testing-view/src/features/keyBindings/components/KeyBindingsDialog.tsx @@ -5,8 +5,8 @@ import { DialogDescription, DialogHeader, DialogTitle, -} from "@workspace/ui"; -import { Plus } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { Plus } from "@hyperloop-upv/frontend-kit/icons"; import { useState } from "react"; import { useShallow } from "zustand/shallow"; import { useStore } from "../../../store/store"; diff --git a/frontend/testing-view/src/features/keyBindings/components/OrphanedKeyBindingCard.tsx b/frontend/testing-view/src/features/keyBindings/components/OrphanedKeyBindingCard.tsx index 7afcbff84..c95a85cf5 100644 --- a/frontend/testing-view/src/features/keyBindings/components/OrphanedKeyBindingCard.tsx +++ b/frontend/testing-view/src/features/keyBindings/components/OrphanedKeyBindingCard.tsx @@ -1,5 +1,5 @@ -import { Badge, Button } from "@workspace/ui"; -import { AlertTriangle, X } from "@workspace/ui/icons"; +import { Badge, Button } from "@hyperloop-upv/frontend-kit"; +import { AlertTriangle, X } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../../store/store"; import type { KeyBinding } from "../types/keyBinding"; diff --git a/frontend/testing-view/src/features/keyBindings/hooks/useGlobalKeyBindings.ts b/frontend/testing-view/src/features/keyBindings/hooks/useGlobalKeyBindings.ts index bc53f6e72..c196fcc63 100644 --- a/frontend/testing-view/src/features/keyBindings/hooks/useGlobalKeyBindings.ts +++ b/frontend/testing-view/src/features/keyBindings/hooks/useGlobalKeyBindings.ts @@ -1,4 +1,4 @@ -import { logger, socketService } from "@workspace/core"; +import { logger, socketService } from "@hyperloop-upv/frontend-kit/core"; import { useEffect } from "react"; import { useLogger } from "../../../hooks/useLogger"; import { getDefaultParameterValues } from "../../../lib/commandUtils"; diff --git a/frontend/testing-view/src/features/workspace/components/DndOverlay.tsx b/frontend/testing-view/src/features/workspace/components/DndOverlay.tsx index 16ebaab93..c53aa59b2 100644 --- a/frontend/testing-view/src/features/workspace/components/DndOverlay.tsx +++ b/frontend/testing-view/src/features/workspace/components/DndOverlay.tsx @@ -1,5 +1,5 @@ import { DragOverlay } from "@dnd-kit/core"; -import { Badge } from "@workspace/ui"; +import { Badge } from "@hyperloop-upv/frontend-kit"; import { TelemetryChart } from "../../charts/components/TelemetryChart"; import type { WorkspaceChartConfig } from "../../charts/types/charts"; import type { DndActiveData } from "../types/dndData"; diff --git a/frontend/testing-view/src/features/workspace/components/EmptyWorkspace.tsx b/frontend/testing-view/src/features/workspace/components/EmptyWorkspace.tsx index 489f8e804..14de73b44 100644 --- a/frontend/testing-view/src/features/workspace/components/EmptyWorkspace.tsx +++ b/frontend/testing-view/src/features/workspace/components/EmptyWorkspace.tsx @@ -1,5 +1,5 @@ -import { Button } from "@workspace/ui"; -import { LayoutGrid, Plus } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { LayoutGrid, Plus } from "@hyperloop-upv/frontend-kit/icons"; interface EmptyWorkspaceProps { onAddChart: () => void; diff --git a/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx b/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx index 460db5e9e..292e0318f 100644 --- a/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx +++ b/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx @@ -1,6 +1,6 @@ -import { Button, Separator } from "@workspace/ui"; -import { FolderOpen, Settings2 } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Button, Separator } from "@hyperloop-upv/frontend-kit"; +import { FolderOpen, Settings2 } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { LOGGER_CONTROL_CONFIG } from "../../../constants/loggerControlConfig"; import { useLogger } from "../../../hooks/useLogger"; import { useOpenFolder } from "../../../hooks/useOpenFolder"; diff --git a/frontend/testing-view/src/features/workspace/components/MainPanel.tsx b/frontend/testing-view/src/features/workspace/components/MainPanel.tsx index 9c4f2caa5..49a6bc74d 100644 --- a/frontend/testing-view/src/features/workspace/components/MainPanel.tsx +++ b/frontend/testing-view/src/features/workspace/components/MainPanel.tsx @@ -1,5 +1,5 @@ import { useDroppable } from "@dnd-kit/core"; -import { cn } from "@workspace/ui/lib"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useStore } from "../../../store/store"; import { ChartsGrid } from "../../charts/components/ChartsGrid"; import type { DndActiveData } from "../types/dndData"; diff --git a/frontend/testing-view/src/features/workspace/components/Toolbar.tsx b/frontend/testing-view/src/features/workspace/components/Toolbar.tsx index ccfb6a2cc..8cd0ba71f 100644 --- a/frontend/testing-view/src/features/workspace/components/Toolbar.tsx +++ b/frontend/testing-view/src/features/workspace/components/Toolbar.tsx @@ -1,5 +1,5 @@ -import { Button } from "@workspace/ui"; -import { ChevronLeft, Plus } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { ChevronLeft, Plus } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../../store/store"; interface TestingToolbarProps { diff --git a/frontend/testing-view/src/features/workspace/components/WorkspaceDialog.tsx b/frontend/testing-view/src/features/workspace/components/WorkspaceDialog.tsx index b261884ff..31ace59de 100644 --- a/frontend/testing-view/src/features/workspace/components/WorkspaceDialog.tsx +++ b/frontend/testing-view/src/features/workspace/components/WorkspaceDialog.tsx @@ -1,4 +1,4 @@ -import { Button } from "@workspace/ui"; +import { Button } from "@hyperloop-upv/frontend-kit"; import { Dialog, DialogContent, @@ -6,10 +6,10 @@ import { DialogFooter, DialogHeader, DialogTitle, -} from "@workspace/ui/components/shadcn/dialog"; -import { Input } from "@workspace/ui/components/shadcn/input"; -import { Label } from "@workspace/ui/components/shadcn/label"; -import { Textarea } from "@workspace/ui/components/shadcn/textarea"; +} from "@hyperloop-upv/frontend-kit/components/shadcn/dialog"; +import { Input } from "@hyperloop-upv/frontend-kit/components/shadcn/input"; +import { Label } from "@hyperloop-upv/frontend-kit/components/shadcn/label"; +import { Textarea } from "@hyperloop-upv/frontend-kit/components/shadcn/textarea"; import { useEffect, useState } from "react"; interface WorkspaceDialogProps { diff --git a/frontend/testing-view/src/features/workspace/components/WorkspaceSwitcher.tsx b/frontend/testing-view/src/features/workspace/components/WorkspaceSwitcher.tsx index 6a1a90607..980990168 100644 --- a/frontend/testing-view/src/features/workspace/components/WorkspaceSwitcher.tsx +++ b/frontend/testing-view/src/features/workspace/components/WorkspaceSwitcher.tsx @@ -7,7 +7,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, useSidebar, -} from "@workspace/ui"; +} from "@hyperloop-upv/frontend-kit"; import { ChevronsUpDown, Folder, @@ -15,8 +15,8 @@ import { Plus, SquareLibrary, Trash2, -} from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; import { useStore } from "../../../store/store"; import type { Workspace } from "../types/workspace"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx index ff41e515e..2451f1767 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx @@ -2,7 +2,7 @@ import { ResizableHandle, ResizablePanel, ResizablePanelGroup, -} from "@workspace/ui"; +} from "@hyperloop-upv/frontend-kit"; import { useStore } from "../../../../store/store"; import { CommandsSection } from "./sections/CommandsSection"; import MessagesSection from "./sections/MessagesSection"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx index 737f6ec91..8e54d6409 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx @@ -1,4 +1,4 @@ -import { Button } from "@workspace/ui"; +import { Button } from "@hyperloop-upv/frontend-kit"; import { Activity, MessageSquare, @@ -6,7 +6,7 @@ import { PanelRight, Terminal, X, -} from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../../../store/store"; import { RightSidebarToggle } from "./RightSidebarToggle"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarToggle.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarToggle.tsx index 65a6d16e7..d39ff7b2f 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarToggle.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarToggle.tsx @@ -4,7 +4,7 @@ import { TooltipContent, TooltipProvider, TooltipTrigger, -} from "@workspace/ui"; +} from "@hyperloop-upv/frontend-kit"; import type { ReactNode } from "react"; interface RightSidebarToggleProps { diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessageItem.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessageItem.tsx index 4b5ccbcb9..4958930e2 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessageItem.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessageItem.tsx @@ -3,9 +3,9 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger, -} from "@workspace/ui"; -import { ChevronDown } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit"; +import { ChevronDown } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; import { MESSAGE_KIND_COLORS } from "../../../../../constants/messageKindColors"; import { formatTimestamp } from "../../../../../lib/utils"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessagesSection.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessagesSection.tsx index 5343bb876..35e1d07a5 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessagesSection.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/MessagesSection.tsx @@ -1,5 +1,5 @@ -import { Button } from "@workspace/ui"; -import { Trash2 } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { Trash2 } from "@hyperloop-upv/frontend-kit/icons"; import { useStore } from "../../../../../store/store"; import { MessagesList } from "./MessagesList"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryHeader.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryHeader.tsx index f0ff3c78b..78106ea6c 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryHeader.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryHeader.tsx @@ -1,4 +1,4 @@ -import { ChevronDown, ChevronLeft } from "@workspace/ui/icons"; +import { ChevronDown, ChevronLeft } from "@hyperloop-upv/frontend-kit/icons"; interface CategoryHeaderProps { name: string; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryItem.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryItem.tsx index 3622797d8..0932d1cfc 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryItem.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/CategoryItem.tsx @@ -1,4 +1,4 @@ -import { Collapsible, CollapsibleContent } from "@workspace/ui"; +import { Collapsible, CollapsibleContent } from "@hyperloop-upv/frontend-kit"; import { type ComponentType } from "react"; import { useShallow } from "zustand/shallow"; import { useStore } from "../../../../../store/store"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/EmptyTab.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/EmptyTab.tsx index ec9885d21..655931fc9 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/EmptyTab.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/EmptyTab.tsx @@ -1,6 +1,6 @@ // EmptyTabState.tsx -import { Button } from "@workspace/ui"; -import { Filter, ListFilterPlus } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { Filter, ListFilterPlus } from "@hyperloop-upv/frontend-kit/icons"; interface EmptyTabProps { title: string; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx index d585ad9b6..5dda2d51b 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx @@ -1,5 +1,5 @@ -import { Button } from "@workspace/ui"; -import { AlertTriangle, ListFilterPlus } from "@workspace/ui/icons"; +import { Button } from "@hyperloop-upv/frontend-kit"; +import { AlertTriangle, ListFilterPlus } from "@hyperloop-upv/frontend-kit/icons"; import { useShallow } from "zustand/shallow"; import { detectExtraBoards } from "../../../../../lib/utils"; import { useStore } from "../../../../../store/store"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/VirtualizedList.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/VirtualizedList.tsx index c646ffeb3..010ab6793 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/VirtualizedList.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/VirtualizedList.tsx @@ -1,6 +1,6 @@ // frontend/testing-view/src/components/common/VirtualizedList.tsx import { useVirtualizer } from "@tanstack/react-virtual"; -import { cn } from "@workspace/ui/lib"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useCallback, useRef } from "react"; import type { BoardName } from "../../../../../types/data/board"; import type { VirtualRow } from "../../../../../types/data/virtualization"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandItem.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandItem.tsx index df9ac8168..c62fca81c 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandItem.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandItem.tsx @@ -1,12 +1,12 @@ -import { logger, socketService } from "@workspace/core"; +import { logger, socketService } from "@hyperloop-upv/frontend-kit/core"; import { Badge, Collapsible, CollapsibleContent, CollapsibleTrigger, -} from "@workspace/ui"; -import { ChevronDown, Play, Send } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +} from "@hyperloop-upv/frontend-kit"; +import { ChevronDown, Play, Send } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useState } from "react"; import { getDefaultParameterValues } from "../../../../../../lib/commandUtils"; import { useStore } from "../../../../../../store/store"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandParameters.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandParameters.tsx index dcf19f32a..c1335cbb9 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandParameters.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/commands/CommandParameters.tsx @@ -7,7 +7,7 @@ import { SelectItem, SelectTrigger, SelectValue, -} from "@workspace/ui"; +} from "@hyperloop-upv/frontend-kit"; import type { CommandParameter, EnumCommandParameter, diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/ChartPicker.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/ChartPicker.tsx index 8a06598d0..ec1a238db 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/ChartPicker.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/ChartPicker.tsx @@ -6,8 +6,8 @@ import { DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, -} from "@workspace/ui"; -import { Plus } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { Plus } from "@hyperloop-upv/frontend-kit/icons"; import type { WorkspaceChartConfig } from "../../../../../charts/types/charts"; interface ChartPickerProps { diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryHeader.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryHeader.tsx index fb4edf7a2..54bae57ab 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryHeader.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryHeader.tsx @@ -1,6 +1,6 @@ -import { Badge, Separator } from "@workspace/ui"; -import { Activity, ChevronDown } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Badge, Separator } from "@hyperloop-upv/frontend-kit"; +import { Activity, ChevronDown } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { memo, useEffect, useRef, useState } from "react"; import { useStore } from "../../../../../../store/store"; import type { TelemetryCatalogItem } from "../../../../../../types/data/telemetryCatalogItem"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryItem.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryItem.tsx index d263e7cd6..9a9897f1e 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryItem.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryItem.tsx @@ -2,7 +2,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger, -} from "@workspace/ui"; +} from "@hyperloop-upv/frontend-kit"; import { memo } from "react"; import { useStore } from "../../../../../../store/store"; import type { TelemetryCatalogItem } from "../../../../../../types/data/telemetryCatalogItem"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryValue.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryValue.tsx index ab9934224..aac4c9df3 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryValue.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/TelemetryValue.tsx @@ -1,6 +1,6 @@ -import { Badge } from "@workspace/ui"; -import { Check, X } from "@workspace/ui/icons"; -import { cn } from "@workspace/ui/lib"; +import { Badge } from "@hyperloop-upv/frontend-kit"; +import { Check, X } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useCallback } from "react"; import { useStore } from "../../../../../../store/store"; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/VariableItem.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/VariableItem.tsx index c53865b97..4fb335e83 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/VariableItem.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/telemetry/VariableItem.tsx @@ -1,6 +1,6 @@ import { useDraggable } from "@dnd-kit/core"; -import { Badge } from "@workspace/ui"; -import { cn } from "@workspace/ui/lib"; +import { Badge } from "@hyperloop-upv/frontend-kit"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; import { useShallow } from "zustand/shallow"; import { canAddSeriesToChart, diff --git a/frontend/testing-view/src/hooks/useAppConfigs.ts b/frontend/testing-view/src/hooks/useAppConfigs.ts index 07b885fda..c52d26780 100644 --- a/frontend/testing-view/src/hooks/useAppConfigs.ts +++ b/frontend/testing-view/src/hooks/useAppConfigs.ts @@ -1,4 +1,4 @@ -import { useFetchConfig } from "@workspace/ui/hooks"; +import { useFetchConfig } from "@hyperloop-upv/frontend-kit/hooks"; import { useEffect } from "react"; import { useStore } from "../store/store"; import type { OrdersData, PacketsData } from "../types/data/board"; diff --git a/frontend/testing-view/src/hooks/useAppMode.ts b/frontend/testing-view/src/hooks/useAppMode.ts index 79951cdc4..67e2aa66c 100644 --- a/frontend/testing-view/src/hooks/useAppMode.ts +++ b/frontend/testing-view/src/hooks/useAppMode.ts @@ -1,4 +1,4 @@ -import { logger } from "@workspace/core"; +import { logger } from "@hyperloop-upv/frontend-kit/core"; import { useCallback, useEffect } from "react"; import { useStore } from "../store/store"; import type { OrdersData, PacketsData } from "../types/data/board"; diff --git a/frontend/testing-view/src/hooks/useBoardData.ts b/frontend/testing-view/src/hooks/useBoardData.ts index 22ff3d8f9..82cdf0c74 100644 --- a/frontend/testing-view/src/hooks/useBoardData.ts +++ b/frontend/testing-view/src/hooks/useBoardData.ts @@ -1,4 +1,4 @@ -import { logger } from "@workspace/core"; +import { logger } from "@hyperloop-upv/frontend-kit/core"; import { useMemo } from "react"; import { formatName } from "../lib/utils"; import { MOCK_COMMANDS_CATALOG } from "../mocks/commands"; diff --git a/frontend/testing-view/src/hooks/useErrorHandler.ts b/frontend/testing-view/src/hooks/useErrorHandler.ts index fcba6be94..9abbc7f8e 100644 --- a/frontend/testing-view/src/hooks/useErrorHandler.ts +++ b/frontend/testing-view/src/hooks/useErrorHandler.ts @@ -1,5 +1,5 @@ -import { logger } from "@workspace/core"; -import useErrorSubscription from "@workspace/ui/hooks/webSocket/useErrorSubscription"; +import { logger } from "@hyperloop-upv/frontend-kit/core"; +import useErrorSubscription from "@hyperloop-upv/frontend-kit/hooks/webSocket/useErrorSubscription"; import { useEffect } from "react"; import { useStore } from "../store/store"; diff --git a/frontend/testing-view/src/hooks/useLogger.ts b/frontend/testing-view/src/hooks/useLogger.ts index 1f612a591..45182476b 100644 --- a/frontend/testing-view/src/hooks/useLogger.ts +++ b/frontend/testing-view/src/hooks/useLogger.ts @@ -1,5 +1,5 @@ -import { logger, socketService } from "@workspace/core"; -import { useTopic } from "@workspace/ui/hooks"; +import { logger, socketService } from "@hyperloop-upv/frontend-kit/core"; +import { useTopic } from "@hyperloop-upv/frontend-kit/hooks"; import { useEffect, useState } from "react"; import { config } from "../../config"; import { useStore } from "../store/store"; diff --git a/frontend/testing-view/src/hooks/useOpenFolder.ts b/frontend/testing-view/src/hooks/useOpenFolder.ts index 25c65b3f1..bb33e01f5 100644 --- a/frontend/testing-view/src/hooks/useOpenFolder.ts +++ b/frontend/testing-view/src/hooks/useOpenFolder.ts @@ -1,4 +1,4 @@ -import { logger } from "@workspace/core"; +import { logger } from "@hyperloop-upv/frontend-kit/core"; export const useOpenFolder = () => { const openFolder = (path?: string) => { diff --git a/frontend/testing-view/src/index.css b/frontend/testing-view/src/index.css index 1ba0c75ad..07cbe7182 100644 --- a/frontend/testing-view/src/index.css +++ b/frontend/testing-view/src/index.css @@ -1,6 +1,6 @@ -@import "@workspace/ui/globals.css"; +@import "@hyperloop-upv/frontend-kit/globals.css"; /* Ensure Tailwind v4 scans testing-view source files directly. - The @source paths in globals.css resolve via the @workspace/ui symlink + The @source paths in globals.css resolve via the @hyperloop-upv/frontend-kit symlink and don't correctly reach this project's source tree. */ @source "./**/*.{ts,tsx}"; diff --git a/frontend/testing-view/src/layout/AppLayout.tsx b/frontend/testing-view/src/layout/AppLayout.tsx index 407a8bb9e..e1abad52e 100644 --- a/frontend/testing-view/src/layout/AppLayout.tsx +++ b/frontend/testing-view/src/layout/AppLayout.tsx @@ -1,4 +1,4 @@ -import { SidebarInset, SidebarProvider } from "@workspace/ui/components"; +import { SidebarInset, SidebarProvider } from "@hyperloop-upv/frontend-kit/components"; import React, { useEffect } from "react"; import Header from "../components/header/Header"; import AppSidebar from "../components/leftSidebar/AppSidebar"; diff --git a/frontend/testing-view/src/lib/utils.test.ts b/frontend/testing-view/src/lib/utils.test.ts index e98d286cf..6066db679 100644 --- a/frontend/testing-view/src/lib/utils.test.ts +++ b/frontend/testing-view/src/lib/utils.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { typeBadgeClasses, getTypeBadgeClass } from "@workspace/ui/lib"; +import { typeBadgeClasses, getTypeBadgeClass } from "@hyperloop-upv/frontend-kit/lib"; import type { FilterScope } from "../features/filtering/types/filters"; import type { MessageTimestamp } from "../types/data/message"; import { diff --git a/frontend/testing-view/src/lib/utils.ts b/frontend/testing-view/src/lib/utils.ts index cbb9a32c1..93943445d 100644 --- a/frontend/testing-view/src/lib/utils.ts +++ b/frontend/testing-view/src/lib/utils.ts @@ -1,6 +1,6 @@ -import type { VariableValue } from "@workspace/core"; +import type { VariableValue } from "@hyperloop-upv/frontend-kit/core"; import { ACRONYMS } from "../constants/acronyms"; -export { getTypeBadgeClass } from "@workspace/ui/lib"; +export { getTypeBadgeClass } from "@hyperloop-upv/frontend-kit/lib"; import type { FilterScope, TabFilter, diff --git a/frontend/testing-view/src/pages/Testing.tsx b/frontend/testing-view/src/pages/Testing.tsx index d9c57e1ed..d8fa89583 100644 --- a/frontend/testing-view/src/pages/Testing.tsx +++ b/frontend/testing-view/src/pages/Testing.tsx @@ -3,8 +3,8 @@ import { ResizableHandle, ResizablePanel, ResizablePanelGroup, -} from "@workspace/ui"; -import { SquareLibrary } from "@workspace/ui/icons"; +} from "@hyperloop-upv/frontend-kit"; +import { SquareLibrary } from "@hyperloop-upv/frontend-kit/icons"; import { FilterController } from "../features/filtering/components/FilterController"; import { useGlobalKeyBindings } from "../features/keyBindings/hooks/useGlobalKeyBindings"; import { DndOverlay } from "../features/workspace/components/DndOverlay"; diff --git a/frontend/testing-view/src/types/telemetry/telemetry.ts b/frontend/testing-view/src/types/telemetry/telemetry.ts index 330c63722..306d00915 100644 --- a/frontend/testing-view/src/types/telemetry/telemetry.ts +++ b/frontend/testing-view/src/types/telemetry/telemetry.ts @@ -1,4 +1,4 @@ -import type { TelemetryPacket } from "@workspace/core"; +import type { TelemetryPacket } from "@hyperloop-upv/frontend-kit/core"; /** * Map of telemetry packets per telemetry packetid. diff --git a/frontend/testing-view/tsconfig.json b/frontend/testing-view/tsconfig.json index 3b2ce502f..a9428b2d0 100644 --- a/frontend/testing-view/tsconfig.json +++ b/frontend/testing-view/tsconfig.json @@ -11,8 +11,7 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": ["./*"], - "@workspace/ui/*": ["../frontend-kit/ui/src/*"] + "@/*": ["./*"] } }, "exclude": ["node_modules"] diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index f094c3328..17c874774 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -1,3 +1,3 @@ { - "extends": "@workspace/typescript-config/base.json" + "extends": "@hyperloop-upv/typescript-config/base.json" } diff --git a/package.json b/package.json index 02a60047e..931a30035 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,11 @@ "lint": "turbo lint", "preview": "turbo preview", "test": "turbo test", - "ui:add": "pnpm dlx shadcn@latest add -c frontend/frontend-kit/ui" + "ui:add": "pnpm dlx shadcn@latest add -c frontend/frontend-kit/kit" }, "devDependencies": { - "@workspace/eslint-config": "workspace:*", - "@workspace/typescript-config": "workspace:*", + "@hyperloop-upv/eslint-config": "workspace:*", + "@hyperloop-upv/typescript-config": "workspace:*", "prettier": "^3.8.1", "prettier-plugin-tailwindcss": "^0.7.2", "turbo": "^2.8.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62b462a5e..767efaa60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,10 +8,10 @@ importers: .: devDependencies: - '@workspace/eslint-config': + '@hyperloop-upv/eslint-config': specifier: workspace:* - version: link:frontend/frontend-kit/esling-config - '@workspace/typescript-config': + version: link:frontend/frontend-kit/eslint-config + '@hyperloop-upv/typescript-config': specifier: workspace:* version: link:frontend/frontend-kit/typescript-config prettier: @@ -76,15 +76,15 @@ importers: frontend/adj-view: dependencies: + '@hyperloop-upv/frontend-kit': + specifier: workspace:* + version: link:../frontend-kit/kit '@tailwindcss/vite': specifier: ^4.1.18 version: 4.3.0(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) '@vitejs/plugin-react-swc': specifier: ^4.2.3 version: 4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) - '@workspace/ui': - specifier: workspace:* - version: link:../frontend-kit/ui lucide-react: specifier: ^0.563.0 version: 0.563.0(react@19.2.4) @@ -98,18 +98,18 @@ importers: specifier: ^4.1.18 version: 4.3.0 devDependencies: + '@hyperloop-upv/eslint-config': + specifier: workspace:^ + version: link:../frontend-kit/eslint-config + '@hyperloop-upv/typescript-config': + specifier: workspace:* + version: link:../frontend-kit/typescript-config '@types/react': specifier: 19.2.11 version: 19.2.11 '@types/react-dom': specifier: 19.2.3 version: 19.2.3(@types/react@19.2.11) - '@workspace/eslint-config': - specifier: workspace:^ - version: link:../frontend-kit/esling-config - '@workspace/typescript-config': - specifier: workspace:* - version: link:../frontend-kit/typescript-config eslint: specifier: ^9.39.2 version: 9.39.4(jiti@2.6.1) @@ -122,18 +122,15 @@ importers: frontend/competition-view: dependencies: + '@hyperloop-upv/frontend-kit': + specifier: workspace:* + version: link:../frontend-kit/kit '@tailwindcss/vite': specifier: ^4.1.18 version: 4.3.0(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) '@vitejs/plugin-react-swc': specifier: ^4.2.3 version: 4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) - '@workspace/core': - specifier: workspace:* - version: link:../frontend-kit/core - '@workspace/ui': - specifier: workspace:* - version: link:../frontend-kit/ui lucide-react: specifier: ^0.563.0 version: 0.563.0(react@19.2.4) @@ -156,18 +153,18 @@ importers: specifier: ^5.0.11 version: 5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: + '@hyperloop-upv/eslint-config': + specifier: workspace:^ + version: link:../frontend-kit/eslint-config + '@hyperloop-upv/typescript-config': + specifier: workspace:* + version: link:../frontend-kit/typescript-config '@types/react': specifier: ^19.2.11 version: 19.2.11 '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.11) - '@workspace/eslint-config': - specifier: workspace:^ - version: link:../frontend-kit/esling-config - '@workspace/typescript-config': - specifier: workspace:* - version: link:../frontend-kit/typescript-config eslint: specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) @@ -183,15 +180,15 @@ importers: frontend/flashing-view: dependencies: + '@hyperloop-upv/frontend-kit': + specifier: workspace:* + version: link:../frontend-kit/kit '@tailwindcss/vite': specifier: ^4.1.18 version: 4.3.0(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) '@vitejs/plugin-react-swc': specifier: ^4.2.3 version: 4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) - '@workspace/ui': - specifier: workspace:* - version: link:../frontend-kit/ui lucide-react: specifier: ^0.563.0 version: 0.563.0(react@19.2.4) @@ -205,18 +202,18 @@ importers: specifier: ^4.1.18 version: 4.3.0 devDependencies: + '@hyperloop-upv/eslint-config': + specifier: workspace:^ + version: link:../frontend-kit/eslint-config + '@hyperloop-upv/typescript-config': + specifier: workspace:* + version: link:../frontend-kit/typescript-config '@types/react': specifier: 19.2.11 version: 19.2.11 '@types/react-dom': specifier: 19.2.3 version: 19.2.3(@types/react@19.2.11) - '@workspace/eslint-config': - specifier: workspace:^ - version: link:../frontend-kit/esling-config - '@workspace/typescript-config': - specifier: workspace:* - version: link:../frontend-kit/typescript-config eslint: specifier: ^9.39.2 version: 9.39.4(jiti@2.6.1) @@ -227,51 +224,38 @@ importers: specifier: ^7.3.1 version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0) - frontend/frontend-kit/core: - dependencies: - rxjs: - specifier: ^7.8.2 - version: 7.8.2 - devDependencies: - '@workspace/eslint-config': - specifier: workspace:* - version: link:../esling-config - eslint: - specifier: ^9.39.2 - version: 9.39.2(jiti@2.6.1) - - frontend/frontend-kit/esling-config: + frontend/frontend-kit/eslint-config: devDependencies: '@eslint/js': specifier: ^9.39.2 - version: 9.39.2 + version: 9.39.4 '@typescript-eslint/eslint-plugin': specifier: ^8.54.0 - version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': specifier: ^8.54.0 - version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: specifier: ^9.39.2 - version: 9.39.2(jiti@2.6.1) + version: 9.39.4(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.39.2(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-only-warn: specifier: ^1.1.0 version: 1.1.0 eslint-plugin-react: specifier: ^7.37.5 - version: 7.37.5(eslint@9.39.2(jiti@2.6.1)) + version: 7.37.5(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-hooks: specifier: ^7.0.1 - version: 7.0.1(eslint@9.39.2(jiti@2.6.1)) + version: 7.0.1(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-refresh: specifier: ^0.5.0 - version: 0.5.0(eslint@9.39.2(jiti@2.6.1)) + version: 0.5.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-turbo: specifier: ^2.8.3 - version: 2.8.3(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.3) + version: 2.8.3(eslint@9.39.4(jiti@2.6.1))(turbo@2.8.3) globals: specifier: ^17.3.0 version: 17.3.0 @@ -280,11 +264,9 @@ importers: version: 5.9.3 typescript-eslint: specifier: ^8.54.0 - version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - - frontend/frontend-kit/typescript-config: {} + version: 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - frontend/frontend-kit/ui: + frontend/frontend-kit/kit: dependencies: '@base-ui/react': specifier: ^1.3.0 @@ -325,9 +307,6 @@ importers: '@radix-ui/react-tooltip': specifier: ^1.2.8 version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@workspace/core': - specifier: workspace:* - version: link:../core class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -368,6 +347,12 @@ importers: specifier: ^5.0.11 version: 5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: + '@hyperloop-upv/eslint-config': + specifier: workspace:* + version: link:../eslint-config + '@hyperloop-upv/typescript-config': + specifier: workspace:* + version: link:../typescript-config '@maximka76667/icons-master': specifier: ^1.0.3 version: 1.0.3 @@ -386,27 +371,26 @@ importers: '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.11) - '@workspace/eslint-config': - specifier: workspace:* - version: link:../esling-config - '@workspace/typescript-config': - specifier: workspace:* - version: link:../typescript-config eslint: specifier: ^9.39.2 - version: 9.39.2(jiti@2.6.1) + version: 9.39.4(jiti@2.6.1) tailwindcss: specifier: ^4.1.18 - version: 4.1.18 + version: 4.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 + frontend/frontend-kit/typescript-config: {} + frontend/logging-view: dependencies: '@dnd-kit/core': specifier: ^6.3.1 version: 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@hyperloop-upv/frontend-kit': + specifier: workspace:* + version: link:../frontend-kit/kit '@tailwindcss/vite': specifier: ^4.1.18 version: 4.3.0(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) @@ -419,12 +403,6 @@ importers: '@vitejs/plugin-react-swc': specifier: ^4.2.3 version: 4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) - '@workspace/core': - specifier: workspace:* - version: link:../frontend-kit/core - '@workspace/ui': - specifier: workspace:* - version: link:../frontend-kit/ui jspdf: specifier: ^4.2.1 version: 4.2.1 @@ -453,18 +431,18 @@ importers: specifier: ^5.0.11 version: 5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: + '@hyperloop-upv/eslint-config': + specifier: workspace:^ + version: link:../frontend-kit/eslint-config + '@hyperloop-upv/typescript-config': + specifier: workspace:* + version: link:../frontend-kit/typescript-config '@types/react': specifier: ^19.2.11 version: 19.2.11 '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.11) - '@workspace/eslint-config': - specifier: workspace:^ - version: link:../frontend-kit/esling-config - '@workspace/typescript-config': - specifier: workspace:* - version: link:../frontend-kit/typescript-config eslint: specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) @@ -492,6 +470,9 @@ importers: '@dnd-kit/utilities': specifier: ^3.2.2 version: 3.2.2(react@19.2.4) + '@hyperloop-upv/frontend-kit': + specifier: workspace:* + version: link:../frontend-kit/kit '@radix-ui/react-slot': specifier: ^1.2.4 version: 1.2.4(@types/react@19.2.11)(react@19.2.4) @@ -507,12 +488,6 @@ importers: '@vitejs/plugin-react-swc': specifier: ^4.2.3 version: 4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) - '@workspace/core': - specifier: workspace:* - version: link:../frontend-kit/core - '@workspace/ui': - specifier: workspace:* - version: link:../frontend-kit/ui lodash: specifier: ^4.17.23 version: 4.17.23 @@ -541,18 +516,18 @@ importers: specifier: ^5.0.11 version: 5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: + '@hyperloop-upv/eslint-config': + specifier: workspace:^ + version: link:../frontend-kit/eslint-config + '@hyperloop-upv/typescript-config': + specifier: workspace:* + version: link:../frontend-kit/typescript-config '@types/react': specifier: ^19.2.11 version: 19.2.11 '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.11) - '@workspace/eslint-config': - specifier: workspace:^ - version: link:../frontend-kit/esling-config - '@workspace/typescript-config': - specifier: workspace:* - version: link:../frontend-kit/typescript-config eslint: specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) @@ -959,24 +934,12 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@floating-ui/core@1.7.4': - resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} - '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} - '@floating-ui/dom@1.7.5': - resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} - '@floating-ui/dom@1.7.6': resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} - '@floating-ui/react-dom@2.1.7': - resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - '@floating-ui/react-dom@2.1.8': resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} peerDependencies: @@ -3343,6 +3306,7 @@ packages: eslint@9.39.4: resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -6212,30 +6176,15 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 - '@floating-ui/core@1.7.4': - dependencies: - '@floating-ui/utils': 0.2.11 - '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 - '@floating-ui/dom@1.7.5': - dependencies: - '@floating-ui/core': 1.7.4 - '@floating-ui/utils': 0.2.11 - '@floating-ui/dom@1.7.6': dependencies: '@floating-ui/core': 1.7.5 '@floating-ui/utils': 0.2.11 - '@floating-ui/react-dom@2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@floating-ui/dom': 1.7.5 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@floating-ui/dom': 1.7.6 @@ -6817,7 +6766,7 @@ snapshots: '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) @@ -7642,15 +7591,15 @@ snapshots: '@types/node': 25.2.0 optional: true - '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.54.0 - '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.54.0 - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.4.0(typescript@5.9.3) @@ -7658,14 +7607,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.54.0 '@typescript-eslint/types': 8.54.0 '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -7688,13 +7637,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.54.0 '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -7717,13 +7666,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.54.0 '@typescript-eslint/types': 8.54.0 '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -8902,28 +8851,28 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-plugin-only-warn@1.1.0: {} - eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.0 - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) hermes-parser: 0.25.1 zod: 4.3.6 zod-validation-error: 4.0.2(zod@4.3.6) transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.5.0(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-react-refresh@0.5.0(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-react@7.37.5(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.6.1)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -8931,11 +8880,11 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.2 - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 + minimatch: 3.1.5 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 @@ -8945,10 +8894,10 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.8.3(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.3): + eslint-plugin-turbo@2.8.3(eslint@9.39.4(jiti@2.6.1))(turbo@2.8.3): dependencies: dotenv: 16.0.3 - eslint: 9.39.2(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) turbo: 2.8.3 eslint-scope@8.4.0: @@ -11332,13 +11281,13 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.39.2(jiti@2.6.1) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color From 33337f9f5dea703b45b4d86204ff6ee9d51a031d Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 13:13:11 +0100 Subject: [PATCH 07/12] feat(frontend-kit): build the kit for publication Publishing needs compiled output: an external consumer gets .tsx inside node_modules, and @vitejs/plugin-react-swc does not transform files there. Builds with Vite in library mode using Rollup's preserveModules, which mirrors src/ into dist/ so the wildcard subpath exports keep resolving as components are added, with no entry list to maintain. Chose Rollup over tsc and tsup because neither rewrites relative specifiers: both would emit extensionless imports, which is invalid ESM and only works because Vite retries extensions. Verified the output imports ../../lib/utils.js, with the extension. - exports still point at src/, so the five apps keep today's HMR straight into kit source. publishConfig.exports points at dist/ and is what a consumer sees. This requires pnpm publish: npm ignores the override and would ship a package pointing at .tsx. - Ship src/ alongside dist/ so the published globals.css keeps its own @source glob working against the package's own sources. No build-time CSS transform and no generated second stylesheet. - react, react-dom, lucide-react, tailwindcss and tw-animate-css become peers. Two copies of React break hooks, and LucideIcon leaks into the public props of SegmentedControl. - Drop the preinstall guard, which npm and yarn would run from inside a dependency and abort the consumer's install on. - Drop next-themes, zod and zustand: unused since the store was emptied. - Re-inject the 18 "use client" directives, which Rollup strips from the emitted JS. - Enforce the React-free boundary of src/core with a lint rule instead of only documenting it in the README. All five apps build with unchanged CSS output; tarball asserted for private, preinstall, exports retargeting, peers and workspace: leakage. --- frontend/frontend-kit/kit/eslint.config.js | 28 +- frontend/frontend-kit/kit/package.json | 105 ++++- frontend/frontend-kit/kit/src/store/index.ts | 5 + frontend/frontend-kit/kit/tsconfig.build.json | 13 + frontend/frontend-kit/kit/vite.config.ts | 88 +++++ .../typescript-config/package.json | 5 +- pnpm-lock.yaml | 359 ++++++++++++++++-- 7 files changed, 550 insertions(+), 53 deletions(-) create mode 100644 frontend/frontend-kit/kit/tsconfig.build.json create mode 100644 frontend/frontend-kit/kit/vite.config.ts diff --git a/frontend/frontend-kit/kit/eslint.config.js b/frontend/frontend-kit/kit/eslint.config.js index c091004bc..4865ba27c 100644 --- a/frontend/frontend-kit/kit/eslint.config.js +++ b/frontend/frontend-kit/kit/eslint.config.js @@ -1,4 +1,30 @@ import { config } from "@hyperloop-upv/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ -export default config; +export default [ + ...config, + { + // src/core is published as the ./core subpath and must stay usable outside + // a React app, so the React-free boundary is enforced rather than just + // documented in the README. + files: ["src/core/**/*.ts"], + rules: { + "no-restricted-imports": [ + "error", + { + paths: [ + { + name: "react", + message: + "src/core must stay React-free. Anything needing React belongs in src/hooks or src/components.", + }, + { + name: "react-dom", + message: "src/core must stay React-free.", + }, + ], + }, + ], + }, + }, +]; diff --git a/frontend/frontend-kit/kit/package.json b/frontend/frontend-kit/kit/package.json index 6eeb0070d..557f1a461 100644 --- a/frontend/frontend-kit/kit/package.json +++ b/frontend/frontend-kit/kit/package.json @@ -1,14 +1,41 @@ { "name": "@hyperloop-upv/frontend-kit", "version": "0.1.0", + "description": "Shared React + Tailwind component kit and WebSocket layer for Hyperloop UPV frontends", + "license": "MIT", "type": "module", - "private": true, + "repository": { + "type": "git", + "url": "git+https://github.com/Hyperloop-UPV/software.git", + "directory": "frontend/frontend-kit/kit" + }, + "homepage": "https://github.com/Hyperloop-UPV/software/tree/develop/frontend/frontend-kit/kit", + "bugs": { + "url": "https://github.com/Hyperloop-UPV/software/issues" + }, + "sideEffects": [ + "**/*.css" + ], + "files": [ + "dist", + "src", + "postcss.config.mjs", + "components.json", + "README.md" + ], "scripts": { - "preinstall": "npx only-allow pnpm", + "build": "vite build", "lint": "eslint .", "icon:add": "icons-master add", "icon:remove": "icons-master remove" }, + "peerDependencies": { + "lucide-react": ">=0.500.0 <1", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tailwindcss": "^4.1.0", + "tw-animate-css": "^1.4.0" + }, "dependencies": { "@base-ui/react": "^1.3.0", "@radix-ui/react-checkbox": "^1.3.3", @@ -25,30 +52,31 @@ "@radix-ui/react-tooltip": "^1.2.8", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "lucide-react": "^0.563.0", - "next-themes": "^0.4.6", "radix-ui": "^1.4.3", - "react": "^19.2.4", - "react-dom": "^19.2.4", "react-resizable-panels": "^4.6.0", "rxjs": "^7.8.2", - "tailwind-merge": "^3.4.0", - "tw-animate-css": "^1.4.0", - "zod": "^4.3.6", - "zustand": "^5.0.11" + "tailwind-merge": "^3.4.0" }, "devDependencies": { + "@hyperloop-upv/eslint-config": "workspace:*", + "@hyperloop-upv/typescript-config": "workspace:*", "@maximka76667/icons-master": "^1.0.3", "@tailwindcss/postcss": "^4.1.18", "@turbo/gen": "^2.8.3", "@types/node": "^25.2.0", "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", - "@hyperloop-upv/eslint-config": "workspace:*", - "@hyperloop-upv/typescript-config": "workspace:*", + "@vitejs/plugin-react-swc": "^4.2.3", "eslint": "^9.39.2", + "lucide-react": "^0.563.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", "tailwindcss": "^4.1.18", - "typescript": "^5.9.3" + "tinyglobby": "^0.2.17", + "tw-animate-css": "^1.4.0", + "typescript": "^5.9.3", + "vite": "^7.3.1", + "vite-plugin-dts": "^5.1.2" }, "exports": { ".": "./src/index.ts", @@ -63,7 +91,54 @@ "./hooks/*": "./src/hooks/*.ts", "./store": "./src/store/index.ts", "./icons": "./src/icons/index.ts", - "./outreach/*": "./src/outreach/*" + "./outreach/*": "./src/outreach/*", + "./package.json": "./package.json" }, - "description": "Shared React + Tailwind component kit and WebSocket layer for Hyperloop UPV frontends" + "publishConfig": { + "registry": "https://npm.pkg.github.com", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./core": { + "types": "./dist/core/index.d.ts", + "default": "./dist/core/index.js" + }, + "./globals.css": "./src/styles/globals.css", + "./postcss.config": "./postcss.config.mjs", + "./lib": { + "types": "./dist/lib/index.d.ts", + "default": "./dist/lib/index.js" + }, + "./components": { + "types": "./dist/components/index.d.ts", + "default": "./dist/components/index.js" + }, + "./hooks": { + "types": "./dist/hooks/index.d.ts", + "default": "./dist/hooks/index.js" + }, + "./icons": { + "types": "./dist/icons/index.d.ts", + "default": "./dist/icons/index.js" + }, + "./lib/*": { + "types": "./dist/lib/*.d.ts", + "default": "./dist/lib/*.js" + }, + "./components/*": { + "types": "./dist/components/*.d.ts", + "default": "./dist/components/*.js" + }, + "./hooks/*": { + "types": "./dist/hooks/*.d.ts", + "default": "./dist/hooks/*.js" + }, + "./outreach/*": "./src/outreach/*", + "./package.json": "./package.json" + } + } } diff --git a/frontend/frontend-kit/kit/src/store/index.ts b/frontend/frontend-kit/kit/src/store/index.ts index b0baa1aa0..86a1b09fe 100644 --- a/frontend/frontend-kit/kit/src/store/index.ts +++ b/frontend/frontend-kit/kit/src/store/index.ts @@ -1 +1,6 @@ +// NOTE: ./use-dark-mode-store does not exist, so this barrel is broken and +// nothing imports it. It is left in place, and in the dev exports, but excluded +// from the build (vite.config.ts), from tsconfig.build.json and from +// publishConfig.exports. If you add use-dark-mode-store.ts, re-add "./store" in +// those three places for it to work from the published package. export * from "./use-dark-mode-store"; diff --git a/frontend/frontend-kit/kit/tsconfig.build.json b/frontend/frontend-kit/kit/tsconfig.build.json new file mode 100644 index 000000000..991dd6126 --- /dev/null +++ b/frontend/frontend-kit/kit/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": false, + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"], + "exclude": ["src/store", "node_modules", "dist"] +} diff --git a/frontend/frontend-kit/kit/vite.config.ts b/frontend/frontend-kit/kit/vite.config.ts new file mode 100644 index 000000000..89edaee08 --- /dev/null +++ b/frontend/frontend-kit/kit/vite.config.ts @@ -0,0 +1,88 @@ +import { readFileSync } from "node:fs"; +import { isAbsolute, resolve } from "node:path"; +import react from "@vitejs/plugin-react-swc"; +import { globSync } from "tinyglobby"; +import { defineConfig, type Plugin } from "vite"; +import dts from "vite-plugin-dts"; + +/** + * Rollup strips module-level directives from the emitted JavaScript, so the + * 18 shadcn files that opt into client rendering would lose it. They are inert + * in Vite and Electron but required by a React Server Components consumer, so + * put them back on the chunks whose source had one. + */ +const preserveUseClient = (): Plugin => ({ + name: "preserve-use-client", + renderChunk(code, chunk) { + const source = chunk.facadeModuleId; + if (!source) return null; + + const directive = readFileSync(source, "utf8").trimStart(); + if (!directive.startsWith('"use client"') && !directive.startsWith("'use client'")) { + return null; + } + + return { code: `"use client";\n${code}`, map: null }; + }, +}); + +// Every source file is its own Rollup entry. Together with preserveModules this +// mirrors src/ into dist/, which is what keeps the wildcard subpath exports +// ("./components/*") resolvable in the published package: a new component works +// with no entry list to maintain. +const entries = globSync(["src/**/*.{ts,tsx}"], { + ignore: [ + // ./store re-exports ./use-dark-mode-store, which does not exist. Kept on + // disk and in the dev exports, left out of the published surface. + "src/store/**", + "src/**/*.test.{ts,tsx}", + "src/**/*.d.ts", + ], +}).map((file) => resolve(file)); + +export default defineConfig({ + plugins: [ + react(), + preserveUseClient(), + dts({ + tsconfigPath: "./tsconfig.build.json", + entryRoot: "src", + outDir: "dist", + // One .d.ts per module, mirroring dist/. Rolling them into a single file + // would break per-subpath type resolution. + rollupTypes: false, + insertTypesEntry: false, + }), + ], + build: { + target: "es2022", + outDir: "dist", + emptyOutDir: true, + // Keeps the Tailwind class strings readable and the output debuggable. The + // consuming app minifies anyway. + minify: false, + sourcemap: true, + rollupOptions: { + input: entries, + // Vite defaults this to false for app builds, which Rollup rejects + // together with preserveModules. + preserveEntrySignatures: "strict", + // Anything that is not a relative or absolute path is a bare specifier, + // i.e. a dependency: leave it as an import instead of inlining it. + external: (id) => !id.startsWith(".") && !isAbsolute(id), + output: { + format: "es", + dir: "dist", + preserveModules: true, + preserveModulesRoot: "src", + entryFileNames: "[name].js", + chunkFileNames: "[name].js", + }, + onwarn(warning, warn) { + // preserveUseClient puts these back; Rollup's warning is expected. + if (warning.code === "MODULE_LEVEL_DIRECTIVE") return; + warn(warning); + }, + }, + }, +}); diff --git a/frontend/frontend-kit/typescript-config/package.json b/frontend/frontend-kit/typescript-config/package.json index f1ead743a..87fa43108 100644 --- a/frontend/frontend-kit/typescript-config/package.json +++ b/frontend/frontend-kit/typescript-config/package.json @@ -1,8 +1,5 @@ { "name": "@hyperloop-upv/typescript-config", "version": "0.0.0", - "private": true, - "publishConfig": { - "access": "public" - } + "private": true } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 767efaa60..af1732f70 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -313,21 +313,9 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 - lucide-react: - specifier: ^0.563.0 - version: 0.563.0(react@19.2.4) - next-themes: - specifier: ^0.4.6 - version: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) radix-ui: specifier: ^1.4.3 version: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: - specifier: ^19.2.4 - version: 19.2.4 - react-dom: - specifier: ^19.2.4 - version: 19.2.4(react@19.2.4) react-resizable-panels: specifier: ^4.6.0 version: 4.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -337,15 +325,6 @@ importers: tailwind-merge: specifier: ^3.4.0 version: 3.4.0 - tw-animate-css: - specifier: ^1.4.0 - version: 1.4.0 - zod: - specifier: ^4.3.6 - version: 4.3.6 - zustand: - specifier: ^5.0.11 - version: 5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: '@hyperloop-upv/eslint-config': specifier: workspace:* @@ -371,15 +350,39 @@ importers: '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.11) + '@vitejs/plugin-react-swc': + specifier: ^4.2.3 + version: 4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) eslint: specifier: ^9.39.2 version: 9.39.4(jiti@2.6.1) + lucide-react: + specifier: ^0.563.0 + version: 0.563.0(react@19.2.4) + react: + specifier: ^19.2.4 + version: 19.2.4 + react-dom: + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) tailwindcss: specifier: ^4.1.18 version: 4.3.0 + tinyglobby: + specifier: ^0.2.17 + version: 0.2.17 + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 typescript: specifier: ^5.9.3 version: 5.9.3 + vite: + specifier: ^7.3.1 + version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0) + vite-plugin-dts: + specifier: ^5.1.2 + version: 5.1.2(esbuild@0.27.2)(rollup@4.57.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) frontend/frontend-kit/typescript-config: {} @@ -1849,6 +1852,15 @@ packages: '@rolldown/pluginutils@1.0.0-rc.2': resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + '@rollup/pluginutils@5.5.1': + resolution: {integrity: sha512-P9ZvnfouRu4MSC+ilERaw6FmZs8zqKhpHxEs4aGDGWQAMzQGXnhvCSvoNwokfNvdt7t3Y5Y4p6gStQgezeIqug==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.57.1': resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} cpu: [arm] @@ -2475,6 +2487,28 @@ packages: '@vitest/utils@4.0.18': resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + '@volar/language-core@2.4.30': + resolution: {integrity: sha512-73fjwEV8wat6aOZ6U/y/hqtE30ocrIWECg67b0txGczOMNw+MffLmvJ5fnFfN9drVUEYZzLdaNo6VAy6G6avMw==} + + '@volar/language-service@2.4.30': + resolution: {integrity: sha512-w/xDsASiqC71ggCOm7sTDXDNk/l72XEptodeRC68tgZ0e5QM4hM3zAqBGC7mBctvhrpYwKfMG+t9xcUo2hEFtA==} + peerDependencies: + typescript: <7 + peerDependenciesMeta: + typescript: + optional: true + + '@volar/source-map@2.4.30': + resolution: {integrity: sha512-zym1ob/KwDDyN+0jGVtxwbxJSRRnUvv5HspCtz3yEfVVdCG4/dzxJktMGPAgemqRuVs81O0o/y0q3qOUErR8kg==} + + '@volar/typescript@2.4.30': + resolution: {integrity: sha512-/DgA5tgYFPfrLFuSjIMXMGHk1LQv2+P8eny6+BhGNzFJELWIW7UZlc56ZLIRFhLsPpMfIFxM8/HvOPBggrjTZg==} + peerDependencies: + typescript: <7 + peerDependenciesMeta: + typescript: + optional: true + '@xmldom/xmldom@0.8.11': resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} engines: {node: '>=10.0.0'} @@ -2498,6 +2532,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -2919,6 +2958,9 @@ packages: resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} engines: {node: '>=0.10.0'} + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + compress-commons@4.1.2: resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} engines: {node: '>= 10'} @@ -2930,6 +2972,12 @@ packages: resolution: {integrity: sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==} engines: {node: '>=20'} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.3.2: + resolution: {integrity: sha512-ZUAKhKlkCOrIGKc8cj7zek9s9z1mveHif/25nUshI2BzCRzF7KH7KHa+Lnh2ubq+e1tIlaFuP763mzW4qVoehg==} + config-file-ts@0.2.6: resolution: {integrity: sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==} @@ -3296,6 +3344,7 @@ packages: eslint@9.39.2: resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -3335,6 +3384,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -3353,6 +3405,9 @@ packages: exponential-backoff@3.1.3: resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + exsolve@1.2.0: + resolution: {integrity: sha512-h1pQPR9XoeSMdntRNCjyTznaume4UpfXrULBnlkZ2CUM/G5eSa+pBByGldO5uR8dxbPC+OuJXsPPNf+JZ81ADg==} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -3552,6 +3607,9 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -4003,6 +4061,9 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + lazy-val@1.0.5: resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} @@ -4154,6 +4215,10 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + local-pkg@1.2.1: + resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} + engines: {node: '>=14'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -4370,6 +4435,9 @@ packages: engines: {node: '>=10'} hasBin: true + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -4409,12 +4477,6 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} - next-themes@0.4.6: - resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} - peerDependencies: - react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - no-case@2.3.2: resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} @@ -4562,6 +4624,9 @@ packages: pascal-case@2.0.1: resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-case@2.1.1: resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} @@ -4618,6 +4683,16 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.4.0: + resolution: {integrity: sha512-07Fys7iVx0X6TcviMOgogM1Lk33ZyqOezMnU79S+kffWqwolG/5W9V8EgQSeYCIfFTYVgssRbnH630Oa2+soBA==} + playwright-core@1.58.2: resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} engines: {node: '>=18'} @@ -4742,6 +4817,9 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -5274,6 +5352,10 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + tinygradient@1.1.5: resolution: {integrity: sha512-8nIfc2vgQ4TeLnk2lFj4tRLvvJwEfQuabdsmvDdQPT0xlk9TaNtpGd6nNRxXoK6vQhN6RSzj+Cnp5tTQmpxmbw==} @@ -5429,6 +5511,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -5461,6 +5546,40 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unplugin-dts@1.1.2: + resolution: {integrity: sha512-RDqy90XUmFj6rz4U5YoTMdYdaCJe2ZnQZaWIjkWS4952Gv0zBTQyqWtlGgVMPYHa982dURvyoc+sUOFIcDFv+w==} + peerDependencies: + '@microsoft/api-extractor': '>=7' + '@rspack/core': ^1 + '@vue/language-core': ^3.1.5 + esbuild: '*' + rolldown: '*' + rollup: '>=3' + typescript: '>=4' + vite: '>=3' + webpack: ^4 || ^5 + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@rspack/core': + optional: true + '@vue/language-core': + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + until-async@3.0.2: resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} @@ -5530,6 +5649,20 @@ packages: resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} engines: {node: '>=0.6.0'} + vite-plugin-dts@5.1.2: + resolution: {integrity: sha512-1bXUz836sWq6ewEMQre3ZtNFVfZk/92DppgCCKP8tWx/NWwV2wHuXlRHb2TztHjbikPxvyAGLGu7hVh94Plwww==} + peerDependencies: + '@microsoft/api-extractor': '>=7' + rollup: '>=3' + vite: '>=3' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + rollup: + optional: true + vite: + optional: true + vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -5604,9 +5737,28 @@ packages: jsdom: optional: true + vscode-jsonrpc@10.0.0: + resolution: {integrity: sha512-USSfxg0vDIpTQqlQBGxF3mBARyoS8cU7LHLpbYNh6dOJt32dlskxPWB0Irrh5TllTmyf7oNLAvqDqzklbwwnpA==} + engines: {node: '>=14.17.0'} + + vscode-languageserver-protocol@3.18.5: + resolution: {integrity: sha512-FW4fBMzZ99N8xeob4py0l050wgCoRgTpEq5Xcsb9lM1bc29UKGR/wSV+4knaqFxssFHajy7OzNiKP/m3U1ZEuA==} + + vscode-languageserver-textdocument@1.0.16: + resolution: {integrity: sha512-qeNEuOi9a3qkqRf7Gfez2WL2VwlBTLCNekHBGO9kxPVUp9XuY15yfTJ9jwvOwKI0I2MhUUfZq95NSp+LK1CLQg==} + + vscode-languageserver-types@3.18.5: + resolution: {integrity: sha512-kPd6+JQNz3HMJvjKlqUxERSlZHAntl/aGpsk7ImwIh0ewDKDcjgAEyVSYciPiOJD3ftbK9IrfiqUeTZLSbCizw==} + + vscode-uri@3.2.0: + resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + when-exit@2.1.5: resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} @@ -7148,6 +7300,14 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.2': {} + '@rollup/pluginutils@5.5.1(rollup@4.57.1)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.57.1 + '@rollup/rollup-android-arm-eabi@4.57.1': optional: true @@ -7753,6 +7913,30 @@ snapshots: '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 + '@volar/language-core@2.4.30': + dependencies: + '@volar/source-map': 2.4.30 + + '@volar/language-service@2.4.30(typescript@5.9.3)': + dependencies: + '@volar/language-core': 2.4.30 + vscode-languageserver-protocol: 3.18.5 + vscode-languageserver-textdocument: 1.0.16 + vscode-uri: 3.2.0 + optionalDependencies: + typescript: 5.9.3 + + '@volar/source-map@2.4.30': {} + + '@volar/typescript@2.4.30(typescript@5.9.3)': + dependencies: + '@volar/language-core': 2.4.30 + '@volar/language-service': 2.4.30(typescript@5.9.3) + path-browserify: 1.0.1 + vscode-uri: 3.2.0 + optionalDependencies: + typescript: 5.9.3 + '@xmldom/xmldom@0.8.11': {} abbrev@3.0.1: {} @@ -7767,6 +7951,8 @@ snapshots: acorn@8.15.0: {} + acorn@8.19.0: {} + agent-base@6.0.2: dependencies: debug: 4.4.3 @@ -8358,6 +8544,8 @@ snapshots: compare-version@0.1.2: {} + compare-versions@6.1.1: {} + compress-commons@4.1.2: dependencies: buffer-crc32: 0.2.13 @@ -8379,6 +8567,10 @@ snapshots: semver: 7.7.3 uint8array-extras: 1.5.0 + confbox@0.1.8: {} + + confbox@0.3.2: {} + config-file-ts@0.2.6: dependencies: glob: 10.5.0 @@ -9009,6 +9201,8 @@ snapshots: estraverse@5.3.0: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -9031,6 +9225,8 @@ snapshots: exponential-backoff@3.1.3: {} + exsolve@1.2.0: {} + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -9105,6 +9301,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + fflate@0.8.3: {} figures@3.2.0: @@ -9262,6 +9462,8 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} + glob@10.5.0: dependencies: foreground-child: 3.3.1 @@ -9771,6 +9973,8 @@ snapshots: dependencies: json-buffer: 3.0.1 + kolorist@1.8.0: {} + lazy-val@1.0.5: {} lazystream@1.0.1: @@ -9880,6 +10084,12 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + local-pkg@1.2.1: + dependencies: + mlly: 1.8.2 + pkg-types: 2.4.0 + quansync: 0.2.11 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -10078,6 +10288,13 @@ snapshots: mkdirp@1.0.4: {} + mlly@1.8.2: + dependencies: + acorn: 8.19.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + ms@2.1.3: {} msw@2.14.6(@types/node@25.2.0)(typescript@5.9.3): @@ -10147,11 +10364,6 @@ snapshots: netmask@2.0.2: {} - next-themes@0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - no-case@2.3.2: dependencies: lower-case: 1.1.4 @@ -10350,6 +10562,8 @@ snapshots: camel-case: 3.0.0 upper-case-first: 1.1.2 + path-browserify@1.0.1: {} + path-case@2.1.1: dependencies: no-case: 2.3.2 @@ -10389,6 +10603,20 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.7: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + pkg-types@2.4.0: + dependencies: + confbox: 0.3.2 + exsolve: 1.2.0 + pathe: 2.0.3 + playwright-core@1.58.2: {} playwright@1.58.2: @@ -10466,6 +10694,8 @@ snapshots: punycode@2.3.1: {} + quansync@0.2.11: {} + queue-microtask@1.2.3: {} quick-lru@5.1.1: {} @@ -11130,6 +11360,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + tinygradient@1.1.5: dependencies: '@types/tinycolor2': 1.4.6 @@ -11297,6 +11532,8 @@ snapshots: typescript@6.0.3: optional: true + ufo@1.6.4: {} + uglify-js@3.19.3: optional: true @@ -11323,6 +11560,32 @@ snapshots: universalify@2.0.1: {} + unplugin-dts@1.1.2(esbuild@0.27.2)(rollup@4.57.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)): + dependencies: + '@rollup/pluginutils': 5.5.1(rollup@4.57.1) + '@volar/typescript': 2.4.30(typescript@5.9.3) + compare-versions: 6.1.1 + debug: 4.4.3 + glob-to-regexp: 0.4.1 + kolorist: 1.8.0 + local-pkg: 1.2.1 + magic-string: 0.30.21 + typescript: 5.9.3 + unplugin: 2.3.11 + optionalDependencies: + esbuild: 0.27.2 + rollup: 4.57.1 + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0) + transitivePeerDependencies: + - supports-color + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + until-async@3.0.2: optional: true @@ -11390,6 +11653,21 @@ snapshots: extsprintf: 1.4.1 optional: true + vite-plugin-dts@5.1.2(esbuild@0.27.2)(rollup@4.57.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)): + dependencies: + unplugin-dts: 1.1.2(esbuild@0.27.2)(rollup@4.57.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0)) + optionalDependencies: + rollup: 4.57.1 + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0) + transitivePeerDependencies: + - '@rspack/core' + - '@vue/language-core' + - esbuild + - rolldown + - supports-color + - typescript + - webpack + vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.32.0): dependencies: esbuild: 0.27.2 @@ -11397,7 +11675,7 @@ snapshots: picomatch: 4.0.3 postcss: 8.5.6 rollup: 4.57.1 - tinyglobby: 0.2.15 + tinyglobby: 0.2.17 optionalDependencies: '@types/node': 25.2.0 fsevents: 2.3.3 @@ -11478,10 +11756,25 @@ snapshots: - tsx - yaml + vscode-jsonrpc@10.0.0: {} + + vscode-languageserver-protocol@3.18.5: + dependencies: + vscode-jsonrpc: 10.0.0 + vscode-languageserver-types: 3.18.5 + + vscode-languageserver-textdocument@1.0.16: {} + + vscode-languageserver-types@3.18.5: {} + + vscode-uri@3.2.0: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 + webpack-virtual-modules@0.6.2: {} + when-exit@2.1.5: {} which-boxed-primitive@1.1.1: From addb67e8a1a6a85e7ac386dec0cc0a2d40de9689 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 13:16:57 +0100 Subject: [PATCH 08/12] docs(frontend-kit): document the single package and external use The workspace tables still listed ui and core as two packages. Rewrites the kit README around the published package: where code goes and why src/core may not import React, the build and why Rollup rather than tsc or tsup, why the tarball ships src/, and a consumer recipe covering peers, index.css, the vite dedupe, the tsconfig, pointing the socket at a remote backend and registering a logger module. States that the registry is not set up yet and that a tarball from pnpm pack is the way to consume it meanwhile. --- README.md | 3 +- frontend/README.md | 3 +- frontend/frontend-kit/kit/README.md | 136 ++++++++++++++++++++++++++-- 3 files changed, 131 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ad1b6ba76..ea2a5c2d7 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,7 @@ Our `pnpm-workspace.yaml` defines the following workspaces: | `blcu-programming` | Python | FastAPI service that flashes firmware to the BLCU board via TFTP | | `hyperloop-control-station` | JS | The main Control Station electron desktop application | | `e2e` | TS | End-to-end tests for the whole app (Playwright) | -| `@hyperloop-upv/frontend-kit` | TS/React | Shared UI component library (frontend-kit) | -| `@hyperloop-upv/frontend-kit/core` | TS | Shared business logic and types (frontend-kit) | +| `@hyperloop-upv/frontend-kit` | TS/React | Shared UI components, hooks, icons and the WebSocket layer (its `./core` subpath) | | `@hyperloop-upv/eslint-config` | ESLint | Common ESLint configuration (frontend-kit) | | `@hyperloop-upv/typescript-config` | TS | Common TypeScript configuration (frontend-kit) | diff --git a/frontend/README.md b/frontend/README.md index d78fb77b2..aba6db2f5 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -15,8 +15,7 @@ The frontend is organized as 7 workspaces out of 10 in the whole monorepo, divid | `testing-view` | Primary telemetry testing and debugging interface | | `competition-view` | Competition-focused UI (simplified view) | | `flashing-view` | UI for flashing firmware to the BLCU board | -| `frontend-kit/kit` or `@hyperloop-upv/frontend-kit` | Component library built on shadcn/ui and Radix UI | -| `frontend-kit/kit/src/core` or `@hyperloop-upv/frontend-kit/core` | Shared business logic, WebSocket utilities, and types | +| `frontend-kit/kit` or `@hyperloop-upv/frontend-kit` | Component library built on shadcn/ui and Radix UI, plus the framework-agnostic `./core` subpath (WebSocket, logging, types) | | `frontend-kit/eslint-config` or `@hyperloop-upv/eslint-config` | Common ESLint configurations | | `frontend-kit/typescript-config` or `@hyperloop-upv/typescript-config` | Common TypeScript configurations | diff --git a/frontend/frontend-kit/kit/README.md b/frontend/frontend-kit/kit/README.md index 5154c9140..749c62ae2 100644 --- a/frontend/frontend-kit/kit/README.md +++ b/frontend/frontend-kit/kit/README.md @@ -1,15 +1,38 @@ -# UI Package - Frontend Kit +# `@hyperloop-upv/frontend-kit` -This package is the main UI and React shared component library for the Hyperloop Control Station. It provides reusable, styled components and hooks built on top of **React**, **Shadcn/UI**, and **Tailwind CSS**. +The shared frontend package for the Hyperloop Control Station: reusable styled +components and hooks built on **React**, **Shadcn/UI** and **Tailwind CSS**, +plus the framework-agnostic WebSocket and logging layer. + +It is built for publication, so a frontend living in another repository can use +it too. See [Using it from another repository](#using-it-from-another-repository). ## Project Guidelines -### React-Only Logic +### Where code goes + +> - Logic that needs React hooks (`useState`, `useEffect`, ...) or TSX belongs +> in `src/components`, `src/hooks` or `src/lib`. +> - **Logic that does NOT need React** (websocket connections, for example) +> belongs in `src/core`, published as the `./core` subpath. That boundary is +> enforced by a lint rule, not just convention: `src/core` may not import +> React. It keeps `./core` usable from a plain Node script or an Electron main +> process. + +### Import paths -> This package is specifically for **UI and React-related components**. -> -> - If your logic requires React hooks (`useState`, `useEffect`, etc.) or TSX, it belongs here. -> - **If your logic does NOT need React** (e.g., websocket connections), it should be implemented in the `@hyperloop-upv/frontend-kit/core` package. This keeps the codebase clean and allows for better reuse across different environments. +```ts +import { Button } from "@hyperloop-upv/frontend-kit/components"; +import { useTopic } from "@hyperloop-upv/frontend-kit/hooks"; +import { ChevronDown } from "@hyperloop-upv/frontend-kit/icons"; +import { cn } from "@hyperloop-upv/frontend-kit/lib"; +import { socketService } from "@hyperloop-upv/frontend-kit/core"; +import logo from "@hyperloop-upv/frontend-kit/outreach/main/logo_icon.svg"; +``` + +Inside this package, always use **relative** imports. Referring to the package +by its own name makes the published build depend on self-reference resolution, +which bundlers support unevenly. --- @@ -34,3 +57,102 @@ pnpm icon:add src/icons # Remove an existing icon export (Example: pnpm icon:remove arrow-up src/icons) pnpm icon:remove src/icons ``` + +--- + +## Build + +```bash +pnpm --filter @hyperloop-upv/frontend-kit build +``` + +Vite in library mode with Rollup's `preserveModules`, which mirrors `src/` into +`dist/`. That is what keeps the wildcard subpath exports (`./components/*`) +resolving as components are added, with no entry list to maintain. Rollup is +used rather than `tsc` or `tsup` because it rewrites relative specifiers with +real `.js` extensions; the other two emit extensionless imports, which are not +valid ESM. + +`exports` points at `src/`, so the five apps in this monorepo keep compiling +kit source directly and keep their HMR. `publishConfig.exports` points at +`dist/` and is what an external consumer sees. **Publish with `pnpm publish`:** +`npm publish` ignores that override and would ship a package whose exports +point at `.tsx`, with no error at publish time. + +The tarball ships `src/` as well as `dist/`. That is deliberate: the published +`globals.css` lives in `src/styles/` and its own `@source` directive resolves +relative to itself, so Tailwind finds the kit's classes inside `node_modules` +with no build-time transform. + +--- + +## Using it from another repository + +> The registry setup is not in place yet. Until it is, build a tarball with +> `pnpm --filter @hyperloop-upv/frontend-kit exec pnpm pack` and install that +> file directly. + +Install the package and the peer dependencies it expects you to own: + +```bash +pnpm add @hyperloop-upv/frontend-kit +pnpm add react react-dom lucide-react tw-animate-css +pnpm add -D tailwindcss @tailwindcss/vite +``` + +`src/index.css`: + +```css +@import "@hyperloop-upv/frontend-kit/globals.css"; + +/* Add your own sources. The kit's stylesheet can only register files inside + the kit, because its directive resolves relative to node_modules. */ +@source "./**/*.{ts,tsx}"; +``` + +That single import brings the theme variables, the four themes, the dark and +pink variants, the `@theme inline` map, the base layer, scrollbars, +`tw-animate-css` and the Archivo font. + +`vite.config.ts`: + +```ts +import tailwindcss from "@tailwindcss/vite"; +import react from "@vitejs/plugin-react-swc"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [react(), tailwindcss()], + // The kit declares react/react-dom as peers; dedupe guarantees one copy, + // since two copies of React break hooks. + resolve: { dedupe: ["react", "react-dom"] }, +}); +``` + +Do not add `@radix-ui/*` to your own dependencies. The kit owns those, and two +copies of the same Radix package cause real focus-trap and scroll-lock bugs. + +Your `tsconfig` needs **no `paths` entry** for the kit, and must use +`"moduleResolution": "bundler"` (or `"nodenext"`) so TypeScript honours the +package's `exports` map. + +### Pointing it at a backend + +The socket defaults to `ws://127.0.0.1:4000/backend`. For anything else, set it +once when the app boots: + +```ts +import { configureSocket } from "@hyperloop-upv/frontend-kit/core"; + +configureSocket({ url: import.meta.env.VITE_WS_URL }); +// or: configureSocket({ host: "pod.local", port: 8080, secure: true }); +``` + +### Registering your own logger module + +```ts +import { ansi, createLogger, registerLoggerColor } from "@hyperloop-upv/frontend-kit/core"; + +registerLoggerColor("pod-dashboard", ansi.cyan); +export const log = createLogger("pod-dashboard"); +``` From bdba2e569a40fc140b0c9403245cd35387c37b7d Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 13:32:10 +0100 Subject: [PATCH 09/12] ci: fix dead pnpm filters in the frontend tests workflow The install step passed --filter=ui --filter=core. pnpm filters by package name, and those were never the names: the packages were @workspace/ui and @workspace/core, now merged into @hyperloop-upv/frontend-kit. Both filters selected nothing. Uses --filter="./frontend/**" instead, matching the build and test steps in the same job, so the install cannot drift from the package names again. --- .github/workflows/frontend-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/frontend-tests.yaml b/.github/workflows/frontend-tests.yaml index 4ee2617d7..ffac902a4 100644 --- a/.github/workflows/frontend-tests.yaml +++ b/.github/workflows/frontend-tests.yaml @@ -29,7 +29,7 @@ jobs: cache: "pnpm" - name: Install dependencies - run: pnpm install --frozen-lockfile --filter=testing-view --filter=flashing-view --filter=competition-view --filter=logging-view --filter=adj-view --filter=ui --filter=core + run: pnpm install --frozen-lockfile --filter="./frontend/**" - name: Build frontend run: pnpm build --filter="./frontend/**" From c68665eedde8dc19ae751c1bee38d92893051dc8 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 13:39:24 +0100 Subject: [PATCH 10/12] ci: publish the frontend kit to GitHub Packages Adds the registry scope mapping and a manual publish workflow, so the kit can reach a frontend living in another repository. The root .npmrc carries no auth token on purpose. Every @hyperloop-upv/* dependency here is a workspace link, so pnpm never contacts the registry and nobody needs a token to install; a committed _authToken=${NODE_AUTH_TOKEN} would break pnpm install for anyone without that variable. Verified that a frozen-lockfile install still succeeds with no token present. The workflow is workflow_dispatch only and defaults to dry-run, so its first ever run cannot publish by accident, and the publish step is gated on an explicit boolean false so it fails closed. Before the irreversible step it checks the dispatched version against the committed one and asserts the tarball: private, the preinstall hook, publishConfig.exports actually being applied, the ./core subpath, the peers, a leaked workspace: range, and that src/ ships so Tailwind can scan the kit inside node_modules. Publishing uses pnpm, not npm: npm ignores publishConfig.exports and would ship a package whose exports point at .tsx, with no error. Both scripted steps were extracted from the YAML and run locally against the real tarball. --- .github/workflows/publish-frontend-kit.yaml | 146 ++++++++++++++++++++ .npmrc | 11 ++ 2 files changed, 157 insertions(+) create mode 100644 .github/workflows/publish-frontend-kit.yaml create mode 100644 .npmrc diff --git a/.github/workflows/publish-frontend-kit.yaml b/.github/workflows/publish-frontend-kit.yaml new file mode 100644 index 000000000..7b005defe --- /dev/null +++ b/.github/workflows/publish-frontend-kit.yaml @@ -0,0 +1,146 @@ +name: Publish Frontend Kit + +# Publishes @hyperloop-upv/frontend-kit to GitHub Packages so a frontend in +# another repository can install it. +# +# Manual on purpose, mirroring release.yaml. Run it once with dry-run left on +# (the default) and read the tarball listing in the log, then run it again with +# dry-run off. A published version can never be reused: if 0.1.0 is wrong, the +# fix is to publish 0.1.1. + +on: + workflow_dispatch: + inputs: + version: + description: "Version to publish. Must already be committed in the package.json, e.g. 0.1.0" + required: true + dry-run: + description: "Pack and check only, do not publish" + type: boolean + default: true + tag: + description: "npm dist-tag" + default: "latest" + +jobs: + publish: + name: Publish @hyperloop-upv/frontend-kit + runs-on: ubuntu-latest + permissions: + contents: read + # Not the default. Without it, publishing fails with a bare 403. + packages: write + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "24" + cache: "pnpm" + # Writes an auth-ready npmrc outside the working tree, so the git + # tree stays clean. + registry-url: "https://npm.pkg.github.com" + scope: "@hyperloop-upv" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check the committed version matches the input + run: | + set -euo pipefail + committed=$(node -p "require('./frontend/frontend-kit/kit/package.json').version") + if [ "$committed" != "${{ inputs.version }}" ]; then + echo "::error::package.json says $committed but you dispatched ${{ inputs.version }}" + exit 1 + fi + echo "version $committed" + + - name: Build + run: pnpm build --filter=@hyperloop-upv/frontend-kit + + - name: Pack + run: | + set -euo pipefail + mkdir -p /tmp/kit + pnpm --filter @hyperloop-upv/frontend-kit exec pnpm pack --pack-destination /tmp/kit + echo "::group::Tarball contents" + tar -tzf /tmp/kit/hyperloop-upv-frontend-kit-${{ inputs.version }}.tgz | sort + echo "::endgroup::" + + # Catches the failures that are cheap to prevent and impossible to undo + # once a version is published. + - name: Check the tarball + run: | + set -euo pipefail + T=/tmp/kit/hyperloop-upv-frontend-kit-${{ inputs.version }}.tgz + + # Via a file, not a pipe: a heredoc would occupy stdin and the + # script would read nothing. + tar -xzOf "$T" package/package.json > /tmp/kit/packed.json + + python3 - <<'PY' + import json, sys + + p = json.load(open("/tmp/kit/packed.json")) + failures = [] + + def check(cond, msg): + print((" ok " if cond else " FAIL ") + msg) + if not cond: + failures.append(msg) + + check(not p.get("private"), "private:true does not survive") + check("preinstall" not in p.get("scripts", {}), "the preinstall hook does not survive") + check( + p["exports"]["."]["default"].startswith("./dist"), + "publishConfig.exports was applied (npm publish would skip it)", + ) + check(p["exports"]["./core"]["default"] == "./dist/core/index.js", "./core points at dist") + check( + p["exports"]["./globals.css"] == "./src/styles/globals.css", + "globals.css is served from the shipped src, so Tailwind can scan it", + ) + check( + set(p.get("peerDependencies", {})) + >= {"react", "react-dom", "lucide-react", "tailwindcss", "tw-animate-css"}, + "the five peer dependencies are declared", + ) + check( + not any(str(v).startswith("workspace:") for v in p.get("dependencies", {}).values()), + "no literal workspace: range leaked into the tarball", + ) + + if failures: + sys.exit("\nRefusing to publish: " + "; ".join(failures)) + print("\ntarball ok") + PY + + # Tailwind needs the kit's sources to find its classes in node_modules. + tar -tzf "$T" | grep -qx 'package/src/components/shadcn/sidebar.tsx' \ + || { echo "::error::src/ is missing from the tarball"; exit 1; } + echo " ok src/ ships alongside dist/" + + - uses: actions/upload-artifact@v4 + with: + name: frontend-kit-${{ inputs.version }} + path: /tmp/kit/*.tgz + retention-days: 7 + + # Fails closed: anything other than an explicit boolean false skips this. + - name: Publish + if: ${{ inputs.dry-run == false }} + run: pnpm publish --filter=@hyperloop-upv/frontend-kit --no-git-checks --tag ${{ inputs.tag }} + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Summary + run: | + if [ "${{ inputs.dry-run }}" = "true" ]; then + echo "### Dry run: nothing was published" >> $GITHUB_STEP_SUMMARY + echo "Tarball for \`${{ inputs.version }}\` is attached as an artifact. Re-run with dry-run off to publish." >> $GITHUB_STEP_SUMMARY + else + echo "### Published \`@hyperloop-upv/frontend-kit@${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY + echo "Check the package visibility under Organisation -> Packages -> Package settings." >> $GITHUB_STEP_SUMMARY + fi diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..3aa5e8bf2 --- /dev/null +++ b/.npmrc @@ -0,0 +1,11 @@ +; Where to look for the @hyperloop-upv scope. Needed so that `pnpm publish` +; targets GitHub Packages instead of npmjs.com. +; +; Deliberately no auth token line here: every @hyperloop-upv/* dependency in +; this monorepo is a workspace link, so pnpm never contacts the registry and +; nobody needs a token to install. Adding _authToken=${NODE_AUTH_TOKEN} would +; make `pnpm install` fail for anyone without that variable set. +; +; That holds only while no @hyperloop-upv/* dependency here comes from the +; registry. If one ever does, auth becomes mandatory for all contributors. +@hyperloop-upv:registry=https://npm.pkg.github.com From 41a173341feac9c57556c799564d41daaaf2e7a2 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 13:39:48 +0100 Subject: [PATCH 11/12] docs(frontend-kit): document registry consumption and releasing The README still said the registry was not set up. Documents the consumer .npmrc, the classic PAT with read:packages that GitHub Packages requires even to download a public package, the CI permissions, and the release steps with the warning that a published version can never be reused. --- frontend/frontend-kit/kit/README.md | 57 +++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/frontend/frontend-kit/kit/README.md b/frontend/frontend-kit/kit/README.md index 749c62ae2..53489ec61 100644 --- a/frontend/frontend-kit/kit/README.md +++ b/frontend/frontend-kit/kit/README.md @@ -88,11 +88,36 @@ with no build-time transform. ## Using it from another repository -> The registry setup is not in place yet. Until it is, build a tarball with -> `pnpm --filter @hyperloop-upv/frontend-kit exec pnpm pack` and install that -> file directly. +The kit is published to **GitHub Packages**, not npmjs.com. That registry +requires a token for every request, **including downloading a public package**, +so there is a one-time setup per contributor and per CI job. -Install the package and the peer dependencies it expects you to own: +`.npmrc` in the consuming repository: + +``` +@hyperloop-upv:registry=https://npm.pkg.github.com +//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN} +``` + +Each contributor exports `NODE_AUTH_TOKEN` with a **classic** personal access +token carrying the `read:packages` scope, from +. Use a classic token: fine-grained ones +still have patchy support for this registry. Without the variable, the install +fails with `ERR_PNPM_FETCH_401`. + +In CI, use the job's own token and grant it read access to packages: + +```yaml +permissions: + contents: read + packages: read # required even for a public package +steps: + - run: pnpm install --frozen-lockfile + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` + +Then install the package and the peer dependencies it expects you to own: ```bash pnpm add @hyperloop-upv/frontend-kit @@ -100,6 +125,10 @@ pnpm add react react-dom lucide-react tw-animate-css pnpm add -D tailwindcss @tailwindcss/vite ``` +> To try a change before it is published, build a tarball with +> `pnpm --filter @hyperloop-upv/frontend-kit exec pnpm pack` and +> `pnpm add` that file directly. No registry and no token involved. + `src/index.css`: ```css @@ -156,3 +185,23 @@ import { ansi, createLogger, registerLoggerColor } from "@hyperloop-upv/frontend registerLoggerColor("pod-dashboard", ansi.cyan); export const log = createLogger("pod-dashboard"); ``` + +--- + +## Releasing + +1. Bump `version` in this `package.json` and commit it. +2. Actions -> **Publish Frontend Kit** -> enter the version, leave **dry-run + on**. Read the tarball listing in the log; the tarball is attached as an + artifact if you want to install it somewhere first. +3. Run it again with **dry-run off**. +4. First release only: check the package is public under Organisation -> + Packages -> Package settings, and that this repository has write access. + +**A published version can never be reused.** Deleting a version does not free +the number. If `0.1.0` is wrong, publish `0.1.1`. + +The five apps in this monorepo stay on `workspace:*` and are unaffected by what +is published: pnpm always prefers the local link. Only an external consumer +pins a published range such as `^0.1.0`, which on `0.x` picks up patches but +requires a deliberate edit to move to `0.2.0`. From 2bb04c04a4ef78c6f2e0de36626c95574c75c5c5 Mon Sep 17 00:00:00 2001 From: Javier Ribal del Rio Date: Sat, 31 Oct 2026 13:46:08 +0100 Subject: [PATCH 12/12] ci: release the frontend kit alongside the control station Every Control Station release now publishes the kit at the same version, so v11.3.2 of the station and @hyperloop-upv/frontend-kit@11.3.2 refer to the same commit. The publish workflow gains a workflow_call trigger and release.yaml calls it as its last job, gated on the whole release having succeeded: publishing cannot be undone and must not happen for a release that failed to build. A publish-kit input, on by default, opts out. The version is injected in CI with pnpm version --no-git-tag-version rather than read from the committed package.json, which is the convention electron-app already follows; the kit's version becomes the same 0.0.0 placeholder, and the git tag is the record of what shipped. Prereleases get the next dist-tag instead of latest. The repo has shipped 11.3.2-beta-2 and 11.3.2-1, and publishing either as latest would make a prerelease the default install for every consumer. The dist-tag derivation and the version guard were both extracted from the YAML and run locally across the version formats this repo uses, including a leading v and the empty case. --- .github/workflows/publish-frontend-kit.yaml | 106 +++++++++++++++----- .github/workflows/release.yaml | 21 ++++ frontend/frontend-kit/kit/README.md | 63 ++++++++++-- frontend/frontend-kit/kit/package.json | 2 +- 4 files changed, 155 insertions(+), 37 deletions(-) diff --git a/.github/workflows/publish-frontend-kit.yaml b/.github/workflows/publish-frontend-kit.yaml index 7b005defe..ee6d1ac4f 100644 --- a/.github/workflows/publish-frontend-kit.yaml +++ b/.github/workflows/publish-frontend-kit.yaml @@ -3,24 +3,44 @@ name: Publish Frontend Kit # Publishes @hyperloop-upv/frontend-kit to GitHub Packages so a frontend in # another repository can install it. # -# Manual on purpose, mirroring release.yaml. Run it once with dry-run left on -# (the default) and read the tarball listing in the log, then run it again with -# dry-run off. A published version can never be reused: if 0.1.0 is wrong, the -# fix is to publish 0.1.1. +# Normally runs as part of release.yaml, at the same version as the Control +# Station, so the two always ship together. Can also be dispatched on its own +# to cut a kit-only release. +# +# As with electron-app, the version is injected here and is not committed: the +# number in package.json is a placeholder, and the git tag created by +# release.yaml is the record of what was published from which commit. +# +# A published version can never be reused. Deleting it does not free the +# number: if 11.3.2 is wrong, publish 11.3.3. on: + workflow_call: + inputs: + version: + description: "Version to publish, without a leading v" + required: true + type: string + dry-run: + description: "Pack and check only, do not publish" + type: boolean + default: true + tag: + description: "npm dist-tag. Derived from the version when empty" + type: string + default: "" workflow_dispatch: inputs: version: - description: "Version to publish. Must already be committed in the package.json, e.g. 0.1.0" + description: "Version to publish (e.g., 11.3.2)" required: true dry-run: description: "Pack and check only, do not publish" type: boolean default: true tag: - description: "npm dist-tag" - default: "latest" + description: "npm dist-tag. Leave empty to derive it from the version" + default: "" jobs: publish: @@ -34,6 +54,8 @@ jobs: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 + with: + version: 10.26.0 - uses: actions/setup-node@v4 with: @@ -44,44 +66,72 @@ jobs: registry-url: "https://npm.pkg.github.com" scope: "@hyperloop-upv" - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check the committed version matches the input + - name: Resolve version and dist-tag + id: resolve + shell: bash run: | set -euo pipefail - committed=$(node -p "require('./frontend/frontend-kit/kit/package.json').version") - if [ "$committed" != "${{ inputs.version }}" ]; then - echo "::error::package.json says $committed but you dispatched ${{ inputs.version }}" + + # release.yaml tags as v, so accept either spelling. + version="${{ inputs.version }}" + version="${version#v}" + + if [ -z "$version" ]; then + echo "::error::version is empty" exit 1 fi - echo "version $committed" + + requested="${{ inputs.tag }}" + if [ -n "$requested" ]; then + tag="$requested" + elif [ "${version#*-}" != "$version" ]; then + # A prerelease such as 11.3.2-beta-2 must not land on "latest", or + # it becomes the default install for every consumer. + tag="next" + else + tag="latest" + fi + + echo "version=$version" >> $GITHUB_OUTPUT + echo "tag=$tag" >> $GITHUB_OUTPUT + echo "publishing $version under dist-tag $tag" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + # Same approach as electron-app in release.yaml: set it here, do not + # expect it committed. + - name: Set the version + working-directory: frontend/frontend-kit/kit + run: pnpm version ${{ steps.resolve.outputs.version }} --no-git-tag-version --allow-same-version - name: Build run: pnpm build --filter=@hyperloop-upv/frontend-kit - name: Pack + shell: bash run: | set -euo pipefail mkdir -p /tmp/kit pnpm --filter @hyperloop-upv/frontend-kit exec pnpm pack --pack-destination /tmp/kit echo "::group::Tarball contents" - tar -tzf /tmp/kit/hyperloop-upv-frontend-kit-${{ inputs.version }}.tgz | sort + tar -tzf /tmp/kit/hyperloop-upv-frontend-kit-${{ steps.resolve.outputs.version }}.tgz | sort echo "::endgroup::" # Catches the failures that are cheap to prevent and impossible to undo # once a version is published. - name: Check the tarball + shell: bash run: | set -euo pipefail - T=/tmp/kit/hyperloop-upv-frontend-kit-${{ inputs.version }}.tgz + T=/tmp/kit/hyperloop-upv-frontend-kit-${{ steps.resolve.outputs.version }}.tgz # Via a file, not a pipe: a heredoc would occupy stdin and the # script would read nothing. tar -xzOf "$T" package/package.json > /tmp/kit/packed.json - python3 - <<'PY' - import json, sys + EXPECTED_VERSION="${{ steps.resolve.outputs.version }}" python3 - <<'PY' + import json, os, sys p = json.load(open("/tmp/kit/packed.json")) failures = [] @@ -91,6 +141,10 @@ jobs: if not cond: failures.append(msg) + check( + p["version"] == os.environ["EXPECTED_VERSION"], + f"version is {os.environ['EXPECTED_VERSION']}, got {p['version']}", + ) check(not p.get("private"), "private:true does not survive") check("preinstall" not in p.get("scripts", {}), "the preinstall hook does not survive") check( @@ -124,23 +178,25 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: frontend-kit-${{ inputs.version }} + name: frontend-kit-${{ steps.resolve.outputs.version }} path: /tmp/kit/*.tgz retention-days: 7 # Fails closed: anything other than an explicit boolean false skips this. - name: Publish if: ${{ inputs.dry-run == false }} - run: pnpm publish --filter=@hyperloop-upv/frontend-kit --no-git-checks --tag ${{ inputs.tag }} + run: pnpm publish --filter=@hyperloop-upv/frontend-kit --no-git-checks --tag ${{ steps.resolve.outputs.tag }} env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Summary + shell: bash run: | - if [ "${{ inputs.dry-run }}" = "true" ]; then + V='${{ steps.resolve.outputs.version }}' + if [ '${{ inputs.dry-run }}' = 'true' ]; then echo "### Dry run: nothing was published" >> $GITHUB_STEP_SUMMARY - echo "Tarball for \`${{ inputs.version }}\` is attached as an artifact. Re-run with dry-run off to publish." >> $GITHUB_STEP_SUMMARY + echo "Tarball for \`$V\` is attached as an artifact. Re-run with dry-run off to publish." >> $GITHUB_STEP_SUMMARY else - echo "### Published \`@hyperloop-upv/frontend-kit@${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY - echo "Check the package visibility under Organisation -> Packages -> Package settings." >> $GITHUB_STEP_SUMMARY + echo "### Published \`@hyperloop-upv/frontend-kit@$V\`" >> $GITHUB_STEP_SUMMARY + echo "dist-tag: \`${{ steps.resolve.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY fi diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 11e23b750..8ee9c41cf 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -30,6 +30,10 @@ on: description: "Include ADJ Viewer" type: boolean default: true + publish-kit: + description: "Publish @hyperloop-upv/frontend-kit at this same version" + type: boolean + default: true jobs: @@ -44,6 +48,7 @@ jobs: include_flashing: ${{ steps.get_version.outputs.include_flashing }} include_logging: ${{ steps.get_version.outputs.include_logging }} include_adj: ${{ steps.get_version.outputs.include_adj }} + publish_kit: ${{ steps.get_version.outputs.publish_kit }} steps: - name: Determine version id: get_version @@ -55,6 +60,7 @@ jobs: echo "include_flashing=${{ github.event.inputs.include-flashing }}" >> $GITHUB_OUTPUT echo "include_logging=${{ github.event.inputs.include-logging }}" >> $GITHUB_OUTPUT echo "include_adj=${{ github.event.inputs.include-adj }}" >> $GITHUB_OUTPUT + echo "publish_kit=${{ github.event.inputs.publish-kit }}" >> $GITHUB_OUTPUT create-draft-release: name: Create Draft Release @@ -380,3 +386,18 @@ jobs: | xargs gh release upload v${{ needs.determine-version.outputs.version }} --clobber env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + publish-frontend-kit: + name: Publish Frontend Kit + # Last, and only once the Control Station release itself succeeded: + # publishing to the registry cannot be undone, so it must not happen for a + # release that failed to build. + needs: [determine-version, package-and-upload] + if: needs.determine-version.outputs.publish_kit == 'true' + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-frontend-kit.yaml + with: + version: ${{ needs.determine-version.outputs.version }} + dry-run: false diff --git a/frontend/frontend-kit/kit/README.md b/frontend/frontend-kit/kit/README.md index 53489ec61..8c3f279ff 100644 --- a/frontend/frontend-kit/kit/README.md +++ b/frontend/frontend-kit/kit/README.md @@ -190,18 +190,59 @@ export const log = createLogger("pod-dashboard"); ## Releasing -1. Bump `version` in this `package.json` and commit it. -2. Actions -> **Publish Frontend Kit** -> enter the version, leave **dry-run - on**. Read the tarball listing in the log; the tarball is attached as an - artifact if you want to install it somewhere first. -3. Run it again with **dry-run off**. -4. First release only: check the package is public under Organisation -> - Packages -> Package settings, and that this repository has write access. +The kit rides along with the Control Station: **Actions -> Release Electron App** +publishes the kit at the same version as its last job, so `v11.3.2` of the +Control Station and `@hyperloop-upv/frontend-kit@11.3.2` always mean the same +commit. Nothing extra to run. The `publish-kit` input, on by default, turns it +off for a release that should not move the package. + +That job is last and depends on the whole release succeeding, because +publishing cannot be undone and must not happen for a release that failed to +build. + +**The `version` in this `package.json` is a placeholder**, the same `0.0.0` +convention `electron-app` uses. CI injects the real number with +`pnpm version --no-git-tag-version`, and the git tag is the record of what was +published from which commit. Do not bump it by hand expecting it to mean +anything. + +### The dist-tag + +A version with a prerelease part (`11.3.2-beta-2`, `11.3.2-1`) is published +under the `next` dist-tag instead of `latest`, so `pnpm add +@hyperloop-upv/frontend-kit` keeps resolving to the last stable release. Taking +a prerelease is then explicit: + +```bash +pnpm add @hyperloop-upv/frontend-kit@next +``` + +### Publishing the kit on its own + +For a kit-only release, Actions -> **Publish Frontend Kit** -> enter the +version, leave **dry-run on**. It packs, prints the tarball contents and +attaches it as an artifact without publishing. Read that, then run it again +with dry-run off. Pick a version above the last published one; the Control +Station numbering is shared, so a kit-only release normally takes the next +patch. + +First release only: check the package is public under Organisation -> Packages +-> Package settings, and that this repository has write access. **A published version can never be reused.** Deleting a version does not free -the number. If `0.1.0` is wrong, publish `0.1.1`. +the number. If `11.3.2` is wrong, publish `11.3.3`. + +### Versioning, and what it means for a consumer + +Versions are shared with the Control Station, so the numbers track **releases +of the station, not the kit's own API**. A minor bump may carry a breaking +change to a component, and a major bump may change nothing here at all. An +external consumer should therefore pin the exact version it was tested +against, or pin a patch range and read the release notes before moving: + +```json +"@hyperloop-upv/frontend-kit": "~11.3.2" +``` The five apps in this monorepo stay on `workspace:*` and are unaffected by what -is published: pnpm always prefers the local link. Only an external consumer -pins a published range such as `^0.1.0`, which on `0.x` picks up patches but -requires a deliberate edit to move to `0.2.0`. +is published: pnpm always prefers the local link. diff --git a/frontend/frontend-kit/kit/package.json b/frontend/frontend-kit/kit/package.json index 557f1a461..74395fb25 100644 --- a/frontend/frontend-kit/kit/package.json +++ b/frontend/frontend-kit/kit/package.json @@ -1,6 +1,6 @@ { "name": "@hyperloop-upv/frontend-kit", - "version": "0.1.0", + "version": "0.0.0", "description": "Shared React + Tailwind component kit and WebSocket layer for Hyperloop UPV frontends", "license": "MIT", "type": "module",