diff --git a/frontend/app/block/block.less b/frontend/app/block/block.less
index b214012f..7151084a 100644
--- a/frontend/app/block/block.less
+++ b/frontend/app/block/block.less
@@ -133,21 +133,6 @@
}
}
- .iconbutton {
- cursor: pointer;
- opacity: 0.7;
- align-items: center;
-
- &:hover {
- opacity: 1;
- }
-
- &.disabled {
- cursor: default;
- opacity: 0.45 !important;
- }
- }
-
.connection-button {
display: flex;
align-items: center;
diff --git a/frontend/app/block/blockframe.tsx b/frontend/app/block/blockframe.tsx
index f5f0bcc8..40ba0c94 100644
--- a/frontend/app/block/blockframe.tsx
+++ b/frontend/app/block/blockframe.tsx
@@ -8,7 +8,6 @@ import {
ConnectionButton,
ControllerStatusIcon,
getBlockHeaderIcon,
- IconButton,
Input,
} from "@/app/block/blockutil";
import { Button } from "@/app/element/button";
@@ -29,6 +28,7 @@ import {
} from "@/app/store/global";
import * as services from "@/app/store/services";
import { WshServer } from "@/app/store/wshserver";
+import { IconButton } from "@/element/iconbutton";
import { MagnifyIcon } from "@/element/magnify";
import { NodeModel } from "@/layout/index";
import * as keyutil from "@/util/keyutil";
@@ -88,7 +88,7 @@ function handleHeaderContextMenu(
ContextMenuModel.showContextMenu(menu, e);
}
-function getViewIconElem(viewIconUnion: string | HeaderIconButton, blockData: Block): JSX.Element {
+function getViewIconElem(viewIconUnion: string | IconButtonDecl, blockData: Block): JSX.Element {
if (viewIconUnion == null || typeof viewIconUnion === "string") {
const viewIcon = viewIconUnion as string;
return
{getBlockHeaderIcon(viewIcon, blockData)}
;
@@ -99,7 +99,7 @@ function getViewIconElem(viewIconUnion: string | HeaderIconButton, blockData: Bl
const OptMagnifyButton = React.memo(
({ magnified, toggleMagnify, disabled }: { magnified: boolean; toggleMagnify: () => void; disabled: boolean }) => {
- const magnifyDecl: HeaderIconButton = {
+ const magnifyDecl: IconButtonDecl = {
elemtype: "iconbutton",
icon: ,
title: magnified ? "Minimize" : "Magnify",
@@ -124,7 +124,7 @@ function computeEndIcons(
if (endIconButtons && endIconButtons.length > 0) {
endIconsElem.push(...endIconButtons.map((button, idx) => ));
}
- const settingsDecl: HeaderIconButton = {
+ const settingsDecl: IconButtonDecl = {
elemtype: "iconbutton",
icon: "cog",
title: "Settings",
@@ -139,7 +139,7 @@ function computeEndIcons(
disabled={magnifyDisabled}
/>
);
- const closeDecl: HeaderIconButton = {
+ const closeDecl: IconButtonDecl = {
elemtype: "iconbutton",
icon: "xmark-large",
title: "Close",
diff --git a/frontend/app/block/blockutil.tsx b/frontend/app/block/blockutil.tsx
index 17ae041d..06ce5664 100644
--- a/frontend/app/block/blockutil.tsx
+++ b/frontend/app/block/blockutil.tsx
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
import { NumActiveConnColors } from "@/app/block/blockframe";
-import { useLongClick } from "@/app/hook/useLongClick";
import { getConnStatusAtom, waveEventSubscribe, WOS } from "@/app/store/global";
import * as services from "@/app/store/services";
import { makeORef } from "@/app/store/wos";
@@ -139,20 +138,6 @@ export function getBlockHeaderIcon(blockIcon: string, blockData: Block): React.R
return blockIconElem;
}
-export const IconButton = React.memo(({ decl, className }: { decl: HeaderIconButton; className?: string }) => {
- const buttonRef = React.useRef(null);
- useLongClick(buttonRef, decl.click, decl.longClick, decl.disabled);
- return (
-
- {typeof decl.icon === "string" ? : decl.icon}
-
- );
-});
-
interface ConnectionButtonProps {
connection: string;
changeConnModalAtom: jotai.PrimitiveAtom;
diff --git a/frontend/app/element/copybutton.less b/frontend/app/element/copybutton.less
index db485579..1689a0f9 100644
--- a/frontend/app/element/copybutton.less
+++ b/frontend/app/element/copybutton.less
@@ -2,15 +2,10 @@
// SPDX-License-Identifier: Apache-2.0
.copy-button {
- padding: 5px 5px !important;
- opacity: 0.5;
-
- &:hover {
- opacity: 1;
- }
-
&.copied {
opacity: 1;
- color: var(--success-color);
+ i {
+ color: var(--success-color);
+ }
}
}
diff --git a/frontend/app/element/copybutton.tsx b/frontend/app/element/copybutton.tsx
index 0fbe3090..a5e26bc5 100644
--- a/frontend/app/element/copybutton.tsx
+++ b/frontend/app/element/copybutton.tsx
@@ -3,8 +3,8 @@
import { clsx } from "clsx";
import { useEffect, useRef, useState } from "react";
-import { Button } from "./button";
import "./copybutton.less";
+import { IconButton } from "./iconbutton";
type CopyButtonProps = {
title: string;
@@ -43,13 +43,16 @@ const CopyButton = ({ title, className, onClick }: CopyButtonProps) => {
}, []);
return (
-
+
);
};
diff --git a/frontend/app/element/iconbutton.less b/frontend/app/element/iconbutton.less
new file mode 100644
index 00000000..bf1a3f6a
--- /dev/null
+++ b/frontend/app/element/iconbutton.less
@@ -0,0 +1,14 @@
+.iconbutton {
+ cursor: pointer;
+ opacity: 0.7;
+ align-items: center;
+
+ &:hover {
+ opacity: 1;
+ }
+
+ &.disabled {
+ cursor: default;
+ opacity: 0.45 !important;
+ }
+}
diff --git a/frontend/app/element/iconbutton.tsx b/frontend/app/element/iconbutton.tsx
new file mode 100644
index 00000000..88a13013
--- /dev/null
+++ b/frontend/app/element/iconbutton.tsx
@@ -0,0 +1,19 @@
+import { useLongClick } from "@/app/hook/useLongClick";
+import { makeIconClass } from "@/util/util";
+import clsx from "clsx";
+import { memo, useRef } from "react";
+import "./iconbutton.less";
+
+export const IconButton = memo(({ decl, className }: { decl: IconButtonDecl; className?: string }) => {
+ const buttonRef = useRef(null);
+ useLongClick(buttonRef, decl.click, decl.longClick, decl.disabled);
+ return (
+
+ {typeof decl.icon === "string" ? : decl.icon}
+
+ );
+});
diff --git a/frontend/app/element/markdown.less b/frontend/app/element/markdown.less
index 0b448bc7..5d2e55c0 100644
--- a/frontend/app/element/markdown.less
+++ b/frontend/app/element/markdown.less
@@ -85,29 +85,12 @@
top: 0;
right: 0;
border-radius: 4px;
+ backdrop-filter: blur(8px);
+ margin: 2px 2px;
+ padding: 4px 4px;
align-items: center;
justify-content: flex-end;
-
- i {
- color: var(--line-actions-inactive-color);
- margin-left: 4px;
-
- &:first-child {
- margin-left: 0px;
- }
-
- &:hover {
- color: var(--line-actions-active-color);
- }
-
- &.fa-check {
- color: var(--success-color);
- }
-
- &.fa-square-terminal {
- cursor: pointer;
- }
- }
+ gap: 4px;
}
&:hover .codeblock-actions {
diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx
index 288ffb9c..86f2f836 100644
--- a/frontend/app/element/markdown.tsx
+++ b/frontend/app/element/markdown.tsx
@@ -17,6 +17,7 @@ import rehypeSlug from "rehype-slug";
import RemarkFlexibleToc, { TocItem } from "remark-flexible-toc";
import remarkGfm from "remark-gfm";
import { openLink } from "../store/global";
+import { IconButton } from "./iconbutton";
import "./markdown.less";
const Link = ({
@@ -90,7 +91,16 @@ const CodeBlock = ({ children, onClickExecute }: CodeBlockProps) => {
{children}
- {onClickExecute && }
+ {onClickExecute && (
+
+ )}
);
diff --git a/frontend/app/view/helpview/helpview.tsx b/frontend/app/view/helpview/helpview.tsx
index 42859c5c..3f72ff85 100644
--- a/frontend/app/view/helpview/helpview.tsx
+++ b/frontend/app/view/helpview/helpview.tsx
@@ -183,7 +183,7 @@ Other useful metadata values to override block titles, icons, colors, themes, et
class HelpViewModel implements ViewModel {
viewType: string;
showTocAtom: PrimitiveAtom;
- endIconButtons: Atom;
+ endIconButtons: Atom;
constructor() {
this.viewType = "help";
@@ -195,7 +195,7 @@ class HelpViewModel implements ViewModel {
title: "Table of Contents",
click: () => this.showTocToggle(),
},
- ] as HeaderIconButton[]);
+ ] as IconButtonDecl[]);
}
showTocToggle() {
diff --git a/frontend/app/view/preview/preview.tsx b/frontend/app/view/preview/preview.tsx
index 149288de..a106f0c1 100644
--- a/frontend/app/view/preview/preview.tsx
+++ b/frontend/app/view/preview/preview.tsx
@@ -80,11 +80,11 @@ export class PreviewModel implements ViewModel {
blockId: string;
nodeModel: NodeModel;
blockAtom: jotai.Atom;
- viewIcon: jotai.Atom;
+ viewIcon: jotai.Atom;
viewName: jotai.Atom;
viewText: jotai.Atom;
- preIconButton: jotai.Atom;
- endIconButtons: jotai.Atom;
+ preIconButton: jotai.Atom;
+ endIconButtons: jotai.Atom;
previewTextRef: React.RefObject;
editMode: jotai.Atom;
canPreview: jotai.PrimitiveAtom;
@@ -294,7 +294,7 @@ export class PreviewModel implements ViewModel {
icon: "arrows-rotate",
click: () => this.refreshCallback?.(),
},
- ] as HeaderIconButton[];
+ ] as IconButtonDecl[];
} else if (!isCeView && mimeType.startsWith("text/markdown")) {
return [
{
@@ -303,7 +303,7 @@ export class PreviewModel implements ViewModel {
title: "Table of Contents",
click: () => this.markdownShowTocToggle(),
},
- ] as HeaderIconButton[];
+ ] as IconButtonDecl[];
}
return null;
});
diff --git a/frontend/app/view/waveai/waveai.tsx b/frontend/app/view/waveai/waveai.tsx
index caad06a5..348f540b 100644
--- a/frontend/app/view/waveai/waveai.tsx
+++ b/frontend/app/view/waveai/waveai.tsx
@@ -44,11 +44,11 @@ export class WaveAiModel implements ViewModel {
viewType: string;
blockId: string;
blockAtom: Atom;
- viewIcon?: Atom;
+ viewIcon?: Atom;
viewName?: Atom;
viewText?: Atom;
- preIconButton?: Atom;
- endIconButtons?: Atom;
+ preIconButton?: Atom;
+ endIconButtons?: Atom;
messagesAtom: PrimitiveAtom>;
addMessageAtom: WritableAtom;
updateLastMessageAtom: WritableAtom;
diff --git a/frontend/app/view/webview/webview.tsx b/frontend/app/view/webview/webview.tsx
index ff61dda5..4a7a85b3 100644
--- a/frontend/app/view/webview/webview.tsx
+++ b/frontend/app/view/webview/webview.tsx
@@ -18,7 +18,7 @@ export class WebViewModel implements ViewModel {
viewType: string;
blockId: string;
blockAtom: jotai.Atom;
- viewIcon: jotai.Atom;
+ viewIcon: jotai.Atom;
viewName: jotai.Atom;
viewText: jotai.Atom;
url: jotai.PrimitiveAtom;
diff --git a/frontend/types/custom.d.ts b/frontend/types/custom.d.ts
index 5281d3b8..9f7916d7 100644
--- a/frontend/types/custom.d.ts
+++ b/frontend/types/custom.d.ts
@@ -148,9 +148,9 @@ declare global {
type SubjectWithRef = rxjs.Subject & { refCount: number; release: () => void };
- type HeaderElem = HeaderIconButton | HeaderText | HeaderInput | HeaderDiv | HeaderTextButton | ConnectionButton;
+ type HeaderElem = IconButtonDecl | HeaderText | HeaderInput | HeaderDiv | HeaderTextButton | ConnectionButton;
- type HeaderIconButton = {
+ type IconButtonDecl = {
elemtype: "iconbutton";
icon: string | React.ReactNode;
className?: string;
@@ -207,11 +207,11 @@ declare global {
interface ViewModel {
viewType: string;
- viewIcon?: jotai.Atom;
+ viewIcon?: jotai.Atom;
viewName?: jotai.Atom;
viewText?: jotai.Atom;
- preIconButton?: jotai.Atom;
- endIconButtons?: jotai.Atom;
+ preIconButton?: jotai.Atom;
+ endIconButtons?: jotai.Atom;
blockBg?: jotai.Atom;
manageConnection?: jotai.Atom;