From d45ce418d87441346110d7b23150a18b14e771fb Mon Sep 17 00:00:00 2001 From: Paolo Scattolin Date: Fri, 16 Oct 2026 13:48:43 +0200 Subject: [PATCH 1/9] Remove Info and Secondary variants and adjust warning color --- src/components/Badge.tsx | 8 ++++---- src/components/Button.tsx | 4 ++-- src/components/Icon.tsx | 2 +- src/components/Modal.tsx | 2 +- src/components/NotificationCard.tsx | 10 +++++----- src/components/Spinner.tsx | 2 +- src/components/cards/Card.tsx | 2 +- src/components/utils.test.ts | 14 +------------- src/components/utils.ts | 4 ---- .../timeline-tab-view/TimelineTabView.tsx | 4 ++-- .../playbook-detail-page/PlaybookDetailCards.tsx | 6 +++--- .../playbook-detail-page/PlaybookTimeline.tsx | 2 +- src/theme/theme.ts | 10 +++++----- 13 files changed, 27 insertions(+), 43 deletions(-) diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 7e694ec..343afbb 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -9,7 +9,7 @@ interface BadgeProps extends React.HTMLAttributes { /** * Badge component for compact status/label pills. - * Displays colored badges with different variants (success, warning, error, info) and shapes. + * Displays colored badges with different variants (primary, success, warning, error, accent) and shapes. * Supports interactive mode with hover effects for clickable badges. * @param $variant - Visual variant using ThemeVariant enum. * @param $shape - Shape of the badge: BadgeShape.Pill (fully rounded ends) or BadgeShape.Rounded (medium border radius). Defaults to Pill. @@ -31,15 +31,15 @@ export const Badge = styled.span` border-radius: ${({ $shape = BadgeShape.Pill, theme }) => $shape === BadgeShape.Rounded ? theme.radius.md : theme.radius.full}; border: 1px solid - ${({ $variant = ThemeVariant.Info, theme }) => + ${({ $variant = ThemeVariant.Primary, theme }) => getVariantColors(theme, $variant).border}; font: ${({ theme }) => theme.typography.small.font}; line-height: ${({ theme }) => theme.fonts.lineHeight.mini}; - background: ${({ $variant = ThemeVariant.Info, theme }) => + background: ${({ $variant = ThemeVariant.Primary, theme }) => getVariantColors(theme, $variant).bg}; - color: ${({ $variant = ThemeVariant.Info, theme }) => + color: ${({ $variant = ThemeVariant.Primary, theme }) => getVariantColors(theme, $variant).text}; ${({ $isInteractive, theme }) => diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 529e611..342986c 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -20,7 +20,7 @@ export interface ButtonProps extends React.ButtonHTMLAttributes(({ children }) => ({ border-radius: ${({ theme }) => theme.radius.md}; - ${({ $variant = ThemeVariant.Info, $ghost, theme }) => { + ${({ $variant = ThemeVariant.Primary, $ghost, theme }) => { const colors = getVariantColors(theme, $variant); return ` diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index e91ece3..97d3505 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -61,7 +61,7 @@ const IconWrapper = styled.span<{ * Renders Tabler icons with theme sizes and optional round containers. * @param $icon - Tabler icon component from @tabler/icons-react * @param $size - ThemeSize enum (default: ThemeSize.Large, corrisponding to 16px) - * @param $variant - "primary" | "secondary" | "success" | "warning" | "error" | "info" (only used with $round) + * @param $variant - "primary" | "success" | "warning" | "error" | "accent" (only used with $round) * @param $ghost - boolean (default: false) - renders transparent background with colored border (only used with $round) * @param $round - boolean (default: false) - renders icon in a round container with variant colors * @param $stroke - number (default: 2) - stroke width of the icon diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index 7c23e74..4619337 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -87,7 +87,7 @@ const Body = styled.div` * Typically contains action buttons like Cancel/Confirm. * @example * - * + * * * */ diff --git a/src/components/NotificationCard.tsx b/src/components/NotificationCard.tsx index b702e12..d0d7d94 100644 --- a/src/components/NotificationCard.tsx +++ b/src/components/NotificationCard.tsx @@ -10,7 +10,7 @@ export interface NotificationCardProps extends React.HTMLAttributesSomething went wrong. Please try again.

* * @example - * // Info notification (default) + * // Primary notification (default) * *

This is an informational message.

*
@@ -38,12 +38,12 @@ export const NotificationCard = styled.div` border-radius: ${({ theme }) => theme.radius.md}; border: 1px solid - ${({ $variant = ThemeVariant.Info, theme }) => + ${({ $variant = ThemeVariant.Primary, theme }) => getVariantColors(theme, $variant).border}; - background: ${({ $variant = ThemeVariant.Info, theme }) => + background: ${({ $variant = ThemeVariant.Primary, theme }) => getVariantColors(theme, $variant).bg}; - color: ${({ $variant = ThemeVariant.Info, theme }) => + color: ${({ $variant = ThemeVariant.Primary, theme }) => getVariantColors(theme, $variant).text}; font: ${({ theme }) => theme.typography.body.font}; diff --git a/src/components/Spinner.tsx b/src/components/Spinner.tsx index c9132fb..54c8a3b 100644 --- a/src/components/Spinner.tsx +++ b/src/components/Spinner.tsx @@ -63,7 +63,7 @@ export interface SpinnerProps extends React.HTMLAttributes { * @param $size - Size of the spinning element * @param $color - Custom hex/rgb color string for the spinning accent color. Overrides $variant if provided. * @param $trackColor - Custom hex/rgb color string for the background ring track. Uses theme colors if not specified. - * @param $variant - Theme color variant: "primary", "success", "error", "warning", "info", "accent", "secondary". Determines accent color from theme. Defaults to "primary". + * @param $variant - Theme color variant: "primary", "success", "error", "warning", "accent". Determines accent color from theme. Defaults to "primary". * @param $withContainer - When true, wraps the spinner in a centered flex container with padding. Defaults to false. * @param className - Optional CSS class name for custom positioning or styling overrides. * @example diff --git a/src/components/cards/Card.tsx b/src/components/cards/Card.tsx index 3504ff9..d29bc50 100644 --- a/src/components/cards/Card.tsx +++ b/src/components/cards/Card.tsx @@ -74,7 +74,7 @@ export const CardBody = styled.div` * Card footer section for actions, aligned to the right. * @example * - * + * * * */ diff --git a/src/components/utils.test.ts b/src/components/utils.test.ts index 2981f14..299c7c8 100644 --- a/src/components/utils.test.ts +++ b/src/components/utils.test.ts @@ -20,18 +20,12 @@ describe("Component utility functions", () => { expect(getVariantColors(theme, ThemeVariant.Error)).toEqual( theme.colors.error, ); - expect(getVariantColors(theme, ThemeVariant.Info)).toEqual( - theme.colors.info, - ); expect(getVariantColors(theme, ThemeVariant.Primary)).toEqual( theme.colors.info, ); expect(getVariantColors(theme, ThemeVariant.Accent)).toEqual( theme.colors.accent, ); - expect(getVariantColors(theme, ThemeVariant.Secondary)).toEqual( - theme.colors.accent, - ); }); test("returns correct colors for all variants with dark theme", () => { @@ -44,18 +38,12 @@ describe("Component utility functions", () => { expect(getVariantColors(darkTheme, ThemeVariant.Error)).toEqual( darkTheme.colors.error, ); - expect(getVariantColors(darkTheme, ThemeVariant.Info)).toEqual( - darkTheme.colors.info, - ); expect(getVariantColors(darkTheme, ThemeVariant.Primary)).toEqual( darkTheme.colors.info, ); expect(getVariantColors(darkTheme, ThemeVariant.Accent)).toEqual( darkTheme.colors.accent, ); - expect(getVariantColors(darkTheme, ThemeVariant.Secondary)).toEqual( - darkTheme.colors.accent, - ); }); test("returns different colors for light and dark themes", () => { @@ -72,7 +60,7 @@ describe("Component utility functions", () => { ThemeVariant.Success, ThemeVariant.Warning, ThemeVariant.Error, - ThemeVariant.Info, + ThemeVariant.Primary, ThemeVariant.Accent, ]; diff --git a/src/components/utils.ts b/src/components/utils.ts index 8f3fe7c..c3b6413 100644 --- a/src/components/utils.ts +++ b/src/components/utils.ts @@ -14,10 +14,8 @@ export const enum ThemeVariant { Success = "success", Warning = "warning", Error = "error", - Info = "info", Accent = "accent", Primary = "primary", - Secondary = "secondary", } /** @@ -128,10 +126,8 @@ export const getVariantColors = ( [ThemeVariant.Success]: "success", [ThemeVariant.Warning]: "warning", [ThemeVariant.Error]: "error", - [ThemeVariant.Info]: "info", [ThemeVariant.Primary]: "info", [ThemeVariant.Accent]: "accent", - [ThemeVariant.Secondary]: "accent", }; return themeObj.colors[variantMap[variant]] as VariantColors; }; diff --git a/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.tsx b/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.tsx index 309aa9f..efbda1b 100644 --- a/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.tsx +++ b/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.tsx @@ -157,7 +157,7 @@ export const TimelineTabView: React.FC = ({ @@ -290,7 +290,7 @@ const UserPendingActionCard: React.FC = ({ onClick }) => { return ( - + User action required diff --git a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailCards.tsx b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailCards.tsx index c97043d..ad0e935 100644 --- a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailCards.tsx +++ b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailCards.tsx @@ -51,7 +51,7 @@ export const PlaybookMainDetails: React.FC = ({ Type {playbook_types?.map((type, idx) => ( - + {type} )) || "N/A"} @@ -121,7 +121,7 @@ export const PlaybookAdditionalDetails: React.FC< Impact - {impact} + {impact} )} @@ -144,7 +144,7 @@ export const PlaybookAdditionalDetails: React.FC< {labels.map((label, idx) => ( {label} diff --git a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.tsx b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.tsx index 0338313..2df75c9 100644 --- a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.tsx +++ b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.tsx @@ -69,7 +69,7 @@ export const PlaybookTimeline: React.FC = ({ Type - + {step.type} diff --git a/src/theme/theme.ts b/src/theme/theme.ts index 0616af3..1b64187 100644 --- a/src/theme/theme.ts +++ b/src/theme/theme.ts @@ -69,9 +69,9 @@ export const theme = { }, warning: { bg: "#fff7a3", - border: "#facc15", + border: "#eab308", text: "#ca8a04", - solidBg: "#facc15", + solidBg: "#eab308", solidText: "#ffffff", }, accent: { @@ -278,10 +278,10 @@ export const darkTheme: Theme = { }, warning: { bg: "#2e2a1a", - border: "#facc15", + border: "#eab308", text: "#fde68a", - solidBg: "#facc15", - solidText: "#1f2937", + solidBg: "#eab308", + solidText: "#ffffff", }, accent: { bg: "#2a1f3d", From bd4f61c208a76868b07fbdad84595dcd3a31b656 Mon Sep 17 00:00:00 2001 From: Paolo Scattolin Date: Fri, 16 Oct 2026 13:49:58 +0200 Subject: [PATCH 2/9] Match button borders to their fill in every state --- src/components/Button.tsx | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 342986c..24a8f68 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -71,27 +71,31 @@ export const Button = styled.button.attrs(({ children }) => ({ ${({ $variant = ThemeVariant.Primary, $ghost, theme }) => { const colors = getVariantColors(theme, $variant); - + const darken = (amount: string) => + `color-mix(in srgb, ${colors.solidBg}, ${theme.colors.shade} ${amount})`; + const hoverBg = $ghost + ? colors.solidBg + : darken(theme.interactions.hoverDarken); + const activeBg = darken(theme.interactions.activeDarken); + const disabledBorder = $ghost + ? theme.colors.gray[500] + : theme.colors.gray[300]; + + // A filled button always has a border in the same color as its fill. return ` - border: 1px solid ${colors.border}; + border: 1px solid ${$ghost ? colors.border : colors.solidBg}; background-color: ${$ghost ? "transparent" : colors.solidBg}; color: ${$ghost ? colors.border : colors.solidText}; &:hover:not(:disabled) { - background-color: color-mix( - in srgb, - ${colors.solidBg}, - ${theme.colors.shade} ${theme.interactions.hoverDarken} - ); + border-color: ${hoverBg}; + background-color: ${hoverBg}; } &:active:not(:disabled) { - background-color: color-mix( - in srgb, - ${colors.solidBg}, - ${theme.colors.shade} ${theme.interactions.activeDarken} - ); + border-color: ${activeBg}; + background-color: ${activeBg}; } ${ @@ -105,7 +109,7 @@ export const Button = styled.button.attrs(({ children }) => ({ } &:disabled { - border-color: ${theme.colors.gray[500]}; + border-color: ${disabledBorder}; background-color: ${$ghost ? "transparent" : theme.colors.gray[300]}; opacity: ${theme.interactions.disabledOpacity}; From eaaf5f734e7d12938ca67ff0f85a4575cb83cf95 Mon Sep 17 00:00:00 2001 From: Paolo Scattolin Date: Fri, 16 Oct 2026 13:51:09 +0200 Subject: [PATCH 3/9] Add shared heights for buttons, inputs and selects --- src/components/Button.tsx | 39 +++++------------- src/components/CopyButton.tsx | 2 - src/components/FileDrop.tsx | 1 - src/components/Form.tsx | 41 ++++++++++++++----- src/components/Icon.tsx | 6 --- src/components/Popover.tsx | 7 +--- src/components/Tabs.tsx | 5 +-- src/components/Typography.tsx | 4 -- src/components/utils.ts | 33 +++++++++++++++ src/pages/main-page/MainPage.tsx | 6 +-- .../monitoring-page/ExecutionDetailPage.tsx | 5 +-- .../playbooks-page/PlaybooksPage.tsx | 1 - .../PlaybookDetailPage.tsx | 4 -- src/theme/theme.ts | 6 +++ 14 files changed, 87 insertions(+), 73 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 24a8f68..2bf8a45 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,9 +1,7 @@ -import { Children } from "react"; import styled from "styled-components"; -import { ControlLabel } from "./Typography"; import { ButtonWidth, - getThemeSizeValuesByThemeSize, + getControlSize, getVariantColors, ThemeSize, ThemeVariant, @@ -22,7 +20,7 @@ export interface ButtonProps extends React.ButtonHTMLAttributesComplete Task */ -export const Button = styled.button.attrs(({ children }) => ({ - children: Children.map(children, (child) => - typeof child === "string" || typeof child === "number" - ? {child} - : child, - ), -}))` +export const Button = styled.button` display: inline-flex; align-items: center; justify-content: center; - gap: ${({ $size = ThemeSize.Medium }) => - getThemeSizeValuesByThemeSize($size)}; ${({ $width }) => ($width === ButtonWidth.Full ? "width: 100%;" : "")} ${({ $size = ThemeSize.Medium, theme }) => { - switch ($size) { - case ThemeSize.Small: - return ` - padding: ${theme.spacing.xs} ${theme.spacing.sm}; - `; - case ThemeSize.Medium: - return ` - padding: ${theme.spacing.sm} ${theme.spacing.md}; - `; - case ThemeSize.Large: - default: - return ` - padding: ${theme.spacing.md} ${theme.spacing.lg}; - `; - } + const { height, paddingX, gap } = getControlSize(theme, $size); + return ` + gap: ${gap}; + height: ${height}; + padding: 0 ${paddingX}; + `; }} border-radius: ${({ theme }) => theme.radius.md}; @@ -121,6 +102,8 @@ export const Button = styled.button.attrs(({ children }) => ({ }} font: ${({ theme }) => theme.typography.bodyMedium.font}; + font-size: ${({ $size = ThemeSize.Medium, theme }) => + getControlSize(theme, $size).fontSize}; cursor: pointer; transition: diff --git a/src/components/CopyButton.tsx b/src/components/CopyButton.tsx index b71340c..8880dc7 100644 --- a/src/components/CopyButton.tsx +++ b/src/components/CopyButton.tsx @@ -5,7 +5,6 @@ import toast from "react-hot-toast"; import { formatErrorForToast } from "@/api/utils"; import { Button } from "./Button"; import Icon from "./Icon"; -import { ThemeSize } from "./utils"; export interface CopyButtonProps extends React.ButtonHTMLAttributes { $text: string; @@ -40,7 +39,6 @@ export const CopyButton: React.FC = ({ * */ export const Modal: React.FC & { Header: typeof Header; + Title: typeof Title; Body: typeof Body; Footer: typeof Footer; CloseButton: typeof ModalCloseButton; @@ -208,6 +219,7 @@ export const Modal: React.FC & { }; Modal.Header = Header; +Modal.Title = Title; Modal.Body = Body; Modal.Footer = Footer; Modal.CloseButton = ModalCloseButton; diff --git a/src/components/cards/Card.tsx b/src/components/cards/Card.tsx index d29bc50..6486974 100644 --- a/src/components/cards/Card.tsx +++ b/src/components/cards/Card.tsx @@ -57,7 +57,7 @@ export const CardHeader = styled.div` export const CardTitle = styled.h2` margin: 0; - font: ${({ theme }) => theme.typography.bodyMedium.font}; + font: ${({ theme }) => theme.typography.h2.font}; color: ${({ theme }) => theme.colors.text.primary}; `; /** diff --git a/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx b/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx index d225ccf..37e89b1 100644 --- a/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx +++ b/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx @@ -37,9 +37,8 @@ export const Section = styled.div` `; export const SectionTitle = styled.h4` - font: ${({ theme }) => theme.typography.bodyMedium.font}; + font: ${({ theme }) => theme.typography.h4.font}; color: ${({ theme }) => theme.colors.text.primary}; - font-weight: 600; margin: 0 0 ${({ theme }) => theme.spacing.md} 0; `; diff --git a/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.tsx b/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.tsx index 8563c3a..5ea3135 100644 --- a/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.tsx +++ b/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.tsx @@ -134,7 +134,7 @@ export const ManualActionModal: React.FC = ({ aria-label="Manual action required" > - Manual action required + Manual action required diff --git a/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx b/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx index 42fc25b..b9274b1 100644 --- a/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx +++ b/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx @@ -122,9 +122,8 @@ export const TimelineHeader = styled.div` export const TimelineTitle = styled.h3` margin: 0; - font: ${({ theme }) => theme.typography.body.font}; + font: ${({ theme }) => theme.typography.h3.font}; color: ${({ theme }) => theme.colors.text.primary}; - font-weight: 500; `; export const TimelineMetaBadge = styled.div` diff --git a/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx b/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx index 8d2f5f1..ff5fba0 100644 --- a/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx +++ b/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx @@ -34,9 +34,9 @@ export const PlaybookInfo = styled.div` margin-right: ${({ theme }) => theme.spacing.lg}; `; -export const PlaybookName = styled.h4` +export const PlaybookName = styled.h3` color: ${({ theme }) => theme.colors.text.primary}; - font: ${({ theme }) => theme.typography.h4.font}; + font: ${({ theme }) => theme.typography.h3.font}; `; export const PlaybookDescription = styled.p` diff --git a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx index 5bf7ca2..d68c45b 100644 --- a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx +++ b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx @@ -104,9 +104,9 @@ export const StepCardHeader = styled.div<{ $expanded: boolean }>` } `; -export const StepCardTitle = styled.h5` +export const StepCardTitle = styled.h3` margin: 0; - font: ${({ theme }) => theme.typography.bodyMedium.font}; + font: ${({ theme }) => theme.typography.h3.font}; color: ${({ theme }) => theme.colors.text.primary}; `; diff --git a/src/pages/main-page/playbooks-page/playbook-detail-page/RunPlaybookModal.tsx b/src/pages/main-page/playbooks-page/playbook-detail-page/RunPlaybookModal.tsx index ad82832..ca98c73 100644 --- a/src/pages/main-page/playbooks-page/playbook-detail-page/RunPlaybookModal.tsx +++ b/src/pages/main-page/playbooks-page/playbook-detail-page/RunPlaybookModal.tsx @@ -78,7 +78,7 @@ export const RunPlaybookModal: React.FC = ({ aria-label="Run playbook" > - Run playbook + Run playbook !mutation.isPending && onClose()} disabled={mutation.isPending} diff --git a/src/pages/main-page/playbooks-page/shared.styles.tsx b/src/pages/main-page/playbooks-page/shared.styles.tsx index 0373380..17b43a1 100644 --- a/src/pages/main-page/playbooks-page/shared.styles.tsx +++ b/src/pages/main-page/playbooks-page/shared.styles.tsx @@ -30,7 +30,7 @@ export const EditorTextarea = styled.textarea<{ $hasError: boolean }>` $hasError ? theme.colors.error.border : theme.colors.border.medium}; background-color: ${({ theme }) => theme.colors.background.secondary}; color: ${({ theme }) => theme.colors.text.primary}; - font: ${({ theme }) => theme.typography.code_medium.font}; + font: ${({ theme }) => theme.typography.code.font}; resize: vertical; transition: all ${({ theme }) => theme.transitions.base}; diff --git a/src/theme/theme.ts b/src/theme/theme.ts index 23de124..eac9020 100644 --- a/src/theme/theme.ts +++ b/src/theme/theme.ts @@ -9,10 +9,6 @@ const fonts = { sm: "0.875rem", // 14px base: "1rem", // 16px lg: "1.125rem", // 18px - xl: "1.25rem", // 20px - "2xl": "1.5rem", // 24px - "3xl": "1.875rem", // 30px - "4xl": "2.25rem", // 36px }, weight: { normal: 400, @@ -188,17 +184,14 @@ export const theme = { info: 3000, }, typography: { - h1: { - font: `${fonts.weight.bold} ${fonts.size["4xl"]}/${fonts.lineHeight.tight} ${fonts.family.primary}`, - }, h2: { - font: `${fonts.weight.semibold} ${fonts.size["2xl"]}/${fonts.lineHeight.tight} ${fonts.family.primary}`, + font: `${fonts.weight.semibold} ${fonts.size.lg}/${fonts.lineHeight.tight} ${fonts.family.primary}`, }, h3: { - font: `${fonts.weight.semibold} ${fonts.size.xl}/${fonts.lineHeight.tight} ${fonts.family.primary}`, + font: `${fonts.weight.semibold} ${fonts.size.base}/${fonts.lineHeight.tight} ${fonts.family.primary}`, }, h4: { - font: `${fonts.weight.semibold} ${fonts.size.lg}/${fonts.lineHeight.tight} ${fonts.family.primary}`, + font: `${fonts.weight.semibold} ${fonts.size.sm}/${fonts.lineHeight.tight} ${fonts.family.primary}`, }, body: { font: `${fonts.weight.normal} ${fonts.size.base}/${fonts.lineHeight.normal} ${fonts.family.primary}`, @@ -212,12 +205,9 @@ export const theme = { small: { font: `${fonts.weight.normal} ${fonts.size.xs}/${fonts.lineHeight.tight} ${fonts.family.primary}`, }, - code_small: { + code: { font: `${fonts.weight.normal} ${fonts.size.sm}/${fonts.lineHeight.relaxed} ${fonts.family.mono}`, }, - code_medium: { - font: `${fonts.weight.normal} ${fonts.size.base}/${fonts.lineHeight.relaxed} ${fonts.family.mono}`, - }, }, interactions: { subtleMix: "12%", From f250fe98d38a342509245e769f084d5a0e807eee Mon Sep 17 00:00:00 2001 From: Paolo Scattolin Date: Fri, 16 Oct 2026 13:55:02 +0200 Subject: [PATCH 6/9] Add global CSS reset and remove redundant styles --- src/components/Button.tsx | 1 - src/components/CodeEditor.tsx | 1 - src/components/Containers.tsx | 2 - src/components/FileDrop.tsx | 1 - src/components/Form.tsx | 2 - src/components/Icon.tsx | 4 +- src/components/Modal.tsx | 5 -- src/components/Popover.tsx | 12 ----- src/components/Sidebar.tsx | 1 - src/components/Table.tsx | 2 - src/components/Tabs.tsx | 4 -- src/components/Typography.tsx | 6 --- src/components/cards/Card.tsx | 3 -- src/components/cards/ExpandableCard.tsx | 5 -- src/pages/NotFoundPage.tsx | 5 +- src/pages/main-page/MainPage.styles.tsx | 5 +- .../ExecutionDetailPage.styles.tsx | 1 - .../DetailsTabView.styles.tsx | 12 ----- .../ManualActionModal.styles.tsx | 15 ------ .../TimelineTabView.styles.tsx | 34 ------------ .../PlaybookCreatePage.styles.tsx | 52 ------------------- .../playbooks-page/PlaybooksPage.styles.tsx | 4 +- .../PlaybookTimeline.styles.tsx | 5 +- .../playbooks-page/shared.styles.tsx | 1 - src/theme/GlobalStyles.ts | 31 +++++++++++ 25 files changed, 39 insertions(+), 175 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 2bf8a45..3a2ee6e 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -105,7 +105,6 @@ export const Button = styled.button` font-size: ${({ $size = ThemeSize.Medium, theme }) => getControlSize(theme, $size).fontSize}; - cursor: pointer; transition: background-color ${({ theme }) => theme.transitions.fast}, border-color ${({ theme }) => theme.transitions.fast}, diff --git a/src/components/CodeEditor.tsx b/src/components/CodeEditor.tsx index de8a27b..1e6a745 100644 --- a/src/components/CodeEditor.tsx +++ b/src/components/CodeEditor.tsx @@ -12,7 +12,6 @@ const EditorTextarea = styled.textarea<{ $minHeight?: string; }>` width: 100%; - box-sizing: border-box; min-height: ${({ $minHeight = "400px" }) => $minHeight}; padding: ${({ theme }) => theme.spacing.md}; diff --git a/src/components/Containers.tsx b/src/components/Containers.tsx index 31d90bc..97109ad 100644 --- a/src/components/Containers.tsx +++ b/src/components/Containers.tsx @@ -31,8 +31,6 @@ export const PageContainer = styled.div` background-position: center; background-repeat: no-repeat; `} - - padding: 0; `; export const CenteredCardContent = styled.div` diff --git a/src/components/FileDrop.tsx b/src/components/FileDrop.tsx index 7c19bf9..0aed70d 100644 --- a/src/components/FileDrop.tsx +++ b/src/components/FileDrop.tsx @@ -39,7 +39,6 @@ const DropZone = styled.div<{ `; const DropZoneText = styled.p` - margin: 0; font: ${({ theme }) => theme.typography.body.font}; color: ${({ theme }) => theme.colors.text.secondary}; `; diff --git a/src/components/Form.tsx b/src/components/Form.tsx index 393f325..ecb85cd 100644 --- a/src/components/Form.tsx +++ b/src/components/Form.tsx @@ -17,7 +17,6 @@ interface ControlSizeProps { */ export const Input = styled.input` width: 100%; - box-sizing: border-box; border: 1px solid ${({ theme }) => theme.colors.border.medium}; border-radius: ${({ theme }) => theme.radius.md}; @@ -66,7 +65,6 @@ export const Input = styled.input` */ const StyledSelect = styled.select` width: 100%; - box-sizing: border-box; appearance: none; -webkit-appearance: none; diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 2981827..cd44317 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -29,9 +29,9 @@ const IconWrapper = styled.span<{ vertical-align: middle; height: ${({ $size, $round }) => - $round ? `${$size + $size * 0.5}px` : `${$size}px`}; + $round ? `${$size * 1.5}px` : `${$size}px`}; width: ${({ $size, $round }) => - $round ? `${$size + $size * 0.5}px` : `${$size}px`}; + $round ? `${$size * 1.5}px` : `${$size}px`}; ${({ $round }) => $round ? "border-radius: 50%;" : ""} diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index fcdae0b..62a6ed9 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -118,12 +118,7 @@ const CloseButton = styled.button` display: flex; align-items: center; - border: none; - background: none; - color: ${({ theme }) => theme.colors.primary.text}; - - cursor: pointer; `; /** diff --git a/src/components/Popover.tsx b/src/components/Popover.tsx index 685985a..637c3de 100644 --- a/src/components/Popover.tsx +++ b/src/components/Popover.tsx @@ -12,13 +12,7 @@ const PopoverTrigger = styled.button<{ $anchorName: string }>` padding: ${({ theme }) => `${theme.spacing.sm} ${theme.spacing.md}`}; - border: 0; border-radius: ${({ theme }) => theme.radius.md}; - background: transparent; - - color: inherit; - - cursor: pointer; &:hover { background: ${({ theme }) => theme.colors.info.bg}; @@ -37,7 +31,6 @@ const PopoverContent = styled.div<{ $anchorName: string }>` position-area: block-end span-inline-end; position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline; - box-sizing: border-box; inline-size: max-content; min-inline-size: min(10rem, calc(100vw - 1rem)); max-inline-size: min(18rem, calc(100vw - 1rem)); @@ -74,21 +67,16 @@ const PopoverItemButton = styled.button` align-items: center; gap: ${({ theme }) => theme.spacing.sm}; - box-sizing: border-box; inline-size: 100%; padding: ${({ theme }) => `${theme.spacing.sm} ${theme.spacing.md}`}; - border: 0; border-radius: ${({ theme }) => theme.radius.md}; - background: transparent; color: ${({ theme }) => theme.colors.info.border}; font: ${({ theme }) => theme.typography.caption.font}; text-align: start; - cursor: pointer; - &:hover:not(:disabled) { background: color-mix( in srgb, diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 355eb3f..f73212e 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -91,7 +91,6 @@ export const NavItem = styled.a<{ $isActive?: boolean }>` border-radius: ${({ theme }) => theme.radius.md}; color: ${({ theme }) => theme.colors.text.secondary}; - border: none; padding: ${({ theme }) => `${theme.spacing.sm} ${theme.spacing.lg}`}; gap: ${({ theme }) => theme.spacing.md}; diff --git a/src/components/Table.tsx b/src/components/Table.tsx index a1ba760..d8aa5da 100644 --- a/src/components/Table.tsx +++ b/src/components/Table.tsx @@ -33,8 +33,6 @@ export const Table = styled.table` font: ${({ theme }) => theme.typography.body.font}; color: ${({ theme }) => theme.colors.table.rowText}; - - background: transparent; `; /** diff --git a/src/components/Tabs.tsx b/src/components/Tabs.tsx index 999402e..423e134 100644 --- a/src/components/Tabs.tsx +++ b/src/components/Tabs.tsx @@ -67,9 +67,6 @@ const TabButton = styled.button<{ $active: boolean }>` padding: ${({ theme }) => `${theme.spacing.sm} ${theme.spacing.md}`}; - background: none; - border: none; - border-bottom: 2px solid ${({ theme, $active }) => $active ? theme.colors.primary.main : "transparent"}; @@ -78,7 +75,6 @@ const TabButton = styled.button<{ $active: boolean }>` $active ? theme.colors.primary.main : theme.colors.text.secondary}; font: ${({ theme }) => theme.typography.body.font}; - cursor: pointer; transition: all ${({ theme }) => theme.transitions.base}; &:hover { diff --git a/src/components/Typography.tsx b/src/components/Typography.tsx index 07aa6a2..e1066ef 100644 --- a/src/components/Typography.tsx +++ b/src/components/Typography.tsx @@ -16,7 +16,6 @@ export interface TextProps extends React.HTMLAttributes { export const Text = styled.p` font: ${({ theme }) => theme.typography.body.font}; color: ${({ $color, theme }) => $color || theme.colors.text.secondary}; - margin: 0; `; interface ExpandableTextContainerProps extends React.HTMLAttributes { @@ -40,13 +39,8 @@ const ExpandableTextContainer = styled.div` `; const ExpandToggle = styled.button` - background: none; - border: none; - color: ${({ theme }) => theme.colors.primary.main}; font: ${({ theme }) => theme.typography.small.font}; - cursor: pointer; - padding: 0; margin-top: ${({ theme }) => theme.spacing.xs}; text-decoration: underline; diff --git a/src/components/cards/Card.tsx b/src/components/cards/Card.tsx index 6486974..5d2a28a 100644 --- a/src/components/cards/Card.tsx +++ b/src/components/cards/Card.tsx @@ -11,7 +11,6 @@ import styled from "styled-components"; * */ export const CardContainer = styled.div` - box-sizing: border-box; width: 100%; background: ${({ theme }) => theme.colors.background.primary}; @@ -55,8 +54,6 @@ export const CardHeader = styled.div` * Execution Report */ export const CardTitle = styled.h2` - margin: 0; - font: ${({ theme }) => theme.typography.h2.font}; color: ${({ theme }) => theme.colors.text.primary}; `; diff --git a/src/components/cards/ExpandableCard.tsx b/src/components/cards/ExpandableCard.tsx index 0020f13..420414c 100644 --- a/src/components/cards/ExpandableCard.tsx +++ b/src/components/cards/ExpandableCard.tsx @@ -9,11 +9,6 @@ const ToggleButton = styled.span` display: inline-flex; align-items: center; justify-content: center; - - padding: 0; - border: none; - background: transparent; - color: inherit; `; const ToggleIconWrapper = styled.span<{ $expanded: boolean }>` diff --git a/src/pages/NotFoundPage.tsx b/src/pages/NotFoundPage.tsx index c254474..72b9602 100644 --- a/src/pages/NotFoundPage.tsx +++ b/src/pages/NotFoundPage.tsx @@ -64,7 +64,7 @@ const ErrorContainer = styled.div` box-shadow: ${({ theme }) => theme.shadows.base}; /* Sizing */ - width: 28rem; + width: 32rem; text-align: center; `; @@ -73,14 +73,12 @@ const ErrorCode = styled.h1` font-size: 5rem; font-weight: ${({ theme }) => theme.fonts.weight.bold}; color: ${({ theme }) => theme.colors.primary.main}; - margin: 0; line-height: 1; `; const ErrorTitle = styled.h2` /* Typography */ color: ${({ theme }) => theme.colors.text.primary}; - margin: 0; font: ${({ theme }) => theme.typography.h2.font}; `; @@ -88,7 +86,6 @@ const ErrorDescription = styled.p` /* Typography & Layout */ color: ${({ theme }) => theme.colors.text.secondary}; max-width: 400px; - margin: 0; font: ${({ theme }) => theme.typography.body.font}; `; diff --git a/src/pages/main-page/MainPage.styles.tsx b/src/pages/main-page/MainPage.styles.tsx index 253ea76..5fab7ab 100644 --- a/src/pages/main-page/MainPage.styles.tsx +++ b/src/pages/main-page/MainPage.styles.tsx @@ -21,7 +21,7 @@ export const MainHeader = styled.header` background-color: ${({ theme }) => theme.colors.background.primary}; border-bottom: 1px solid ${({ theme }) => theme.colors.border.light}; padding: ${({ theme }) => theme.spacing.lg} ${({ theme }) => theme.spacing.xl}; - min-height: 2rem; + min-height: 4rem; @media (max-width: 768px) { .mobile-logo { @@ -46,11 +46,8 @@ export const MainContent = styled.main` export const MobileMenuButton = styled.button` display: none; - background: none; - border: none; color: ${({ theme }) => theme.colors.text.primary}; - cursor: pointer; @media (max-width: 768px) { display: flex; diff --git a/src/pages/main-page/monitoring-page/ExecutionDetailPage.styles.tsx b/src/pages/main-page/monitoring-page/ExecutionDetailPage.styles.tsx index 01a32a8..d7152c4 100644 --- a/src/pages/main-page/monitoring-page/ExecutionDetailPage.styles.tsx +++ b/src/pages/main-page/monitoring-page/ExecutionDetailPage.styles.tsx @@ -2,7 +2,6 @@ import styled from "styled-components"; export const DetailsGrid = styled.div` width: 100%; - box-sizing: border-box; display: grid; /* minmax(0, ...) stops long unbreakable values (IDs, commands) from widening a track and pushing content out of the grid */ diff --git a/src/pages/main-page/monitoring-page/details-tab-view/DetailsTabView.styles.tsx b/src/pages/main-page/monitoring-page/details-tab-view/DetailsTabView.styles.tsx index 77063d0..2bea185 100644 --- a/src/pages/main-page/monitoring-page/details-tab-view/DetailsTabView.styles.tsx +++ b/src/pages/main-page/monitoring-page/details-tab-view/DetailsTabView.styles.tsx @@ -6,13 +6,6 @@ export const DetailedContainer = styled.div` gap: ${({ theme }) => theme.spacing.md}; `; -export const DetailedItemHeaderRow = styled.div` - display: flex; - align-items: center; - justify-content: space-between; - gap: ${({ theme }) => theme.spacing.md}; -`; - export const DetailedItemSummary = styled.div` display: flex; gap: ${({ theme }) => theme.spacing.md}; @@ -23,8 +16,6 @@ export const DetailedItemSummary = styled.div` export const CodeBlock = styled.pre` width: 100%; - box-sizing: border-box; - margin: 0; background: ${({ theme }) => theme.colors.background.secondary}; border: 1px solid ${({ theme }) => theme.colors.border.light}; border-radius: ${({ theme }) => theme.radius.md}; @@ -37,7 +28,6 @@ export const CodeBlock = styled.pre` export const VariableListContainer = styled.div` width: 100%; - box-sizing: border-box; display: flex; flex-direction: column; gap: ${({ theme }) => theme.spacing.sm}; @@ -45,7 +35,6 @@ export const VariableListContainer = styled.div` export const VariableItemRow = styled.div` width: 100%; - box-sizing: border-box; display: flex; gap: ${({ theme }) => theme.spacing.md}; padding: ${({ theme }) => theme.spacing.sm} ${({ theme }) => theme.spacing.md}; @@ -58,7 +47,6 @@ export const VariableItemRow = styled.div` export const VariableCellValue = styled.div` width: 100%; min-width: 0; - box-sizing: border-box; font: ${({ theme }) => theme.typography.body.font}; color: ${({ theme }) => theme.colors.text.primary}; word-break: break-word; diff --git a/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx b/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx index 37e89b1..f78a0eb 100644 --- a/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx +++ b/src/pages/main-page/monitoring-page/timeline-tab-view/ManualActionModal.styles.tsx @@ -1,20 +1,6 @@ import { IconInfoCircle } from "@tabler/icons-react"; import styled from "styled-components"; -import { ModalCloseButton } from "@/components"; - -export const StyledCloseButton = styled(ModalCloseButton)` - color: #ffffff; - opacity: 0.9; - font-size: 24px; - font-weight: bold; - transition: opacity 0.2s; - - &:hover { - opacity: 1; - } -`; - export const StepSummary = styled.div` margin-bottom: ${({ theme }) => theme.spacing.lg}; `; @@ -28,7 +14,6 @@ export const StepName = styled.h3` export const StepDescription = styled.p` font: ${({ theme }) => theme.typography.body.font}; color: ${({ theme }) => theme.colors.text.secondary}; - margin: 0; line-height: 1.5; `; diff --git a/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx b/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx index b9274b1..8f7f92c 100644 --- a/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx +++ b/src/pages/main-page/monitoring-page/timeline-tab-view/TimelineTabView.styles.tsx @@ -6,7 +6,6 @@ export const TimelineContainer = styled.div` display: flex; flex-direction: column; gap: ${({ theme }) => theme.spacing.lg}; - padding: 0; `; export const TimelineRow = styled.div<{ $delay?: number }>` @@ -37,26 +36,6 @@ export const TimelineIconContainer = styled.div` z-index: 2; `; -export const SpinnerIconContainer = styled.div<{ - $variant: "primary" | "warning"; -}>` - display: inline-flex; - align-items: center; - justify-content: center; - height: 24px; - width: 24px; - border-radius: 50%; - background-color: ${({ theme, $variant }) => - $variant === "warning" - ? theme.colors.warning.solidBg - : theme.colors.primary.main}; - border: 1px solid - ${({ theme, $variant }) => - $variant === "warning" - ? theme.colors.warning.border - : theme.colors.primary.main}; -`; - export const TimelineLeftCell = styled.div` display: flex; justify-content: flex-end; @@ -80,18 +59,12 @@ export const TimelineItemWrapper = styled.div<{ $side: "left" | "right" }>` export const TimelineItem = styled.div` position: relative; width: fit-content; - padding: 0; - border: none; - background: transparent; box-shadow: none; `; export const UserReplyItem = styled.div` position: relative; width: fit-content; - padding: 0; - border: none; - background: transparent; box-shadow: none; `; @@ -115,13 +88,9 @@ export const TimelineHeader = styled.div` align-items: center; justify-content: space-between; gap: ${({ theme }) => theme.spacing.md}; - padding: 0; - border: none; - background: transparent; `; export const TimelineTitle = styled.h3` - margin: 0; font: ${({ theme }) => theme.typography.h3.font}; color: ${({ theme }) => theme.colors.text.primary}; `; @@ -130,9 +99,6 @@ export const TimelineMetaBadge = styled.div` display: inline-flex; align-items: center; gap: ${({ theme }) => theme.spacing.sm}; - padding: 0; - background: transparent; - border: none; border-radius: 0; font: ${({ theme }) => theme.typography.small.font}; color: ${({ theme }) => theme.colors.text.secondary}; diff --git a/src/pages/main-page/playbooks-page/PlaybookCreatePage.styles.tsx b/src/pages/main-page/playbooks-page/PlaybookCreatePage.styles.tsx index 9afec1f..ebcba65 100644 --- a/src/pages/main-page/playbooks-page/PlaybookCreatePage.styles.tsx +++ b/src/pages/main-page/playbooks-page/PlaybookCreatePage.styles.tsx @@ -21,7 +21,6 @@ export const MethodButton = styled.button<{ $active: boolean }>` $active ? theme.colors.info.bg : theme.colors.background.primary}; color: ${({ theme }) => theme.colors.text.primary}; font: ${({ theme }) => theme.typography.bodyMedium.font}; - cursor: pointer; transition: all ${({ theme }) => theme.transitions.base}; &:hover { @@ -34,54 +33,3 @@ export const MethodButton = styled.button<{ $active: boolean }>` cursor: not-allowed; } `; - -export const DropZone = styled.div<{ - $isDragActive: boolean; - $hasError: boolean; -}>` - border: 2px dashed - ${({ theme, $isDragActive, $hasError }) => - $hasError - ? theme.colors.error.border - : $isDragActive - ? theme.colors.info.border - : theme.colors.border.medium}; - border-radius: ${({ theme }) => theme.radius.md}; - padding: ${({ theme }) => theme.spacing["3xl"]}; - text-align: center; - background-color: ${({ theme, $isDragActive }) => - $isDragActive ? theme.colors.info.bg : theme.colors.background.secondary}; - cursor: pointer; - transition: all ${({ theme }) => theme.transitions.base}; - min-height: 300px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: ${({ theme }) => theme.spacing.md}; - - &:hover { - border-color: ${({ theme }) => theme.colors.info.border}; - background-color: ${({ theme }) => theme.colors.info.bg}; - } -`; - -export const DropZoneText = styled.p` - margin: 0; - font: ${({ theme }) => theme.typography.body.font}; - color: ${({ theme }) => theme.colors.text.secondary}; -`; - -export const DropZoneHint = styled.span` - font: ${({ theme }) => theme.typography.small.font}; - color: ${({ theme }) => theme.colors.text.tertiary}; -`; - -export const FileName = styled.div` - font: ${({ theme }) => theme.typography.bodyMedium.font}; - color: ${({ theme }) => theme.colors.text.primary}; - margin-top: ${({ theme }) => theme.spacing.md}; - display: flex; - align-items: center; - gap: ${({ theme }) => theme.spacing.sm}; -`; diff --git a/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx b/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx index ff5fba0..a3ffdd5 100644 --- a/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx +++ b/src/pages/main-page/playbooks-page/PlaybooksPage.styles.tsx @@ -94,8 +94,8 @@ export const TimelineStep = styled.div<{ $position: "top" | "bottom" }>` `; export const TimelineDot = styled.div<{ $type: string }>` - width: 12px; - height: 12px; + width: 16px; + height: 16px; border: 2px solid ${({ theme }) => theme.colors.background.primary}; border-radius: ${({ theme }) => theme.radius.full}; diff --git a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx index d68c45b..8cfba9e 100644 --- a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx +++ b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookTimeline.styles.tsx @@ -52,8 +52,8 @@ export const TimelineDotCenter = styled.div<{ $type: string }>` left: 50%; top: 24px; transform: translate(-50%, -50%); - width: 16px; - height: 16px; + width: 22px; + height: 22px; border-radius: ${({ theme }) => theme.radius.full}; background-color: ${({ theme, $type }) => { switch ($type) { @@ -105,7 +105,6 @@ export const StepCardHeader = styled.div<{ $expanded: boolean }>` `; export const StepCardTitle = styled.h3` - margin: 0; font: ${({ theme }) => theme.typography.h3.font}; color: ${({ theme }) => theme.colors.text.primary}; `; diff --git a/src/pages/main-page/playbooks-page/shared.styles.tsx b/src/pages/main-page/playbooks-page/shared.styles.tsx index 17b43a1..17f1866 100644 --- a/src/pages/main-page/playbooks-page/shared.styles.tsx +++ b/src/pages/main-page/playbooks-page/shared.styles.tsx @@ -21,7 +21,6 @@ export const EditorContainer = styled.div` export const EditorTextarea = styled.textarea<{ $hasError: boolean }>` width: 100%; - box-sizing: border-box; min-height: 500px; padding: ${({ theme }) => theme.spacing.md}; border-radius: ${({ theme }) => theme.radius.md}; diff --git a/src/theme/GlobalStyles.ts b/src/theme/GlobalStyles.ts index 9710227..948c4a7 100644 --- a/src/theme/GlobalStyles.ts +++ b/src/theme/GlobalStyles.ts @@ -2,10 +2,41 @@ import { createGlobalStyle } from "styled-components"; export const GlobalStyles = createGlobalStyle` *, *::before, *::after { + box-sizing: border-box; margin: 0; padding: 0; } + input, button, textarea, select { + font: inherit; + color: inherit; + } + + button { + background: none; + border: none; + cursor: pointer; + } + + /* Headings are chosen for document structure; their look comes from theme.typography. */ + h1, h2, h3, h4, h5, h6 { + font-size: inherit; + font-weight: inherit; + } + + p, h1, h2, h3, h4, h5, h6 { + overflow-wrap: break-word; + } + + p { + text-wrap: pretty; + } + + img { + display: block; + max-width: 100%; + } + html, body, #root { height: 100%; width: 100%; From 174e41c7acb68c31ee1e8b9496ed8b0f750309de Mon Sep 17 00:00:00 2001 From: Paolo Scattolin Date: Fri, 16 Oct 2026 13:56:07 +0200 Subject: [PATCH 7/9] Fix FileDrop and ExportButton defaults and small layout details --- src/components/ExportButton.tsx | 8 +------- src/components/FileDrop.tsx | 11 ++++++++++- src/pages/main-page/MainPage.styles.tsx | 1 + .../playbook-detail-page/PlaybookDetailPage.tsx | 1 + src/theme/theme.ts | 2 +- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/components/ExportButton.tsx b/src/components/ExportButton.tsx index 769ebe9..b7e93c0 100644 --- a/src/components/ExportButton.tsx +++ b/src/components/ExportButton.tsx @@ -1,6 +1,5 @@ import React from "react"; import { Button } from "./Button"; -import { ButtonWidth } from "./utils"; import { downloadExport, ExportFormat } from "./export"; export type { ExportFormat } from "./export"; @@ -43,12 +42,7 @@ export const ExportButton: React.FC = ({ }; return ( - ); diff --git a/src/components/FileDrop.tsx b/src/components/FileDrop.tsx index 0aed70d..2d188e2 100644 --- a/src/components/FileDrop.tsx +++ b/src/components/FileDrop.tsx @@ -21,7 +21,7 @@ const DropZone = styled.div<{ text-align: center; cursor: pointer; - min-height: 400px; + min-height: 12rem; display: flex; flex-direction: column; align-items: center; @@ -36,6 +36,15 @@ const DropZone = styled.div<{ border-color: ${({ theme }) => theme.colors.info.border}; background-color: ${({ theme }) => theme.colors.info.bg}; } + + /* Disabled state comes from the hidden file input right before the label. */ + input:disabled + label & { + opacity: ${({ theme }) => theme.interactions.disabledOpacity}; + cursor: not-allowed; + + border-color: ${({ theme }) => theme.colors.border.medium}; + background-color: ${({ theme }) => theme.colors.background.secondary}; + } `; const DropZoneText = styled.p` diff --git a/src/pages/main-page/MainPage.styles.tsx b/src/pages/main-page/MainPage.styles.tsx index 5fab7ab..113244a 100644 --- a/src/pages/main-page/MainPage.styles.tsx +++ b/src/pages/main-page/MainPage.styles.tsx @@ -39,6 +39,7 @@ export const MainHeader = styled.header` export const MainContent = styled.main` flex: 1; overflow-y: auto; + scrollbar-gutter: stable; padding: ${({ theme }) => theme.spacing.lg}; min-width: 550px; background-color: ${({ theme }) => theme.colors.secondary.bg}; diff --git a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailPage.tsx b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailPage.tsx index 10a8acf..4a5dc6d 100644 --- a/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailPage.tsx +++ b/src/pages/main-page/playbooks-page/playbook-detail-page/PlaybookDetailPage.tsx @@ -208,6 +208,7 @@ export const PlaybookDetailPage: React.FC = () => { Date: Fri, 16 Oct 2026 13:57:13 +0200 Subject: [PATCH 8/9] Make component prop names consistent --- src/components/Badge.tsx | 10 ++--- src/components/Button.tsx | 13 +++---- src/components/CodeEditor.tsx | 18 ++++----- src/components/CopyButton.tsx | 12 +++--- src/components/ExportButton.tsx | 10 ++--- src/components/FileDrop.tsx | 28 +++++++------- src/components/Link.tsx | 37 ++++++++----------- src/components/RadioGroup.tsx | 20 ++++++---- src/components/Tabs.tsx | 26 ++++++------- src/components/Typography.tsx | 20 +++++----- src/components/utils.ts | 5 --- src/pages/LoginPage.tsx | 9 ++--- src/pages/NotFoundPage.tsx | 5 +-- src/pages/main-page/MainPage.tsx | 5 +-- .../monitoring-page/ExecutionDetailPage.tsx | 4 +- .../details-tab-view/DetailsTabView.tsx | 4 +- .../timeline-tab-view/VariableInputs.tsx | 4 +- .../playbooks-page/PlaybookCreatePage.tsx | 8 ++-- .../playbooks-page/PlaybookEditPage.tsx | 4 +- .../PlaybookDetailPage.tsx | 11 +++--- 20 files changed, 120 insertions(+), 133 deletions(-) diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 343afbb..68260a9 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -4,7 +4,7 @@ import { BadgeShape, ThemeVariant, getVariantColors } from "./utils"; interface BadgeProps extends React.HTMLAttributes { $variant?: ThemeVariant; $shape?: BadgeShape; - $isInteractive?: boolean; + $isClickable?: boolean; } /** @@ -13,13 +13,13 @@ interface BadgeProps extends React.HTMLAttributes { * Supports interactive mode with hover effects for clickable badges. * @param $variant - Visual variant using ThemeVariant enum. * @param $shape - Shape of the badge: BadgeShape.Pill (fully rounded ends) or BadgeShape.Rounded (medium border radius). Defaults to Pill. - * @param $isInteractive - When true, adds hover/active states including translateY animation and shadow for clickable badges. Defaults to false. + * @param $isClickable - When true, adds hover/active states including translateY animation and shadow for clickable badges. Defaults to false. * @example * // Simple success badge * Active * @example * // Interactive warning badge with rounded shape - * Click me + * Click me */ export const Badge = styled.span` display: inline-flex; @@ -42,8 +42,8 @@ export const Badge = styled.span` color: ${({ $variant = ThemeVariant.Primary, theme }) => getVariantColors(theme, $variant).text}; - ${({ $isInteractive, theme }) => - $isInteractive + ${({ $isClickable, theme }) => + $isClickable ? ` cursor: pointer; transition: transform ${theme.transitions.base}, diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 3a2ee6e..0df0780 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,6 +1,5 @@ import styled from "styled-components"; import { - ButtonWidth, getControlSize, getVariantColors, ThemeSize, @@ -11,7 +10,7 @@ export interface ButtonProps extends React.ButtonHTMLAttributesSubmit + * * @example - * // Ghost error button with auto width - * + * // Ghost error button + * * @example * // Large success button * @@ -37,7 +36,7 @@ export const Button = styled.button` align-items: center; justify-content: center; - ${({ $width }) => ($width === ButtonWidth.Full ? "width: 100%;" : "")} + ${({ $fullWidth }) => ($fullWidth ? "width: 100%;" : "")} ${({ $size = ThemeSize.Medium, theme }) => { const { height, paddingX, gap } = getControlSize(theme, $size); diff --git a/src/components/CodeEditor.tsx b/src/components/CodeEditor.tsx index 1e6a745..c645b13 100644 --- a/src/components/CodeEditor.tsx +++ b/src/components/CodeEditor.tsx @@ -43,8 +43,8 @@ const EditorTextarea = styled.textarea<{ export interface CodeEditorProps extends React.HTMLAttributes { $value: string; $onChange: (value: string) => void; - $placeholder?: string; - $disabled?: boolean; + placeholder?: string; + disabled?: boolean; $hasError?: boolean; $minHeight?: string; } @@ -54,22 +54,22 @@ export interface CodeEditorProps extends React.HTMLAttributes { * It is a controlled component and relies on `$value` / `$onChange` for state. * @param $value - Current text content of the editor. * @param $onChange - Callback invoked with new text when the content changes. - * @param $placeholder - Optional placeholder text when editor is empty. - * @param $disabled - When true the editor is non-editable and shows disabled visuals. + * @param placeholder - Optional placeholder text when editor is empty. + * @param disabled - When true the editor is non-editable and shows disabled visuals. * @param $hasError - When true the editor displays an error border state. * @param $minHeight - Optional CSS min-height for the editor area (defaults to `400px`). * @example: * */ export const CodeEditor: React.FC = ({ $value, $onChange, - $placeholder, - $disabled, + placeholder, + disabled, $hasError, $minHeight, ...rest @@ -79,8 +79,8 @@ export const CodeEditor: React.FC = ({ $onChange(e.target.value)} - placeholder={$placeholder} - disabled={$disabled} + placeholder={placeholder} + disabled={disabled} $hasError={$hasError} $minHeight={$minHeight} /> diff --git a/src/components/CopyButton.tsx b/src/components/CopyButton.tsx index 8880dc7..5aa0851 100644 --- a/src/components/CopyButton.tsx +++ b/src/components/CopyButton.tsx @@ -7,28 +7,28 @@ import { Button } from "./Button"; import Icon from "./Icon"; export interface CopyButtonProps extends React.ButtonHTMLAttributes { - $text: string; + $value: string; } /** * Small icon-only button to copy text to clipboard. - * @param $text - The text to copy to clipboard. + * @param $value - The text to copy to the clipboard. * @param title - The tooltip/title for the button (default: "Copy"). * @param disabled - Whether the button is disabled (default: false). * @example - * + * */ export const CopyButton: React.FC = ({ - $text, + $value, disabled = false, ...rest }) => { const handleClick = async (e: React.MouseEvent) => { e.stopPropagation(); - if (disabled || !$text) return; + if (disabled || !$value) return; try { - await navigator.clipboard.writeText($text); + await navigator.clipboard.writeText($value); toast.success("Copied to clipboard"); } catch (err) { toast.error(formatErrorForToast(err, "Failed to copy to clipboard")); diff --git a/src/components/ExportButton.tsx b/src/components/ExportButton.tsx index b7e93c0..01cf1f2 100644 --- a/src/components/ExportButton.tsx +++ b/src/components/ExportButton.tsx @@ -7,7 +7,7 @@ export type { ExportFormat } from "./export"; export interface ExportButtonProps extends React.ComponentProps { $data: unknown; $format: ExportFormat; - $filename?: string; + $fileName?: string; $onSuccess?: () => void; $onError?: (err: unknown) => void; } @@ -16,17 +16,17 @@ export interface ExportButtonProps extends React.ComponentProps { * ExportButton component to export data as a file in various formats. * * @param $data - The value to export. Can be any serializable value for json or a string for txt. - * @param $filename - Optional suggested filename. If not provided, defaults to export-.. + * @param $fileName - Optional suggested filename. If not provided, defaults to export-.. * @param $format - **(required)** Selects how to transform data into a Blob. Can be 'json', 'txt', or a custom function returning { blob, filename? }. * @param $onSuccess - Optional callback invoked after successful export. * @param $onError - Optional callback invoked if export fails. * @example - * Export + * Export */ export const ExportButton: React.FC = ({ $data, $format, - $filename, + $fileName, $onSuccess, $onError, children, @@ -34,7 +34,7 @@ export const ExportButton: React.FC = ({ }) => { const handleClick = () => { try { - downloadExport($data, $format, $filename); + downloadExport($data, $format, $fileName); if ($onSuccess) $onSuccess(); } catch (err) { if ($onError) $onError(err); diff --git a/src/components/FileDrop.tsx b/src/components/FileDrop.tsx index 2d188e2..fa7f2d4 100644 --- a/src/components/FileDrop.tsx +++ b/src/components/FileDrop.tsx @@ -72,8 +72,8 @@ export interface FileDropProps extends React.HTMLAttributes { $onChange: (content: string, filename?: string) => void; $onRemove?: () => void; $accept?: string; - $disabled?: boolean; - $error?: string; + disabled?: boolean; + $hasError?: boolean; } /** @@ -85,8 +85,8 @@ export interface FileDropProps extends React.HTMLAttributes { * @param $onChange - Called with (content, filename) when a file is selected or dropped. * @param $onRemove - Optional callback when the remove button is clicked. * @param $accept - File extension filter (e.g. ".json"). Defaults to ".json". - * @param $disabled - When true, disables interactions. - * @param $error - Optional error message to display under the drop zone. + * @param disabled - When true, disables interactions. + * @param $hasError - When true the drop zone shows an error border. The page shows the error message itself. * @example * setFile(content)} $accept=".json" /> */ @@ -95,8 +95,8 @@ export const FileDrop: React.FC = ({ $onChange, $onRemove, $accept = ".json", - $disabled, - $error, + disabled, + $hasError = false, ...rest }) => { const [isDragActive, setIsDragActive] = useState(false); @@ -122,7 +122,7 @@ export const FileDrop: React.FC = ({ (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); - if ($disabled) return; + if (disabled) return; setIsDragActive(false); const files = e.dataTransfer.files; if (files && files.length > 0) { @@ -134,17 +134,17 @@ export const FileDrop: React.FC = ({ readFile(file); } }, - [$accept, $disabled, $onChange, readFile], + [$accept, disabled, $onChange, readFile], ); const handleDragOver = useCallback( (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); - if ($disabled) return; + if (disabled) return; setIsDragActive(true); }, - [$disabled], + [disabled], ); const handleDragLeave = useCallback( @@ -179,18 +179,18 @@ export const FileDrop: React.FC = ({ accept={$accept} onChange={handleFileSelect} style={{ display: "none" }} - disabled={$disabled} + disabled={disabled} />