Switch from Less to Scss (#1335)

Less hasn't received an update in over a year and the parser is missing
some modern syntax like relative colors so this switches us to scss
This commit is contained in:
Evan Simkowitz 2024-11-21 16:05:04 -08:00 committed by GitHub
parent 59c570ddcf
commit 2e91ee843c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
124 changed files with 615 additions and 523 deletions

View File

@ -3,9 +3,9 @@ import type { Preview } from "@storybook/react";
import React from "react"; import React from "react";
import { DndProvider } from "react-dnd"; import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend"; import { HTML5Backend } from "react-dnd-html5-backend";
import "../frontend/app/theme.less"; import "../frontend/app/theme.scss";
import "../frontend/app/app.less"; import "../frontend/app/app.scss";
import "../frontend/app/reset.less"; import "../frontend/app/reset.scss";
import "./global.css"; import "./global.css";
import { light, dark } from "./theme"; import { light, dark } from "./theme";
import { DocsContainer } from "@storybook/addon-docs"; import { DocsContainer } from "@storybook/addon-docs";

View File

@ -30,6 +30,13 @@ export default defineConfig({
"process.env.WS_NO_BUFFER_UTIL": "true", "process.env.WS_NO_BUFFER_UTIL": "true",
"process.env.WS_NO_UTF_8_VALIDATE": "true", "process.env.WS_NO_UTF_8_VALIDATE": "true",
}, },
css: {
preprocessorOptions: {
scss: {
api: "modern-compiler", // or "modern"
},
},
},
}, },
preload: { preload: {
root: ".", root: ".",
@ -76,5 +83,12 @@ export default defineConfig({
targets: [{ src: "node_modules/monaco-editor/min/vs/*", dest: "monaco" }], targets: [{ src: "node_modules/monaco-editor/min/vs/*", dest: "monaco" }],
}), }),
], ],
css: {
preprocessorOptions: {
scss: {
api: "modern-compiler", // or "modern"
},
},
},
}, },
}); });

View File

