Skip to content

symbols-bar: optionally show labels and slightly tweak margins #8420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/packages/frontend/account/other-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,21 @@ export function OtherSettings(props: Readonly<Props>): React.JSX.Element {
);
}

function render_show_symbol_bar_labels(): Rendered {
return (
<Checkbox
checked={!!props.other_settings.get("show_symbol_bar_labels")}
onChange={(e) => on_change("show_symbol_bar_labels", e.target.checked)}
>
<FormattedMessage
id="account.other-settings.symbol_bar_labels"
defaultMessage={`<strong>Show Symbol Bar Labels:</strong>
show labels in the frame editor symbol bar`}
/>
</Checkbox>
);
}

function render_default_file_sort(): Rendered {
return (
<LabeledRow
Expand Down Expand Up @@ -672,6 +687,7 @@ export function OtherSettings(props: Readonly<Props>): React.JSX.Element {
{render_hide_project_popovers()}
{render_hide_file_popovers()}
{render_hide_button_tooltips()}
{render_show_symbol_bar_labels()}
<Checkbox
checked={!!props.other_settings.get("hide_navbar_balance")}
onChange={(e) => on_change("hide_navbar_balance", e.target.checked)}
Expand Down
4 changes: 4 additions & 0 deletions src/packages/frontend/account/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ export class AccountStore extends Store<AccountState> {
if (!tours) return false;
return tours.includes(tour) || tours.includes("all");
}

showSymbolBarLabels(): boolean {
return this.getIn(["other_settings", "show_symbol_bar_labels"], false);
}
}

// A user is anonymous if they have not provided a way to sign
Expand Down
1 change: 1 addition & 0 deletions src/packages/frontend/account/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export interface AccountState {
[OTHER_SETTINGS_REPLY_ENGLISH_KEY]?: string;
no_email_new_messages?: boolean;
use_balance_toward_subscriptions?: boolean;
show_symbol_bar_labels?: boolean; // whether to show labels on the menu buttons
[ACTIVITY_BAR_LABELS]?: boolean; // whether to show labels on the vertical activity bar
}>;
stripe_customer?: TypedMap<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Icon, IconName, isIconName } from "@cocalc/frontend/components/icon";
import { IS_MOBILE } from "@cocalc/frontend/feature";
import { IntlMessage, isIntlMessage } from "@cocalc/frontend/i18n";
import { cmp, filename_extension, trunc_middle } from "@cocalc/util/misc";
// import { FrameTitleBarProps } from "../title-bar";
import { COLORS } from "@cocalc/util/theme";
import { EditorDescription } from "../types";
import { COMMANDS } from "./commands";
import { APPLICATION_MENU, SEARCH_COMMANDS } from "./const";
Expand All @@ -26,8 +26,6 @@ const MAX_TITLE_WIDTH = 20;
const MAX_SEARCH_RESULTS = 10;
const ICON_WIDTH = "28px";

const BUTTON_LABELS = false;

export class ManageCommands {
// TODO: setting this to FrameTitleBarProps causes type issues in frame-editors/jupyter-editor/editor.ts
// So, there is probably a fundamental problem with that mapping into "AllActions"
Expand Down Expand Up @@ -445,6 +443,11 @@ export class ManageCommands {
});
};

showSymbolBarLabels = (): boolean => {
const account = redux.getStore("account");
return account.showSymbolBarLabels();
};

