Files
portainer/app/react/components/LogViewer/ToggleButton.tsx
agent_coder 331319f7f1 feat(logs): theme-aware log viewer (standard colors), fill height
Per maintainer feedback ('сделай поддержку светлой/темной темы', 'цвета фона
карточки подтяни к стандартным', and the white gap below):
- Drop the hardcoded dark palette; style the card/header/toolbar with the
  project's standard theme tokens (Card/Card.Header token set) + th-dark: /
  th-highcontrast: variants, so it adapts to light/dark/high-contrast like every
  other Portainer view. Reuse project Button/Input/Checkbox/Icon components; the
  log body uses the themed .log_viewer class; the range picker inherits themed
  form-control styling.
- Fill the available page height (root flex column, calc(100vh - nav/header),
  log body flex:1 min-h:0 overflow-y) so there's no dead white space below.
Layout (single toolbar row, three toggles, gutter), real data, and props are
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 21:35:49 +03:00

48 lines
1.3 KiB
TypeScript

import { ComponentType } from 'react';
import clsx from 'clsx';
import { AutomationTestingProps } from '@/types';
import { Button } from '@@/buttons';
interface Props extends AutomationTestingProps {
active: boolean;
onChange: (active: boolean) => void;
label: string;
/** A lucide-style icon component (rendered at a small fixed size). */
icon: ComponentType<{ size?: number | string }>;
title?: string;
}
/**
* An independent on/off toggle rendered as the project's themed Button with
* `aria-pressed`. The viewer's Line numbers / Timestamp / Wrap lines controls
* are independent toggles (not a single-select segmented control), so each is
* its own ToggleButton. Active uses the primary (pressed) colour, inactive the
* neutral default; both come from the theme so the pill adapts to light/dark/
* high-contrast like the rest of the app.
*/
export function ToggleButton({
active,
onChange,
label,
icon: Icon,
title,
'data-cy': dataCy,
}: Props) {
return (
<Button
color={active ? 'primary' : 'default'}
size="small"
icon={Icon}
title={title}
aria-pressed={active}
onClick={() => onChange(!active)}
className={clsx('!m-0', !active && 'th-dark:!text-gray-4')}
data-cy={dataCy}
>
{label}
</Button>
);
}