mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-25 21:55:49 +00:00
chore: UI Polish for Zoom and Keybindings panel (#7376)
* chore: ui polishing for zoom panel * fix: replace IconRefresh with IconReload in Zoom and Keybindings components * chore: resolved ui issues * test: check test cases * fix: adjust width properties in StyledWrapper component * fix: update keybindings UI layout and tooltip removal * chore: semantics --------- Co-authored-by: Sid <siddharth@usebruno.com> Co-authored-by: shubh-bruno <shubh-bruno@shubh-bruno.local>
This commit is contained in:
@@ -4,7 +4,6 @@ const StyledWrapper = styled.div`
|
||||
color: ${(props) => props.theme.text};
|
||||
|
||||
.zoom-field {
|
||||
width: 120px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -16,7 +15,7 @@ const StyledWrapper = styled.div`
|
||||
}
|
||||
|
||||
.custom-select {
|
||||
width: 80px;
|
||||
width: fit-content;
|
||||
height: 35.89px;
|
||||
padding: 0 0.5rem;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -3,7 +3,9 @@ import get from 'lodash/get';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { savePreferences } from 'providers/ReduxStore/slices/app';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { IconReload } from '@tabler/icons';
|
||||
import { IconChevronDown, IconCheck } from '@tabler/icons';
|
||||
import Button from 'ui/Button/index';
|
||||
const { percentageToZoomLevel } = require('@usebruno/common');
|
||||
|
||||
// Zoom options for dropdown (50% to 150%)
|
||||
@@ -85,10 +87,12 @@ const Zoom = () => {
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<div className="flex flex-row gap-1 items-end">
|
||||
<div>
|
||||
<label className="block">Interface Zoom</label>
|
||||
</div>
|
||||
<div className="flex flex-row gap-1 items-center mt-2">
|
||||
<div className="zoom-field" ref={dropdownRef}>
|
||||
<label className="block">Interface Zoom</label>
|
||||
<div className="custom-select mt-2" onClick={() => setIsOpen(!isOpen)}>
|
||||
<div className="custom-select" onClick={() => setIsOpen(!isOpen)}>
|
||||
<span className="selected-value">{selectedOption?.label}</span>
|
||||
<IconChevronDown size={14} className="chevron-icon" />
|
||||
</div>
|
||||
@@ -108,13 +112,13 @@ const Zoom = () => {
|
||||
)}
|
||||
</div>
|
||||
{!isDefault && (
|
||||
<button
|
||||
type="button"
|
||||
className="reset-btn"
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<IconReload />}
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onClick={handleResetToDefault}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
|
||||
@@ -2,7 +2,7 @@ import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
max-height: calc(100% - 30px);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -17,7 +17,6 @@ const StyledWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.reset-all-btn {
|
||||
@@ -45,6 +44,20 @@ const StyledWrapper = styled.div`
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.keybinding-row .edit-btn,
|
||||
.keybinding-row .reset-btn {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.button-placeholder {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.keybinding-row:hover .edit-btn {
|
||||
opacity: 0.9;
|
||||
}
|
||||
@@ -117,23 +130,13 @@ const StyledWrapper = styled.div`
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.kb-tooltip {
|
||||
border-radius: 8px;
|
||||
padding: 6px 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
max-width: 320px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.kb-tooltip--error {
|
||||
color: ${(props) => props.theme.colors?.text?.red || '#ef4444'};
|
||||
.tooltip-mod.tooltip-mod--error{
|
||||
color: ${(props) => props.theme.status.danger.text} !important;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
flex: 1 1 auto;
|
||||
margin-bottom: 24px;
|
||||
min-height: 0;
|
||||
max-height: 650px;
|
||||
overflow-y: auto;
|
||||
|
||||
border-radius: 8px;
|
||||
@@ -170,9 +173,7 @@ const StyledWrapper = styled.div`
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
|
||||
background: ${(props) => props.theme.background};
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
background: ${(props) => props.theme.background.base};
|
||||
|
||||
color: ${(props) => props.theme.table.thead.color};
|
||||
font-size: ${(props) => props.theme.font.size.base};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useDispatch, useSelector } from 'react-redux';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { IconRefresh, IconPencil } from '@tabler/icons';
|
||||
import { IconReload, IconPencil } from '@tabler/icons';
|
||||
import { isMacOS } from 'utils/common/platform';
|
||||
|
||||
import { savePreferences } from 'providers/ReduxStore/slices/app';
|
||||
@@ -171,7 +171,7 @@ const Keybindings = () => {
|
||||
// ✏️ which row is allowed to edit (pencil clicked)
|
||||
const [editingAction, setEditingAction] = useState(null);
|
||||
|
||||
// hover tracking (for showing pencil/refresh only on hover row)
|
||||
// hover tracking (for showing pencil/reset only on hover row)
|
||||
const [hoveredAction, setHoveredAction] = useState(null);
|
||||
|
||||
// Recording state
|
||||
@@ -280,7 +280,7 @@ const Keybindings = () => {
|
||||
...(preferences?.keyBindings || {}),
|
||||
[action]: {
|
||||
...(preferences?.keyBindings?.[action] || {}),
|
||||
name: preferences?.keyBindings?.[action]?.name || action,
|
||||
name: preferences?.keyBindings?.[action]?.name || DEFAULT_KEY_BINDINGS?.[action]?.name || action,
|
||||
[os]: nextKeys
|
||||
}
|
||||
}
|
||||
@@ -497,13 +497,6 @@ const Keybindings = () => {
|
||||
|
||||
return (
|
||||
<StyledWrapper className="w-full">
|
||||
<Tooltip
|
||||
id="kb-editing-error-tooltip"
|
||||
place="bottom-start"
|
||||
opacity={1}
|
||||
className="kb-tooltip kb-tooltip--error"
|
||||
/>
|
||||
|
||||
<div className="section-header">
|
||||
<span>Keybindings</span>
|
||||
{hasDirtyRows && (
|
||||
@@ -513,8 +506,7 @@ const Keybindings = () => {
|
||||
onClick={resetAllKeybindings}
|
||||
title="Reset all keybindings to default"
|
||||
>
|
||||
<IconRefresh size={12} stroke={1} />
|
||||
|
||||
<IconReload size={14} stroke={1} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -535,7 +527,7 @@ const Keybindings = () => {
|
||||
const isDirty = isRowDirty(action);
|
||||
|
||||
const showPencil = isHovered && !isEditing && !isDirty;
|
||||
const showRefresh = isDirty && !isEditing;
|
||||
const showReset = isDirty && !isEditing;
|
||||
const hasError = Boolean(errorByAction[action]?.message);
|
||||
const errorMessage = errorByAction[action]?.message;
|
||||
const inputId = `kb-input-${action}`;
|
||||
@@ -548,7 +540,6 @@ const Keybindings = () => {
|
||||
onMouseLeave={() => setHoveredAction((prev) => (prev === action ? null : prev))}
|
||||
>
|
||||
<td data-testid={`keybinding-name-${action}`}>{row.name}</td>
|
||||
|
||||
<td>
|
||||
<div className="keybinding-row">
|
||||
<div className="shortcut-wrap">
|
||||
@@ -562,7 +553,12 @@ const Keybindings = () => {
|
||||
value={renderValue(action)}
|
||||
readOnly={!isEditing}
|
||||
onKeyDown={(e) => handleKeyDown(action, e)}
|
||||
onKeyUp={(e) => handleKeyUp(action, e)}
|
||||
onKeyUp={(e) => {
|
||||
if (hasError) {
|
||||
return stopEditing(action);
|
||||
}
|
||||
handleKeyUp(action, e);
|
||||
}}
|
||||
onBlur={() => {
|
||||
// If there's an error, reset to original value instead of keeping invalid state
|
||||
if (isEditing && hasError) {
|
||||
@@ -581,12 +577,12 @@ const Keybindings = () => {
|
||||
opacity={1}
|
||||
isOpen={true}
|
||||
content={errorMessage}
|
||||
className="kb-tooltip kb-tooltip--error"
|
||||
className="tooltip-mod tooltip-mod--error"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showRefresh && (
|
||||
{showReset ? (
|
||||
<button
|
||||
type="button"
|
||||
className="reset-btn"
|
||||
@@ -594,10 +590,10 @@ const Keybindings = () => {
|
||||
onClick={() => resetRowToDefault(action)}
|
||||
title="Reset to default"
|
||||
>
|
||||
<IconRefresh size={12} stroke={1} />
|
||||
<IconReload size={14} stroke={1} />
|
||||
</button>
|
||||
)}
|
||||
{showPencil && (
|
||||
) : null}
|
||||
{showPencil ? (
|
||||
<button
|
||||
type="button"
|
||||
className="edit-btn"
|
||||
@@ -605,9 +601,9 @@ const Keybindings = () => {
|
||||
onClick={() => startEditing(action)}
|
||||
title="Edit shortcut"
|
||||
>
|
||||
<IconPencil size={12} stroke={1.5} />
|
||||
<IconPencil size={14} stroke={1.5} />
|
||||
</button>
|
||||
)}
|
||||
) : null}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -3,7 +3,7 @@ import styled from 'styled-components';
|
||||
const StyledWrapper = styled.div`
|
||||
div.tabs {
|
||||
padding: 12px;
|
||||
min-width: 160px;
|
||||
min-width: 180px;
|
||||
|
||||
div.tab {
|
||||
display: flex;
|
||||
@@ -38,7 +38,7 @@ const StyledWrapper = styled.div`
|
||||
}
|
||||
|
||||
section.tab-panel {
|
||||
min-height: 70vh;
|
||||
max-height: calc(100% - 24px);
|
||||
overflow-y: auto;
|
||||
flex-grow: 1;
|
||||
padding: 12px;
|
||||
|
||||
Reference in New Issue
Block a user