style
This commit is contained in:
@@ -189,7 +189,6 @@ const Sidebar = ({
|
||||
onSelectTenant,
|
||||
onOpenSettings,
|
||||
onUploadFiles,
|
||||
loading = false,
|
||||
}) => {
|
||||
const {
|
||||
setCollapsed,
|
||||
@@ -318,6 +317,50 @@ const Sidebar = ({
|
||||
cycleThemeMode();
|
||||
}, [cycleThemeMode]);
|
||||
|
||||
const themeMenuSection =
|
||||
typeof neutralHue === 'number' || typeof neutralHue === 'string'
|
||||
? (
|
||||
<div className="menu__section">
|
||||
<div className="menu__heading menu__heading--with-actions">
|
||||
<span>Theme</span>
|
||||
<div className="menu__heading-actions">
|
||||
<button
|
||||
type="button"
|
||||
className="icon-button"
|
||||
onClick={handleThemeModeToggle}
|
||||
aria-label={`Switch theme (next: ${nextThemeLabel})`}
|
||||
title={`Theme: ${themeModeLabel} (next: ${nextThemeLabel})`}
|
||||
>
|
||||
{themeModeIcon}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="icon-button"
|
||||
onClick={handleNeutralHueReset}
|
||||
aria-label="Reset neutral hue"
|
||||
title="Reset neutral hue"
|
||||
>
|
||||
<RestoreIcon size={16} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<label className="menu__slider" htmlFor={neutralHueInputId}>
|
||||
<span className="menu__slider-label">Hue</span>
|
||||
<input
|
||||
id={neutralHueInputId}
|
||||
type="range"
|
||||
min="0"
|
||||
max="360"
|
||||
step="1"
|
||||
value={neutralHue}
|
||||
onChange={(event) => handleNeutralHueChange(event.target.value)}
|
||||
/>
|
||||
<span className="menu__slider-value">{neutralHue}°</span>
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
|
||||
const handleSearchInputChange = useCallback(
|
||||
(event) => {
|
||||
onSearchChange?.(event.target.value);
|
||||
@@ -348,6 +391,7 @@ const Sidebar = ({
|
||||
offset: 6,
|
||||
});
|
||||
const showTenantList = tenants.length > 1;
|
||||
const menuClassName = `menu${!showTenantList && !themeMenuSection ? ' menu--simple' : ''}`;
|
||||
|
||||
const toggleTenantMenu = useCallback(() => {
|
||||
if (!tenantMenuOpen && tenants.length === 0 && onSelectTenant) {
|
||||
@@ -426,50 +470,6 @@ const Sidebar = ({
|
||||
);
|
||||
|
||||
const rootNode = folderNodes.get('root');
|
||||
const themeControls =
|
||||
typeof neutralHue === 'number' || typeof neutralHue === 'string'
|
||||
? (
|
||||
<div className="sidebar-section sidebar-theme">
|
||||
<div className="sidebar-section__header">
|
||||
<h3>Theme</h3>
|
||||
<div className="sidebar-section__actions">
|
||||
<button
|
||||
type="button"
|
||||
className="icon-button"
|
||||
onClick={handleThemeModeToggle}
|
||||
aria-label={`Switch theme (next: ${nextThemeLabel})`}
|
||||
title={`Theme: ${themeModeLabel} (next: ${nextThemeLabel})`}
|
||||
>
|
||||
{themeModeIcon}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="icon-button"
|
||||
onClick={handleNeutralHueReset}
|
||||
aria-label="Reset neutral hue"
|
||||
title="Reset neutral hue"
|
||||
>
|
||||
<RestoreIcon size={16} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<label className="sidebar-slider" htmlFor={neutralHueInputId}>
|
||||
<span className="sidebar-slider__label">Hue</span>
|
||||
<input
|
||||
id={neutralHueInputId}
|
||||
type="range"
|
||||
min="0"
|
||||
max="360"
|
||||
step="1"
|
||||
value={neutralHue}
|
||||
onChange={(event) => handleNeutralHueChange(event.target.value)}
|
||||
/>
|
||||
<span className="sidebar-slider__value">{neutralHue}°</span>
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<aside className="sidebar">
|
||||
<input
|
||||
@@ -505,7 +505,7 @@ const Sidebar = ({
|
||||
&& typeof document !== 'undefined'
|
||||
? createPortal(
|
||||
<div
|
||||
className={`menu${showTenantList ? '' : ' menu--simple'}`}
|
||||
className={menuClassName}
|
||||
ref={tenantMenuRef}
|
||||
role="menu"
|
||||
aria-label="Account menu"
|
||||
@@ -540,7 +540,7 @@ const Sidebar = ({
|
||||
<div className="menu__footer">
|
||||
<button
|
||||
type="button"
|
||||
className="menu__settings"
|
||||
className="menu__button"
|
||||
onClick={handleSettingsFromMenu}
|
||||
>
|
||||
<SettingsIcon size={16} />
|
||||
@@ -548,13 +548,14 @@ const Sidebar = ({
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="menu__logout"
|
||||
className="menu__button menu__button--danger"
|
||||
onClick={handleLogoutFromMenu}
|
||||
>
|
||||
<LogoutIcon size={16} />
|
||||
Log out
|
||||
</button>
|
||||
</div>
|
||||
{themeMenuSection}
|
||||
</div>,
|
||||
document.body,
|
||||
)
|
||||
@@ -760,7 +761,6 @@ const Sidebar = ({
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{themeControls ? <div className="sidebar__footer">{themeControls}</div> : null}
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -200,12 +200,23 @@
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.sidebar__title-chevron {
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
.sidebar__title-button .sidebar__title-chevron {
|
||||
opacity: 0;
|
||||
transform: translateY(-1px);
|
||||
transition:
|
||||
opacity 0.12s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
.sidebar__title-button:hover .sidebar__title-chevron,
|
||||
.sidebar__title-button:focus-visible .sidebar__title-chevron,
|
||||
.sidebar__title-chevron.is-open {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidebar__title-chevron.is-open {
|
||||
transform: rotate(180deg);
|
||||
transform: rotate(180deg) translateY(-1px);
|
||||
}
|
||||
|
||||
.menu {
|
||||
@@ -225,10 +236,10 @@
|
||||
.menu__list {
|
||||
max-height: 260px;
|
||||
overflow-y: auto;
|
||||
padding: 0.35rem 0;
|
||||
padding: 0.35rem 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.15rem;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.menu__heading {
|
||||
@@ -238,17 +249,25 @@
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.menu__heading--with-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.menu button.menu__item,
|
||||
.menu .menu__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 0.6rem;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
padding: 0.55rem 1rem;
|
||||
padding: 0.45rem 0.75rem;
|
||||
border: none;
|
||||
border-radius: 0.4rem;
|
||||
background: none;
|
||||
color: inherit;
|
||||
color: var(--sidebar-fg);
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
@@ -267,6 +286,7 @@
|
||||
.menu .menu__item.active {
|
||||
font-weight: 600;
|
||||
color: var(--accent);
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
.menu button.menu__item:focus-visible,
|
||||
@@ -313,7 +333,50 @@
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.menu__settings {
|
||||
|
||||
.menu__section {
|
||||
border-top: 1px solid var(--border);
|
||||
padding: 0.35rem 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.menu__heading-actions {
|
||||
display: inline-flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.menu__slider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
padding: 0 1rem 0.25rem;
|
||||
}
|
||||
|
||||
.menu__section > .menu__slider {
|
||||
margin-top: -0.25rem;
|
||||
}
|
||||
|
||||
.menu__slider input[type='range'] {
|
||||
flex: 1;
|
||||
accent-color: var(--accent);
|
||||
}
|
||||
|
||||
.menu__slider-label {
|
||||
min-width: 2.5rem;
|
||||
}
|
||||
|
||||
.menu__slider-value {
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--fg);
|
||||
min-width: 3rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.menu__button {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -325,30 +388,22 @@
|
||||
cursor: pointer;
|
||||
padding: 0.4rem 0.5rem;
|
||||
border-radius: 0.35rem;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
}
|
||||
|
||||
.menu__settings:hover,
|
||||
.menu__settings:focus-visible {
|
||||
.menu__button:hover,
|
||||
.menu__button:focus-visible {
|
||||
background: var(--sidebar-hover-bg);
|
||||
}
|
||||
|
||||
.menu__logout {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
border: none;
|
||||
background: none;
|
||||
.menu__button--danger {
|
||||
color: var(--danger);
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
padding: 0.4rem 0.5rem;
|
||||
border-radius: 0.35rem;
|
||||
}
|
||||
|
||||
.menu__logout:hover,
|
||||
.menu__logout:focus-visible {
|
||||
.menu__button--danger:hover,
|
||||
.menu__button--danger:focus-visible {
|
||||
background: var(--surface-danger-subtle);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.sidebar__search {
|
||||
|
||||
Reference in New Issue
Block a user