Replace classnames with clsx (#634)

[`clsx`](https://www.npmjs.com/package/clsx) is a drop-in replacement
for `classnames` that is a quarter of the size and is faster.
This commit is contained in:
Evan Simkowitz 2024-05-02 11:40:44 -07:00 committed by GitHub
parent e973a6ff8f
commit ea0cf62b67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 142 additions and 155 deletions

View File

@ -26,7 +26,7 @@
"@tanstack/react-table": "^8.10.3",
"autobind-decorator": "^2.4.0",
"base64-js": "^1.5.1",
"classnames": "^2.3.1",
"clsx": "^2.1.1",
"dayjs": "^1.11.3",
"dompurify": "^3.0.2",
"electron-squirrel-startup": "^1.0.0",
@ -70,7 +70,6 @@
"@babel/preset-typescript": "^7.17.12",
"@electron/rebuild": "^3.6.0",
"@svgr/webpack": "^8.1.0",
"@types/classnames": "^2.3.1",
"@types/electron": "^1.6.10",
"@types/node": "^20.11.0",
"@types/papaparse": "^5.3.10",

View File

@ -4,7 +4,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import cn from "classnames";
import { clsx } from "clsx";
import { boundMethod } from "autobind-decorator";
import { If } from "tsx-control-statements/components";
@ -133,7 +133,7 @@ class App extends React.Component<{}, {}> {
const rightSidebarCollapsed = GlobalModel.rightSidebarModel.getCollapsed();
const activeMainView = GlobalModel.activeMainView.get();
const lightDarkClass = GlobalModel.isDarkTheme.get() ? "is-dark" : "is-light";
const mainClassName = cn(
const mainClassName = clsx(
"platform-" + platform,
{
"mainsidebar-collapsed": mainSidebarCollapsed,

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import { If, For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel } from "@/models";
import { CmdStrCode, Markdown } from "@/common/elements";
@ -152,11 +152,11 @@ class Bookmark extends React.Component<BookmarkProps, {}> {
return (
<div
data-bookmarkid={bm.bookmarkid}
className={cn("bookmark focus-parent is-editing", {
className={clsx("bookmark focus-parent is-editing", {
"pending-delete": model.pendingDelete.get() == bm.bookmarkid,
})}
>
<div className={cn("focus-indicator", { active: isSelected })} />
<div className={clsx("focus-indicator", { active: isSelected })} />
<div className="bookmark-edit">
<div className="field">
<label className="label">Description (markdown)</label>
@ -198,12 +198,12 @@ class Bookmark extends React.Component<BookmarkProps, {}> {
}
return (
<div
className={cn("bookmark focus-parent", {
className={clsx("bookmark focus-parent", {
"pending-delete": model.pendingDelete.get() == bm.bookmarkid,
})}
onClick={this.handleClick}
>
<div className={cn("focus-indicator", { active: isSelected })} />
<div className={clsx("focus-indicator", { active: isSelected })} />
<div className="bookmark-id-div">{bm.bookmarkid.substr(0, 8)}</div>
<div className="bookmark-content">
<If condition={hasDesc}>

View File

@ -1,6 +1,6 @@
import * as React from "react";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import "./button.less";
@ -35,7 +35,7 @@ class Button extends React.Component<ButtonProps> {
return (
<button
className={cn("wave-button", { disabled }, { "term-inline": termInline }, className)}
className={clsx("wave-button", { disabled }, { "term-inline": termInline }, className)}
onClick={this.handleClick}
disabled={disabled}
style={style}

View File

@ -3,7 +3,7 @@
import * as React from "react";
import * as mobx from "mobx";
import cn from "classnames";
import { clsx } from "clsx";
import "./checkbox.less";
@ -49,7 +49,7 @@ class Checkbox extends React.Component<
const checkboxId = id || this.generatedId;
return (
<div className={cn("checkbox", className)}>
<div className={clsx("checkbox", className)}>
<input
type="checkbox"
id={checkboxId}

View File

@ -3,7 +3,7 @@
import * as React from "react";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { If } from "tsx-control-statements/components";
import { ReactComponent as CheckIcon } from "@/assets/icons/line/check.svg";
@ -41,7 +41,7 @@ class CmdStrCode extends React.Component<
render() {
let { isCopied, cmdstr, fontSize, limitHeight } = this.props;
return (
<div className={cn("cmdstr-code", { "is-large": fontSize == "large" }, { "limit-height": limitHeight })}>
<div className={clsx("cmdstr-code", { "is-large": fontSize == "large" }, { "limit-height": limitHeight })}>
<If condition={isCopied}>
<div key="copied" className="copied-indicator">
<div>copied</div>

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef, createRef } from "react";
import * as mobx from "mobx";
import ReactDOM from "react-dom";
import dayjs from "dayjs";
import cn from "classnames";
import { clsx } from "clsx";
import { Button } from "@/elements";
import { If } from "tsx-control-statements/components";
import { GlobalModel } from "@/models";
@ -102,7 +102,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
return (
<div className="day-picker-header">
<div
className={cn({ fade: showYearAccordion })}
className={clsx({ fade: showYearAccordion })}
onClick={() => {
if (!showYearAccordion) {
setExpandedYear(selDate.year()); // Set expandedYear when opening accordion
@ -111,7 +111,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
}}
>
{selDate.format("MMMM YYYY")}
<span className={cn("dropdown-arrow", { fade: showYearAccordion })}></span>
<span className={clsx("dropdown-arrow", { fade: showYearAccordion })}></span>
</div>
<If condition={!showYearAccordion}>
<div className="arrows">
@ -250,14 +250,14 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
</div>
<If condition={expandedYear === year}>
<div
className={cn("month-container", {
className={clsx("month-container", {
expanded: expandedYear === year,
})}
>
{Array.from({ length: 12 }, (_, i) => i + 1).map((month) => (
<div
key={month}
className={cn("month", {
className={clsx("month", {
selected: year === currentYear && month === selDate.month() + 1,
})}
onClick={() => handleMonthYearSelect(month, year)}

View File

@ -4,7 +4,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { If } from "tsx-control-statements/components";
import ReactDOM from "react-dom";
import { v4 as uuidv4 } from "uuid";
@ -239,11 +239,11 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
const dropdownMenu = isOpen
? ReactDOM.createPortal(
<div className={cn("wave-dropdown-menu")} ref={this.menuRef} style={this.calculatePosition()}>
<div className={clsx("wave-dropdown-menu")} ref={this.menuRef} style={this.calculatePosition()}>
{options.map((option, index) => (
<div
key={option.value}
className={cn("wave-dropdown-item unselectable", {
className={clsx("wave-dropdown-item unselectable", {
"wave-dropdown-item-highlighted": index === highlightedIndex,
})}
onClick={(e) => this.handleSelect(option, e)}
@ -265,7 +265,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
}
return (
<div
className={cn("wave-dropdown", className, {
className={clsx("wave-dropdown", className, {
"wave-dropdown-error": isError,
"no-label": !label,
})}
@ -279,7 +279,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
<If condition={label}>
<div
className={cn("wave-dropdown-label unselectable", {
className={clsx("wave-dropdown-label unselectable", {
float: shouldLabelFloat,
"offset-left": decoration?.startDecoration,
})}
@ -288,14 +288,14 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
</div>
</If>
<div
className={cn("wave-dropdown-display unselectable truncate", {
className={clsx("wave-dropdown-display unselectable truncate", {
"offset-left": decoration?.startDecoration,
})}
style={selectedOptionLabelStyle}
>
{selectedOptionLabel}
</div>
<div className={cn("wave-dropdown-arrow", { "wave-dropdown-arrow-rotate": isOpen })}>
<div className={clsx("wave-dropdown-arrow", { "wave-dropdown-arrow-rotate": isOpen })}>
<i className="fa-sharp fa-solid fa-chevron-down"></i>
</div>
{dropdownMenu}

View File

@ -5,7 +5,7 @@ import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { If } from "tsx-control-statements/components";
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
import { GlobalModel } from "@/models";
@ -121,7 +121,7 @@ class InlineSettingsTextEdit extends React.Component<
render() {
if (this.isEditing.get()) {
return (
<div className={cn("settings-input inline-edit", "edit-active")}>
<div className={clsx("settings-input inline-edit", "edit-active")}>
<div className="field has-addons">
<div className="control">
<input
@ -163,7 +163,7 @@ class InlineSettingsTextEdit extends React.Component<
);
} else {
return (
<div onClick={this.clickEdit} className={cn("settings-input inline-edit", "edit-not-active")}>
<div onClick={this.clickEdit} className={clsx("settings-input inline-edit", "edit-not-active")}>
{this.props.text}
<If condition={this.props.showIcon}>
<i className="fa-sharp fa-solid fa-pen" />

View File

@ -3,7 +3,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import cn from "classnames";
import { clsx } from "clsx";
import "./inputdecoration.less";
@ -18,7 +18,7 @@ class InputDecoration extends React.Component<InputDecorationProps, {}> {
const { children, position = "end" } = this.props;
return (
<div
className={cn("wave-input-decoration", {
className={clsx("wave-input-decoration", {
"start-position": position === "start",
"end-position": position === "end",
})}

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import * as React from "react";
import cn from "classnames";
import { clsx } from "clsx";
import { ButtonProps } from "./button";
interface LinkButtonProps extends ButtonProps {
@ -16,7 +16,7 @@ class LinkButton extends React.Component<LinkButtonProps> {
const { leftIcon, rightIcon, children, className, ...rest } = this.props;
return (
<a {...rest} className={cn(`wave-button link-button`, className)}>
<a {...rest} className={clsx(`wave-button link-button`, className)}>
{leftIcon && <span className="icon-left">{leftIcon}</span>}
{children}
{rightIcon && <span className="icon-right">{rightIcon}</span>}

View File

@ -3,7 +3,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel } from "@/models";
import "./mainview.less";
@ -24,7 +24,7 @@ class MainView extends React.Component<{
const maxWidthSubtractor = sidebarModel.getCollapsed() ? 0 : sidebarModel.getWidth();
return (
<div
className={cn("mainview", this.props.className)}
className={clsx("mainview", this.props.className)}
style={{ maxWidth: `calc(100vw - ${maxWidthSubtractor}px)` }}
>
<div className="header-container">

View File

@ -5,7 +5,7 @@ import * as React from "react";
import * as mobxReact from "mobx-react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel } from "@/models";
import { v4 as uuidv4 } from "uuid";
@ -22,7 +22,7 @@ function LinkRenderer(props: any): any {
}
function HeaderRenderer(props: any, hnum: number): any {
return <div className={cn("title", "is-" + hnum)}>{props.children}</div>;
return <div className={clsx("title", "is-" + hnum)}>{props.children}</div>;
}
function CodeRenderer(props: any): any {
@ -53,7 +53,7 @@ class CodeBlockMarkdown extends React.Component<
return (
<pre
ref={this.blockRef}
className={cn({ selected: selected })}
className={clsx({ selected: selected })}
onClick={(event) => clickHandler(event, this.blockIndex)}
>
{this.props.children}
@ -110,7 +110,7 @@ class Markdown extends React.Component<
pre: (props) => this.CodeBlockRenderer(props, codeSelect, curCodeSelectIndex, this.curUuid),
};
return (
<div className={cn("markdown content", this.props.extraClassName)} style={this.props.style}>
<div className={clsx("markdown content", this.props.extraClassName)} style={this.props.style}>
<ReactMarkdown remarkPlugins={[remarkGfm]} components={markdownComponents}>
{text}
</ReactMarkdown>

View File

@ -4,7 +4,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { If } from "tsx-control-statements/components";
import { TextFieldState, TextField } from "./textfield";
@ -48,7 +48,7 @@ class PasswordField extends TextField {
// The input should always receive the real value
const inputProps = {
className: cn("wave-textfield-inner-input", { "offset-left": decoration?.startDecoration }),
className: clsx("wave-textfield-inner-input", { "offset-left": decoration?.startDecoration }),
ref: this.inputRef,
id: label,
value: inputValue, // Always use the real value here
@ -63,7 +63,7 @@ class PasswordField extends TextField {
return (
<div
className={cn(`wave-textfield wave-password ${className || ""}`, {
className={clsx(`wave-textfield wave-password ${className || ""}`, {
focused: focused,
error: error,
"no-label": !label,
@ -72,7 +72,7 @@ class PasswordField extends TextField {
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
<div className="wave-textfield-inner">
<label
className={cn("wave-textfield-inner-label", {
className={clsx("wave-textfield-inner-label", {
float: this.state.hasContent || this.state.focused || placeholder,
"offset-left": decoration?.startDecoration,
})}

View File

@ -5,7 +5,7 @@ import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalCommandRunner, SidebarModel } from "@/models";
import { MagicLayout } from "@/app/magiclayout";
@ -142,7 +142,7 @@ class ResizableSidebar extends React.Component<ResizableSidebarProps> {
const isCollapsed = model.getCollapsed();
return (
<div className={cn("sidebar", className, { collapsed: isCollapsed })} style={{ width, minWidth: width }}>
<div className={clsx("sidebar", className, { collapsed: isCollapsed })} style={{ width, minWidth: width }}>
<div className="sidebar-content">{children(this.toggleCollapsed)}</div>
<div
className="sidebar-handle"

View File

@ -3,7 +3,7 @@
import * as React from "react";
import { isBlank } from "@/util/util";
import cn from "classnames";
import { clsx } from "clsx";
class TabIcon extends React.Component<{ icon: string; color: string }> {
render() {
@ -20,7 +20,7 @@ class TabIcon extends React.Component<{ icon: string; color: string }> {
color = "green";
}
return (
<div className={cn("tabicon", "color-" + color)}>
<div className={clsx("tabicon", "color-" + color)}>
<i className={iconClass} />
</div>
);

View File

@ -3,7 +3,7 @@
import * as React from "react";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { If } from "tsx-control-statements/components";
import "./textfield.less";
@ -140,7 +140,7 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
return (
<div
className={cn("wave-textfield", className, {
className={clsx("wave-textfield", className, {
focused: focused,
error: error,
disabled: disabled,
@ -154,7 +154,7 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
<div className="wave-textfield-inner">
<If condition={label}>
<label
className={cn("wave-textfield-inner-label", {
className={clsx("wave-textfield-inner-label", {
float: this.state.hasContent || this.state.focused || placeholder,
"offset-left": decoration?.startDecoration,
})}
@ -164,7 +164,7 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
</label>
</If>
<input
className={cn("wave-textfield-inner-input", "wave-input", {
className={clsx("wave-textfield-inner-input", "wave-input", {
"offset-left": decoration?.startDecoration,
})}
ref={this.inputRef}

View File

@ -4,7 +4,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import ReactDOM from "react-dom";
import "./tooltip.less";
@ -63,7 +63,7 @@ class Tooltip extends React.Component<TooltipProps, TooltipState> {
const style = this.calculatePosition();
return ReactDOM.createPortal(
<div className={cn("wave-tooltip", this.props.className)} style={style}>
<div className={clsx("wave-tooltip", this.props.className)} style={style}>
{this.props.icon && <div className="wave-tooltip-icon">{this.props.icon}</div>}
<div className="wave-tooltip-message">{this.props.message}</div>
</div>,

View File

@ -1,5 +1,5 @@
import React, { Component, ReactNode } from "react";
import cn from "classnames";
import { clsx } from "clsx";
interface ErrorBoundaryState {
hasError: boolean;
@ -43,7 +43,7 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
const { plugin } = this.props;
return (
<div className={cn("load-error-text", { "view-error": !plugin })}>
<div className={clsx("load-error-text", { "view-error": !plugin })}>
<div>{`${error?.message}`}</div>
{plugin && <div>An error occurred in the {plugin} plugin</div>}
</div>

View File

@ -1,5 +1,5 @@
import React from "react";
import cn from "classnames";
import { clsx } from "clsx";
import { ReactComponent as SpinnerIndicator } from "@/assets/icons/spinner-indicator.svg";
import * as appconst from "@/app/appconst";
@ -16,7 +16,7 @@ export const FrontIcon: React.FC<PositionalIconProps> = (props) => {
return (
<div
ref={props.divRef}
className={cn("front-icon", "positional-icon", props.className)}
className={clsx("front-icon", "positional-icon", props.className)}
onClick={props.onClick}
>
<div className="positional-icon-inner">{props.children}</div>
@ -28,7 +28,7 @@ export const CenteredIcon: React.FC<PositionalIconProps> = (props) => {
return (
<div
ref={props.divRef}
className={cn("centered-icon", "positional-icon", props.className)}
className={clsx("centered-icon", "positional-icon", props.className)}
onClick={props.onClick}
>
<div className="positional-icon-inner">{props.children}</div>
@ -169,7 +169,7 @@ export const StatusIndicator: React.FC<StatusIndicatorProps> = (props) => {
statusIndicator = (
<CenteredIcon
divRef={iconRef}
className={cn(className, indicatorLevelClass, spinnerVisibleClass, "status-indicator")}
className={clsx(className, indicatorLevelClass, spinnerVisibleClass, "status-indicator")}
>
<SpinnerIndicator className={spinnerVisible ? "spin" : null} />
</CenteredIcon>

View File

@ -9,7 +9,7 @@ import { GlobalModel } from "@/models";
import { Modal, LinkButton } from "@/elements";
import * as util from "@/util/util";
import * as appconst from "@/app/appconst";
import cn from "classnames";
import { clsx } from "clsx";
import { If } from "tsx-control-statements/components";
import logo from "@/assets/waveterm-logo-with-bg.svg";
@ -36,7 +36,7 @@ class AboutModal extends React.Component<{}, {}> {
const isUpToDate = !showUpdateStatus || GlobalModel.appUpdateStatus.get() !== "ready";
return (
<div className={cn("status", { outdated: !isUpToDate })}>
<div className={clsx("status", { outdated: !isUpToDate })}>
<If condition={!isUpToDate}>
<div>
<i className="fa-sharp fa-solid fa-triangle-exclamation" />

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import { For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
import { SettingsError, Modal, Dropdown, Tooltip } from "@/elements";
import * as util from "@/util/util";

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import { If, For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, GlobalCommandRunner } from "@/models";
import { Modal, TextField, InputDecoration, Tooltip } from "@/elements";
import * as util from "@/util/util";
@ -287,7 +287,7 @@ class TabSwitcherModal extends React.Component<{}, {}> {
<div
key={option.sessionId + "/" + option.screenId}
ref={this.optionRefs[index]}
className={cn("search-option unselectable", {
className={clsx("search-option unselectable", {
"focused-option": this.focusedIdx.get() === index,
})}
onClick={() => this.handleSelect(index)}

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import { If, For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "@/models";
import { Modal, Tooltip, Button, Status } from "@/elements";
import * as util from "@/util/util";
@ -370,7 +370,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
</div>
<div
key="term"
className={cn(
className={clsx(
"terminal-wrapper",
{ focus: isTermFocused },
remote != null ? "status-" + remote.status : null

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "@/models";
import cn from "classnames";
import { clsx } from "clsx";
import { isBlank } from "@/util/util";
import "./prompt.less";
@ -108,7 +108,7 @@ class Prompt extends React.Component<
let remoteElem = null;
if (remoteStr != "local") {
remoteElem = (
<span title={remoteTitle} className={cn("term-prompt-remote", remoteColorClass)}>
<span title={remoteTitle} className={clsx("term-prompt-remote", remoteColorClass)}>
[{remoteStr}]{" "}
</span>
);
@ -124,10 +124,10 @@ class Prompt extends React.Component<
render() {
const rptr = this.props.rptr;
if (rptr == null || isBlank(rptr.remoteid)) {
return <span className={cn("term-prompt", "color-green")}>&nbsp;</span>;
return <span className={clsx("term-prompt", "color-green")}>&nbsp;</span>;
}
let { remoteElem, isRoot } = this.getRemoteElem();
let termClassNames = cn(
let termClassNames = clsx(
"term-prompt",
{ "term-prompt-color": this.props.color },
{ "term-prompt-isroot": isRoot }

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import { If, For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, RemotesModel, GlobalCommandRunner } from "@/models";
import { Button, Status } from "@/common/elements";
import * as util from "@/util/util";
@ -185,7 +185,7 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
<For index="idx" each="item" of={items}>
<tr
key={item.remoteid}
className={cn("connections-item", {
className={clsx("connections-item", {
hovered: this.state.hoveredItemId === item.remoteid,
})}
onClick={() => this.handleRead(item.remoteid)} // Moved onClick here

View File

@ -7,7 +7,7 @@ import * as mobx from "mobx";
import { If, For } from "tsx-control-statements/components";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, GlobalCommandRunner } from "@/models";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
@ -137,7 +137,7 @@ class HistoryCmdStr extends React.Component<
render() {
const { cmdstr, fontSize, limitHeight } = this.props;
return (
<div className={cn("cmdstr-code", { "is-large": fontSize == "large" }, { "limit-height": limitHeight })}>
<div className={clsx("cmdstr-code", { "is-large": fontSize == "large" }, { "limit-height": limitHeight })}>
<div key="code" className="code-div">
<code>{cmdstr}</code>
</div>
@ -490,7 +490,7 @@ class HistoryView extends React.Component<{}, {}> {
</Button>
</div>
</div>
<div key="control1" className={cn("control-bar", "is-top", { "is-hidden": items.length == 0 })}>
<div key="control1" className={clsx("control-bar", "is-top", { "is-hidden": items.length == 0 })}>
<div className="control-checkbox" onClick={this.handleControlCheckbox} title="Toggle Selection">
<HistoryCheckbox
checked={numSelected > 0 && numSelected == items.length}
@ -498,7 +498,7 @@ class HistoryView extends React.Component<{}, {}> {
/>
</div>
<div
className={cn(
className={clsx(
"control-button delete-button",
{ "is-disabled": numSelected == 0 },
{ "is-active": hvm.deleteActive.get() }
@ -515,14 +515,14 @@ class HistoryView extends React.Component<{}, {}> {
Showing {offset + 1}-{offset + items.length}
</div>
<div
className={cn("showing-btn", { "is-disabled": offset == 0 })}
className={clsx("showing-btn", { "is-disabled": offset == 0 })}
onClick={offset != 0 ? this.handlePrev : null}
>
<ChevronLeftIcon className="icon" />
</div>
<div className="btn-spacer" />
<div
className={cn("showing-btn", { "is-disabled": !hasMore })}
className={clsx("showing-btn", { "is-disabled": !hasMore })}
onClick={hasMore ? this.handleNext : null}
>
<ChevronRightIcon className="icon" />
@ -538,7 +538,7 @@ class HistoryView extends React.Component<{}, {}> {
<For index="idx" each="item" of={items}>
<div
key={item.historyid}
className={cn("row history-item", {
className={clsx("row history-item", {
"is-selected": hvm.selectedItems.get(item.historyid),
})}
>
@ -608,21 +608,21 @@ class HistoryView extends React.Component<{}, {}> {
</div>
<div
key="control2"
className={cn("control-bar", "is-bottom", { "is-hidden": items.length == 0 || !hasMore })}
className={clsx("control-bar", "is-bottom", { "is-hidden": items.length == 0 || !hasMore })}
>
<div className="spacer" />
<div className="showing-text">
Showing {offset + 1}-{offset + items.length}
</div>
<div
className={cn("showing-btn", { "is-disabled": offset == 0 })}
className={clsx("showing-btn", { "is-disabled": offset == 0 })}
onClick={offset != 0 ? this.handlePrev : null}
>
<ChevronLeftIcon className="icon" />
</div>
<div className="btn-spacer" />
<div
className={cn("showing-btn", { "is-disabled": !hasMore })}
className={clsx("showing-btn", { "is-disabled": !hasMore })}
onClick={hasMore ? this.handleNext : null}
>
<ChevronRightIcon className="icon" />

View File

@ -11,7 +11,7 @@ import localizedFormat from "dayjs/plugin/localizedFormat";
import { Choose, If, Otherwise, When } from "tsx-control-statements/components";
import { GlobalModel, GlobalCommandRunner, Cmd } from "@/models";
import { termHeightFromRows } from "@/util/textmeasure";
import cn from "classnames";
import { clsx } from "clsx";
import { getTermPtyData } from "@/util/modelutil";
import { renderCmdText } from "@/common/elements";
@ -172,7 +172,7 @@ class LineActions extends React.Component<{ screen: LineContainerType; line: Lin
<div
key="bookmark"
title="Bookmark"
className={cn("line-icon", "line-bookmark")}
className={clsx("line-icon", "line-bookmark")}
onClick={this.clickBookmark}
>
<i className="fa-sharp fa-regular fa-bookmark fa-fw" />
@ -180,7 +180,7 @@ class LineActions extends React.Component<{ screen: LineContainerType; line: Lin
<div
key="minimize"
title={`${isMinimized ? "Show Output" : "Hide Output"}`}
className={cn("line-icon", isMinimized ? "active" : "")}
className={clsx("line-icon", isMinimized ? "active" : "")}
onClick={this.clickMinimize}
>
<Choose>
@ -220,7 +220,7 @@ class LineActions extends React.Component<{ screen: LineContainerType; line: Lin
<div
key="bookmark"
title="Bookmark"
className={cn("line-icon", "line-bookmark")}
className={clsx("line-icon", "line-bookmark")}
onClick={this.clickBookmark}
>
<i className="fa-sharp fa-regular fa-bookmark fa-fw" />
@ -254,7 +254,7 @@ class LineHeader extends React.Component<{ screen: LineContainerType; line: Line
<React.Fragment>
<div
key="meta2"
className={cn(
className={clsx(
"meta meta-line2 cmdtext-expanded no-highlight-scrollbar scrollbar-hide-until-hover",
{
"is-multiline": isMultiLine,
@ -304,7 +304,7 @@ class LineHeader extends React.Component<{ screen: LineContainerType; line: Line
const { line, cmd } = this.props;
const hidePrompt = getIsHidePrompt(line);
return (
<div key="header" className={cn("line-header", { "hide-prompt": hidePrompt })}>
<div key="header" className={clsx("line-header", { "hide-prompt": hidePrompt })}>
{this.renderMeta1(cmd)}
<If condition={!hidePrompt}>{this.renderCmdText(cmd)}</If>
</div>
@ -349,7 +349,7 @@ class SmallLineAvatar extends React.Component<{ line: LineType; cmd: Cmd; onRigh
return (
<>
<div className="linenum">{lineNumStr}</div>
<div title={iconTitle} className={cn("status-icon", "status-" + status)}>
<div title={iconTitle} className={clsx("status-icon", "status-" + status)}>
{icon}
</div>
</>
@ -567,7 +567,7 @@ class LineCmd extends React.Component<
const { screen, line, width } = this.props;
contentHeight = screen.getUsedRows(lineutil.getRendererContext(line), line, cmd, width);
}
const mainDivCn = cn("line", "line-cmd");
const mainDivCn = clsx("line", "line-cmd");
if (DebugHeightProblems && line.linenum >= MinLine && line.linenum <= MaxLine) {
heightLog[line.linenum] = heightLog[line.linenum] || {};
heightLog[line.linenum].contentHeight = contentHeight;
@ -582,7 +582,7 @@ class LineCmd extends React.Component<
>
<LineHeader screen={screen} line={line} cmd={cmd} />
<div
className={cn("line-content", { "zero-height": contentHeight == 0 })}
className={clsx("line-content", { "zero-height": contentHeight == 0 })}
style={{ height: contentHeight }}
/>
</div>
@ -801,7 +801,7 @@ class LineCmd extends React.Component<
.get();
const isRunning = cmd.isRunning();
const cmdError = cmdShouldMarkError(cmd);
const mainDivCn = cn(
const mainDivCn = clsx(
"line",
"line-cmd",
{ selected: isSelected },
@ -830,7 +830,7 @@ class LineCmd extends React.Component<
onContextMenu={this.handleContextMenu}
>
<If condition={isSelected || cmdError}>
<div key="mask" className={cn("line-mask", { "error-mask": cmdError })}></div>
<div key="mask" className={clsx("line-mask", { "error-mask": cmdError })}></div>
</If>
<LineActions screen={screen} line={line} cmd={cmd} />
<LineHeader screen={screen} line={line} cmd={cmd} />
@ -971,7 +971,7 @@ class LineText extends React.Component<
name: "computed-isSelected",
})
.get();
const mainClass = cn("line", "line-text", "focus-parent", { selected: isSelected });
const mainClass = clsx("line", "line-text", "focus-parent", { selected: isSelected });
return (
<div
className={mainClass}

View File

@ -7,7 +7,7 @@ import * as mobx from "mobx";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import { If, For, When, Otherwise, Choose } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { debounce, throttle } from "throttle-debounce";
@ -496,7 +496,7 @@ class LinesView extends React.Component<
// let lineElem = <Line key={line.lineid} line={line} screen={screen} width={width} visible={this.visibleMap.get(lineNumStr)} staticRender={this.staticRender.get()} onHeightChange={this.onHeightChange} overrideCollapsed={this.collapsedMap.get(lineNumStr)} topBorder={topBorder} renderMode={renderMode}/>;
lineElements.push(lineElem);
}
let linesClass = cn("lines", renderMode == "normal" ? "lines-expanded" : "lines-collapsed", "wide-scrollbar");
let linesClass = clsx("lines", renderMode == "normal" ? "lines-expanded" : "lines-collapsed", "wide-scrollbar");
return (
<div key="lines" className={linesClass} onScroll={this.scrollHandler} ref={this.linesRef}>
<div className="lines-spacer"></div>

View File

@ -5,7 +5,7 @@ import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import dayjs from "dayjs";
import { If } from "tsx-control-statements/components";
@ -38,7 +38,7 @@ class SideBarItem extends React.Component<{
render() {
return (
<div
className={cn("item", "unselectable", "hoverEffect", this.props.className)}
className={clsx("item", "unselectable", "hoverEffect", this.props.className)}
onClick={this.props.onClick}
>
<FrontIcon>{this.props.frontIcon}</FrontIcon>
@ -201,7 +201,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
return (
<SideBarItem
key={session.sessionId}
className={cn({ bold: isActive, highlight: showHighlight })}
className={clsx({ bold: isActive, highlight: showHighlight })}
frontIcon={<span className="index">{index + 1}</span>}
contents={session.name.get()}
endIcons={[
@ -269,7 +269,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
<SideBarItem
key="history"
frontIcon={<i className="fa-sharp fa-regular fa-clock-rotate-left icon" />}
className={cn({ highlight: historyActive })}
className={clsx({ highlight: historyActive })}
contents="History"
endIcons={[<HotKeyIcon key="hotkey" hotkey="H" />]}
onClick={this.handleHistoryClick}
@ -278,7 +278,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
<SideBarItem
key="connections"
frontIcon={<i className="fa-sharp fa-regular fa-globe icon " />}
className={cn({ highlight: connectionsActive })}
className={clsx({ highlight: connectionsActive })}
contents="Connections"
onClick={this.handleConnectionsClick}
/>
@ -325,7 +325,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
<SideBarItem
key="settings"
frontIcon={<SettingsIcon className="icon" />}
className={cn({ highlight: settingsActive })}
className={clsx({ highlight: settingsActive })}
contents="Settings"
onClick={this.handleSettingsClick}
/>

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import * as React from "react";
import cn from "classnames";
import { clsx } from "clsx";
import { Choose, If, Otherwise, When } from "tsx-control-statements/components";
import { observer } from "mobx-react";
@ -24,7 +24,7 @@ export const AuxiliaryCmdView: React.FC<AuxiliaryCmdViewProps> = observer((props
const { title, className, iconClass, titleBarContents, children, onClose, onScrollbarInitialized } = props;
return (
<div className={cn("auxview", className)}>
<div className={clsx("auxview", className)}>
<If condition={title || onClose || titleBarContents || iconClass}>
<div className="auxview-titlebar">
<If condition={iconClass != null}>

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import { Choose, If, When } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
@ -185,7 +185,7 @@ class CmdInput extends React.Component<{}, {}> {
}
return (
<div ref={this.cmdInputRef} className={cn("cmd-input", hasOpenView, { active: focusVal })}>
<div ref={this.cmdInputRef} className={clsx("cmd-input", hasOpenView, { active: focusVal })}>
<Choose>
<When condition={openView === appconst.InputAuxView_History}>
<div className="cmd-input-grow-spacer"></div>
@ -239,7 +239,7 @@ class CmdInput extends React.Component<{}, {}> {
<If condition={numRunningLines > 0}>
<div
key="running"
className={cn("cmdinput-icon", "running-cmds", { active: filterRunning })}
className={clsx("cmdinput-icon", "running-cmds", { active: filterRunning })}
title="Filter for Running Commands"
onClick={() => this.toggleFilter(screen)}
>
@ -277,7 +277,7 @@ class CmdInput extends React.Component<{}, {}> {
</If>
<div
key="input"
className={cn(
className={clsx(
"cmd-input-field field has-addons",
inputMode != null ? "inputmode-" + inputMode : null
)}

View File

@ -7,7 +7,7 @@ import * as mobx from "mobx";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import { If, For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "@/models";
@ -132,7 +132,7 @@ class HItem extends React.Component<
return (
<div
key={hitem.historynum}
className={cn(
className={clsx(
"history-item",
{ "is-selected": isSelected },
{ "history-haderror": hitem.haderror },
@ -256,7 +256,7 @@ class HistoryInfo extends React.Component<{}, {}> {
onScrollbarInitialized={this.handleScrollbarInitialized}
>
<div
className={cn(
className={clsx(
"history-items",
{ "show-remotes": !opts.limitRemote },
{ "show-sessions": opts.queryType == "global" }

View File

@ -5,7 +5,7 @@ import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { If, For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "@/models";
@ -86,7 +86,7 @@ class InfoMsg extends React.Component<{}, {}> {
<div
onClick={() => this.handleCompClick(istr)}
key={idx}
className={cn(
className={clsx(
"info-comp",
{ "has-space": this.hasSpace(istr) },
{ "metacmd-comp": istr.startsWith("^") }

View File

@ -7,7 +7,7 @@ import * as mobx from "mobx";
import * as util from "@/util/util";
import { If } from "tsx-control-statements/components";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
import { getMonoFontSize } from "@/util/textmeasure";
import * as appconst from "@/app/appconst";
@ -652,7 +652,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
onSelect={this.onSelect}
placeholder="Type here..."
maxLength={MaxInputLength}
className={cn("textarea", { "display-disabled": auxViewFocused })}
className={clsx("textarea", { "display-disabled": auxViewFocused })}
></textarea>
<input
key="history"

View File

@ -3,7 +3,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import { If, For } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalCommandRunner, GlobalModel, Screen } from "@/models";
import { TextField, Dropdown } from "@/elements";
import { getRemoteStrWithAlias } from "@/common/prompt/prompt";
@ -183,7 +183,7 @@ class TabRemoteSelector extends React.Component<{ screen: Screen; errorMessage?:
startDecoration: (
<div className="lefticon">
<GlobeIcon className="globe-icon" />
<StatusCircleIcon className={cn("status-icon", "status-" + curRemote.status)} />
<StatusCircleIcon className={clsx("status-icon", "status-" + curRemote.status)} />
</div>
),
}}

View File

@ -7,7 +7,7 @@ import * as mobx from "mobx";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import { If } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { debounce } from "throttle-debounce";
import dayjs from "dayjs";
import { GlobalCommandRunner, ForwardLineContainer, GlobalModel, ScreenLines, Screen, Session } from "@/models";
@ -116,7 +116,7 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
<div className="screen-view" ref={this.screenViewRef}>
<div className="window-view" style={{ width: "100%" }}>
<div key="lines" className="lines"></div>
<div key="window-empty" className={cn("window-empty")}>
<div key="window-empty" className={clsx("window-empty")}>
<div className="flex-centered-column">
<code className="text-standard">[no workspace]</code>
<If condition={sessionCount == 0}>
@ -136,7 +136,7 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
<div className="screen-view" ref={this.screenViewRef}>
<div className="window-view" style={{ width: "100%" }}>
<div key="lines" className="lines"></div>
<div key="window-empty" className={cn("window-empty")}>
<div key="window-empty" className={clsx("window-empty")}>
<div className="flex-centered-column">
<code className="text-standard">[no active tab]</code>
<If condition={screens.length == 0}>
@ -479,7 +479,7 @@ class ScreenWindowView extends React.Component<ScreenWindowViewProps, {}> {
return (
<div className="window-view" ref={this.windowViewRef} data-screenid={screen.screenId} style={{ width }}>
<div key="lines" className="lines"></div>
<div key="window-empty" className={cn("window-empty", { "should-fade": fade })}>
<div key="window-empty" className={clsx("window-empty", { "should-fade": fade })}>
<div className="text-standard">{message}</div>
</div>
</div>
@ -559,7 +559,7 @@ class ScreenWindowView extends React.Component<ScreenWindowViewProps, {}> {
<If condition={lines.length == 0 && screen.nextLineNum.get() != 1}>
<div className="window-empty" ref={this.windowViewRef} data-screenid={screen.screenId}>
<div key="lines" className="lines"></div>
<div key="window-empty" className={cn("window-empty")}>
<div key="window-empty" className={clsx("window-empty")}>
<div>
<code className="text-standard">
[workspace="{session.name.get()}" tab="{screen.name.get()}"]

View File

@ -5,7 +5,7 @@ import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
import { ActionsIcon, StatusIndicator, CenteredIcon } from "@/common/icons/icons";
import * as constants from "@/app/appconst";
@ -131,7 +131,7 @@ class ScreenTab extends React.Component<
value={screen}
id={"screentab-" + screen.screenId}
data-screenid={screen.screenId}
className={cn(
className={clsx(
"screen-tab",
{ "is-active": activeScreenId == screen.screenId, "is-archived": screen.archived.get() },
"color-" + screen.getTabColor()

View File

@ -7,7 +7,7 @@ import * as mobx from "mobx";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import { For, If } from "tsx-control-statements/components";
import cn from "classnames";
import { clsx } from "clsx";
import { GlobalModel, GlobalCommandRunner, Session, Screen } from "@/models";
import { ReactComponent as AddIcon } from "@/assets/icons/add.svg";
import { Reorder } from "framer-motion";

View File

@ -4,7 +4,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import cn from "classnames";
import { clsx } from "clsx";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { If } from "tsx-control-statements/components";
@ -234,7 +234,7 @@ class WorkspaceView extends React.Component<{}, {}> {
return (
<div
ref={this.sessionRef}
className={cn("mainview", "session-view", { "is-hidden": isHidden })}
className={clsx("mainview", "session-view", { "is-hidden": isHidden })}
id={sessionId}
data-sessionid={sessionId}
style={{
@ -246,7 +246,7 @@ class WorkspaceView extends React.Component<{}, {}> {
</If>
<ScreenTabs key={"tabs-" + sessionId} session={session} />
<If condition={activeScreen != null}>
<div key="pulldown" className={cn("tab-settings-pulldown", { closed: !showTabSettings })}>
<div key="pulldown" className={clsx("tab-settings-pulldown", { closed: !showTabSettings })}>
<Button className="close-button secondary ghost" onClick={this.toggleTabSettings}>
<i className="fa-solid fa-sharp fa-xmark-large" />
</Button>

View File

@ -6,7 +6,7 @@ import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import Editor, { Monaco } from "@monaco-editor/react";
import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
import cn from "classnames";
import { clsx } from "clsx";
import { If } from "tsx-control-statements/components";
import { Markdown, Button } from "@/elements";
import { GlobalModel, GlobalCommandRunner } from "@/models";
@ -579,7 +579,7 @@ class SourceCodeRenderer extends React.Component<
<div className="flex-spacer" />
<div className="code-statusbar">
<If condition={message != null}>
<div className={cn("code-message", { error: message.status == "error" })}>
<div className={clsx("code-message", { error: message.status == "error" })}>
{this.state.message.text}
</div>
</If>

View File

@ -7,7 +7,7 @@ import * as mobx from "mobx";
import { debounce } from "throttle-debounce";
import * as util from "@/util/util";
import { GlobalModel } from "@/models";
import cn from "classnames";
import { clsx } from "clsx";
class SimpleBlobRendererModel {
context: RendererContext;
@ -247,7 +247,7 @@ class SimpleBlobRenderer extends React.Component<
return (
<div
ref={this.wrapperDivRef}
className={cn("renderer-loading", { "zero-height": height == 0 })}
className={clsx("renderer-loading", { "zero-height": height == 0 })}
style={{ minHeight: height, fontSize: model.opts.termFontSize }}
>
loading content <i className="fa fa-ellipsis fa-fade" />
@ -260,7 +260,7 @@ class SimpleBlobRenderer extends React.Component<
}
let { festate, cmdstr, exitcode } = this.props.initParams.rawCmd;
return (
<div ref={this.wrapperDivRef} className={cn("sr-wrapper", { "zero-height": model.savedHeight == 0 })}>
<div ref={this.wrapperDivRef} className={clsx("sr-wrapper", { "zero-height": model.savedHeight == 0 })}>
<Comp
cwd={festate.cwd}
cmdstr={cmdstr}

View File

@ -15,7 +15,7 @@ import {
import { useTableNav } from "@table-nav/react";
import SortUpIcon from "./img/sort-up-solid.svg";
import SortDownIcon from "./img/sort-down-solid.svg";
import cn from "classnames";
import { clsx } from "clsx";
import "./csv.less";
@ -190,7 +190,7 @@ const CSVRenderer: FC<Props> = (props: Props) => {
return (
<div
className={cn("csv-renderer", { show: tableLoaded })}
className={clsx("csv-renderer", { show: tableLoaded })}
style={{ height: tableLoaded ? "auto" : savedHeight }}
>
<table className="probe">

View File

@ -10,7 +10,7 @@ import localizedFormat from "dayjs/plugin/localizedFormat";
import { If } from "tsx-control-statements/components";
import { GlobalModel } from "@/models";
import { termHeightFromRows } from "@/util/textmeasure";
import cn from "classnames";
import { clsx } from "clsx";
import * as lineutil from "@/app/line/lineutil";
import "./terminal.less";
@ -207,7 +207,7 @@ class TerminalRenderer extends React.Component<{
<div
ref={this.elemRef}
key="term-wrap"
className={cn(
className={clsx(
"terminal-wrapper",
{ focus: isFocused },
{ "cmd-done": !cmd.isRunning() },

View File

@ -2529,13 +2529,6 @@
"@types/node" "*"
"@types/responselike" "^1.0.0"
"@types/classnames@^2.3.1":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.3.1.tgz#3c2467aa0f1a93f1f021e3b9bcf938bd5dfdc0dd"
integrity sha512-zeOWb0JGBoVmlQoznvqXbE0tEC/HONsnoUNH19Hc96NFsTAwTXbTqb8FMYkru1F/iqp7a18Ws3nWJvtA1sHD1A==
dependencies:
classnames "*"
"@types/connect-history-api-fallback@^1.5.4":
version "1.5.4"
resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3"
@ -3691,16 +3684,6 @@ ci-info@^3.2.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4"
integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==
classnames@*:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
classnames@^2.3.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
@ -3756,6 +3739,11 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
color-convert@^1.9.0, color-convert@^1.9.3:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"