diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 77280cd0e..ce8ae26e1 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -38,6 +38,7 @@ jobs: shell: bash bump-winget: if: ${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, 'beta') }} + needs: [publish] runs-on: windows-latest steps: - uses: actions/checkout@v4 @@ -48,8 +49,10 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install winget uses: Cyberboss/install-winget@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Install wingetcreate - run: winget install wingetcreate --accept-package-agreements + run: winget install -e --silent --accept-package-agreements --accept-source-agreements wingetcreate shell: pwsh - name: Submit WinGet version bump run: "task artifacts:winget:publish:${{ github.ref_name }}" diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index f6307cf83..ef6b1049e 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -3,9 +3,9 @@ import type { Preview } from "@storybook/react"; import React from "react"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; -import "../frontend/app/theme.less"; -import "../frontend/app/app.less"; -import "../frontend/app/reset.less"; +import "../frontend/app/theme.scss"; +import "../frontend/app/app.scss"; +import "../frontend/app/reset.scss"; import "./global.css"; import { light, dark } from "./theme"; import { DocsContainer } from "@storybook/addon-docs"; diff --git a/docs/docs/releasenotes.mdx b/docs/docs/releasenotes.mdx index 34704bcb0..9d5ccc614 100644 --- a/docs/docs/releasenotes.mdx +++ b/docs/docs/releasenotes.mdx @@ -19,10 +19,14 @@ New minor release that introduces Wave's connected computing extensions. We've i - New block/zone aliases (client, global, block, workspace, temp) - `wsh ai` file attachments are now rendered with special handling in the AI block - New ephemeral block type for creating modal widgets which will not disturb the underlying layout +- Editing the AI presets file from the Wave AI block now brings up an ephemeral editor +- Clicking outside of a magnified bglock will now un-magnify it - New button to clear the AI chat (also bound to Cmd-L) +- New button to reset terminal commands in custom cmd widgets - [bugfix] Presets directory was not loading correctly on Windows - [bugfix] Magnified blocks were not showing correct on startup - [bugfix] Window opacity and background color was not getting applied properly in all cases +- [bugfix] Fix terminal theming when applying global defaults [#1287](https://github.com/wavetermdev/waveterm/issues/1287) - MacOS 10.15 (Catalina) is no longer supported - Other bug fixes, docs improvements, and dependency bumps diff --git a/electron.vite.config.ts b/electron.vite.config.ts index f2d8572d9..f90eec2d6 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -30,6 +30,13 @@ export default defineConfig({ "process.env.WS_NO_BUFFER_UTIL": "true", "process.env.WS_NO_UTF_8_VALIDATE": "true", }, + css: { + preprocessorOptions: { + scss: { + api: "modern-compiler", // or "modern" + }, + }, + }, }, preload: { root: ".", @@ -76,5 +83,12 @@ export default defineConfig({ targets: [{ src: "node_modules/monaco-editor/min/vs/*", dest: "monaco" }], }), ], + css: { + preprocessorOptions: { + scss: { + api: "modern-compiler", // or "modern" + }, + }, + }, }, }); diff --git a/frontend/app/app.less b/frontend/app/app.scss similarity index 96% rename from frontend/app/app.less rename to frontend/app/app.scss index f208d85d9..d2cc0275d 100644 --- a/frontend/app/app.less +++ b/frontend/app/app.scss @@ -1,8 +1,8 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "./reset.less"; -@import "./theme.less"; +@use "reset.scss"; +@use "theme.scss"; body { display: flex; @@ -12,7 +12,7 @@ body { color: var(--main-text-color); font: var(--base-font); overflow: hidden; - background: var(--main-bg-color); + background: rgb(from var(--main-bg-color) r g b / var(--window-opacity)); -webkit-font-smoothing: auto; backface-visibility: hidden; transform: translateZ(0); diff --git a/frontend/app/app.tsx b/frontend/app/app.tsx index b32bc3bf1..f2bb79b09 100644 --- a/frontend/app/app.tsx +++ b/frontend/app/app.tsx @@ -17,7 +17,6 @@ import { getElemAsStr } from "@/util/focusutil"; import * as keyutil from "@/util/keyutil"; import * as util from "@/util/util"; import clsx from "clsx"; -import Color from "color"; import debug from "debug"; import { Provider, useAtomValue } from "jotai"; import "overlayscrollbars/overlayscrollbars.css"; @@ -28,7 +27,7 @@ import { AppBackground } from "./app-bg"; import { CenteredDiv } from "./element/quickelems"; import { NotificationBubbles } from "./notification/notificationbubbles"; -import "./app.less"; +import "./app.scss"; const dlog = debug("wave:app"); const focusLog = debug("wave:focus"); @@ -130,21 +129,24 @@ function AppSettingsUpdater() { const isTransparentOrBlur = (windowSettings?.["window:transparent"] || windowSettings?.["window:blur"]) ?? false; const opacity = util.boundNumber(windowSettings?.["window:opacity"] ?? 0.8, 0, 1); - let baseBgColor = windowSettings?.["window:bgcolor"]; + const baseBgColor = windowSettings?.["window:bgcolor"]; const mainDiv = document.getElementById("main"); // console.log("window settings", windowSettings, isTransparentOrBlur, opacity, baseBgColor, mainDiv); if (isTransparentOrBlur) { mainDiv.classList.add("is-transparent"); - const rootStyles = getComputedStyle(document.documentElement); - if (baseBgColor == null) { - baseBgColor = rootStyles.getPropertyValue("--main-bg-color").trim(); + if (opacity != null) { + document.body.style.setProperty("--window-opacity", `${opacity}`); + } else { + document.body.style.removeProperty("--window-opacity"); } - const color = new Color(baseBgColor); - const rgbaColor = color.alpha(opacity).string(); - document.body.style.backgroundColor = rgbaColor; } else { mainDiv.classList.remove("is-transparent"); - document.body.style.backgroundColor = "var(--main-bg-color)"; + document.body.style.removeProperty("--window-opacity"); + } + if (baseBgColor != null) { + document.body.style.setProperty("--main-bg-color", baseBgColor); + } else { + document.body.style.removeProperty("--main-bg-color"); } }, [windowSettings]); return null; diff --git a/frontend/app/block/block.less b/frontend/app/block/block.scss similarity index 98% rename from frontend/app/block/block.less rename to frontend/app/block/block.scss index 94b40e4bb..b3db9222e 100644 --- a/frontend/app/block/block.less +++ b/frontend/app/block/block.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .block { display: flex; @@ -118,7 +118,7 @@ } .block-frame-text { - .ellipsis(); + @include mixins.ellipsis(); font: var(--fixed-font); font-size: 11px; opacity: 0.7; @@ -324,7 +324,7 @@ } .connstatus-status { - .ellipsis(); + @include mixins.ellipsis(); display: flex; flex-direction: column; align-items: flex-start; @@ -333,7 +333,7 @@ width: 100%; .connstatus-status-text { - .ellipsis(); + @include mixins.ellipsis(); max-width: 100%; font-size: 11px; font-style: normal; @@ -344,7 +344,7 @@ } .connstatus-error { - .ellipsis(); + @include mixins.ellipsis(); width: 94%; font-size: 11px; font-style: normal; diff --git a/frontend/app/block/block.tsx b/frontend/app/block/block.tsx index 95a0f4ec6..05d13aae3 100644 --- a/frontend/app/block/block.tsx +++ b/frontend/app/block/block.tsx @@ -34,7 +34,7 @@ import { WebView, WebViewModel, makeWebViewModel } from "@/view/webview/webview" import clsx from "clsx"; import { atom, useAtomValue } from "jotai"; import { Suspense, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; -import "./block.less"; +import "./block.scss"; import { BlockFrame } from "./blockframe"; import { blockViewToIcon, blockViewToName } from "./blockutil"; diff --git a/frontend/app/element/avatar.less b/frontend/app/element/avatar.scss similarity index 94% rename from frontend/app/element/avatar.less rename to frontend/app/element/avatar.scss index 49158bbc1..e5495cc44 100644 --- a/frontend/app/element/avatar.less +++ b/frontend/app/element/avatar.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .avatar { position: relative; @@ -53,5 +53,5 @@ } } - .avatar-dims-mixin(); + @include mixins.avatar-dims-mixin(); } diff --git a/frontend/app/element/avatar.tsx b/frontend/app/element/avatar.tsx index 34b20bc90..c6afe67ae 100644 --- a/frontend/app/element/avatar.tsx +++ b/frontend/app/element/avatar.tsx @@ -3,7 +3,7 @@ import { memo } from "react"; import clsx from "clsx"; -import "./avatar.less"; +import "./avatar.scss"; interface AvatarProps { name: string; diff --git a/frontend/app/element/button.less b/frontend/app/element/button.scss similarity index 94% rename from frontend/app/element/button.less rename to frontend/app/element/button.scss index 97580de10..cca0930c0 100644 --- a/frontend/app/element/button.less +++ b/frontend/app/element/button.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .button { // override default button appearance @@ -158,9 +158,9 @@ } // Include mixins - .border-radius-mixin(); - .vertical-padding-mixin(); - .horizontal-padding-mixin(); - .font-size-mixin(); - .font-weight-mixin(); + @include mixins.border-radius-mixin(); + @include mixins.vertical-padding-mixin(); + @include mixins.horizontal-padding-mixin(); + @include mixins.font-size-mixin(); + @include mixins.font-weight-mixin(); } diff --git a/frontend/app/element/button.tsx b/frontend/app/element/button.tsx index cd8447b78..499bcdb8f 100644 --- a/frontend/app/element/button.tsx +++ b/frontend/app/element/button.tsx @@ -4,7 +4,7 @@ import clsx from "clsx"; import { forwardRef, memo, ReactNode, useImperativeHandle, useRef } from "react"; -import "./button.less"; +import "./button.scss"; interface ButtonProps extends React.ButtonHTMLAttributes { className?: string; diff --git a/frontend/app/element/collapsiblemenu.less b/frontend/app/element/collapsiblemenu.scss similarity index 94% rename from frontend/app/element/collapsiblemenu.less rename to frontend/app/element/collapsiblemenu.scss index 0a37113f5..b73f1f083 100644 --- a/frontend/app/element/collapsiblemenu.less +++ b/frontend/app/element/collapsiblemenu.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .collapsible-menu { list-style: none; @@ -32,7 +32,7 @@ } .collapsible-menu-item-text { - .ellipsis(); + @include mixins.ellipsis(); text-decoration: none; } diff --git a/frontend/app/element/collapsiblemenu.tsx b/frontend/app/element/collapsiblemenu.tsx index 6dd3385ce..d830934c6 100644 --- a/frontend/app/element/collapsiblemenu.tsx +++ b/frontend/app/element/collapsiblemenu.tsx @@ -3,7 +3,7 @@ import clsx from "clsx"; import React, { memo, useState } from "react"; -import "./collapsiblemenu.less"; +import "./collapsiblemenu.scss"; interface VerticalNavProps { items: MenuItem[]; diff --git a/frontend/app/element/copybutton.less b/frontend/app/element/copybutton.scss similarity index 100% rename from frontend/app/element/copybutton.less rename to frontend/app/element/copybutton.scss diff --git a/frontend/app/element/copybutton.tsx b/frontend/app/element/copybutton.tsx index a5e26bc5e..c51ff681c 100644 --- a/frontend/app/element/copybutton.tsx +++ b/frontend/app/element/copybutton.tsx @@ -3,7 +3,7 @@ import { clsx } from "clsx"; import { useEffect, useRef, useState } from "react"; -import "./copybutton.less"; +import "./copybutton.scss"; import { IconButton } from "./iconbutton"; type CopyButtonProps = { diff --git a/frontend/app/element/emojipalette.less b/frontend/app/element/emojipalette.scss similarity index 100% rename from frontend/app/element/emojipalette.less rename to frontend/app/element/emojipalette.scss diff --git a/frontend/app/element/emojipalette.tsx b/frontend/app/element/emojipalette.tsx index f0bf45bc0..11eeb0245 100644 --- a/frontend/app/element/emojipalette.tsx +++ b/frontend/app/element/emojipalette.tsx @@ -8,7 +8,7 @@ import { Button } from "./button"; import { Input, InputGroup, InputLeftElement } from "./input"; import { Popover, PopoverButton, PopoverContent } from "./popover"; -import "./emojipalette.less"; +import "./emojipalette.scss"; type EmojiItem = { emoji: string; name: string }; diff --git a/frontend/app/element/expandablemenu.less b/frontend/app/element/expandablemenu.scss similarity index 96% rename from frontend/app/element/expandablemenu.less rename to frontend/app/element/expandablemenu.scss index 949c8349b..741ee91f6 100644 --- a/frontend/app/element/expandablemenu.less +++ b/frontend/app/element/expandablemenu.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .expandable-menu { display: flex; @@ -20,7 +20,7 @@ border-radius: 4px; .label { - .ellipsis(); + @include mixins.ellipsis(); } } diff --git a/frontend/app/element/expandablemenu.tsx b/frontend/app/element/expandablemenu.tsx index 92c84a2c4..a6367bacb 100644 --- a/frontend/app/element/expandablemenu.tsx +++ b/frontend/app/element/expandablemenu.tsx @@ -5,7 +5,7 @@ import { clsx } from "clsx"; import { atom, useAtom } from "jotai"; import { Children, ReactElement, ReactNode, cloneElement, isValidElement, useRef } from "react"; -import "./expandablemenu.less"; +import "./expandablemenu.scss"; // Define the global atom for managing open groups const openGroupsAtom = atom<{ [key: string]: boolean }>({}); diff --git a/frontend/app/element/flyoutmenu.less b/frontend/app/element/flyoutmenu.scss similarity index 94% rename from frontend/app/element/flyoutmenu.less rename to frontend/app/element/flyoutmenu.scss index a4dcc7d16..83f20c1f6 100644 --- a/frontend/app/element/flyoutmenu.less +++ b/frontend/app/element/flyoutmenu.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .menu { position: absolute; @@ -38,7 +38,7 @@ justify-content: space-between; .label { - .ellipsis(); + @include mixins.ellipsis(); text-decoration: none; } } diff --git a/frontend/app/element/flyoutmenu.tsx b/frontend/app/element/flyoutmenu.tsx index 9510da501..8dcde7ff9 100644 --- a/frontend/app/element/flyoutmenu.tsx +++ b/frontend/app/element/flyoutmenu.tsx @@ -6,7 +6,7 @@ import clsx from "clsx"; import { createRef, Fragment, memo, ReactNode, useRef, useState } from "react"; import ReactDOM from "react-dom"; -import "./flyoutmenu.less"; +import "./flyoutmenu.scss"; type MenuProps = { items: MenuItem[]; diff --git a/frontend/app/element/iconbutton.less b/frontend/app/element/iconbutton.scss similarity index 100% rename from frontend/app/element/iconbutton.less rename to frontend/app/element/iconbutton.scss diff --git a/frontend/app/element/iconbutton.tsx b/frontend/app/element/iconbutton.tsx index c6cee2a22..d1a147ee8 100644 --- a/frontend/app/element/iconbutton.tsx +++ b/frontend/app/element/iconbutton.tsx @@ -5,7 +5,7 @@ import { useLongClick } from "@/app/hook/useLongClick"; import { makeIconClass } from "@/util/util"; import clsx from "clsx"; import { memo, useRef } from "react"; -import "./iconbutton.less"; +import "./iconbutton.scss"; export const IconButton = memo(({ decl, className }: { decl: IconButtonDecl; className?: string }) => { const buttonRef = useRef(null); diff --git a/frontend/app/element/input.less b/frontend/app/element/input.scss similarity index 82% rename from frontend/app/element/input.less rename to frontend/app/element/input.scss index e3cf54686..fda37d42a 100644 --- a/frontend/app/element/input.less +++ b/frontend/app/element/input.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .input { width: 100%; @@ -28,11 +28,11 @@ } // Include mixins - .border-radius-mixin(); - .vertical-padding-mixin(); - .horizontal-padding-mixin(); - .font-size-mixin(); - .font-weight-mixin(); + @include mixins.border-radius-mixin(); + @include mixins.vertical-padding-mixin(); + @include mixins.horizontal-padding-mixin(); + @include mixins.font-size-mixin(); + @include mixins.font-weight-mixin(); } /* Styles when an InputGroup is present */ @@ -87,7 +87,7 @@ } // Include mixins - .border-radius-mixin(); - .font-size-mixin(); - .font-weight-mixin(); + @include mixins.border-radius-mixin(); + @include mixins.font-size-mixin(); + @include mixins.font-weight-mixin(); } diff --git a/frontend/app/element/input.tsx b/frontend/app/element/input.tsx index 76fa56de5..71b3fa1ff 100644 --- a/frontend/app/element/input.tsx +++ b/frontend/app/element/input.tsx @@ -4,7 +4,7 @@ import clsx from "clsx"; import React, { forwardRef, memo, useImperativeHandle, useRef, useState } from "react"; -import "./input.less"; +import "./input.scss"; interface InputGroupProps { children: React.ReactNode; diff --git a/frontend/app/element/linkbutton.less b/frontend/app/element/linkbutton.scss similarity index 64% rename from frontend/app/element/linkbutton.less rename to frontend/app/element/linkbutton.scss index d58ca0e22..c4409a077 100644 --- a/frontend/app/element/linkbutton.less +++ b/frontend/app/element/linkbutton.scss @@ -1,6 +1,6 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -&.link-button { - text-decoration: none; +.link-button { + text-decoration: none; } diff --git a/frontend/app/element/linkbutton.tsx b/frontend/app/element/linkbutton.tsx index 5ffa5b979..b03c1a085 100644 --- a/frontend/app/element/linkbutton.tsx +++ b/frontend/app/element/linkbutton.tsx @@ -4,7 +4,7 @@ import { clsx } from "clsx"; import * as React from "react"; -import "./linkbutton.less"; +import "./linkbutton.scss"; interface LinkButtonProps { href: string; diff --git a/frontend/app/element/magnify.less b/frontend/app/element/magnify.scss similarity index 100% rename from frontend/app/element/magnify.less rename to frontend/app/element/magnify.scss diff --git a/frontend/app/element/magnify.tsx b/frontend/app/element/magnify.tsx index 7ccbb3e0f..be5325e41 100644 --- a/frontend/app/element/magnify.tsx +++ b/frontend/app/element/magnify.tsx @@ -3,7 +3,7 @@ import clsx from "clsx"; import MagnifySVG from "../asset/magnify.svg"; -import "./magnify.less"; +import "./magnify.scss"; interface MagnifyIconProps { enabled: boolean; diff --git a/frontend/app/element/markdown.less b/frontend/app/element/markdown.scss similarity index 100% rename from frontend/app/element/markdown.less rename to frontend/app/element/markdown.scss diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx index 11e98a28c..c6e58fb63 100644 --- a/frontend/app/element/markdown.tsx +++ b/frontend/app/element/markdown.tsx @@ -21,7 +21,7 @@ import RemarkFlexibleToc, { TocItem } from "remark-flexible-toc"; import remarkGfm from "remark-gfm"; import { openLink } from "../store/global"; import { IconButton } from "./iconbutton"; -import "./markdown.less"; +import "./markdown.scss"; const Link = ({ setFocusedHeading, diff --git a/frontend/app/element/menubutton.less b/frontend/app/element/menubutton.scss similarity index 100% rename from frontend/app/element/menubutton.less rename to frontend/app/element/menubutton.scss diff --git a/frontend/app/element/menubutton.tsx b/frontend/app/element/menubutton.tsx index 40edb80e0..c4873c78e 100644 --- a/frontend/app/element/menubutton.tsx +++ b/frontend/app/element/menubutton.tsx @@ -2,7 +2,7 @@ import clsx from "clsx"; import { memo, useState } from "react"; import { Button } from "./button"; import { FlyoutMenu } from "./flyoutmenu"; -import "./menubutton.less"; +import "./menubutton.scss"; const MenuButtonComponent = ({ items, className, text, title }: MenuButtonProps) => { const [isOpen, setIsOpen] = useState(false); diff --git a/frontend/app/element/modal.less b/frontend/app/element/modal.scss similarity index 100% rename from frontend/app/element/modal.less rename to frontend/app/element/modal.scss diff --git a/frontend/app/element/modal.tsx b/frontend/app/element/modal.tsx index 173ba5f5b..5499d4fe7 100644 --- a/frontend/app/element/modal.tsx +++ b/frontend/app/element/modal.tsx @@ -4,7 +4,7 @@ import { Button } from "@/element/button"; import React from "react"; -import "./modal.less"; +import "./modal.scss"; interface ModalProps { id?: string; diff --git a/frontend/app/element/multilineinput.less b/frontend/app/element/multilineinput.scss similarity index 100% rename from frontend/app/element/multilineinput.less rename to frontend/app/element/multilineinput.scss diff --git a/frontend/app/element/multilineinput.tsx b/frontend/app/element/multilineinput.tsx index 881cbffd6..fe54259a9 100644 --- a/frontend/app/element/multilineinput.tsx +++ b/frontend/app/element/multilineinput.tsx @@ -4,7 +4,7 @@ import clsx from "clsx"; import React, { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react"; -import "./multilineinput.less"; +import "./multilineinput.scss"; interface MultiLineInputProps { value?: string; diff --git a/frontend/app/element/notification.less b/frontend/app/element/notification.scss similarity index 100% rename from frontend/app/element/notification.less rename to frontend/app/element/notification.scss diff --git a/frontend/app/element/popover.less b/frontend/app/element/popover.scss similarity index 87% rename from frontend/app/element/popover.less rename to frontend/app/element/popover.scss index 35d3f823a..32af28ef3 100644 --- a/frontend/app/element/popover.less +++ b/frontend/app/element/popover.scss @@ -5,7 +5,7 @@ min-width: 100px; min-height: 150px; position: absolute; - z-index: 1000; // TODO: put this in theme.less + z-index: 1000; // TODO: put this in theme.scss display: flex; padding: 2px; gap: 1px; diff --git a/frontend/app/element/popover.tsx b/frontend/app/element/popover.tsx index f5c47de04..cac445981 100644 --- a/frontend/app/element/popover.tsx +++ b/frontend/app/element/popover.tsx @@ -26,7 +26,7 @@ import { useState, } from "react"; -import "./popover.less"; +import "./popover.scss"; interface PopoverProps { children: ReactNode; diff --git a/frontend/app/element/quickelems.less b/frontend/app/element/quickelems.scss similarity index 100% rename from frontend/app/element/quickelems.less rename to frontend/app/element/quickelems.scss diff --git a/frontend/app/element/quickelems.tsx b/frontend/app/element/quickelems.tsx index c4bf8b926..d344e8d75 100644 --- a/frontend/app/element/quickelems.tsx +++ b/frontend/app/element/quickelems.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import React from "react"; -import "./quickelems.less"; +import "./quickelems.scss"; function CenteredLoadingDiv() { return loading...; diff --git a/frontend/app/element/quicktips.less b/frontend/app/element/quicktips.scss similarity index 100% rename from frontend/app/element/quicktips.less rename to frontend/app/element/quicktips.scss diff --git a/frontend/app/element/quicktips.tsx b/frontend/app/element/quicktips.tsx index 397b2a61a..39387d6d5 100644 --- a/frontend/app/element/quicktips.tsx +++ b/frontend/app/element/quicktips.tsx @@ -3,7 +3,7 @@ import { MagnifyIcon } from "@/app/element/magnify"; import { PLATFORM } from "@/app/store/global"; -import "./quicktips.less"; +import "./quicktips.scss"; const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { const parts = keyDecl.split(":"); diff --git a/frontend/app/element/searchinput.less b/frontend/app/element/searchinput.scss similarity index 100% rename from frontend/app/element/searchinput.less rename to frontend/app/element/searchinput.scss diff --git a/frontend/app/element/toggle.less b/frontend/app/element/toggle.scss similarity index 100% rename from frontend/app/element/toggle.less rename to frontend/app/element/toggle.scss diff --git a/frontend/app/element/toggle.tsx b/frontend/app/element/toggle.tsx index 939776a56..64a3bf0d1 100644 --- a/frontend/app/element/toggle.tsx +++ b/frontend/app/element/toggle.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { useRef } from "react"; -import "./toggle.less"; +import "./toggle.scss"; interface ToggleProps { checked: boolean; diff --git a/frontend/app/element/typingindicator.less b/frontend/app/element/typingindicator.scss similarity index 64% rename from frontend/app/element/typingindicator.less rename to frontend/app/element/typingindicator.scss index bf7474013..dae78ed8f 100644 --- a/frontend/app/element/typingindicator.less +++ b/frontend/app/element/typingindicator.scss @@ -1,21 +1,21 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@dot-width: 11px; -@dot-color: var(--success-color); -@speed: 1.5s; +$dot-width: 11px; +$dot-color: var(--success-color); +$speed: 1.5s; .typing { position: relative; - height: @dot-width; + height: $dot-width; span { content: ""; - animation: blink @speed infinite; + animation: blink $speed infinite; animation-fill-mode: both; - height: @dot-width; - width: @dot-width; - background: @dot-color; + height: $dot-width; + width: $dot-width; + background: $dot-color; position: absolute; left: 0; top: 0; @@ -23,12 +23,12 @@ &:nth-child(2) { animation-delay: 0.2s; - margin-left: @dot-width * 1.5; + margin-left: $dot-width * 1.5; } &:nth-child(3) { animation-delay: 0.4s; - margin-left: @dot-width * 3; + margin-left: $dot-width * 3; } } } diff --git a/frontend/app/element/typingindicator.tsx b/frontend/app/element/typingindicator.tsx index 1f63d7676..5f63c71d6 100644 --- a/frontend/app/element/typingindicator.tsx +++ b/frontend/app/element/typingindicator.tsx @@ -3,7 +3,7 @@ import { clsx } from "clsx"; -import "./typingindicator.less"; +import "./typingindicator.scss"; type TypingIndicatorProps = { className?: string; diff --git a/frontend/app/element/windowdrag.less b/frontend/app/element/windowdrag.scss similarity index 100% rename from frontend/app/element/windowdrag.less rename to frontend/app/element/windowdrag.scss diff --git a/frontend/app/element/windowdrag.tsx b/frontend/app/element/windowdrag.tsx index 3c356d06a..a60d2dfba 100644 --- a/frontend/app/element/windowdrag.tsx +++ b/frontend/app/element/windowdrag.tsx @@ -4,7 +4,7 @@ import { clsx } from "clsx"; import React, { forwardRef } from "react"; -import "./windowdrag.less"; +import "./windowdrag.scss"; interface WindowDragProps { className?: string; diff --git a/frontend/app/mixins.less b/frontend/app/mixins.scss similarity index 96% rename from frontend/app/mixins.less rename to frontend/app/mixins.scss index 9117c5c74..eb451d9bf 100644 --- a/frontend/app/mixins.less +++ b/frontend/app/mixins.scss @@ -1,14 +1,14 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -.ellipsis() { +@mixin ellipsis(){ display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.border-radius-mixin() { +@mixin border-radius-mixin(){ &.border-radius-2 { border-radius: 4px; } @@ -38,7 +38,7 @@ } } -.vertical-padding-mixin() { +@mixin vertical-padding-mixin(){ &.vertical-padding-0 { padding-top: 0px; padding-bottom: 0px; @@ -85,7 +85,7 @@ } } -.horizontal-padding-mixin() { +@mixin horizontal-padding-mixin(){ &.horizontal-padding-0 { padding-left: 0px; padding-right: 0px; @@ -132,7 +132,7 @@ } } -.font-size-mixin() { +@mixin font-size-mixin(){ &.font-size-10 { font-size: 10px; } @@ -186,7 +186,7 @@ } } -.font-weight-mixin() { +@mixin font-weight-mixin(){ &.font-weight-100 { font-weight: 100; } @@ -210,7 +210,7 @@ } } -.avatar-dims-mixin() { +@mixin avatar-dims-mixin(){ &.size-xs { width: 20px; height: 20px; diff --git a/frontend/app/modals/about.less b/frontend/app/modals/about.scss similarity index 100% rename from frontend/app/modals/about.less rename to frontend/app/modals/about.scss diff --git a/frontend/app/modals/about.tsx b/frontend/app/modals/about.tsx index b20511755..3e34ef655 100644 --- a/frontend/app/modals/about.tsx +++ b/frontend/app/modals/about.tsx @@ -9,7 +9,7 @@ import { Modal } from "./modal"; import { isDev } from "@/util/isdev"; import { useState } from "react"; import { getApi } from "../store/global"; -import "./about.less"; +import "./about.scss"; interface AboutModalProps {} diff --git a/frontend/app/modals/messagemodal.less b/frontend/app/modals/messagemodal.scss similarity index 100% rename from frontend/app/modals/messagemodal.less rename to frontend/app/modals/messagemodal.scss diff --git a/frontend/app/modals/messagemodal.tsx b/frontend/app/modals/messagemodal.tsx index c781d19a7..69ada2e7c 100644 --- a/frontend/app/modals/messagemodal.tsx +++ b/frontend/app/modals/messagemodal.tsx @@ -5,7 +5,7 @@ import { Modal } from "@/app/modals/modal"; import { modalsModel } from "@/app/store/modalmodel"; import { ReactNode } from "react"; -import "./messagemodal.less"; +import "./messagemodal.scss"; const MessageModal = ({ children }: { children: ReactNode }) => { function closeModal() { diff --git a/frontend/app/modals/modal.less b/frontend/app/modals/modal.scss similarity index 100% rename from frontend/app/modals/modal.less rename to frontend/app/modals/modal.scss diff --git a/frontend/app/modals/modal.tsx b/frontend/app/modals/modal.tsx index bdf14602b..a0964733c 100644 --- a/frontend/app/modals/modal.tsx +++ b/frontend/app/modals/modal.tsx @@ -6,7 +6,7 @@ import clsx from "clsx"; import { forwardRef } from "react"; import ReactDOM from "react-dom"; -import "./modal.less"; +import "./modal.scss"; interface ModalProps { children?: React.ReactNode; diff --git a/frontend/app/modals/tos.less b/frontend/app/modals/tos.scss similarity index 100% rename from frontend/app/modals/tos.less rename to frontend/app/modals/tos.scss diff --git a/frontend/app/modals/tos.tsx b/frontend/app/modals/tos.tsx index 8f428f405..f0519ebdb 100644 --- a/frontend/app/modals/tos.tsx +++ b/frontend/app/modals/tos.tsx @@ -13,7 +13,7 @@ import { QuickTips } from "@/app/element/quicktips"; import { atoms, getApi } from "@/app/store/global"; import { modalsModel } from "@/app/store/modalmodel"; import { atom, PrimitiveAtom, useAtom, useAtomValue, useSetAtom } from "jotai"; -import "./tos.less"; +import "./tos.scss"; const pageNumAtom: PrimitiveAtom = atom(1); diff --git a/frontend/app/modals/typeaheadmodal.less b/frontend/app/modals/typeaheadmodal.scss similarity index 97% rename from frontend/app/modals/typeaheadmodal.less rename to frontend/app/modals/typeaheadmodal.scss index caa8ca24d..a6665d058 100644 --- a/frontend/app/modals/typeaheadmodal.less +++ b/frontend/app/modals/typeaheadmodal.scss @@ -1,7 +1,7 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../mixins.less"; +@use "../mixins.scss"; .type-ahead-modal-backdrop { position: absolute; @@ -97,7 +97,7 @@ } .typeahead-item-name { - .ellipsis(); + @include mixins.ellipsis(); display: flex; gap: 8px; font-size: 11px; diff --git a/frontend/app/modals/typeaheadmodal.tsx b/frontend/app/modals/typeaheadmodal.tsx index b1883410d..5ab1a555c 100644 --- a/frontend/app/modals/typeaheadmodal.tsx +++ b/frontend/app/modals/typeaheadmodal.tsx @@ -8,7 +8,7 @@ import clsx from "clsx"; import React, { forwardRef, useLayoutEffect, useRef } from "react"; import ReactDOM from "react-dom"; -import "./typeaheadmodal.less"; +import "./typeaheadmodal.scss"; interface SuggestionsProps { suggestions?: SuggestionsType[]; diff --git a/frontend/app/modals/userinputmodal.less b/frontend/app/modals/userinputmodal.scss similarity index 100% rename from frontend/app/modals/userinputmodal.less rename to frontend/app/modals/userinputmodal.scss diff --git a/frontend/app/modals/userinputmodal.tsx b/frontend/app/modals/userinputmodal.tsx index 7d8ea9d15..5721d78de 100644 --- a/frontend/app/modals/userinputmodal.tsx +++ b/frontend/app/modals/userinputmodal.tsx @@ -8,7 +8,7 @@ import * as keyutil from "@/util/keyutil"; import { UserInputService } from "../store/services"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import "./userinputmodal.less"; +import "./userinputmodal.scss"; const UserInputModal = (userInputRequest: UserInputRequest) => { const [responseText, setResponseText] = useState(""); diff --git a/frontend/app/notification/notificationbubbles.less b/frontend/app/notification/notificationbubbles.scss similarity index 100% rename from frontend/app/notification/notificationbubbles.less rename to frontend/app/notification/notificationbubbles.scss diff --git a/frontend/app/notification/notificationbubbles.tsx b/frontend/app/notification/notificationbubbles.tsx index 8b18af102..0e439eb91 100644 --- a/frontend/app/notification/notificationbubbles.tsx +++ b/frontend/app/notification/notificationbubbles.tsx @@ -6,7 +6,7 @@ import { FloatingPortal, useFloating, useInteractions } from "@floating-ui/react import clsx from "clsx"; import { useAtomValue } from "jotai"; import { useEffect, useState } from "react"; -import "./notificationbubbles.less"; +import "./notificationbubbles.scss"; import { NotificationItem } from "./notificationitem"; import { useNotification } from "./usenotification"; diff --git a/frontend/app/notification/notificationitem.less b/frontend/app/notification/notificationitem.scss similarity index 68% rename from frontend/app/notification/notificationitem.less rename to frontend/app/notification/notificationitem.scss index 3eeb31d79..646fe90f3 100644 --- a/frontend/app/notification/notificationitem.less +++ b/frontend/app/notification/notificationitem.scss @@ -1,7 +1,8 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -.notification-title { +.notification { + .notification-title { font-size: 13px; font-style: normal; font-weight: 500; @@ -9,63 +10,63 @@ margin-bottom: 3px; &.green { - color: var(--success-color); + color: var(--success-color); } &.red { - color: var(--error-color); + color: var(--error-color); } &.yellow { - color: var(--warning-color); + color: var(--warning-color); } -} + } -.notification-message { + .notification-message { font-size: 13px; font-style: normal; font-weight: 400; line-height: 18px; opacity: 0.7; -} + } -.notification-actions { + .notification-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; i { - margin-left: 3px; - font-size: 11px; + margin-left: 3px; + font-size: 11px; } -} + } -.close-btn { + .close-btn { position: absolute; top: 5px; right: 5px; -} + } -.lock-btn { + .lock-btn { position: absolute; top: 5px; right: 5px; padding: 10px 8px; font-size: 11px; color: rgb(from var(--main-text-color) r g b / 0.5); -} + } -.notification { + .notification { width: 100%; color: var(--main-text-color); padding: 12px 10px; display: flex; flex-direction: column; position: relative; -} + } -.notification-bubble { + .notification-bubble { position: relative; display: flex; width: 380px; @@ -76,43 +77,43 @@ border: 0.5px solid rgba(255, 255, 255, 0.12); background: #232323; box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25); -} + } -.notification-inner { + .notification-inner { display: flex; align-items: flex-start; column-gap: 6px; .notification-icon { - margin-right: 5px; - margin-top: 1px; + margin-right: 5px; + margin-top: 1px; - i { - font-size: 16px; - } + i { + font-size: 16px; + } - i.green { - color: var(--success-color); - } + i.green { + color: var(--success-color); + } - i.red { - color: var(--error-color); - } + i.red { + color: var(--error-color); + } - i.yellow { - color: var(--warning-color); - } + i.yellow { + color: var(--warning-color); + } } .notification-timestamp { - font-size: 12px; - font-weight: 400; - line-height: 18px; - opacity: 0.5; - margin-bottom: 7px; + font-size: 12px; + font-weight: 400; + line-height: 18px; + opacity: 0.5; + margin-bottom: 7px; } -} - -&.hovered { + } + &.hovered { background: #292929; + } } diff --git a/frontend/app/notification/notificationitem.tsx b/frontend/app/notification/notificationitem.tsx index 25de9822f..b67e73ffb 100644 --- a/frontend/app/notification/notificationitem.tsx +++ b/frontend/app/notification/notificationitem.tsx @@ -5,7 +5,7 @@ import { Button } from "@/element/button"; import { makeIconClass } from "@/util/util"; import clsx from "clsx"; -import "./notificationitem.less"; +import "./notificationitem.scss"; interface NotificationItemProps { notification: NotificationType; onRemove: (id: string) => void; diff --git a/frontend/app/notification/notificationpopover.less b/frontend/app/notification/notificationpopover.scss similarity index 100% rename from frontend/app/notification/notificationpopover.less rename to frontend/app/notification/notificationpopover.scss diff --git a/frontend/app/notification/notificationpopover.tsx b/frontend/app/notification/notificationpopover.tsx index 3ec233a8e..5c390524b 100644 --- a/frontend/app/notification/notificationpopover.tsx +++ b/frontend/app/notification/notificationpopover.tsx @@ -13,7 +13,7 @@ import { NotificationItem } from "./notificationitem"; import { useUpdateNotifier } from "./updatenotifier"; import { useNotification } from "./usenotification"; -import "./notificationpopover.less"; +import "./notificationpopover.scss"; const NotificationPopover = () => { useUpdateNotifier(); diff --git a/frontend/app/reset.less b/frontend/app/reset.scss similarity index 100% rename from frontend/app/reset.less rename to frontend/app/reset.scss diff --git a/frontend/app/store/global.ts b/frontend/app/store/global.ts index cbfdc779e..53fe90da3 100644 --- a/frontend/app/store/global.ts +++ b/frontend/app/store/global.ts @@ -246,7 +246,7 @@ function useBlockMetaKeyAtom(blockId: string, key: T): const settingsAtomCache = new Map>(); -function makeOverrideConfigAtom(blockId: string, key: T): Atom { +function getOverrideConfigAtom(blockId: string, key: T): Atom { const blockCache = getSingleBlockAtomCache(blockId); const overrideAtomName = "#settingsoverride-" + key; let overrideAtom = blockCache.get(overrideAtomName); @@ -271,7 +271,7 @@ function makeOverrideConfigAtom(blockId: string, k } function useOverrideConfigAtom(blockId: string, key: T): SettingsType[T] { - return useAtomValue(makeOverrideConfigAtom(blockId, key)); + return useAtomValue(getOverrideConfigAtom(blockId, key)); } function getSettingsKeyAtom(key: T): Atom { @@ -636,6 +636,7 @@ export { getConnStatusAtom, getHostName, getObjectId, + getOverrideConfigAtom, getSettingsKeyAtom, getUserName, globalStore, @@ -643,7 +644,6 @@ export { initGlobalWaveEventSubs, isDev, loadConnStatus, - makeOverrideConfigAtom, openLink, PLATFORM, pushFlashError, diff --git a/frontend/app/tab/tab.less b/frontend/app/tab/tab.scss similarity index 100% rename from frontend/app/tab/tab.less rename to frontend/app/tab/tab.scss diff --git a/frontend/app/tab/tab.tsx b/frontend/app/tab/tab.tsx index b6c0d2c1e..0b01cf832 100644 --- a/frontend/app/tab/tab.tsx +++ b/frontend/app/tab/tab.tsx @@ -12,7 +12,7 @@ import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "re import { atoms, globalStore, refocusNode } from "@/app/store/global"; import { RpcApi } from "@/app/store/wshclientapi"; import { TabRpcClient } from "@/app/store/wshrpcutil"; -import "./tab.less"; +import "./tab.scss"; interface TabProps { id: string; diff --git a/frontend/app/tab/tabbar.less b/frontend/app/tab/tabbar.scss similarity index 100% rename from frontend/app/tab/tabbar.less rename to frontend/app/tab/tabbar.scss diff --git a/frontend/app/tab/tabbar.tsx b/frontend/app/tab/tabbar.tsx index 4c6723804..74f5f92da 100644 --- a/frontend/app/tab/tabbar.tsx +++ b/frontend/app/tab/tabbar.tsx @@ -12,7 +12,7 @@ import { OverlayScrollbars } from "overlayscrollbars"; import React, { createRef, useCallback, useEffect, useRef, useState } from "react"; import { debounce } from "throttle-debounce"; import { Tab } from "./tab"; -import "./tabbar.less"; +import "./tabbar.scss"; import { UpdateStatusBanner } from "./updatebanner"; import { WorkspaceSwitcher } from "./workspaceswitcher"; diff --git a/frontend/app/tab/tabcontent.less b/frontend/app/tab/tabcontent.scss similarity index 100% rename from frontend/app/tab/tabcontent.less rename to frontend/app/tab/tabcontent.scss diff --git a/frontend/app/tab/tabcontent.tsx b/frontend/app/tab/tabcontent.tsx index cca7dba98..14adae22b 100644 --- a/frontend/app/tab/tabcontent.tsx +++ b/frontend/app/tab/tabcontent.tsx @@ -11,7 +11,7 @@ import * as WOS from "@/store/wos"; import { atom, useAtomValue } from "jotai"; import * as React from "react"; import { useMemo } from "react"; -import "./tabcontent.less"; +import "./tabcontent.scss"; const tileGapSizeAtom = atom((get) => { const settings = get(atoms.settingsAtom); diff --git a/frontend/app/tab/updatebanner.less b/frontend/app/tab/updatebanner.scss similarity index 100% rename from frontend/app/tab/updatebanner.less rename to frontend/app/tab/updatebanner.scss diff --git a/frontend/app/tab/updatebanner.tsx b/frontend/app/tab/updatebanner.tsx index 94b780b19..971ca2c65 100644 --- a/frontend/app/tab/updatebanner.tsx +++ b/frontend/app/tab/updatebanner.tsx @@ -2,7 +2,7 @@ import { Button } from "@/element/button"; import { atoms, getApi } from "@/store/global"; import { useAtomValue } from "jotai"; import { memo, useEffect, useState } from "react"; -import "./updatebanner.less"; +import "./updatebanner.scss"; const UpdateStatusBannerComponent = ({ buttonRef }: { buttonRef: React.RefObject }) => { const appUpdateStatus = useAtomValue(atoms.updaterStatusAtom); diff --git a/frontend/app/tab/workspaceswitcher.less b/frontend/app/tab/workspaceswitcher.scss similarity index 100% rename from frontend/app/tab/workspaceswitcher.less rename to frontend/app/tab/workspaceswitcher.scss diff --git a/frontend/app/tab/workspaceswitcher.tsx b/frontend/app/tab/workspaceswitcher.tsx index a3c06b5be..69e9d6090 100644 --- a/frontend/app/tab/workspaceswitcher.tsx +++ b/frontend/app/tab/workspaceswitcher.tsx @@ -22,7 +22,7 @@ import { OverlayScrollbarsComponent } from "overlayscrollbars-react"; import { memo, useEffect, useRef } from "react"; import WorkspaceSVG from "../asset/workspace.svg"; -import "./workspaceswitcher.less"; +import "./workspaceswitcher.scss"; interface ColorSelectorProps { colors: string[]; diff --git a/frontend/app/theme.less b/frontend/app/theme.scss similarity index 99% rename from frontend/app/theme.less rename to frontend/app/theme.scss index 7a8211470..d79da9467 100644 --- a/frontend/app/theme.less +++ b/frontend/app/theme.scss @@ -7,6 +7,7 @@ :root { --main-text-color: #f7f7f7; --title-font-size: 18px; + --window-opacity: 1; --secondary-text-color: rgb(195, 200, 194); --grey-text-color: #666; --main-bg-color: rgb(34, 34, 34); diff --git a/frontend/app/view/chat/channels.less b/frontend/app/view/chat/channels.scss similarity index 100% rename from frontend/app/view/chat/channels.less rename to frontend/app/view/chat/channels.scss diff --git a/frontend/app/view/chat/channels.tsx b/frontend/app/view/chat/channels.tsx index 90b59415d..e3f0b3760 100644 --- a/frontend/app/view/chat/channels.tsx +++ b/frontend/app/view/chat/channels.tsx @@ -4,7 +4,7 @@ import { CollapsibleMenu } from "@/app/element/collapsiblemenu"; import { memo } from "react"; -import "./channels.less"; +import "./channels.scss"; const Channels = memo(({ channels }: { channels: MenuItem[] }) => { return ; diff --git a/frontend/app/view/chat/chat.less b/frontend/app/view/chat/chat.scss similarity index 100% rename from frontend/app/view/chat/chat.less rename to frontend/app/view/chat/chat.scss diff --git a/frontend/app/view/chat/chat.tsx b/frontend/app/view/chat/chat.tsx index 28cff735e..18ba09b6e 100644 --- a/frontend/app/view/chat/chat.tsx +++ b/frontend/app/view/chat/chat.tsx @@ -10,7 +10,7 @@ import { ChatBox } from "./chatbox"; import { channels, messages, users } from "./data"; import { UserList } from "./userlist"; -import "./chat.less"; +import "./chat.scss"; class ChatModel { viewType: string; diff --git a/frontend/app/view/chat/chatmessages.less b/frontend/app/view/chat/chatmessages.scss similarity index 100% rename from frontend/app/view/chat/chatmessages.less rename to frontend/app/view/chat/chatmessages.scss diff --git a/frontend/app/view/chat/chatmessages.stories.tsx b/frontend/app/view/chat/chatmessages.stories.tsx index 1979c99e5..2444f5bb1 100644 --- a/frontend/app/view/chat/chatmessages.stories.tsx +++ b/frontend/app/view/chat/chatmessages.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { ChatMessages } from "./chatmessages"; -import "./chatmessages.less"; +import "./chatmessages.scss"; export interface ChatMessage { id: string; diff --git a/frontend/app/view/chat/chatmessages.tsx b/frontend/app/view/chat/chatmessages.tsx index 7afa61280..68de17769 100644 --- a/frontend/app/view/chat/chatmessages.tsx +++ b/frontend/app/view/chat/chatmessages.tsx @@ -6,7 +6,7 @@ import clsx from "clsx"; import { OverlayScrollbarsComponent } from "overlayscrollbars-react"; import { memo, useEffect, useRef } from "react"; -import "./chatmessages.less"; +import "./chatmessages.scss"; export interface ChatMessage { id: string; diff --git a/frontend/app/view/chat/userlist.less b/frontend/app/view/chat/userlist.scss similarity index 100% rename from frontend/app/view/chat/userlist.less rename to frontend/app/view/chat/userlist.scss diff --git a/frontend/app/view/chat/userlist.stories.tsx b/frontend/app/view/chat/userlist.stories.tsx index 025d9b380..3fa260aa1 100644 --- a/frontend/app/view/chat/userlist.stories.tsx +++ b/frontend/app/view/chat/userlist.stories.tsx @@ -4,7 +4,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { UserList } from "./userlist"; -import "./userlist.less"; +import "./userlist.scss"; export interface UserStatus { text: string; diff --git a/frontend/app/view/chat/userlist.tsx b/frontend/app/view/chat/userlist.tsx index 925bb8c97..ef5dd517c 100644 --- a/frontend/app/view/chat/userlist.tsx +++ b/frontend/app/view/chat/userlist.tsx @@ -4,7 +4,7 @@ import clsx from "clsx"; import { memo } from "react"; import { Avatar } from "../../element/avatar"; -import "./userlist.less"; +import "./userlist.scss"; export interface UserStatus { label: string; diff --git a/frontend/app/view/codeeditor/codeeditor.less b/frontend/app/view/codeeditor/codeeditor.scss similarity index 100% rename from frontend/app/view/codeeditor/codeeditor.less rename to frontend/app/view/codeeditor/codeeditor.scss diff --git a/frontend/app/view/codeeditor/codeeditor.tsx b/frontend/app/view/codeeditor/codeeditor.tsx index 777dae484..adae7c025 100644 --- a/frontend/app/view/codeeditor/codeeditor.tsx +++ b/frontend/app/view/codeeditor/codeeditor.tsx @@ -16,7 +16,7 @@ import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker"; import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker"; import ymlWorker from "./yamlworker?worker"; -import "./codeeditor.less"; +import "./codeeditor.scss"; // there is a global monaco variable (TODO get the correct TS type) declare var monaco: Monaco; diff --git a/frontend/app/view/helpview/helpview.less b/frontend/app/view/helpview/helpview.scss similarity index 100% rename from frontend/app/view/helpview/helpview.less rename to frontend/app/view/helpview/helpview.scss diff --git a/frontend/app/view/helpview/helpview.tsx b/frontend/app/view/helpview/helpview.tsx index 942ff304a..cccccdb07 100644 --- a/frontend/app/view/helpview/helpview.tsx +++ b/frontend/app/view/helpview/helpview.tsx @@ -7,7 +7,7 @@ import { WebView, WebViewModel } from "@/app/view/webview/webview"; import { fireAndForget } from "@/util/util"; import { atom, useAtomValue } from "jotai"; import { useCallback } from "react"; -import "./helpview.less"; +import "./helpview.scss"; const docsiteWebUrl = "https://docs.waveterm.dev/"; const baseUrlRegex = /http[s]?:\/\/([^:\/])+(:\d+)?/; diff --git a/frontend/app/view/plotview/plotview.less b/frontend/app/view/plotview/plotview.scss similarity index 100% rename from frontend/app/view/plotview/plotview.less rename to frontend/app/view/plotview/plotview.scss diff --git a/frontend/app/view/plotview/plotview.tsx b/frontend/app/view/plotview/plotview.tsx index 077af2659..9b46a821e 100644 --- a/frontend/app/view/plotview/plotview.tsx +++ b/frontend/app/view/plotview/plotview.tsx @@ -7,7 +7,7 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; import * as React from "react"; -import "./plotview.less"; +import "./plotview.scss"; function PlotWindow() { return
; diff --git a/frontend/app/view/preview/csvview.less b/frontend/app/view/preview/csvview.scss similarity index 93% rename from frontend/app/view/preview/csvview.less rename to frontend/app/view/preview/csvview.scss index 21631f585..07514cd71 100644 --- a/frontend/app/view/preview/csvview.less +++ b/frontend/app/view/preview/csvview.scss @@ -1,12 +1,12 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "../../mixins.less"; +@use "../../mixins.scss"; .csv-view { opacity: 0; /* Start with an opacity of 0, meaning it's invisible */ - .ellipsis(); + @include mixins.ellipsis(); overflow-x: auto; overflow-y: hidden; @@ -53,7 +53,7 @@ text-align: left; padding-right: 15px; position: relative; - .ellipsis(); + @include mixins.ellipsis(); .sort-icon { position: absolute; @@ -85,7 +85,7 @@ flex-grow: 2; display: block; text-align: left; - .ellipsis(); + @include mixins.ellipsis(); } } } diff --git a/frontend/app/view/preview/csvview.tsx b/frontend/app/view/preview/csvview.tsx index 2079ce8d7..ca2b223f9 100644 --- a/frontend/app/view/preview/csvview.tsx +++ b/frontend/app/view/preview/csvview.tsx @@ -14,7 +14,7 @@ import Papa from "papaparse"; import { useEffect, useMemo, useRef, useState } from "react"; import { useDimensionsWithExistingRef } from "@/app/hook/useDimensions"; -import "./csvview.less"; +import "./csvview.scss"; const MAX_DATA_SIZE = 10 * 1024 * 1024; // 10MB in bytes diff --git a/frontend/app/view/preview/directorypreview.less b/frontend/app/view/preview/directorypreview.less deleted file mode 100644 index 506c4778c..000000000 --- a/frontend/app/view/preview/directorypreview.less +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2024, Command Line Inc. -// SPDX-License-Identifier: Apache-2.0 - -@import "../../mixins.less"; - -.dir-table-container { - display: flex; - flex-direction: column; - height: 100%; - --min-row-width: 35rem; - .dir-table { - height: 100%; - width: 100%; - --col-size-size: 0.2rem; - display: flex; - flex-direction: column; - - &:not([data-scroll-height="0"]) .dir-table-head::after { - background: rgb(from var(--block-bg-color) r g b / 0.2); - } - - .dir-table-head::after { - content: ""; - z-index: -1; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - backdrop-filter: blur(4px); - } - .dir-table-head { - position: sticky; - top: 0; - z-index: 10; - width: 100%; - border-bottom: 1px solid var(--border-color); - - .dir-table-head-row { - display: flex; - min-width: var(--min-row-width); - padding: 4px 6px; - font-size: 0.75rem; - - .dir-table-head-cell { - flex: 0 0 auto; - user-select: none; - } - .dir-table-head-cell:not(:first-child) { - position: relative; - display: flex; - white-space: nowrap; - overflow: hidden; - - .dir-table-head-cell-content { - padding: 2px 4px; - display: flex; - gap: 0.3rem; - flex: 1 1 auto; - overflow-x: hidden; - letter-spacing: -0.12px; - - .dir-table-head-direction { - margin-right: 0.2rem; - margin-top: 0.2rem; - } - - .dir-table-head-size { - align-self: flex-end; - } - } - - .dir-table-head-resize-box { - width: 12px; - display: flex; - justify-content: center; - flex: 0 0 auto; - .dir-table-head-resize { - cursor: col-resize; - user-select: none; - -webkit-user-select: none; - touch-action: none; - width: 4px; - } - } - } - } - } - - .dir-table-body { - display: flex; - flex-direction: column; - .dir-table-body-search-display { - display: flex; - border-radius: 3px; - padding: 0.25rem 0.5rem; - background-color: var(--warning-color); - - .search-display-close-button { - margin-left: auto; - } - } - - .dir-table-body-scroll-box { - position: relative; - .dummy { - position: absolute; - visibility: hidden; - } - .dir-table-body-row { - display: flex; - align-items: center; - border-radius: 5px; - padding: 0 6px; - min-width: var(--min-row-width); - - &.focused { - background-color: rgb(from var(--accent-color) r g b / 0.5); - color: var(--main-text-color); - - .dir-table-body-cell { - .dir-table-lastmod, - .dir-table-modestr, - .dir-table-size, - .dir-table-type { - color: var(--main-text-color); - } - } - } - - &:focus { - background-color: rgb(from var(--accent-color) r g b / 0.5); - color: var(--main-text-color); - - .dir-table-body-cell { - .dir-table-lastmod, - .dir-table-modestr, - .dir-table-size, - .dir-table-type { - color: var(--main-text-color); - } - } - } - - &:hover:not(:focus):not(.focused) { - background-color: var(--highlight-bg-color); - } - - .dir-table-body-cell { - overflow: hidden; - white-space: nowrap; - padding: 0.25rem; - cursor: default; - font-size: 0.8125rem; - flex: 0 0 auto; - - &.col-size { - text-align: right; - } - - .dir-table-lastmod, - .dir-table-modestr, - .dir-table-size, - .dir-table-type { - color: var(--secondary-text-color); - margin-right: 12px; - } - - .dir-table-type { - .ellipsis(); - } - - .dir-table-modestr { - font-family: Hack; - } - - &:has(.dir-table-name) { - .ellipsis(); - } - .dir-table-name { - font-weight: 500; - } - } - } - } - } - } - - .dir-table-search-line { - display: flex; - justify-content: flex-end; - gap: 0.7rem; - - .dir-table-search-box { - width: 0; - height: 0; - opacity: 0; - padding: 0; - border: none; - pointer-events: none; - } - } -} - -.dir-table-button { - background-color: transparent; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - padding: 0.2rem; - border-radius: 6px; - - input { - width: 0; - height: 0; - opacity: 0; - padding: 0; - border: none; - pointer-events: none; - } - - &:hover { - background-color: var(--highlight-bg-color); - } - - &:focus { - background-color: var(--highlight-bg-color); - } - - &:focus-within { - background-color: var(--highlight-bg-color); - } -} diff --git a/frontend/app/view/preview/directorypreview.scss b/frontend/app/view/preview/directorypreview.scss new file mode 100644 index 000000000..89dc887c5 --- /dev/null +++ b/frontend/app/view/preview/directorypreview.scss @@ -0,0 +1,232 @@ +// Copyright 2024, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +@use "../../mixins.scss"; + +.dir-table-container { + display: flex; + flex-direction: column; + height: 100%; + --min-row-width: 35rem; + .dir-table { + height: 100%; + width: 100%; + --col-size-size: 0.2rem; + display: flex; + flex-direction: column; + + &:not([data-scroll-height="0"]) .dir-table-head::after { + background: oklch(from var(--block-bg-color) calc(l + 0.5) c h); + backdrop-filter: blur(2px); + content: ""; + z-index: -1; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + + .dir-table-head { + position: sticky; + top: 0; + z-index: 10; + width: 100%; + border-bottom: 1px solid var(--border-color); + + .dir-table-head-row { + display: flex; + min-width: var(--min-row-width); + padding: 4px 6px; + font-size: 0.75rem; + + .dir-table-head-cell { + flex: 0 0 auto; + user-select: none; + } + .dir-table-head-cell:not(:first-child) { + position: relative; + display: flex; + white-space: nowrap; + overflow: hidden; + + .dir-table-head-cell-content { + padding: 2px 4px; + display: flex; + gap: 0.3rem; + flex: 1 1 auto; + overflow-x: hidden; + letter-spacing: -0.12px; + + .dir-table-head-direction { + margin-right: 0.2rem; + margin-top: 0.2rem; + } + + .dir-table-head-size { + align-self: flex-end; + } + } + + .dir-table-head-resize-box { + width: 12px; + display: flex; + justify-content: center; + flex: 0 0 auto; + .dir-table-head-resize { + cursor: col-resize; + user-select: none; + -webkit-user-select: none; + touch-action: none; + width: 4px; + } + } + } + } + } + + .dir-table-body { + display: flex; + flex-direction: column; + .dir-table-body-search-display { + display: flex; + border-radius: 3px; + padding: 0.25rem 0.5rem; + background-color: var(--warning-color); + + .search-display-close-button { + margin-left: auto; + } + } + + .dir-table-body-scroll-box { + position: relative; + .dummy { + position: absolute; + visibility: hidden; + } + .dir-table-body-row { + display: flex; + align-items: center; + border-radius: 5px; + padding: 0 6px; + min-width: var(--min-row-width); + + &.focused { + background-color: rgb(from var(--accent-color) r g b / 0.5); + color: var(--main-text-color); + + .dir-table-body-cell { + .dir-table-lastmod, + .dir-table-modestr, + .dir-table-size, + .dir-table-type { + color: var(--main-text-color); + } + } + } + + &:focus { + background-color: rgb(from var(--accent-color) r g b / 0.5); + color: var(--main-text-color); + + .dir-table-body-cell { + .dir-table-lastmod, + .dir-table-modestr, + .dir-table-size, + .dir-table-type { + color: var(--main-text-color); + } + } + } + + &:hover:not(:focus):not(.focused) { + background-color: var(--highlight-bg-color); + } + + .dir-table-body-cell { + overflow: hidden; + white-space: nowrap; + padding: 0.25rem; + cursor: default; + font-size: 0.8125rem; + flex: 0 0 auto; + + &.col-size { + text-align: right; + } + + .dir-table-lastmod, + .dir-table-modestr, + .dir-table-size, + .dir-table-type { + color: var(--secondary-text-color); + margin-right: 12px; + } + + .dir-table-type { + @include mixins.ellipsis(); + } + + .dir-table-modestr { + font-family: Hack; + } + + &:has(.dir-table-name) { + @include mixins.ellipsis(); + } + .dir-table-name { + font-weight: 500; + } + } + } + } + } + } + + .dir-table-search-line { + display: flex; + justify-content: flex-end; + gap: 0.7rem; + + .dir-table-search-box { + width: 0; + height: 0; + opacity: 0; + padding: 0; + border: none; + pointer-events: none; + } + } +} + +.dir-table-button { + background-color: transparent; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + padding: 0.2rem; + border-radius: 6px; + + input { + width: 0; + height: 0; + opacity: 0; + padding: 0; + border: none; + pointer-events: none; + } + + &:hover { + background-color: var(--highlight-bg-color); + } + + &:focus { + background-color: var(--highlight-bg-color); + } + + &:focus-within { + background-color: var(--highlight-bg-color); + } +} diff --git a/frontend/app/view/preview/directorypreview.tsx b/frontend/app/view/preview/directorypreview.tsx index b76b60baa..4335c311e 100644 --- a/frontend/app/view/preview/directorypreview.tsx +++ b/frontend/app/view/preview/directorypreview.tsx @@ -24,7 +24,7 @@ import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overl import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { quote as shellQuote } from "shell-quote"; import { debounce } from "throttle-debounce"; -import "./directorypreview.less"; +import "./directorypreview.scss"; interface DirectoryTableProps { model: PreviewModel; diff --git a/frontend/app/view/preview/preview.less b/frontend/app/view/preview/preview.scss similarity index 100% rename from frontend/app/view/preview/preview.less rename to frontend/app/view/preview/preview.scss diff --git a/frontend/app/view/preview/preview.tsx b/frontend/app/view/preview/preview.tsx index a3089aee5..33986f74e 100644 --- a/frontend/app/view/preview/preview.tsx +++ b/frontend/app/view/preview/preview.tsx @@ -25,7 +25,7 @@ import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api"; import { createRef, memo, useCallback, useEffect, useMemo, useState } from "react"; import { CSVView } from "./csvview"; import { DirectoryPreview } from "./directorypreview"; -import "./preview.less"; +import "./preview.scss"; const MaxFileSize = 1024 * 1024 * 10; // 10MB const MaxCSVSize = 1024 * 1024 * 1; // 1MB diff --git a/frontend/app/view/quicktipsview/quicktipsview.less b/frontend/app/view/quicktipsview/quicktipsview.scss similarity index 100% rename from frontend/app/view/quicktipsview/quicktipsview.less rename to frontend/app/view/quicktipsview/quicktipsview.scss diff --git a/frontend/app/view/quicktipsview/quicktipsview.tsx b/frontend/app/view/quicktipsview/quicktipsview.tsx index a017ff3ab..90d8dc6ff 100644 --- a/frontend/app/view/quicktipsview/quicktipsview.tsx +++ b/frontend/app/view/quicktipsview/quicktipsview.tsx @@ -4,7 +4,7 @@ import { QuickTips } from "@/app/element/quicktips"; import { globalStore } from "@/app/store/global"; import { Atom, atom, PrimitiveAtom } from "jotai"; -import "./quicktipsview.less"; +import "./quicktipsview.scss"; class QuickTipsViewModel implements ViewModel { viewType: string; diff --git a/frontend/app/view/sysinfo/sysinfo.less b/frontend/app/view/sysinfo/sysinfo.scss similarity index 100% rename from frontend/app/view/sysinfo/sysinfo.less rename to frontend/app/view/sysinfo/sysinfo.scss diff --git a/frontend/app/view/sysinfo/sysinfo.tsx b/frontend/app/view/sysinfo/sysinfo.tsx index 1adb6ee43..787be2ff0 100644 --- a/frontend/app/view/sysinfo/sysinfo.tsx +++ b/frontend/app/view/sysinfo/sysinfo.tsx @@ -16,7 +16,7 @@ import { RpcApi } from "@/app/store/wshclientapi"; import { TabRpcClient } from "@/app/store/wshrpcutil"; import { atoms } from "@/store/global"; import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react"; -import "./sysinfo.less"; +import "./sysinfo.scss"; const DefaultNumPoints = 120; diff --git a/frontend/app/view/term/term.less b/frontend/app/view/term/term.scss similarity index 100% rename from frontend/app/view/term/term.less rename to frontend/app/view/term/term.scss diff --git a/frontend/app/view/term/term.tsx b/frontend/app/view/term/term.tsx index c5914258e..66474b5fb 100644 --- a/frontend/app/view/term/term.tsx +++ b/frontend/app/view/term/term.tsx @@ -11,14 +11,16 @@ import { DefaultRouter, TabRpcClient } from "@/app/store/wshrpcutil"; import { TermWshClient } from "@/app/view/term/term-wsh"; import { VDomModel } from "@/app/view/vdom/vdom-model"; import { - WOS, atoms, getBlockComponentModel, + getBlockMetaKeyAtom, getConnStatusAtom, + getOverrideConfigAtom, getSettingsKeyAtom, globalStore, useBlockAtom, useSettingsPrefixAtom, + WOS, } from "@/store/global"; import * as services from "@/store/services"; import * as keyutil from "@/util/keyutil"; @@ -28,7 +30,7 @@ import * as jotai from "jotai"; import * as React from "react"; import { TermStickers } from "./termsticker"; import { TermThemeUpdater } from "./termtheme"; -import { computeTheme } from "./termutil"; +import { computeTheme, DefaultTermTheme } from "./termutil"; import { TermWrap } from "./termwrap"; import "./xterm.css"; @@ -138,16 +140,17 @@ class TermViewModel { } return true; }); + this.termThemeNameAtom = useBlockAtom(blockId, "termthemeatom", () => { + return jotai.atom((get) => { + return get(getOverrideConfigAtom(this.blockId, "term:theme")) ?? DefaultTermTheme; + }); + }); this.blockBg = jotai.atom((get) => { - const blockData = get(this.blockAtom); const fullConfig = get(atoms.fullConfigAtom); - let themeName: string = get(getSettingsKeyAtom("term:theme")); - if (blockData?.meta?.["term:theme"]) { - themeName = blockData.meta["term:theme"]; - } - const theme = computeTheme(fullConfig, themeName); - if (theme != null && theme.background != null) { - return { bg: theme.background }; + const themeName = get(this.termThemeNameAtom); + const [_, bgcolor] = computeTheme(fullConfig, themeName); + if (bgcolor != null) { + return { bg: bgcolor }; } return null; }); @@ -169,13 +172,6 @@ class TermViewModel { return rtnFontSize; }); }); - this.termThemeNameAtom = useBlockAtom(blockId, "termthemeatom", () => { - return jotai.atom((get) => { - const blockData = get(this.blockAtom); - const settingsKeyAtom = getSettingsKeyAtom("term:theme"); - return blockData?.meta?.["term:theme"] ?? get(settingsKeyAtom) ?? "default-dark"; - }); - }); this.noPadding = jotai.atom(true); this.endIconButtons = jotai.atom((get) => { const blockData = get(this.blockAtom); @@ -329,7 +325,7 @@ class TermViewModel { const fullConfig = globalStore.get(atoms.fullConfigAtom); const termThemes = fullConfig?.termthemes ?? {}; const termThemeKeys = Object.keys(termThemes); - const curThemeName = globalStore.get(this.termThemeNameAtom); + const curThemeName = globalStore.get(getBlockMetaKeyAtom(this.blockId, "term:theme")); const defaultFontSize = globalStore.get(getSettingsKeyAtom("term:fontsize")) ?? 12; const blockData = globalStore.get(this.blockAtom); const overrideFontSize = blockData?.meta?.["term:fontsize"]; @@ -346,6 +342,12 @@ class TermViewModel { click: () => this.setTerminalTheme(themeName), }; }); + submenu.unshift({ + label: "Default", + type: "checkbox", + checked: curThemeName == null, + click: () => this.setTerminalTheme(null), + }); const fontSizeSubMenu: ContextMenuItem[] = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18].map( (fontSize: number) => { return { @@ -551,9 +553,8 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => { React.useEffect(() => { const fullConfig = globalStore.get(atoms.fullConfigAtom); - const termTheme = computeTheme(fullConfig, blockData?.meta?.["term:theme"]); - const themeCopy = { ...termTheme }; - themeCopy.background = "#00000000"; + const termThemeName = globalStore.get(model.termThemeNameAtom); + const [termTheme, _] = computeTheme(fullConfig, termThemeName); let termScrollback = 1000; if (termSettings?.["term:scrollback"]) { termScrollback = Math.floor(termSettings["term:scrollback"]); @@ -572,7 +573,7 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => { blockId, connectElemRef.current, { - theme: themeCopy, + theme: termTheme, fontSize: termFontSize, fontFamily: termSettings?.["term:fontfamily"] ?? "Hack", drawBoldTextInBrightColors: false, @@ -650,7 +651,7 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => { return (
- + @@ -659,4 +660,4 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => { ); }; -export { TermViewModel, TerminalView, makeTerminalModel }; +export { makeTerminalModel, TerminalView, TermViewModel }; diff --git a/frontend/app/view/term/termsticker.tsx b/frontend/app/view/term/termsticker.tsx index 1d262b31e..4ef84ccf5 100644 --- a/frontend/app/view/term/termsticker.tsx +++ b/frontend/app/view/term/termsticker.tsx @@ -10,7 +10,7 @@ import clsx from "clsx"; import * as jotai from "jotai"; import * as React from "react"; import GaugeChart from "react-gauge-chart"; -import "./term.less"; +import "./term.scss"; type StickerType = { position: "absolute"; diff --git a/frontend/app/view/term/termtheme.ts b/frontend/app/view/term/termtheme.ts index c18543b71..8852ae15a 100644 --- a/frontend/app/view/term/termtheme.ts +++ b/frontend/app/view/term/termtheme.ts @@ -1,41 +1,28 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 +import { TermViewModel } from "@/app/view/term/term"; +import { computeTheme } from "@/app/view/term/termutil"; import { TermWrap } from "@/app/view/term/termwrap"; -import { atoms, WOS } from "@/store/global"; -import * as util from "@/util/util"; +import { atoms } from "@/store/global"; import { useAtomValue } from "jotai"; import { useEffect } from "react"; interface TermThemeProps { blockId: string; termRef: React.RefObject; + model: TermViewModel; } -const TermThemeUpdater = ({ blockId, termRef }: TermThemeProps) => { +const TermThemeUpdater = ({ blockId, model, termRef }: TermThemeProps) => { const fullConfig = useAtomValue(atoms.fullConfigAtom); - const termthemes = fullConfig?.termthemes; - const [blockData] = WOS.useWaveObjectValue(WOS.makeORef("block", blockId)); - let defaultThemeName = "default-dark"; - let themeName = blockData.meta?.["term:theme"] ?? "default-dark"; - - const defaultTheme: TermThemeType = termthemes?.[defaultThemeName] || ({} as any); - const theme: TermThemeType = termthemes?.[themeName] || ({} as any); - + const blockTermTheme = useAtomValue(model.termThemeNameAtom); + const [theme, _] = computeTheme(fullConfig, blockTermTheme); useEffect(() => { - const combinedTheme = { ...defaultTheme }; - for (const key in theme) { - if (!util.isBlank(theme[key])) { - combinedTheme[key] = theme[key]; - } - } if (termRef.current?.terminal) { - let themeCopy = { ...combinedTheme }; - themeCopy.background = "#00000000"; - termRef.current.terminal.options.theme = themeCopy; + termRef.current.terminal.options.theme = theme; } - }, [defaultTheme, theme]); - + }, [theme]); return null; }; diff --git a/frontend/app/view/term/termutil.ts b/frontend/app/view/term/termutil.ts index 395ebc53e..1bed0e6d5 100644 --- a/frontend/app/view/term/termutil.ts +++ b/frontend/app/view/term/termutil.ts @@ -1,20 +1,18 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -import * as util from "@/util/util"; +export const DefaultTermTheme = "default-dark"; -function computeTheme(fullConfig: FullConfigType, themeName: string): TermThemeType { - let defaultThemeName = "default-dark"; - themeName = themeName ?? "default-dark"; - const defaultTheme: TermThemeType = fullConfig?.termthemes?.[defaultThemeName] || ({} as any); - const theme: TermThemeType = fullConfig?.termthemes?.[themeName] || ({} as any); - const combinedTheme = { ...defaultTheme }; - for (const key in theme) { - if (!util.isBlank(theme[key])) { - combinedTheme[key] = theme[key]; - } +// returns (theme, bgcolor) +function computeTheme(fullConfig: FullConfigType, themeName: string): [TermThemeType, string] { + let theme: TermThemeType = fullConfig?.termthemes?.[themeName]; + if (theme == null) { + theme = fullConfig?.termthemes?.[DefaultTermTheme] || ({} as any); } - return combinedTheme; + const themeCopy = { ...theme }; + let bgcolor = themeCopy.background; + themeCopy.background = "#00000000"; + return [themeCopy, bgcolor]; } export { computeTheme }; diff --git a/frontend/app/view/vdom/vdom.less b/frontend/app/view/vdom/vdom.scss similarity index 100% rename from frontend/app/view/vdom/vdom.less rename to frontend/app/view/vdom/vdom.scss diff --git a/frontend/app/view/vdom/vdom.tsx b/frontend/app/view/vdom/vdom.tsx index ec8fbced8..e1cd414f4 100644 --- a/frontend/app/view/vdom/vdom.tsx +++ b/frontend/app/view/vdom/vdom.tsx @@ -16,7 +16,7 @@ import { validateAndWrapCss, validateAndWrapReactStyle, } from "@/app/view/vdom/vdom-utils"; -import "./vdom.less"; +import "./vdom.scss"; const TextTag = "#text"; const FragmentTag = "#fragment"; diff --git a/frontend/app/view/waveai/waveai.less b/frontend/app/view/waveai/waveai.scss similarity index 100% rename from frontend/app/view/waveai/waveai.less rename to frontend/app/view/waveai/waveai.scss diff --git a/frontend/app/view/waveai/waveai.tsx b/frontend/app/view/waveai/waveai.tsx index 52dcd8e43..ae964d123 100644 --- a/frontend/app/view/waveai/waveai.tsx +++ b/frontend/app/view/waveai/waveai.tsx @@ -16,7 +16,7 @@ import { atom, Atom, PrimitiveAtom, useAtomValue, WritableAtom } from "jotai"; import type { OverlayScrollbars } from "overlayscrollbars"; import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react"; import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; -import "./waveai.less"; +import "./waveai.scss"; interface ChatMessageType { id: string; diff --git a/frontend/app/view/webview/webview.less b/frontend/app/view/webview/webview.scss similarity index 100% rename from frontend/app/view/webview/webview.less rename to frontend/app/view/webview/webview.scss diff --git a/frontend/app/view/webview/webview.tsx b/frontend/app/view/webview/webview.tsx index 7a351c9c8..dee0eef88 100644 --- a/frontend/app/view/webview/webview.tsx +++ b/frontend/app/view/webview/webview.tsx @@ -14,7 +14,7 @@ import clsx from "clsx"; import { WebviewTag } from "electron"; import { Atom, PrimitiveAtom, atom, useAtomValue } from "jotai"; import { Fragment, createRef, memo, useEffect, useRef, useState } from "react"; -import "./webview.less"; +import "./webview.scss"; let webviewPreloadUrl = null; diff --git a/frontend/app/workspace/workspace.less b/frontend/app/workspace/workspace.scss similarity index 100% rename from frontend/app/workspace/workspace.less rename to frontend/app/workspace/workspace.scss diff --git a/frontend/app/workspace/workspace.tsx b/frontend/app/workspace/workspace.tsx index 9932b8b6b..94d390798 100644 --- a/frontend/app/workspace/workspace.tsx +++ b/frontend/app/workspace/workspace.tsx @@ -12,7 +12,7 @@ import { useAtomValue } from "jotai"; import { memo } from "react"; import { NotificationPopover } from "../notification/notificationpopover"; -import "./workspace.less"; +import "./workspace.scss"; const iconRegex = /^[a-z0-9-]+$/; diff --git a/frontend/layout/lib/TileLayout.tsx b/frontend/layout/lib/TileLayout.tsx index e042c418d..d78aa2e2e 100644 --- a/frontend/layout/lib/TileLayout.tsx +++ b/frontend/layout/lib/TileLayout.tsx @@ -21,7 +21,7 @@ import { debounce, throttle } from "throttle-debounce"; import { useDevicePixelRatio } from "use-device-pixel-ratio"; import { LayoutModel } from "./layoutModel"; import { useNodeModel, useTileLayout } from "./layoutModelHooks"; -import "./tilelayout.less"; +import "./tilelayout.scss"; import { LayoutNode, LayoutTreeActionType, diff --git a/frontend/layout/lib/tilelayout.less b/frontend/layout/lib/tilelayout.scss similarity index 100% rename from frontend/layout/lib/tilelayout.less rename to frontend/layout/lib/tilelayout.scss diff --git a/frontend/layout/lib/tilelayout.stories.less b/frontend/layout/lib/tilelayout.stories.scss similarity index 100% rename from frontend/layout/lib/tilelayout.stories.less rename to frontend/layout/lib/tilelayout.stories.scss diff --git a/package.json b/package.json index 4bed4a34a..bb8e416ce 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "productName": "Wave", "description": "Open-Source AI-Native Terminal Built for Seamless Workflows", "license": "Apache-2.0", - "version": "0.9.3-beta.1", + "version": "0.9.3", "homepage": "https://waveterm.dev", "build": { "appId": "dev.commandline.waveterm" @@ -62,11 +62,11 @@ "electron-vite": "^2.3.0", "eslint": "^9.14.0", "eslint-config-prettier": "^9.1.0", - "less": "^4.2.0", "prettier": "^3.3.3", "prettier-plugin-jsdoc": "^1.3.0", "prettier-plugin-organize-imports": "^4.1.0", "rollup-plugin-flow": "^1.1.1", + "sass": "^1.81.0", "semver": "^7.6.3", "storybook": "^8.4.4", "storybook-dark-mode": "^4.0.2", diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index 8c919d6ad..e139c2f2f 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -189,8 +189,8 @@ func readConfigHelper(fileName string, barr []byte, readErr error) (waveobj.Meta func readConfigFileFS(fsys fs.FS, logPrefix string, fileName string) (waveobj.MetaMapType, []ConfigError) { barr, readErr := fs.ReadFile(fsys, fileName) - if readErr != nil && strings.Contains(readErr.Error(), "invalid argument") { - // If we get an `invalid argument` error, we may be using the wrong path separator for the given FS interface. Try switching the separator. + if readErr != nil { + // If we get an error, we may be using the wrong path separator for the given FS interface. Try switching the separator. barr, readErr = fs.ReadFile(fsys, filepath.ToSlash(fileName)) } return readConfigHelper(logPrefix+fileName, barr, readErr) diff --git a/public/style.less b/public/style.scss similarity index 95% rename from public/style.less rename to public/style.scss index b196f3d31..2628f4fdb 100644 --- a/public/style.less +++ b/public/style.scss @@ -1,8 +1,8 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -@import "./reset.less"; -@import "./theme.less"; +@import "./reset.scss"; +@import "./theme.scss"; body { display: flex; diff --git a/yarn.lock b/yarn.lock index cee737013..3d683aae6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3950,6 +3950,150 @@ __metadata: languageName: node linkType: hard +"@parcel/watcher-android-arm64@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-android-arm64@npm:2.5.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-arm64@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-darwin-arm64@npm:2.5.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-x64@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-darwin-x64@npm:2.5.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-freebsd-x64@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-freebsd-x64@npm:2.5.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm-glibc@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-linux-arm-glibc@npm:2.5.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm-musl@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-linux-arm-musl@npm:2.5.0" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-glibc@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-linux-arm64-glibc@npm:2.5.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-musl@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-linux-arm64-musl@npm:2.5.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-glibc@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-linux-x64-glibc@npm:2.5.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-musl@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-linux-x64-musl@npm:2.5.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-win32-arm64@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-win32-arm64@npm:2.5.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-win32-ia32@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-win32-ia32@npm:2.5.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@parcel/watcher-win32-x64@npm:2.5.0": + version: 2.5.0 + resolution: "@parcel/watcher-win32-x64@npm:2.5.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher@npm:^2.4.1": + version: 2.5.0 + resolution: "@parcel/watcher@npm:2.5.0" + dependencies: + "@parcel/watcher-android-arm64": "npm:2.5.0" + "@parcel/watcher-darwin-arm64": "npm:2.5.0" + "@parcel/watcher-darwin-x64": "npm:2.5.0" + "@parcel/watcher-freebsd-x64": "npm:2.5.0" + "@parcel/watcher-linux-arm-glibc": "npm:2.5.0" + "@parcel/watcher-linux-arm-musl": "npm:2.5.0" + "@parcel/watcher-linux-arm64-glibc": "npm:2.5.0" + "@parcel/watcher-linux-arm64-musl": "npm:2.5.0" + "@parcel/watcher-linux-x64-glibc": "npm:2.5.0" + "@parcel/watcher-linux-x64-musl": "npm:2.5.0" + "@parcel/watcher-win32-arm64": "npm:2.5.0" + "@parcel/watcher-win32-ia32": "npm:2.5.0" + "@parcel/watcher-win32-x64": "npm:2.5.0" + detect-libc: "npm:^1.0.3" + is-glob: "npm:^4.0.3" + micromatch: "npm:^4.0.5" + node-addon-api: "npm:^7.0.0" + node-gyp: "npm:latest" + dependenciesMeta: + "@parcel/watcher-android-arm64": + optional: true + "@parcel/watcher-darwin-arm64": + optional: true + "@parcel/watcher-darwin-x64": + optional: true + "@parcel/watcher-freebsd-x64": + optional: true + "@parcel/watcher-linux-arm-glibc": + optional: true + "@parcel/watcher-linux-arm-musl": + optional: true + "@parcel/watcher-linux-arm64-glibc": + optional: true + "@parcel/watcher-linux-arm64-musl": + optional: true + "@parcel/watcher-linux-x64-glibc": + optional: true + "@parcel/watcher-linux-x64-musl": + optional: true + "@parcel/watcher-win32-arm64": + optional: true + "@parcel/watcher-win32-ia32": + optional: true + "@parcel/watcher-win32-x64": + optional: true + checksum: 10c0/9bad727d8b11e5d150ec47459254544c583adaa47d047b8ef65e1c74aede1a0767dc7fc6b8997649dae07318d6ef39caba6a1c405d306398d5bcd47074ec5d29 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -7854,6 +7998,15 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^4.0.0": + version: 4.0.1 + resolution: "chokidar@npm:4.0.1" + dependencies: + readdirp: "npm:^4.0.1" + checksum: 10c0/4bb7a3adc304059810bb6c420c43261a15bb44f610d77c35547addc84faa0374265c3adc67f25d06f363d9a4571962b02679268c40de07676d260de1986efea9 + languageName: node + linkType: hard + "chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" @@ -8360,15 +8513,6 @@ __metadata: languageName: node linkType: hard -"copy-anything@npm:^2.0.1": - version: 2.0.6 - resolution: "copy-anything@npm:2.0.6" - dependencies: - is-what: "npm:^3.14.1" - checksum: 10c0/2702998a8cc015f9917385b7f16b0d85f1f6e5e2fd34d99f14df584838f492f49aa0c390d973684c687e895c5c58d08b308a0400ac3e1e3d6fa1e5884a5402ad - languageName: node - linkType: hard - "copy-text-to-clipboard@npm:^3.2.0": version: 3.2.0 resolution: "copy-text-to-clipboard@npm:3.2.0" @@ -9282,6 +9426,15 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: 10c0/4da0deae9f69e13bc37a0902d78bf7169480004b1fed3c19722d56cff578d16f0e11633b7fbf5fb6249181236c72e90024cbd68f0b9558ae06e281f47326d50d + languageName: node + linkType: hard + "detect-libc@npm:^2.0.0, detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.2, detect-libc@npm:^2.0.3": version: 2.0.3 resolution: "detect-libc@npm:2.0.3" @@ -9821,17 +9974,6 @@ __metadata: languageName: node linkType: hard -"errno@npm:^0.1.1": - version: 0.1.8 - resolution: "errno@npm:0.1.8" - dependencies: - prr: "npm:~1.0.1" - bin: - errno: cli.js - checksum: 10c0/83758951967ec57bf00b5f5b7dc797e6d65a6171e57ea57adcf1bd1a0b477fd9b5b35fae5be1ff18f4090ed156bce1db749fe7e317aac19d485a5d150f6a4936 - languageName: node - linkType: hard - "error-ex@npm:^1.3.1, error-ex@npm:^1.3.2": version: 1.3.2 resolution: "error-ex@npm:1.3.2" @@ -12133,7 +12275,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": +"iconv-lite@npm:0.6, iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -12183,15 +12325,6 @@ __metadata: languageName: node linkType: hard -"image-size@npm:~0.5.0": - version: 0.5.5 - resolution: "image-size@npm:0.5.5" - bin: - image-size: bin/image-size.js - checksum: 10c0/655204163af06732f483a9fe7cce9dff4a29b7b2e88f5c957a5852e8143fa750f5e54b1955a2ca83de99c5220dbd680002d0d4e09140b01433520f4d5a0b1f4c - languageName: node - linkType: hard - "immer@npm:^10.1.1": version: 10.1.1 resolution: "immer@npm:10.1.1" @@ -12206,6 +12339,13 @@ __metadata: languageName: node linkType: hard +"immutable@npm:^5.0.2": + version: 5.0.3 + resolution: "immutable@npm:5.0.3" + checksum: 10c0/3269827789e1026cd25c2ea97f0b2c19be852ffd49eda1b674b20178f73d84fa8d945ad6f5ac5bc4545c2b4170af9f6e1f77129bc1cae7974a4bf9b04a9cdfb9 + languageName: node + linkType: hard + "import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" @@ -12699,13 +12839,6 @@ __metadata: languageName: node linkType: hard -"is-what@npm:^3.14.1": - version: 3.14.1 - resolution: "is-what@npm:3.14.1" - checksum: 10c0/4b770b85454c877b6929a84fd47c318e1f8c2ff70fd72fd625bc3fde8e0c18a6e57345b6e7aa1ee9fbd1c608d27cfe885df473036c5c2e40cd2187250804a2c7 - languageName: node - linkType: hard - "is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" @@ -13137,41 +13270,6 @@ __metadata: languageName: node linkType: hard -"less@npm:^4.2.0": - version: 4.2.0 - resolution: "less@npm:4.2.0" - dependencies: - copy-anything: "npm:^2.0.1" - errno: "npm:^0.1.1" - graceful-fs: "npm:^4.1.2" - image-size: "npm:~0.5.0" - make-dir: "npm:^2.1.0" - mime: "npm:^1.4.1" - needle: "npm:^3.1.0" - parse-node-version: "npm:^1.0.1" - source-map: "npm:~0.6.0" - tslib: "npm:^2.3.0" - dependenciesMeta: - errno: - optional: true - graceful-fs: - optional: true - image-size: - optional: true - make-dir: - optional: true - mime: - optional: true - needle: - optional: true - source-map: - optional: true - bin: - lessc: bin/lessc - checksum: 10c0/8593d547a3e7651555a2c51bac8b148b37ec14e75e6e28ee4ddf27eb49cbcb4b558e50cdefa97d6942a8120fc744ace0d61c43d4c246e098c8828269b14cf5fb - languageName: node - linkType: hard - "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -13475,16 +13573,6 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^2.1.0": - version: 2.1.0 - resolution: "make-dir@npm:2.1.0" - dependencies: - pify: "npm:^4.0.1" - semver: "npm:^5.6.0" - checksum: 10c0/ada869944d866229819735bee5548944caef560d7a8536ecbc6536edca28c72add47cc4f6fc39c54fb25d06b58da1f8994cf7d9df7dadea047064749efc085d8 - languageName: node - linkType: hard - "make-dir@npm:^4.0.0": version: 4.0.0 resolution: "make-dir@npm:4.0.0" @@ -14516,7 +14604,7 @@ __metadata: languageName: node linkType: hard -"mime@npm:1.6.0, mime@npm:^1.4.1": +"mime@npm:1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" bin: @@ -14882,18 +14970,6 @@ __metadata: languageName: node linkType: hard -"needle@npm:^3.1.0": - version: 3.3.1 - resolution: "needle@npm:3.3.1" - dependencies: - iconv-lite: "npm:^0.6.3" - sax: "npm:^1.2.4" - bin: - needle: bin/needle - checksum: 10c0/233b9315d47b735867d03e7a018fb665ee6cacf3a83b991b19538019cf42b538a3e85ca745c840b4c5e9a0ffdca76472f941363bf7c166214ae8cbc650fd4d39 - languageName: node - linkType: hard - "negotiator@npm:0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" @@ -14952,6 +15028,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^7.0.0": + version: 7.1.1 + resolution: "node-addon-api@npm:7.1.1" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/fb32a206276d608037fa1bcd7e9921e177fe992fc610d098aa3128baca3c0050fc1e014fa007e9b3874cf865ddb4f5bd9f43ccb7cbbbe4efaff6a83e920b17e9 + languageName: node + linkType: hard + "node-api-version@npm:^0.2.0": version: 0.2.0 resolution: "node-api-version@npm:0.2.0" @@ -15540,13 +15625,6 @@ __metadata: languageName: node linkType: hard -"parse-node-version@npm:^1.0.1": - version: 1.0.1 - resolution: "parse-node-version@npm:1.0.1" - checksum: 10c0/999cd3d7da1425c2e182dce82b226c6dc842562d3ed79ec47f5c719c32a7f6c1a5352495b894fc25df164be7f2ede4224758255da9902ddef81f2b77ba46bb2c - languageName: node - linkType: hard - "parse-numeric-range@npm:^1.3.0": version: 1.3.0 resolution: "parse-numeric-range@npm:1.3.0" @@ -15746,13 +15824,6 @@ __metadata: languageName: node linkType: hard -"pify@npm:^4.0.1": - version: 4.0.1 - resolution: "pify@npm:4.0.1" - checksum: 10c0/6f9d404b0d47a965437403c9b90eca8bb2536407f03de165940e62e72c8c8b75adda5516c6b9b23675a5877cc0bcac6bdfb0ef0e39414cd2476d5495da40e7cf - languageName: node - linkType: hard - "pkg-dir@npm:^7.0.0": version: 7.0.0 resolution: "pkg-dir@npm:7.0.0" @@ -16467,13 +16538,6 @@ __metadata: languageName: node linkType: hard -"prr@npm:~1.0.1": - version: 1.0.1 - resolution: "prr@npm:1.0.1" - checksum: 10c0/5b9272c602e4f4472a215e58daff88f802923b84bc39c8860376bb1c0e42aaf18c25d69ad974bd06ec6db6f544b783edecd5502cd3d184748d99080d68e4be5f - languageName: node - linkType: hard - "pump@npm:^3.0.0": version: 3.0.2 resolution: "pump@npm:3.0.2" @@ -16962,6 +17026,13 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:^4.0.1": + version: 4.0.2 + resolution: "readdirp@npm:4.0.2" + checksum: 10c0/a16ecd8ef3286dcd90648c3b103e3826db2b766cdb4a988752c43a83f683d01c7059158d623cbcd8bdfb39e65d302d285be2d208e7d9f34d022d912b929217dd + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -18167,6 +18238,23 @@ __metadata: languageName: node linkType: hard +"sass@npm:^1.81.0": + version: 1.81.0 + resolution: "sass@npm:1.81.0" + dependencies: + "@parcel/watcher": "npm:^2.4.1" + chokidar: "npm:^4.0.0" + immutable: "npm:^5.0.2" + source-map-js: "npm:>=0.6.2 <2.0.0" + dependenciesMeta: + "@parcel/watcher": + optional: true + bin: + sass: sass.js + checksum: 10c0/9c59b3c9b4231c18fcb4583cc232dbc4de501ddc11101b7a025e44833e3f3ce6031546dc1cd109ee9f04ebcfb1fe30ff870810af33b8feb9aa9e36dfba9ec1ef + languageName: node + linkType: hard + "satori@npm:^0.1": version: 0.1.2 resolution: "satori@npm:0.1.2" @@ -18275,15 +18363,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^5.6.0": - version: 5.7.2 - resolution: "semver@npm:5.7.2" - bin: - semver: bin/semver - checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 - languageName: node - linkType: hard - "semver@npm:^6.2.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -18758,7 +18837,7 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": +"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf @@ -19647,7 +19726,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2, tslib@npm:^2.8.1": +"tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 @@ -20753,7 +20832,6 @@ __metadata: html-to-image: "npm:^1.11.11" immer: "npm:^10.1.1" jotai: "npm:2.9.3" - less: "npm:^4.2.0" monaco-editor: "npm:^0.52.0" monaco-yaml: "npm:^5.2.3" overlayscrollbars: "npm:^2.10.0" @@ -20780,6 +20858,7 @@ __metadata: remark-github-blockquote-alert: "npm:^1.3.0" rollup-plugin-flow: "npm:^1.1.1" rxjs: "npm:^7.8.1" + sass: "npm:^1.81.0" semver: "npm:^7.6.3" sharp: "npm:^0.33.5" shell-quote: "npm:^1.8.1"