From e79af2274ed00eb1c26a1f515e74b6a4ce603b13 Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 11:45:16 -0700 Subject: [PATCH 1/8] split workspace into workspace/widgets files --- frontend/app/workspace/widgets.tsx | 137 ++++++++++++++++++++++++++ frontend/app/workspace/workspace.tsx | 141 +-------------------------- 2 files changed, 139 insertions(+), 139 deletions(-) create mode 100644 frontend/app/workspace/widgets.tsx diff --git a/frontend/app/workspace/widgets.tsx b/frontend/app/workspace/widgets.tsx new file mode 100644 index 0000000000..09e5856e05 --- /dev/null +++ b/frontend/app/workspace/widgets.tsx @@ -0,0 +1,137 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +import { NotificationPopover } from "@/app/notification/notificationpopover"; +import { ContextMenuModel } from "@/app/store/contextmenu"; +import { RpcApi } from "@/app/store/wshclientapi"; +import { TabRpcClient } from "@/app/store/wshrpcutil"; +import { atoms, createBlock, getApi, isDev } from "@/store/global"; +import { fireAndForget, isBlank, makeIconClass } from "@/util/util"; +import clsx from "clsx"; +import { useAtomValue } from "jotai"; +import { memo } from "react"; + +function sortByDisplayOrder(wmap: { [key: string]: WidgetConfigType }): WidgetConfigType[] { + if (wmap == null) { + return []; + } + const wlist = Object.values(wmap); + wlist.sort((a, b) => { + return (a["display:order"] ?? 0) - (b["display:order"] ?? 0); + }); + return wlist; +} + +async function handleWidgetSelect(widget: WidgetConfigType) { + const blockDef = widget.blockdef; + createBlock(blockDef, widget.magnified); +} + +const Widget = memo(({ widget }: { widget: WidgetConfigType }) => { + return ( +
handleWidgetSelect(widget)} + title={widget.description || widget.label} + > +
+ +
+ {!isBlank(widget.label) ? ( +
+ {widget.label} +
+ ) : null} +
+ ); +}); + +const Widgets = memo(() => { + const fullConfig = useAtomValue(atoms.fullConfigAtom); + const helpWidget: WidgetConfigType = { + icon: "circle-question", + label: "help", + blockdef: { + meta: { + view: "help", + }, + }, + }; + const tipsWidget: WidgetConfigType = { + icon: "lightbulb", + label: "tips", + blockdef: { + meta: { + view: "tips", + }, + }, + }; + const showHelp = fullConfig?.settings?.["widget:showhelp"] ?? true; + const widgets = sortByDisplayOrder(fullConfig?.widgets); + + const handleWidgetsBarContextMenu = (e: React.MouseEvent) => { + e.preventDefault(); + const menu: ContextMenuItem[] = [ + { + label: "Edit widgets.json", + click: () => { + fireAndForget(async () => { + const path = `${getApi().getConfigDir()}/widgets.json`; + const blockDef: BlockDef = { + meta: { view: "preview", file: path }, + }; + await createBlock(blockDef, false, true); + }); + }, + }, + { + label: "Show Help Widgets", + submenu: [ + { + label: "On", + type: "checkbox", + checked: showHelp, + click: () => { + fireAndForget(async () => { + await RpcApi.SetConfigCommand(TabRpcClient, { "widget:showhelp": true }); + }); + }, + }, + { + label: "Off", + type: "checkbox", + checked: !showHelp, + click: () => { + fireAndForget(async () => { + await RpcApi.SetConfigCommand(TabRpcClient, { "widget:showhelp": false }); + }); + }, + }, + ], + }, + ]; + ContextMenuModel.showContextMenu(menu, e); + }; + + return ( +
+ {widgets?.map((data, idx) => )} +
+ {showHelp ? ( + <> + + + + ) : null} + {isDev() ? : null} +
+ ); +}); + +export { Widgets }; diff --git a/frontend/app/workspace/workspace.tsx b/frontend/app/workspace/workspace.tsx index 6a03e3b95f..c4abd13ea0 100644 --- a/frontend/app/workspace/workspace.tsx +++ b/frontend/app/workspace/workspace.tsx @@ -4,150 +4,13 @@ import { ErrorBoundary } from "@/app/element/errorboundary"; import { CenteredDiv } from "@/app/element/quickelems"; import { ModalsRenderer } from "@/app/modals/modalsrenderer"; -import { NotificationPopover } from "@/app/notification/notificationpopover"; -import { ContextMenuModel } from "@/app/store/contextmenu"; -import { RpcApi } from "@/app/store/wshclientapi"; -import { TabRpcClient } from "@/app/store/wshrpcutil"; import { TabBar } from "@/app/tab/tabbar"; import { TabContent } from "@/app/tab/tabcontent"; -import { atoms, createBlock, getApi, isDev } from "@/store/global"; -import { fireAndForget, isBlank, makeIconClass } from "@/util/util"; -import clsx from "clsx"; +import { Widgets } from "@/app/workspace/widgets"; +import { atoms } from "@/store/global"; import { useAtomValue } from "jotai"; import { memo } from "react"; -const iconRegex = /^[a-z0-9-]+$/; - -function keyLen(obj: Object): number { - if (obj == null) { - return 0; - } - return Object.keys(obj).length; -} - -function sortByDisplayOrder(wmap: { [key: string]: WidgetConfigType }): WidgetConfigType[] { - if (wmap == null) { - return []; - } - const wlist = Object.values(wmap); - wlist.sort((a, b) => { - return (a["display:order"] ?? 0) - (b["display:order"] ?? 0); - }); - return wlist; -} - -const Widgets = memo(() => { - const fullConfig = useAtomValue(atoms.fullConfigAtom); - const helpWidget: WidgetConfigType = { - icon: "circle-question", - label: "help", - blockdef: { - meta: { - view: "help", - }, - }, - }; - const tipsWidget: WidgetConfigType = { - icon: "lightbulb", - label: "tips", - blockdef: { - meta: { - view: "tips", - }, - }, - }; - const showHelp = fullConfig?.settings?.["widget:showhelp"] ?? true; - const widgets = sortByDisplayOrder(fullConfig?.widgets); - - const handleWidgetsBarContextMenu = (e: React.MouseEvent) => { - e.preventDefault(); - const menu: ContextMenuItem[] = [ - { - label: "Edit widgets.json", - click: () => { - fireAndForget(async () => { - const path = `${getApi().getConfigDir()}/widgets.json`; - const blockDef: BlockDef = { - meta: { view: "preview", file: path }, - }; - await createBlock(blockDef, false, true); - }); - }, - }, - { - label: "Show Help Widgets", - submenu: [ - { - label: "On", - type: "checkbox", - checked: showHelp, - click: () => { - fireAndForget(async () => { - await RpcApi.SetConfigCommand(TabRpcClient, { "widget:showhelp": true }); - }); - }, - }, - { - label: "Off", - type: "checkbox", - checked: !showHelp, - click: () => { - fireAndForget(async () => { - await RpcApi.SetConfigCommand(TabRpcClient, { "widget:showhelp": false }); - }); - }, - }, - ], - }, - ]; - ContextMenuModel.showContextMenu(menu, e); - }; - - return ( -
- {widgets?.map((data, idx) => )} -
- {showHelp ? ( - <> - - - - ) : null} - {isDev() ? : null} -
- ); -}); - -async function handleWidgetSelect(widget: WidgetConfigType) { - const blockDef = widget.blockdef; - createBlock(blockDef, widget.magnified); -} - -const Widget = memo(({ widget }: { widget: WidgetConfigType }) => { - return ( -
handleWidgetSelect(widget)} - title={widget.description || widget.label} - > -
- -
- {!isBlank(widget.label) ? ( -
- {widget.label} -
- ) : null} -
- ); -}); - const WorkspaceElem = memo(() => { const tabId = useAtomValue(atoms.staticTabId); const ws = useAtomValue(atoms.workspace); From b20be4f2579778131ed01682fb400d10c1968c2e Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 11:51:16 -0700 Subject: [PATCH 2/8] update widget tooltip to use our new component --- frontend/app/element/tooltip.tsx | 2 +- frontend/app/workspace/widgets.tsx | 34 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/frontend/app/element/tooltip.tsx b/frontend/app/element/tooltip.tsx index c15b85060e..73ea4eda4c 100644 --- a/frontend/app/element/tooltip.tsx +++ b/frontend/app/element/tooltip.tsx @@ -132,7 +132,7 @@ export function Tooltip({ }} {...getFloatingProps()} className={cn( - "bg-white dark:bg-panel border border-border rounded-md px-2 py-1 text-xs text-foreground shadow-xl z-50" + "bg-gray-800 border border-border rounded-md px-2 py-1 text-xs text-foreground shadow-xl z-50" )} > {content} diff --git a/frontend/app/workspace/widgets.tsx b/frontend/app/workspace/widgets.tsx index 09e5856e05..2b584753d0 100644 --- a/frontend/app/workspace/widgets.tsx +++ b/frontend/app/workspace/widgets.tsx @@ -5,6 +5,7 @@ import { NotificationPopover } from "@/app/notification/notificationpopover"; import { ContextMenuModel } from "@/app/store/contextmenu"; import { RpcApi } from "@/app/store/wshclientapi"; import { TabRpcClient } from "@/app/store/wshrpcutil"; +import { Tooltip } from "@/app/element/tooltip"; import { atoms, createBlock, getApi, isDev } from "@/store/global"; import { fireAndForget, isBlank, makeIconClass } from "@/util/util"; import clsx from "clsx"; @@ -29,23 +30,24 @@ async function handleWidgetSelect(widget: WidgetConfigType) { const Widget = memo(({ widget }: { widget: WidgetConfigType }) => { return ( -
handleWidgetSelect(widget)} - title={widget.description || widget.label} - > -
- -
- {!isBlank(widget.label) ? ( -
- {widget.label} + +
handleWidgetSelect(widget)} + > +
+
- ) : null} -
+ {!isBlank(widget.label) ? ( +
+ {widget.label} +
+ ) : null} +
+ ); }); From 3b2ceee8aa06272b559d0c3f987c1dbd6c113f08 Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 11:54:13 -0700 Subject: [PATCH 3/8] fix shrinking behavior for widget bar --- frontend/app/workspace/widgets.tsx | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/frontend/app/workspace/widgets.tsx b/frontend/app/workspace/widgets.tsx index 2b584753d0..e218066387 100644 --- a/frontend/app/workspace/widgets.tsx +++ b/frontend/app/workspace/widgets.tsx @@ -30,23 +30,23 @@ async function handleWidgetSelect(widget: WidgetConfigType) { const Widget = memo(({ widget }: { widget: WidgetConfigType }) => { return ( - -
handleWidgetSelect(widget)} - > -
- -
- {!isBlank(widget.label) ? ( -
- {widget.label} -
- ) : null} + handleWidgetSelect(widget)} + > +
+
+ {!isBlank(widget.label) ? ( +
+ {widget.label} +
+ ) : null}
); }); From 3d4409ce815075e27ccd6ddb9518cd01daba8d4f Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 12:16:50 -0700 Subject: [PATCH 4/8] tooltip disable prop --- frontend/app/element/tooltip.tsx | 50 ++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/frontend/app/element/tooltip.tsx b/frontend/app/element/tooltip.tsx index 73ea4eda4c..d49606c42a 100644 --- a/frontend/app/element/tooltip.tsx +++ b/frontend/app/element/tooltip.tsx @@ -1,6 +1,7 @@ // Copyright 2025, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 +import { cn } from "@/util/util"; import { FloatingPortal, autoUpdate, @@ -11,7 +12,6 @@ import { useHover, useInteractions, } from "@floating-ui/react"; -import { cn } from "@/util/util"; import { useEffect, useRef, useState } from "react"; interface TooltipProps { @@ -19,12 +19,13 @@ interface TooltipProps { content: React.ReactNode; placement?: "top" | "bottom" | "left" | "right"; forceOpen?: boolean; + disable?: boolean; divClassName?: string; divStyle?: React.CSSProperties; divOnClick?: (e: React.MouseEvent) => void; } -export function Tooltip({ +function TooltipInner({ children, content, placement = "top", @@ -32,7 +33,7 @@ export function Tooltip({ divClassName, divStyle, divOnClick, -}: TooltipProps) { +}: Omit) { const [isOpen, setIsOpen] = useState(forceOpen); const [isVisible, setIsVisible] = useState(false); const timeoutRef = useRef(null); @@ -63,11 +64,7 @@ export function Tooltip({ } }, placement, - middleware: [ - offset(10), - flip(), - shift({ padding: 12 }), - ], + middleware: [offset(10), flip(), shift({ padding: 12 })], whileElementsMounted: autoUpdate, }); @@ -141,4 +138,39 @@ export function Tooltip({ )} ); -} \ No newline at end of file +} + +export function Tooltip({ + children, + content, + placement = "top", + forceOpen = false, + disable = false, + divClassName, + divStyle, + divOnClick, +}: TooltipProps) { + if (disable) { + return ( +
+ {children} +
+ ); + } + + return ( + + ); +} From 196e5c72053b722074628590dc9df68c9227a8d0 Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 12:41:55 -0700 Subject: [PATCH 5/8] compact mode, remove labels, ellipsis truncation, auto-tooltip --- frontend/app/workspace/widgets.tsx | 110 ++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 19 deletions(-) diff --git a/frontend/app/workspace/widgets.tsx b/frontend/app/workspace/widgets.tsx index e218066387..b176ca0dc8 100644 --- a/frontend/app/workspace/widgets.tsx +++ b/frontend/app/workspace/widgets.tsx @@ -1,16 +1,16 @@ // Copyright 2025, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 +import { Tooltip } from "@/app/element/tooltip"; import { NotificationPopover } from "@/app/notification/notificationpopover"; import { ContextMenuModel } from "@/app/store/contextmenu"; import { RpcApi } from "@/app/store/wshclientapi"; import { TabRpcClient } from "@/app/store/wshrpcutil"; -import { Tooltip } from "@/app/element/tooltip"; import { atoms, createBlock, getApi, isDev } from "@/store/global"; import { fireAndForget, isBlank, makeIconClass } from "@/util/util"; import clsx from "clsx"; import { useAtomValue } from "jotai"; -import { memo } from "react"; +import { memo, useCallback, useEffect, useRef, useState } from "react"; function sortByDisplayOrder(wmap: { [key: string]: WidgetConfigType }): WidgetConfigType[] { if (wmap == null) { @@ -28,11 +28,24 @@ async function handleWidgetSelect(widget: WidgetConfigType) { createBlock(blockDef, widget.magnified); } -const Widget = memo(({ widget }: { widget: WidgetConfigType }) => { +const Widget = memo(({ widget, compact = false }: { widget: WidgetConfigType; compact?: boolean }) => { + const [isTruncated, setIsTruncated] = useState(false); + const labelRef = useRef(null); + + useEffect(() => { + if (!compact && labelRef.current) { + const element = labelRef.current; + setIsTruncated(element.scrollWidth > element.clientWidth); + } + }, [compact, widget.label]); + + const shouldDisableTooltip = compact ? false : !isTruncated; + return ( {
- {!isBlank(widget.label) ? ( -
+ {!compact && !isBlank(widget.label) ? ( +
{widget.label}
) : null} @@ -53,6 +69,10 @@ const Widget = memo(({ widget }: { widget: WidgetConfigType }) => { const Widgets = memo(() => { const fullConfig = useAtomValue(atoms.fullConfigAtom); + const [isCompact, setIsCompact] = useState(false); + const containerRef = useRef(null); + const measurementRef = useRef(null); + const helpWidget: WidgetConfigType = { icon: "circle-question", label: "help", @@ -74,6 +94,38 @@ const Widgets = memo(() => { const showHelp = fullConfig?.settings?.["widget:showhelp"] ?? true; const widgets = sortByDisplayOrder(fullConfig?.widgets); + const checkIfCompactNeeded = useCallback(() => { + if (!containerRef.current || !measurementRef.current) return; + + const containerHeight = containerRef.current.clientHeight; + const measurementHeight = measurementRef.current.scrollHeight; + const gracePeriod = 10; + + const shouldBeCompact = measurementHeight > containerHeight - gracePeriod; + + if (shouldBeCompact !== isCompact) { + setIsCompact(shouldBeCompact); + } + }, [isCompact]); + + useEffect(() => { + const resizeObserver = new ResizeObserver(() => { + checkIfCompactNeeded(); + }); + + if (containerRef.current) { + resizeObserver.observe(containerRef.current); + } + + return () => { + resizeObserver.disconnect(); + }; + }, [checkIfCompactNeeded]); + + useEffect(() => { + checkIfCompactNeeded(); + }, [widgets, showHelp, checkIfCompactNeeded]); + const handleWidgetsBarContextMenu = (e: React.MouseEvent) => { e.preventDefault(); const menu: ContextMenuItem[] = [ @@ -119,20 +171,40 @@ const Widgets = memo(() => { }; return ( -
- {widgets?.map((data, idx) => )} -
- {showHelp ? ( - <> - - - - ) : null} - {isDev() ? : null} -
+ <> +
+ {widgets?.map((data, idx) => )} +
+ {showHelp ? ( + <> + + + + ) : null} + {isDev() ? : null} +
+ +
+ {widgets?.map((data, idx) => ( + + ))} +
+ {showHelp ? ( + <> + + + + ) : null} + {isDev() ? : null} +
+ ); }); From 48b98d27a7f926d6b8f20bf7a45d705cc284df14 Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 12:51:50 -0700 Subject: [PATCH 6/8] supercompact mode for widgets as well --- frontend/app/workspace/widgets.tsx | 84 +++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/frontend/app/workspace/widgets.tsx b/frontend/app/workspace/widgets.tsx index b176ca0dc8..6bfc518df8 100644 --- a/frontend/app/workspace/widgets.tsx +++ b/frontend/app/workspace/widgets.tsx @@ -28,18 +28,18 @@ async function handleWidgetSelect(widget: WidgetConfigType) { createBlock(blockDef, widget.magnified); } -const Widget = memo(({ widget, compact = false }: { widget: WidgetConfigType; compact?: boolean }) => { +const Widget = memo(({ widget, mode }: { widget: WidgetConfigType; mode: "normal" | "compact" | "supercompact" }) => { const [isTruncated, setIsTruncated] = useState(false); const labelRef = useRef(null); useEffect(() => { - if (!compact && labelRef.current) { + if (mode === "normal" && labelRef.current) { const element = labelRef.current; setIsTruncated(element.scrollWidth > element.clientWidth); } - }, [compact, widget.label]); + }, [mode, widget.label]); - const shouldDisableTooltip = compact ? false : !isTruncated; + const shouldDisableTooltip = mode !== "normal" ? false : !isTruncated; return ( handleWidgetSelect(widget)} @@ -55,7 +56,7 @@ const Widget = memo(({ widget, compact = false }: { widget: WidgetConfigType; co
- {!compact && !isBlank(widget.label) ? ( + {mode === "normal" && !isBlank(widget.label) ? (
{ const fullConfig = useAtomValue(atoms.fullConfigAtom); - const [isCompact, setIsCompact] = useState(false); + const [mode, setMode] = useState<"normal" | "compact" | "supercompact">("normal"); const containerRef = useRef(null); const measurementRef = useRef(null); @@ -94,23 +95,36 @@ const Widgets = memo(() => { const showHelp = fullConfig?.settings?.["widget:showhelp"] ?? true; const widgets = sortByDisplayOrder(fullConfig?.widgets); - const checkIfCompactNeeded = useCallback(() => { + const checkModeNeeded = useCallback(() => { if (!containerRef.current || !measurementRef.current) return; const containerHeight = containerRef.current.clientHeight; - const measurementHeight = measurementRef.current.scrollHeight; + const normalHeight = measurementRef.current.scrollHeight; const gracePeriod = 10; - const shouldBeCompact = measurementHeight > containerHeight - gracePeriod; + let newMode: "normal" | "compact" | "supercompact" = "normal"; + + if (normalHeight > containerHeight - gracePeriod) { + newMode = "compact"; + + // Calculate total widget count for supercompact check + const totalWidgets = (widgets?.length || 0) + (showHelp ? 2 : 0); + const minHeightPerWidget = 32; + const requiredHeight = totalWidgets * minHeightPerWidget; + + if (requiredHeight > containerHeight) { + newMode = "supercompact"; + } + } - if (shouldBeCompact !== isCompact) { - setIsCompact(shouldBeCompact); + if (newMode !== mode) { + setMode(newMode); } - }, [isCompact]); + }, [mode, widgets, showHelp]); useEffect(() => { const resizeObserver = new ResizeObserver(() => { - checkIfCompactNeeded(); + checkModeNeeded(); }); if (containerRef.current) { @@ -120,11 +134,11 @@ const Widgets = memo(() => { return () => { resizeObserver.disconnect(); }; - }, [checkIfCompactNeeded]); + }, [checkModeNeeded]); useEffect(() => { - checkIfCompactNeeded(); - }, [widgets, showHelp, checkIfCompactNeeded]); + checkModeNeeded(); + }, [widgets, showHelp, checkModeNeeded]); const handleWidgetsBarContextMenu = (e: React.MouseEvent) => { e.preventDefault(); @@ -177,14 +191,31 @@ const Widgets = memo(() => { className="flex flex-col w-12 overflow-hidden py-1 -ml-1 select-none" onContextMenu={handleWidgetsBarContextMenu} > - {widgets?.map((data, idx) => )} -
- {showHelp ? ( + {mode === "supercompact" ? ( <> - - +
+ {widgets?.map((data, idx) => )} +
+
+ {showHelp ? ( +
+ + +
+ ) : null} - ) : null} + ) : ( + <> + {widgets?.map((data, idx) => )} +
+ {showHelp ? ( + <> + + + + ) : null} + + )} {isDev() ? : null}
@@ -193,17 +224,18 @@ const Widgets = memo(() => { className="flex flex-col w-12 py-1 -ml-1 select-none absolute -z-10 opacity-0 pointer-events-none" > {widgets?.map((data, idx) => ( - + ))}
{showHelp ? ( <> - - + + ) : null} {isDev() ? : null}
+ ); }); From b87037e7ac6d72d20e8fa38f7354d6c7165f3679 Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 13:01:11 -0700 Subject: [PATCH 7/8] convert notification popover to tailwind --- .../app/notification/notificationpopover.scss | 64 ------------------- .../app/notification/notificationpopover.tsx | 16 ++--- 2 files changed, 7 insertions(+), 73 deletions(-) delete mode 100644 frontend/app/notification/notificationpopover.scss diff --git a/frontend/app/notification/notificationpopover.scss b/frontend/app/notification/notificationpopover.scss deleted file mode 100644 index 6a3b983f0c..0000000000 --- a/frontend/app/notification/notificationpopover.scss +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2024, Command Line Inc. -// SPDX-License-Identifier: Apache-2.0 - -.notification-popover { - padding: 8px 2px 8px 0px; - display: flex; - align-items: center; - justify-content: center; - - button { - width: 27px; - height: 26px; - display: flex; - justify-content: center; - - i { - font-size: 17px; - } - } -} - -.notification-content { - display: flex; - width: 380px; - padding: 10px 0 0; - flex-direction: column; - align-items: flex-start; - column-gap: 8px; - border-radius: 8px; - border: 0.5px solid rgba(255, 255, 255, 0.12); - background: #232323; - box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25); - - .divider { - background: rgba(255, 255, 255, 0.08); - height: 1px; - width: 100%; - } - - .header { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - padding: 0 10px 8px 10px; - border-bottom: 1px solid rgba(255, 255, 255, 0.08); - - span { - color: var(--main-text-color); - font-size: 14px; - font-style: normal; - font-weight: 600; - line-height: 16px; - } - } - - .close-all-btn { - font-size: 13px; - font-style: normal; - font-weight: 400; - line-height: 16px; - color: rgba(255, 255, 255, 0.4); - } -} diff --git a/frontend/app/notification/notificationpopover.tsx b/frontend/app/notification/notificationpopover.tsx index 70596852eb..160155f5b8 100644 --- a/frontend/app/notification/notificationpopover.tsx +++ b/frontend/app/notification/notificationpopover.tsx @@ -13,8 +13,6 @@ import { NotificationItem } from "./notificationitem"; import { useUpdateNotifier } from "./updatenotifier"; import { useNotification } from "./usenotification"; -import "./notificationpopover.scss"; - const NotificationPopover = () => { useUpdateNotifier(); const { @@ -51,14 +49,14 @@ const NotificationPopover = () => { return ( i]:text-[17px] horizontal-padding-6 vertical-padding-4 border-radius-", addOnClassNames )} disabled={notifications.length === 0} @@ -67,11 +65,11 @@ const NotificationPopover = () => { {getIcon()} {notifications.length > 0 && ( - -
- Notifications + +
+ Notifications