commandToMenuItem = ({
name = "",
key,
Expand Down Expand Up @@ -482,11 +485,11 @@ export class ManageCommands {
label = (
<>
{icon ?? <Icon name="square" />}
{BUTTON_LABELS && (
{this.showSymbolBarLabels() && (
<div
style={{
fontSize: "11px",
color: "#666",
color: COLORS.GRAY_M,
marginTop: "-10px",
// special case: button='' explicitly means no label
width: cmd.button === "" ? undefined : "50px",
Expand Down
85 changes: 77 additions & 8 deletions src/packages/frontend/frame-editors/frame-tree/title-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
FrameTitleBar - title bar in a frame, in the frame tree
*/

import { Button, Input, InputNumber, Popover, Tooltip } from "antd";
import { ButtonGroup } from "@cocalc/frontend/antd-bootstrap";
import { Button, Dropdown, Input, InputNumber, Popover, Tooltip } from "antd";
import type { MenuProps } from "antd/lib";
import { List } from "immutable";
import { useMemo, useRef } from "react";
import { useIntl } from "react-intl";
import { ButtonGroup } from "@cocalc/frontend/antd-bootstrap";

import {
CSS,
redux,
Expand All @@ -38,6 +40,7 @@ import { excludeFromComputeServer } from "@cocalc/frontend/file-associations";
import { NotebookFrameActions } from "@cocalc/frontend/frame-editors/jupyter-editor/cell-notebook/actions";
import { IntlMessage, isIntlMessage, labels } from "@cocalc/frontend/i18n";
import { JupyterActions } from "@cocalc/frontend/jupyter/browser-actions";
import { ACTIVITY_BAR_TOGGLE_LABELS } from "@cocalc/frontend/project/page/activity-bar-consts";
import { AIGenerateDocumentModal } from "@cocalc/frontend/project/page/home-page/ai-generate-document";
import { isSupportedExtension } from "@cocalc/frontend/project/page/home-page/ai-generate-examples";
import { AvailableFeatures } from "@cocalc/frontend/project_configuration";
Expand Down Expand Up @@ -270,6 +273,10 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
const otherSettings = useRedux(["account", "other_settings"]);
// const hideButtonTooltips = otherSettings.get("hide_button_tooltips");
const darkMode = otherSettings.get("dark_mode");
const showSymbolBarLabels = otherSettings.get(
"show_symbol_bar_labels",
false,
);
const disableTourRefs = useRef<boolean>(false);
const tourRefs = useRef<{ [name: string]: { current: any } }>({});
const getTourRef = (name: string) => {
Expand Down Expand Up @@ -710,8 +717,8 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
label === APPLICATION_MENU
? manageCommands.applicationMenuTitle()
: isIntlMessage(label)
? intl.formatMessage(label)
: label
? intl.formatMessage(label)
: label
}
items={v}
/>
Expand Down Expand Up @@ -1060,6 +1067,11 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
return null;
}
const { disabled, label, key, children, onClick } = item;
const style: CSS = {
color: "#333",
padding: showSymbolBarLabels ? "0" : "7.5px 0 0 0",
height: showSymbolBarLabels ? "36px" : undefined,
} as const;
if (children != null) {
return (
<DropdownMenu
Expand All @@ -1068,7 +1080,7 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
title={label}
items={children}
button={false}
style={{ color: "#333", padding: "7.5px 0 0 0" }}
style={style}
/>
);
} else {
Expand All @@ -1079,14 +1091,53 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
key={key}
disabled={disabled}
onClick={onClick}
style={{ color: "#333", padding: "7.5px 0 0 0" }}
style={style}
>
{label}
</Button>
);
}
}

function wrapButtonBarContextMenu(bar: React.JSX.Element) {
const showSymbolLabel = (
<>
<Tooltip
title={intl.formatMessage({
id: "frame_editors.frame_tree.title_bar.symbols.label.explanation",
defaultMessage:
"If labels are shown, the symbol bar is placed in its own row beneath the menu – otherwise it is smaller and next to the menu.",
})}
>
<Icon name="signature-outlined" />{" "}
{intl.formatMessage(ACTIVITY_BAR_TOGGLE_LABELS, {
show: showSymbolBarLabels,
})}
</Tooltip>
</>
);
const items: MenuProps["items"] = [
{
key: "toggle-labels",
label: showSymbolLabel,
onClick: () => {
redux
.getActions("account")
.set_other_settings("show_symbol_bar_labels", !showSymbolBarLabels);
},
},
];
return (
<Dropdown
trigger={["contextMenu"]}
menu={{ items }}
overlayStyle={{ maxWidth: "400px" }}
>
{bar}
</Dropdown>
);
}

function renderButtonBar(popup = false) {
if (!is_active) {
return null;
Expand All @@ -1105,7 +1156,24 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
if (v.length == 0) {
return null;
}
return <div style={{ marginTop: "5px" }}>{v}</div>;
// if labels are shown, we render two rows – otherwise symbols are next to the menu and frame controls
if (showSymbolBarLabels) {
return wrapButtonBarContextMenu(
<div
style={{
borderBottom: popup ? undefined : "1px solid #ccc",
background: "#fafafa",
opacity: is_active ? undefined : 0.3,
}}
>
<div style={{ marginBottom: "-1px", marginTop: "1px" }}>{v}</div>
</div>,
);
} else {
return wrapButtonBarContextMenu(
<div style={{ marginTop: "3px" }}>{v}</div>,
);
}
}

function renderComputeServerDocStatus() {
Expand Down Expand Up @@ -1253,9 +1321,10 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
{renderMainMenusAndButtons()}
{is_active && renderConnectionStatus()}
{is_active && allButtonsPopover()}
{renderButtonBar()}
{!showSymbolBarLabels ? renderButtonBar() : undefined}
{renderFrameControls()}
</div>
{showSymbolBarLabels ? renderButtonBar() : undefined}
{renderConfirmBar()}
{hasTour && props.is_visible && props.tab_is_visible && (
<TitleBarTour refs={tourRefs} />
Expand Down
3 changes: 2 additions & 1 deletion src/packages/frontend/i18n/trans/ar_EG.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"account.other-settings.mask_files": "<strong>إخفاء الملفات:</strong> تظليل الملفات في عارض الملفات التي ربما لا تريد فتحها",
"account.other-settings.project_popovers": "<strong>إخفاء النوافذ المنبثقة لعلامات التبويب في المشروع:</strong> لا تعرض النوافذ المنبثقة فوق علامات تبويب المشروع",
"account.other-settings.standby_timeout": "مهلة الانتظار",
"account.other-settings.symbol_bar_labels": "<strong>إظهار تسميات شريط الرموز:</strong> إظهار التسميات في شريط رموز محرر الإطار",
"account.other-settings.theme": "السمة",
"account.other-settings.theme.antd.animations": "<b>الرسوم المتحركة</b>: تحريك بعض العناصر بإيجاز، مثل الأزرار",
"account.other-settings.theme.antd.color_scheme": "مخطط الألوان: استخدم ألوان العلامة التجارية بدلاً من الألوان الافتراضية",
Expand Down Expand Up @@ -597,6 +598,7 @@
"frame_editors.frame_tree.title_bar.close": "أغلق هذا الإطار",
"frame_editors.frame_tree.title_bar.maximize": "عرض هذا الإطار فقط",
"frame_editors.frame_tree.title_bar.minimize": "عرض كافة الإطارات",
"frame_editors.frame_tree.title_bar.symbols.label.explanation": "إذا تم عرض التسميات، يتم وضع شريط الرموز في صف خاص به تحت القائمة – وإلا فإنه يكون أصغر ويكون بجانب القائمة.",
"frame-editors.frame-tree.add_remove_icon_button_bar.tooltip": "{isOnButtonBar, select, true {انقر على الأيقونة لإزالتها من شريط الأدوات} other {انقر على الأيقونة لإضافتها إلى شريط الأدوات}}",
"i18n.localization.lang.arabic": "العربية",
"i18n.localization.lang.chinese": "الصينية",
Expand Down Expand Up @@ -1257,7 +1259,6 @@
"project.page.flyouts.new.header_location": "الموقع:",
"project.page.project-licenses.header": "الحصص و{upgrades}",
"project.page.project-licenses.intro": "التراخيص والترقيات حسب الاستخدام تغير الحصص والميزات المتاحة للمشروع",
"project.page.vertical-fixed-tabs.toggle-labels": "{show, select, true {إخفاء التسميات} other {إظهار التسميات}}",
"project.servers.project-servers.description": "يمكنك تشغيل خوادم دفتر ملاحظات مختلفة داخل هذا المشروع بنقرة واحدة. تعمل في نفس البيئة، وتصل إلى نفس الملفات، وتتوقف عندما يتوقف المشروع. يمكنك أيضًا <A>تشغيل خوادمك الخاصة</A>.",
"project.settings.about-box.description.label": "الوصف (ماركداون)",
"project.settings.about-box.image.label": "صورة (اختياري)",
Expand Down
3 changes: 2 additions & 1 deletion src/packages/frontend/i18n/trans/de_DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"account.other-settings.mask_files": "<strong>Dateien maskieren:</strong> Dateien im Dateibetrachter ausgrauen, die Sie wahrscheinlich nicht öffnen möchten",
"account.other-settings.project_popovers": "<strong>Projekt-Tab-Popovers ausblenden:</strong> die Popovers über den Projekt-Tabs nicht anzeigen",
"account.other-settings.standby_timeout": "Standby-Timeout",
"account.other-settings.symbol_bar_labels": "<strong>Symbolleistensymbol-Beschriftungen anzeigen:</strong> Beschriftungen in der Symbolleiste des Rahmeneditors anzeigen",
"account.other-settings.theme": "Thema",
"account.other-settings.theme.antd.animations": "<b>Animationen</b>: einige Aspekte kurz animieren, z. B. Schaltflächen",
"account.other-settings.theme.antd.color_scheme": "<b>Farbschema</b>: Verwenden Sie Markenfarben anstelle der Standardfarben",
Expand Down Expand Up @@ -597,6 +598,7 @@
"frame_editors.frame_tree.title_bar.close": "Schließe dieses Fenster",
"frame_editors.frame_tree.title_bar.maximize": "Nur dieses Fenster anzeigen",
"frame_editors.frame_tree.title_bar.minimize": "Alle Fenster anzeigen",
"frame_editors.frame_tree.title_bar.symbols.label.explanation": "Wenn Beschriftungen angezeigt werden, befindet sich die Symbolleiste in einer eigenen Zeile unterhalb des Menüs – andernfalls ist sie kleiner und neben dem Menü.",
"frame-editors.frame-tree.add_remove_icon_button_bar.tooltip": "{isOnButtonBar, select, true {Klicken Sie auf das Symbol, um es aus der Symbolleiste zu entfernen} other {Klicken Sie auf das Symbol, um es zur Symbolleiste hinzuzufügen}}",
"i18n.localization.lang.arabic": "Arabisch",
"i18n.localization.lang.chinese": "Chinesisch",
Expand Down Expand Up @@ -1257,7 +1259,6 @@
"project.page.flyouts.new.header_location": "Verzeichnis:",
"project.page.project-licenses.header": "Quoten und {upgrades}",
"project.page.project-licenses.intro": "Lizenzen und Pay-as-you-go-Upgrades ändern die Quoten und Funktionen, die einem Projekt zur Verfügung stehen.",
"project.page.vertical-fixed-tabs.toggle-labels": "{show, select, true {Beschriftungen ausblenden} other {Beschriftungen anzeigen}}",
"project.servers.project-servers.description": "Sie können verschiedene Notebook-Server in diesem Projekt mit einem Klick starten. Sie laufen in derselben Umgebung, haben Zugriff auf dieselben Dateien und stoppen, wenn das Projekt stoppt. Sie können auch <A>Ihren eigenen Server starten</A>.",
"project.settings.about-box.description.label": "Beschreibung (Markdown)",
"project.settings.about-box.image.label": "Bild (optional)",
Expand Down
3 changes: 2 additions & 1 deletion src/packages/frontend/i18n/trans/es_ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"account.other-settings.mask_files": "<strong>Archivos ocultos:</strong> atenuar archivos en el visor de archivos que probablemente no desees abrir",
"account.other-settings.project_popovers": "<strong>Ocultar los Popovers de Pestañas de Proyecto:</strong> no mostrar los popovers sobre las pestañas del proyecto",
"account.other-settings.standby_timeout": "Tiempo de espera en espera",
"account.other-settings.symbol_bar_labels": "<strong>Mostrar etiquetas de la barra de símbolos:</strong> mostrar etiquetas en la barra de símbolos del editor de marcos",
"account.other-settings.theme": "Tema",
"account.other-settings.theme.antd.animations": "<b>Animaciones</b>: animar brevemente algunos aspectos, p. ej., botones",
"account.other-settings.theme.antd.color_scheme": "<b>Esquema de Color</b>: usar colores de marca en lugar de colores predeterminados",
Expand Down Expand Up @@ -597,6 +598,7 @@
"frame_editors.frame_tree.title_bar.close": "Cerrar este marco",
"frame_editors.frame_tree.title_bar.maximize": "Mostrar solo este marco",
"frame_editors.frame_tree.title_bar.minimize": "Mostrar todos los marcos",
"frame_editors.frame_tree.title_bar.symbols.label.explanation": "Si se muestran las etiquetas, la barra de símbolos se coloca en su propia fila debajo del menú; de lo contrario, es más pequeña y está al lado del menú.",
"frame-editors.frame-tree.add_remove_icon_button_bar.tooltip": "{isOnButtonBar, select, true {Haga clic en el icono para quitar de la barra de herramientas} other {Haga clic en el icono para añadir a la barra de herramientas}}",
"i18n.localization.lang.arabic": "Árabe",
"i18n.localization.lang.chinese": "Chino",
Expand Down Expand Up @@ -1257,7 +1259,6 @@
"project.page.flyouts.new.header_location": "Ubicación:",
"project.page.project-licenses.header": "Cuotas y {upgrades}",
"project.page.project-licenses.intro": "Las licencias y las actualizaciones de pago por uso cambian las cuotas y características disponibles para un proyecto",
"project.page.vertical-fixed-tabs.toggle-labels": "{show, select, true {Ocultar etiquetas} other {Mostrar etiquetas}}",
"project.servers.project-servers.description": "Puedes ejecutar varios servidores de cuadernos dentro de este proyecto con un solo clic. Se ejecutan en el mismo entorno, tienen acceso a los mismos archivos y se detienen cuando el proyecto se detiene. También puedes <A>ejecutar tus propios servidores</A>.",
"project.settings.about-box.description.label": "Descripción (markdown)",
"project.settings.about-box.image.label": "Imagen (opcional)",
Expand Down
3 changes: 2 additions & 1 deletion src/packages/frontend/i18n/trans/fr_FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"account.other-settings.mask_files": "<strong>Masquer les fichiers :</strong> griser les fichiers dans le visualiseur de fichiers que vous ne souhaitez probablement pas ouvrir",
"account.other-settings.project_popovers": "<strong>Masquer les popovers des onglets de projet :</strong> ne pas afficher les popovers au-dessus des onglets de projet",
"account.other-settings.standby_timeout": "Délai d'attente en veille",
"account.other-settings.symbol_bar_labels": "<strong>Afficher les étiquettes de la barre de symboles :</strong> afficher les étiquettes dans la barre de symboles de l'éditeur de cadre",
"account.other-settings.theme": "Thème",
"account.other-settings.theme.antd.animations": "<b>Animations</b> : animer brièvement certains aspects, par exemple les boutons",
"account.other-settings.theme.antd.color_scheme": "<b>Schéma de couleurs</b> : utiliser les couleurs de marque au lieu des couleurs par défaut",
Expand Down Expand Up @@ -597,6 +598,7 @@
"frame_editors.frame_tree.title_bar.close": "Fermer ce cadre",
"frame_editors.frame_tree.title_bar.maximize": "Afficher seulement ce cadre",
"frame_editors.frame_tree.title_bar.minimize": "Afficher tous les cadres",
"frame_editors.frame_tree.title_bar.symbols.label.explanation": "Si les étiquettes sont affichées, la barre de symboles est placée sur sa propre ligne sous le menu – sinon elle est plus petite et à côté du menu.",
"frame-editors.frame-tree.add_remove_icon_button_bar.tooltip": "{isOnButtonBar, select, true {Cliquez sur l'icône pour retirer de la barre d'outils} other {Cliquez sur l'icône pour ajouter à la barre d'outils}}",
"i18n.localization.lang.arabic": "Arabe",
"i18n.localization.lang.chinese": "Chinois",
Expand Down Expand Up @@ -1257,7 +1259,6 @@
"project.page.flyouts.new.header_location": "Emplacement :",
"project.page.project-licenses.header": "Quotas et {upgrades}",
"project.page.project-licenses.intro": "Les licences et les mises à niveau à la carte modifient les quotas et les fonctionnalités disponibles pour un projet.",
"project.page.vertical-fixed-tabs.toggle-labels": "{show, select, true {Masquer les étiquettes} other {Afficher les étiquettes}}",
"project.servers.project-servers.description": "Vous pouvez exécuter divers serveurs de notebooks à l'intérieur de ce projet en un clic. Ils fonctionnent dans le même environnement, ont accès aux mêmes fichiers et s'arrêtent lorsque le projet s'arrête. Vous pouvez également <A>exécuter vos propres serveurs</A>.",
"project.settings.about-box.description.label": "Description (markdown)",
"project.settings.about-box.image.label": "Image (optionnel)",
Expand Down
Loading