@ -1,8 +1,8 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "./reset.less"; @use "reset.scss";
@import "./theme.less"; @use "theme.scss";
body { body {
display: flex; display: flex;

View File

@ -27,7 +27,7 @@ import { AppBackground } from "./app-bg";
import { CenteredDiv } from "./element/quickelems"; import { CenteredDiv } from "./element/quickelems";
import { NotificationBubbles } from "./notification/notificationbubbles"; import { NotificationBubbles } from "./notification/notificationbubbles";
import "./app.less"; import "./app.scss";
const dlog = debug("wave:app"); const dlog = debug("wave:app");
const focusLog = debug("wave:focus"); const focusLog = debug("wave:focus");

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.block { .block {
display: flex; display: flex;
@ -118,7 +118,7 @@
} }
.block-frame-text { .block-frame-text {
.ellipsis(); @include mixins.ellipsis();
font: var(--fixed-font); font: var(--fixed-font);
font-size: 11px; font-size: 11px;
opacity: 0.7; opacity: 0.7;
@ -324,7 +324,7 @@
} }
.connstatus-status { .connstatus-status {
.ellipsis(); @include mixins.ellipsis();
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
@ -333,7 +333,7 @@
width: 100%; width: 100%;
.connstatus-status-text { .connstatus-status-text {
.ellipsis(); @include mixins.ellipsis();
max-width: 100%; max-width: 100%;
font-size: 11px; font-size: 11px;
font-style: normal; font-style: normal;
@ -344,7 +344,7 @@
} }
.connstatus-error { .connstatus-error {
.ellipsis(); @include mixins.ellipsis();
width: 94%; width: 94%;
font-size: 11px; font-size: 11px;
font-style: normal; font-style: normal;

View File

@ -34,7 +34,7 @@ import { WebView, WebViewModel, makeWebViewModel } from "@/view/webview/webview"
import clsx from "clsx"; import clsx from "clsx";
import { atom, useAtomValue } from "jotai"; import { atom, useAtomValue } from "jotai";
import { Suspense, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import { Suspense, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import "./block.less"; import "./block.scss";
import { BlockFrame } from "./blockframe"; import { BlockFrame } from "./blockframe";
import { blockViewToIcon, blockViewToName } from "./blockutil"; import { blockViewToIcon, blockViewToName } from "./blockutil";

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.avatar { .avatar {
position: relative; position: relative;
@ -53,5 +53,5 @@
} }
} }
.avatar-dims-mixin(); @include mixins.avatar-dims-mixin();
} }

View File

@ -3,7 +3,7 @@
import { memo } from "react"; import { memo } from "react";
import clsx from "clsx"; import clsx from "clsx";
import "./avatar.less"; import "./avatar.scss";
interface AvatarProps { interface AvatarProps {
name: string; name: string;

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.button { .button {
// override default button appearance // override default button appearance
@ -158,9 +158,9 @@
} }
// Include mixins // Include mixins
.border-radius-mixin(); @include mixins.border-radius-mixin();
.vertical-padding-mixin(); @include mixins.vertical-padding-mixin();
.horizontal-padding-mixin(); @include mixins.horizontal-padding-mixin();
.font-size-mixin(); @include mixins.font-size-mixin();
.font-weight-mixin(); @include mixins.font-weight-mixin();
} }

View File

@ -4,7 +4,7 @@
import clsx from "clsx"; import clsx from "clsx";
import { forwardRef, memo, ReactNode, useImperativeHandle, useRef } from "react"; import { forwardRef, memo, ReactNode, useImperativeHandle, useRef } from "react";
import "./button.less"; import "./button.scss";
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
className?: string; className?: string;

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.collapsible-menu { .collapsible-menu {
list-style: none; list-style: none;
@ -32,7 +32,7 @@
} }
.collapsible-menu-item-text { .collapsible-menu-item-text {
.ellipsis(); @include mixins.ellipsis();
text-decoration: none; text-decoration: none;
} }

View File

@ -3,7 +3,7 @@
import clsx from "clsx"; import clsx from "clsx";
import React, { memo, useState } from "react"; import React, { memo, useState } from "react";
import "./collapsiblemenu.less"; import "./collapsiblemenu.scss";
interface VerticalNavProps { interface VerticalNavProps {
items: MenuItem[]; items: MenuItem[];

View File

@ -3,7 +3,7 @@
import { clsx } from "clsx"; import { clsx } from "clsx";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import "./copybutton.less"; import "./copybutton.scss";
import { IconButton } from "./iconbutton"; import { IconButton } from "./iconbutton";
type CopyButtonProps = { type CopyButtonProps = {

View File

@ -8,7 +8,7 @@ import { Button } from "./button";
import { Input, InputGroup, InputLeftElement } from "./input"; import { Input, InputGroup, InputLeftElement } from "./input";
import { Popover, PopoverButton, PopoverContent } from "./popover"; import { Popover, PopoverButton, PopoverContent } from "./popover";
import "./emojipalette.less"; import "./emojipalette.scss";
type EmojiItem = { emoji: string; name: string }; type EmojiItem = { emoji: string; name: string };

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.expandable-menu { .expandable-menu {
display: flex; display: flex;
@ -20,7 +20,7 @@
border-radius: 4px; border-radius: 4px;
.label { .label {
.ellipsis(); @include mixins.ellipsis();
} }
} }

View File

@ -5,7 +5,7 @@ import { clsx } from "clsx";
import { atom, useAtom } from "jotai"; import { atom, useAtom } from "jotai";
import { Children, ReactElement, ReactNode, cloneElement, isValidElement, useRef } from "react"; import { Children, ReactElement, ReactNode, cloneElement, isValidElement, useRef } from "react";
import "./expandablemenu.less"; import "./expandablemenu.scss";
// Define the global atom for managing open groups // Define the global atom for managing open groups
const openGroupsAtom = atom<{ [key: string]: boolean }>({}); const openGroupsAtom = atom<{ [key: string]: boolean }>({});

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.menu { .menu {
position: absolute; position: absolute;
@ -38,7 +38,7 @@
justify-content: space-between; justify-content: space-between;
.label { .label {
.ellipsis(); @include mixins.ellipsis();
text-decoration: none; text-decoration: none;
} }
} }

View File

@ -6,7 +6,7 @@ import clsx from "clsx";
import { createRef, Fragment, memo, ReactNode, useRef, useState } from "react"; import { createRef, Fragment, memo, ReactNode, useRef, useState } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import "./flyoutmenu.less"; import "./flyoutmenu.scss";
type MenuProps = { type MenuProps = {
items: MenuItem[]; items: MenuItem[];

View File

@ -5,7 +5,7 @@ import { useLongClick } from "@/app/hook/useLongClick";
import { makeIconClass } from "@/util/util"; import { makeIconClass } from "@/util/util";
import clsx from "clsx"; import clsx from "clsx";
import { memo, useRef } from "react"; import { memo, useRef } from "react";
import "./iconbutton.less"; import "./iconbutton.scss";
export const IconButton = memo(({ decl, className }: { decl: IconButtonDecl; className?: string }) => { export const IconButton = memo(({ decl, className }: { decl: IconButtonDecl; className?: string }) => {
const buttonRef = useRef<HTMLDivElement>(null); const buttonRef = useRef<HTMLDivElement>(null);

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.input { .input {
width: 100%; width: 100%;
@ -28,11 +28,11 @@
} }
// Include mixins // Include mixins
.border-radius-mixin(); @include mixins.border-radius-mixin();
.vertical-padding-mixin(); @include mixins.vertical-padding-mixin();
.horizontal-padding-mixin(); @include mixins.horizontal-padding-mixin();
.font-size-mixin(); @include mixins.font-size-mixin();
.font-weight-mixin(); @include mixins.font-weight-mixin();
} }
/* Styles when an InputGroup is present */ /* Styles when an InputGroup is present */
@ -87,7 +87,7 @@
} }
// Include mixins // Include mixins
.border-radius-mixin(); @include mixins.border-radius-mixin();
.font-size-mixin(); @include mixins.font-size-mixin();
.font-weight-mixin(); @include mixins.font-weight-mixin();
} }

View File

@ -4,7 +4,7 @@
import clsx from "clsx"; import clsx from "clsx";
import React, { forwardRef, memo, useImperativeHandle, useRef, useState } from "react"; import React, { forwardRef, memo, useImperativeHandle, useRef, useState } from "react";
import "./input.less"; import "./input.scss";
interface InputGroupProps { interface InputGroupProps {
children: React.ReactNode; children: React.ReactNode;

View File

@ -1,6 +1,6 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
&.link-button { .link-button {
text-decoration: none; text-decoration: none;
} }

View File

@ -4,7 +4,7 @@
import { clsx } from "clsx"; import { clsx } from "clsx";
import * as React from "react"; import * as React from "react";
import "./linkbutton.less"; import "./linkbutton.scss";
interface LinkButtonProps { interface LinkButtonProps {
href: string; href: string;

View File

@ -3,7 +3,7 @@
import clsx from "clsx"; import clsx from "clsx";
import MagnifySVG from "../asset/magnify.svg"; import MagnifySVG from "../asset/magnify.svg";
import "./magnify.less"; import "./magnify.scss";
interface MagnifyIconProps { interface MagnifyIconProps {
enabled: boolean; enabled: boolean;

View File

@ -21,7 +21,7 @@ import RemarkFlexibleToc, { TocItem } from "remark-flexible-toc";
import remarkGfm from "remark-gfm"; import remarkGfm from "remark-gfm";
import { openLink } from "../store/global"; import { openLink } from "../store/global";
import { IconButton } from "./iconbutton"; import { IconButton } from "./iconbutton";
import "./markdown.less"; import "./markdown.scss";
const Link = ({ const Link = ({
setFocusedHeading, setFocusedHeading,

View File

@ -2,7 +2,7 @@ import clsx from "clsx";
import { memo, useState } from "react"; import { memo, useState } from "react";
import { Button } from "./button"; import { Button } from "./button";
import { FlyoutMenu } from "./flyoutmenu"; import { FlyoutMenu } from "./flyoutmenu";
import "./menubutton.less"; import "./menubutton.scss";
const MenuButtonComponent = ({ items, className, text, title }: MenuButtonProps) => { const MenuButtonComponent = ({ items, className, text, title }: MenuButtonProps) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);

View File

@ -4,7 +4,7 @@
import { Button } from "@/element/button"; import { Button } from "@/element/button";
import React from "react"; import React from "react";
import "./modal.less"; import "./modal.scss";
interface ModalProps { interface ModalProps {
id?: string; id?: string;

View File

@ -4,7 +4,7 @@
import clsx from "clsx"; import clsx from "clsx";
import React, { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react"; import React, { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react";
import "./multilineinput.less"; import "./multilineinput.scss";
interface MultiLineInputProps { interface MultiLineInputProps {
value?: string; value?: string;

View File

@ -5,7 +5,7 @@
min-width: 100px; min-width: 100px;
min-height: 150px; min-height: 150px;
position: absolute; position: absolute;
z-index: 1000; // TODO: put this in theme.less z-index: 1000; // TODO: put this in theme.scss
display: flex; display: flex;
padding: 2px; padding: 2px;
gap: 1px; gap: 1px;

View File

@ -26,7 +26,7 @@ import {
useState, useState,
} from "react"; } from "react";
import "./popover.less"; import "./popover.scss";
interface PopoverProps { interface PopoverProps {
children: ReactNode; children: ReactNode;

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import React from "react"; import React from "react";
import "./quickelems.less"; import "./quickelems.scss";
function CenteredLoadingDiv() { function CenteredLoadingDiv() {
return <CenteredDiv>loading...</CenteredDiv>; return <CenteredDiv>loading...</CenteredDiv>;

View File

@ -3,7 +3,7 @@
import { MagnifyIcon } from "@/app/element/magnify"; import { MagnifyIcon } from "@/app/element/magnify";
import { PLATFORM } from "@/app/store/global"; import { PLATFORM } from "@/app/store/global";
import "./quicktips.less"; import "./quicktips.scss";
const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { const KeyBinding = ({ keyDecl }: { keyDecl: string }) => {
const parts = keyDecl.split(":"); const parts = keyDecl.split(":");

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import { useRef } from "react"; import { useRef } from "react";
import "./toggle.less"; import "./toggle.scss";
interface ToggleProps { interface ToggleProps {
checked: boolean; checked: boolean;

View File

@ -1,21 +1,21 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@dot-width: 11px; $dot-width: 11px;
@dot-color: var(--success-color); $dot-color: var(--success-color);
@speed: 1.5s; $speed: 1.5s;
.typing { .typing {
position: relative; position: relative;
height: @dot-width; height: $dot-width;
span { span {
content: ""; content: "";
animation: blink @speed infinite; animation: blink $speed infinite;
animation-fill-mode: both; animation-fill-mode: both;
height: @dot-width; height: $dot-width;
width: @dot-width; width: $dot-width;
background: @dot-color; background: $dot-color;
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
@ -23,12 +23,12 @@
&:nth-child(2) { &:nth-child(2) {
animation-delay: 0.2s; animation-delay: 0.2s;
margin-left: @dot-width * 1.5; margin-left: $dot-width * 1.5;
} }
&:nth-child(3) { &:nth-child(3) {
animation-delay: 0.4s; animation-delay: 0.4s;
margin-left: @dot-width * 3; margin-left: $dot-width * 3;
} }
} }
} }

View File

@ -3,7 +3,7 @@
import { clsx } from "clsx"; import { clsx } from "clsx";
import "./typingindicator.less"; import "./typingindicator.scss";
type TypingIndicatorProps = { type TypingIndicatorProps = {
className?: string; className?: string;

View File

@ -4,7 +4,7 @@
import { clsx } from "clsx"; import { clsx } from "clsx";
import React, { forwardRef } from "react"; import React, { forwardRef } from "react";
import "./windowdrag.less"; import "./windowdrag.scss";
interface WindowDragProps { interface WindowDragProps {
className?: string; className?: string;

View File

@ -1,14 +1,14 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
.ellipsis() { @mixin ellipsis(){
display: block; display: block;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.border-radius-mixin() { @mixin border-radius-mixin(){
&.border-radius-2 { &.border-radius-2 {
border-radius: 4px; border-radius: 4px;
} }
@ -38,7 +38,7 @@
} }
} }
.vertical-padding-mixin() { @mixin vertical-padding-mixin(){
&.vertical-padding-0 { &.vertical-padding-0 {
padding-top: 0px; padding-top: 0px;
padding-bottom: 0px; padding-bottom: 0px;
@ -85,7 +85,7 @@
} }
} }
.horizontal-padding-mixin() { @mixin horizontal-padding-mixin(){
&.horizontal-padding-0 { &.horizontal-padding-0 {
padding-left: 0px; padding-left: 0px;
padding-right: 0px; padding-right: 0px;
@ -132,7 +132,7 @@
} }
} }
.font-size-mixin() { @mixin font-size-mixin(){
&.font-size-10 { &.font-size-10 {
font-size: 10px; font-size: 10px;
} }
@ -186,7 +186,7 @@
} }
} }
.font-weight-mixin() { @mixin font-weight-mixin(){
&.font-weight-100 { &.font-weight-100 {
font-weight: 100; font-weight: 100;
} }
@ -210,7 +210,7 @@
} }
} }
.avatar-dims-mixin() { @mixin avatar-dims-mixin(){
&.size-xs { &.size-xs {
width: 20px; width: 20px;
height: 20px; height: 20px;

View File

@ -9,7 +9,7 @@ import { Modal } from "./modal";
import { isDev } from "@/util/isdev"; import { isDev } from "@/util/isdev";
import { useState } from "react"; import { useState } from "react";
import { getApi } from "../store/global"; import { getApi } from "../store/global";
import "./about.less"; import "./about.scss";
interface AboutModalProps {} interface AboutModalProps {}

View File

@ -5,7 +5,7 @@ import { Modal } from "@/app/modals/modal";
import { modalsModel } from "@/app/store/modalmodel"; import { modalsModel } from "@/app/store/modalmodel";
import { ReactNode } from "react"; import { ReactNode } from "react";
import "./messagemodal.less"; import "./messagemodal.scss";
const MessageModal = ({ children }: { children: ReactNode }) => { const MessageModal = ({ children }: { children: ReactNode }) => {
function closeModal() { function closeModal() {

View File

@ -6,7 +6,7 @@ import clsx from "clsx";
import { forwardRef } from "react"; import { forwardRef } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import "./modal.less"; import "./modal.scss";
interface ModalProps { interface ModalProps {
children?: React.ReactNode; children?: React.ReactNode;

View File

@ -13,7 +13,7 @@ import { QuickTips } from "@/app/element/quicktips";
import { atoms, getApi } from "@/app/store/global"; import { atoms, getApi } from "@/app/store/global";
import { modalsModel } from "@/app/store/modalmodel"; import { modalsModel } from "@/app/store/modalmodel";
import { atom, PrimitiveAtom, useAtom, useAtomValue, useSetAtom } from "jotai"; import { atom, PrimitiveAtom, useAtom, useAtomValue, useSetAtom } from "jotai";
import "./tos.less"; import "./tos.scss";
const pageNumAtom: PrimitiveAtom<number> = atom<number>(1); const pageNumAtom: PrimitiveAtom<number> = atom<number>(1);

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../mixins.less"; @use "../mixins.scss";
.type-ahead-modal-backdrop { .type-ahead-modal-backdrop {
position: absolute; position: absolute;
@ -97,7 +97,7 @@
} }
.typeahead-item-name { .typeahead-item-name {
.ellipsis(); @include mixins.ellipsis();
display: flex; display: flex;
gap: 8px; gap: 8px;
font-size: 11px; font-size: 11px;

View File

@ -8,7 +8,7 @@ import clsx from "clsx";
import React, { forwardRef, useLayoutEffect, useRef } from "react"; import React, { forwardRef, useLayoutEffect, useRef } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import "./typeaheadmodal.less"; import "./typeaheadmodal.scss";
interface SuggestionsProps { interface SuggestionsProps {
suggestions?: SuggestionsType[]; suggestions?: SuggestionsType[];

View File

@ -8,7 +8,7 @@ import * as keyutil from "@/util/keyutil";
import { UserInputService } from "../store/services"; import { UserInputService } from "../store/services";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import "./userinputmodal.less"; import "./userinputmodal.scss";
const UserInputModal = (userInputRequest: UserInputRequest) => { const UserInputModal = (userInputRequest: UserInputRequest) => {
const [responseText, setResponseText] = useState(""); const [responseText, setResponseText] = useState("");

View File

@ -6,7 +6,7 @@ import { FloatingPortal, useFloating, useInteractions } from "@floating-ui/react
import clsx from "clsx"; import clsx from "clsx";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import "./notificationbubbles.less"; import "./notificationbubbles.scss";
import { NotificationItem } from "./notificationitem"; import { NotificationItem } from "./notificationitem";
import { useNotification } from "./usenotification"; import { useNotification } from "./usenotification";

View File

@ -1,7 +1,8 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
.notification-title { .notification {
.notification-title {
font-size: 13px; font-size: 13px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -9,63 +10,63 @@
margin-bottom: 3px; margin-bottom: 3px;
&.green { &.green {
color: var(--success-color); color: var(--success-color);
} }
&.red { &.red {
color: var(--error-color); color: var(--error-color);
} }
&.yellow { &.yellow {
color: var(--warning-color); color: var(--warning-color);
} }
} }
.notification-message { .notification-message {
font-size: 13px; font-size: 13px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: 18px; line-height: 18px;
opacity: 0.7; opacity: 0.7;
} }
.notification-actions { .notification-actions {
display: flex; display: flex;
gap: 10px; gap: 10px;
flex-wrap: wrap; flex-wrap: wrap;
margin-top: 10px; margin-top: 10px;
i { i {
margin-left: 3px; margin-left: 3px;
font-size: 11px; font-size: 11px;
} }
} }
.close-btn { .close-btn {
position: absolute; position: absolute;
top: 5px; top: 5px;
right: 5px; right: 5px;
} }
.lock-btn { .lock-btn {
position: absolute; position: absolute;
top: 5px; top: 5px;
right: 5px; right: 5px;
padding: 10px 8px; padding: 10px 8px;
font-size: 11px; font-size: 11px;
color: rgb(from var(--main-text-color) r g b / 0.5); color: rgb(from var(--main-text-color) r g b / 0.5);
} }
.notification { .notification {
width: 100%; width: 100%;
color: var(--main-text-color); color: var(--main-text-color);
padding: 12px 10px; padding: 12px 10px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; position: relative;
} }
.notification-bubble { .notification-bubble {
position: relative; position: relative;
display: flex; display: flex;
width: 380px; width: 380px;
@ -76,43 +77,43 @@
border: 0.5px solid rgba(255, 255, 255, 0.12); border: 0.5px solid rgba(255, 255, 255, 0.12);
background: #232323; background: #232323;
box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25); box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25);
} }
.notification-inner { .notification-inner {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
column-gap: 6px; column-gap: 6px;
.notification-icon { .notification-icon {
margin-right: 5px; margin-right: 5px;
margin-top: 1px; margin-top: 1px;
i { i {
font-size: 16px; font-size: 16px;
} }
i.green { i.green {
color: var(--success-color); color: var(--success-color);
} }
i.red { i.red {
color: var(--error-color); color: var(--error-color);
} }
i.yellow { i.yellow {
color: var(--warning-color); color: var(--warning-color);
} }
} }
.notification-timestamp { .notification-timestamp {
font-size: 12px; font-size: 12px;
font-weight: 400; font-weight: 400;
line-height: 18px; line-height: 18px;
opacity: 0.5; opacity: 0.5;
margin-bottom: 7px; margin-bottom: 7px;
} }
} }
&.hovered {
&.hovered {
background: #292929; background: #292929;
}
} }

View File

@ -5,7 +5,7 @@ import { Button } from "@/element/button";
import { makeIconClass } from "@/util/util"; import { makeIconClass } from "@/util/util";
import clsx from "clsx"; import clsx from "clsx";
import "./notificationitem.less"; import "./notificationitem.scss";
interface NotificationItemProps { interface NotificationItemProps {
notification: NotificationType; notification: NotificationType;
onRemove: (id: string) => void; onRemove: (id: string) => void;

View File

@ -13,7 +13,7 @@ import { NotificationItem } from "./notificationitem";
import { useUpdateNotifier } from "./updatenotifier"; import { useUpdateNotifier } from "./updatenotifier";
import { useNotification } from "./usenotification"; import { useNotification } from "./usenotification";
import "./notificationpopover.less"; import "./notificationpopover.scss";
const NotificationPopover = () => { const NotificationPopover = () => {
useUpdateNotifier(); useUpdateNotifier();

View File

@ -12,7 +12,7 @@ import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "re
import { atoms, globalStore, refocusNode } from "@/app/store/global"; import { atoms, globalStore, refocusNode } from "@/app/store/global";
import { RpcApi } from "@/app/store/wshclientapi"; import { RpcApi } from "@/app/store/wshclientapi";
import { TabRpcClient } from "@/app/store/wshrpcutil"; import { TabRpcClient } from "@/app/store/wshrpcutil";
import "./tab.less"; import "./tab.scss";
interface TabProps { interface TabProps {
id: string; id: string;

View File

@ -12,7 +12,7 @@ import { OverlayScrollbars } from "overlayscrollbars";
import React, { createRef, useCallback, useEffect, useRef, useState } from "react"; import React, { createRef, useCallback, useEffect, useRef, useState } from "react";
import { debounce } from "throttle-debounce"; import { debounce } from "throttle-debounce";
import { Tab } from "./tab"; import { Tab } from "./tab";
import "./tabbar.less"; import "./tabbar.scss";
import { UpdateStatusBanner } from "./updatebanner"; import { UpdateStatusBanner } from "./updatebanner";
import { WorkspaceSwitcher } from "./workspaceswitcher"; import { WorkspaceSwitcher } from "./workspaceswitcher";

View File

@ -11,7 +11,7 @@ import * as WOS from "@/store/wos";
import { atom, useAtomValue } from "jotai"; import { atom, useAtomValue } from "jotai";
import * as React from "react"; import * as React from "react";
import { useMemo } from "react"; import { useMemo } from "react";
import "./tabcontent.less"; import "./tabcontent.scss";
const tileGapSizeAtom = atom((get) => { const tileGapSizeAtom = atom((get) => {
const settings = get(atoms.settingsAtom); const settings = get(atoms.settingsAtom);

View File

@ -2,7 +2,7 @@ import { Button } from "@/element/button";
import { atoms, getApi } from "@/store/global"; import { atoms, getApi } from "@/store/global";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import { memo, useEffect, useState } from "react"; import { memo, useEffect, useState } from "react";
import "./updatebanner.less"; import "./updatebanner.scss";
const UpdateStatusBannerComponent = ({ buttonRef }: { buttonRef: React.RefObject<HTMLButtonElement> }) => { const UpdateStatusBannerComponent = ({ buttonRef }: { buttonRef: React.RefObject<HTMLButtonElement> }) => {
const appUpdateStatus = useAtomValue(atoms.updaterStatusAtom); const appUpdateStatus = useAtomValue(atoms.updaterStatusAtom);

View File

@ -22,7 +22,7 @@ import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
import { memo, useEffect, useRef } from "react"; import { memo, useEffect, useRef } from "react";
import WorkspaceSVG from "../asset/workspace.svg"; import WorkspaceSVG from "../asset/workspace.svg";
import "./workspaceswitcher.less"; import "./workspaceswitcher.scss";
interface ColorSelectorProps { interface ColorSelectorProps {
colors: string[]; colors: string[];

View File

@ -4,7 +4,7 @@
import { CollapsibleMenu } from "@/app/element/collapsiblemenu"; import { CollapsibleMenu } from "@/app/element/collapsiblemenu";
import { memo } from "react"; import { memo } from "react";
import "./channels.less"; import "./channels.scss";
const Channels = memo(({ channels }: { channels: MenuItem[] }) => { const Channels = memo(({ channels }: { channels: MenuItem[] }) => {
return <CollapsibleMenu className="channel-list" items={channels}></CollapsibleMenu>; return <CollapsibleMenu className="channel-list" items={channels}></CollapsibleMenu>;

View File

@ -10,7 +10,7 @@ import { ChatBox } from "./chatbox";
import { channels, messages, users } from "./data"; import { channels, messages, users } from "./data";
import { UserList } from "./userlist"; import { UserList } from "./userlist";
import "./chat.less"; import "./chat.scss";
class ChatModel { class ChatModel {
viewType: string; viewType: string;

View File

@ -3,7 +3,7 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { ChatMessages } from "./chatmessages"; import { ChatMessages } from "./chatmessages";
import "./chatmessages.less"; import "./chatmessages.scss";
export interface ChatMessage { export interface ChatMessage {
id: string; id: string;

View File

@ -6,7 +6,7 @@ import clsx from "clsx";
import { OverlayScrollbarsComponent } from "overlayscrollbars-react"; import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
import { memo, useEffect, useRef } from "react"; import { memo, useEffect, useRef } from "react";
import "./chatmessages.less"; import "./chatmessages.scss";
export interface ChatMessage { export interface ChatMessage {
id: string; id: string;

View File

@ -4,7 +4,7 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { UserList } from "./userlist"; import { UserList } from "./userlist";
import "./userlist.less"; import "./userlist.scss";
export interface UserStatus { export interface UserStatus {
text: string; text: string;

View File

@ -4,7 +4,7 @@
import clsx from "clsx"; import clsx from "clsx";
import { memo } from "react"; import { memo } from "react";
import { Avatar } from "../../element/avatar"; import { Avatar } from "../../element/avatar";
import "./userlist.less"; import "./userlist.scss";
export interface UserStatus { export interface UserStatus {
label: string; label: string;

View File

@ -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 tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
import ymlWorker from "./yamlworker?worker"; import ymlWorker from "./yamlworker?worker";
import "./codeeditor.less"; import "./codeeditor.scss";
// there is a global monaco variable (TODO get the correct TS type) // there is a global monaco variable (TODO get the correct TS type)
declare var monaco: Monaco; declare var monaco: Monaco;

View File

@ -7,7 +7,7 @@ import { WebView, WebViewModel } from "@/app/view/webview/webview";
import { fireAndForget } from "@/util/util"; import { fireAndForget } from "@/util/util";
import { atom, useAtomValue } from "jotai"; import { atom, useAtomValue } from "jotai";
import { useCallback } from "react"; import { useCallback } from "react";
import "./helpview.less"; import "./helpview.scss";
const docsiteWebUrl = "https://docs.waveterm.dev/"; const docsiteWebUrl = "https://docs.waveterm.dev/";
const baseUrlRegex = /http[s]?:\/\/([^:\/])+(:\d+)?/; const baseUrlRegex = /http[s]?:\/\/([^:\/])+(:\d+)?/;

View File

@ -7,7 +7,7 @@ import * as Plot from "@observablehq/plot";
import * as d3 from "d3"; import * as d3 from "d3";
import * as React from "react"; import * as React from "react";
import "./plotview.less"; import "./plotview.scss";
function PlotWindow() { function PlotWindow() {
return <div className="plot-window"></div>; return <div className="plot-window"></div>;

View File

@ -1,12 +1,12 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@import "../../mixins.less"; @use "../../mixins.scss";
.csv-view { .csv-view {
opacity: 0; /* Start with an opacity of 0, meaning it's invisible */ opacity: 0; /* Start with an opacity of 0, meaning it's invisible */
.ellipsis(); @include mixins.ellipsis();
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
@ -53,7 +53,7 @@
text-align: left; text-align: left;
padding-right: 15px; padding-right: 15px;
position: relative; position: relative;
.ellipsis(); @include mixins.ellipsis();
.sort-icon { .sort-icon {
position: absolute; position: absolute;
@ -85,7 +85,7 @@
flex-grow: 2; flex-grow: 2;
display: block; display: block;
text-align: left; text-align: left;
.ellipsis(); @include mixins.ellipsis();
} }
} }
} }

View File

@ -14,7 +14,7 @@ import Papa from "papaparse";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef, useState } from "react";
import { useDimensionsWithExistingRef } from "@/app/hook/useDimensions"; import { useDimensionsWithExistingRef } from "@/app/hook/useDimensions";
import "./csvview.less"; import "./csvview.scss";
const MAX_DATA_SIZE = 10 * 1024 * 1024; // 10MB in bytes const MAX_DATA_SIZE = 10 * 1024 * 1024; // 10MB in bytes

View File

@ -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);
}
}

Some files were not shown because too many files have changed in this diff Show More