fix: ClickStack and HyperDX color token improvements (#1988)

## Summary

- **Link colors**: Override `--mantine-color-anchor` in ClickStack so links use blue in light mode and yellow in dark mode instead of Mantine's default primary color derivation.
- **Checkbox & Radio**: Use `vars` overrides to apply ClickStack accent color to active checkboxes and radios, with contrasting icon colors for readability in both themes.
- **Slider styling**: Replace inline `styles` with semantic tokens (`--color-slider-bar`, `--color-slider-thumb`, `--color-slider-dot`, etc.) and CSS modules for consistent 6px solid dot marks and token-based thumb/mark colors across both ClickStack and HyperDX themes.
- **Subtle Button variant**: Add `variant="subtle"` support to `Button` in both themes (transparent background, hover highlight, standard text color).
- **Docs**: Update `code_style.md` to document `variant="subtle"` as accepted for both `Button` and `ActionIcon`.

### Before

<img width="3896" height="1296" alt="image" src="https://github.com/user-attachments/assets/5a2f109a-88e3-46a1-8e38-95d51dfd5a6b" />

<img width="1806" height="2570" alt="image" src="https://github.com/user-attachments/assets/70cf6786-a487-477b-868f-7f2a18746053" />



### After

<img width="3596" height="1358" alt="image" src="https://github.com/user-attachments/assets/0ad3b885-e6b8-4edd-aade-97516740ed6b" />

<img width="1874" height="2684" alt="image" src="https://github.com/user-attachments/assets/fa00f2cc-49f8-4bd3-8379-3665b760bd4e" />


## Test plan

- [ ] Verify links are blue in ClickStack light mode and yellow in dark mode
- [ ] Verify checkboxes and radio buttons use the accent color when active in both themes
- [ ] Verify checkbox icon is dark in dark mode for contrast
- [ ] Verify slider marks are solid 6px dots, with correct colors in both modes
- [ ] Verify slider thumb uses theme-appropriate colors
- [ ] Verify `<Button variant="subtle">` renders correctly in both themes
- [ ] Verify no visual regressions in HyperDX theme slider styling
This commit is contained in:
Elizabet Oliveira 2026-03-25 19:46:59 +00:00 committed by GitHub
parent 1fb8e35501
commit 6c347a52c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 118 additions and 18 deletions

View file

@ -0,0 +1,10 @@
---
"@hyperdx/app": patch
---
fix: ClickStack and HyperDX color token improvements
- Fix link colors in ClickStack (blue in light mode, yellow in dark mode)
- Override checkbox and radio button colors to use accent color with contrasting icons
- Restyle slider marks as solid 6px dots with semantic color tokens
- Add subtle Button variant to both themes

View file

@ -37,7 +37,7 @@ The project uses Mantine UI with **custom variants** defined in `packages/app/sr
| `variant="secondary"` | Secondary actions (Cancel, Clear, auxiliary actions) | `<Button variant="secondary">Cancel</Button>` |
| `variant="danger"` | Destructive actions (Delete, Remove, Rotate API Key) | `<Button variant="danger">Delete</Button>` |
| `variant="link"` | Link-style actions with no background or border (View Details, navigation-style CTAs) | `<Button variant="link">View Details</Button>` |
| `variant="subtle"` | **ActionIcon only.** Transparent background with hover highlight; for toolbar/utility icons that shouldn't draw attention until hovered (collapse toggles, close buttons, auxiliary controls) | `<ActionIcon variant="subtle">...</ActionIcon>` |
| `variant="subtle"` | Transparent background with hover highlight; for toolbar/utility controls that shouldn't draw attention until hovered (collapse toggles, close buttons, auxiliary actions) | `<Button variant="subtle">Filter</Button>` |
### Correct Usage
@ -45,6 +45,7 @@ The project uses Mantine UI with **custom variants** defined in `packages/app/sr
<Button variant="primary">Save</Button>
<Button variant="secondary">Cancel</Button>
<Button variant="danger">Delete</Button>
<Button variant="subtle">Filter</Button>
<Button variant="link">View Details</Button>
<ActionIcon variant="primary">...</ActionIcon>
<ActionIcon variant="secondary">...</ActionIcon>
@ -70,7 +71,7 @@ The project uses Mantine UI with **custom variants** defined in `packages/app/sr
**Link variant details**: Renders with no background, no border, and muted text color. On hover, text brightens to full contrast. Use for link-style CTAs that should blend into surrounding content (e.g., "View Details", "View Full Trace").
**Subtle variant details (ActionIcon only)**: Transparent background with standard text color. On hover, a subtle background highlight appears (`--color-bg-hover`). This is the **default** ActionIcon variant. Use for toolbar icons, collapse toggles, close buttons, and utility controls that should stay unobtrusive but reveal interactivity on hover. Unlike `link`, `subtle` shows a hover background rather than changing text color.
**Subtle variant details**: Transparent background with standard text color. On hover, a subtle background highlight appears (`--color-bg-hover`). This is the **default** ActionIcon variant. Use for toolbar icons, collapse toggles, close buttons, and utility controls that should stay unobtrusive but reveal interactivity on hover. Unlike `link`, `subtle` shows a hover background rather than changing text color.
**Note**: `variant="filled"` is still valid for **form inputs** (Select, TextInput, etc.), just not for Button/ActionIcon.

View file

@ -74,7 +74,7 @@
/* Click UI Global Tokens - Dark Mode Values */
--click-global-color-stroke-default: #323232;
--click-global-color-accent-default: #faff69;
--click-global-color-accent-default: var(--palette-brand-300);
--click-global-color-background-default: #1f1f1c;
--click-global-color-background-muted: #282828;
--click-global-color-text-default: #fff;
@ -151,6 +151,13 @@
--color-outline-focus: var(--mantine-primary-color-filled);
--input-bd-focus: var(--mantine-primary-color-filled);
/* Slider */
--color-slider-bar: var(--click-global-color-accent-default);
--color-slider-thumb: var(--click-global-color-accent-default);
--color-slider-thumb-border: var(--click-global-color-accent-default);
--color-slider-dot: var(--click-global-color-text-muted);
--color-slider-dot-active: var(--mantine-color-yellow-8);
/* Code / Misc UI */
--color-bg-code: #1d1e30;
--color-border-code: #4d4f66;
@ -195,7 +202,10 @@
/* Mantine Overrides */
--mantine-color-body: var(--color-bg-body) !important;
--mantine-color-text: var(--color-text);
--mantine-color-text: var(--color-text) !important;
--mantine-color-anchor: var(
--click-global-color-text-link-default
) !important;
/* Tabler icons default stroke width - Set default stroke-width to 1.5 for Tabler icons (instead of default 2). This only affects SVGs that have a stroke attribute set. Can be overridden on individual icons by setting strokeWidth prop */
.tabler-icon {
@ -348,6 +358,13 @@
--color-state-focus: #ced4da;
--color-outline-focus: var(--mantine-primary-color-filled);
/* Slider */
--color-slider-bar: var(--click-global-color-accent-default);
--color-slider-thumb: var(--click-global-color-accent-default);
--color-slider-thumb-border: var(--click-global-color-accent-default);
--color-slider-dot: var(--click-global-color-text-muted);
--color-slider-dot-active: var(--mantine-color-gray-3);
/* Code / Misc UI */
--color-bg-code: var(--click-global-color-background-muted);
--color-border-code: #dee2e6;
@ -385,8 +402,11 @@
--color-chart-error-highlight: #ffa090;
/* Mantine Overrides */
--mantine-color-body: var(--color-bg-body);
--mantine-color-text: var(--color-text);
--mantine-color-body: var(--color-bg-body) !important;
--mantine-color-text: var(--color-text) !important;
--mantine-color-anchor: var(
--click-global-color-text-link-default
) !important;
/* Tabler icons default stroke width - Set default stroke-width to 1.5 for Tabler icons (instead of default 2). This only affects SVGs that have a stroke attribute set. Can be overridden on individual icons by setting strokeWidth prop */
.tabler-icon {

View file

@ -1,8 +1,10 @@
import {
ActionIcon,
Button,
Checkbox,
MantineTheme,
MantineThemeOverride,
Radio,
rem,
SegmentedControl,
Select,
@ -13,6 +15,7 @@ import {
} from '@mantine/core';
import variantClasses from '../../../../styles/variants.module.scss';
import componentClasses from '../components.module.scss';
/**
* ClickStack Theme
@ -104,13 +107,14 @@ export const makeTheme = ({
},
}),
Slider: Slider.extend({
styles: {
bar: {
backgroundColor: 'var(--color-bg-brand)',
},
thumb: {
borderColor: 'var(--color-bg-brand)',
vars: () => ({
root: {
'--slider-color': 'var(--color-slider-bar)',
},
}),
classNames: {
thumb: componentClasses.sliderThumb,
mark: componentClasses.sliderMark,
},
}),
Input: {
@ -256,6 +260,13 @@ export const makeTheme = ({
baseVars['--button-color'] = 'var(--mantine-color-red-light-color)';
}
if (props.variant === 'subtle') {
baseVars['--button-bg'] = 'transparent';
baseVars['--button-hover'] = 'var(--color-bg-hover)';
baseVars['--button-color'] = 'var(--color-text)';
baseVars['--button-bd'] = 'none';
}
if (props.variant === 'link') {
baseVars['--button-bg'] = 'transparent';
baseVars['--button-hover'] = 'transparent';
@ -284,6 +295,23 @@ export const makeTheme = ({
},
}),
}),
Checkbox: Checkbox.extend({
vars: () => ({
root: {
'--checkbox-color': 'var(--click-global-color-accent-default)',
'--checkbox-icon-color':
'var(--click-global-color-background-default)',
},
}),
}),
Radio: Radio.extend({
vars: () => ({
root: {
'--radio-color': 'var(--click-global-color-accent-default)',
'--radio-icon-color': 'var(--click-global-color-background-default)',
},
}),
}),
ActionIcon: ActionIcon.extend({
defaultProps: {
variant: 'subtle',

View file

@ -0,0 +1,18 @@
.sliderThumb {
background-color: var(--color-slider-thumb);
border-color: var(--color-slider-thumb-border);
}
.sliderMark {
width: 6px;
height: 6px;
border-radius: 100%;
transform: translateX(1px) translateY(1px);
border-color: var(--color-slider-dot);
background-color: var(--color-slider-dot);
&[data-filled] {
border-color: var(--color-slider-dot-active);
background-color: var(--color-slider-dot-active);
}
}

View file

@ -71,6 +71,13 @@
--color-state-focus: var(--mantine-color-dark-4);
--color-outline-focus: var(--mantine-color-green-4);
/* Slider */
--color-slider-bar: var(--mantine-color-green-4);
--color-slider-thumb: var(--mantine-color-green-4);
--color-slider-thumb-border: var(--mantine-color-green-4);
--color-slider-dot: var(--mantine-color-dark-2);
--color-slider-dot-active: var(--mantine-color-green-8);
/* Code / Misc UI */
--color-bg-code: var(--mantine-color-dark-8);
--color-border-code: var(--mantine-color-dark-6);
@ -178,6 +185,13 @@
--color-state-focus: var(--mantine-color-dark-5);
--color-outline-focus: var(--mantine-color-green-8);
/* Slider */
--color-slider-bar: var(--mantine-color-green-8);
--color-slider-thumb: var(--mantine-color-green-8);
--color-slider-thumb-border: var(--mantine-color-green-8);
--color-slider-dot: var(--mantine-color-gray-6);
--color-slider-dot-active: var(--mantine-color-gray-1);
/* Code / Misc UI - inverted */
--color-bg-code: var(--mantine-color-dark-1);
--color-border-code: var(--mantine-color-dark-3);

View file

@ -14,6 +14,7 @@ import {
import focusClasses from '../../../../styles/focus.module.scss';
import variantClasses from '../../../../styles/variants.module.scss';
import componentClasses from '../components.module.scss';
export const makeTheme = ({
fontFamily = '"IBM Plex Sans", monospace',
@ -120,13 +121,14 @@ export const makeTheme = ({
},
}),
Slider: Slider.extend({
styles: {
bar: {
backgroundColor: 'var(--color-bg-brand)',
},
thumb: {
borderColor: 'var(--color-bg-brand)',
vars: () => ({
root: {
'--slider-color': 'var(--color-slider-bar)',
},
}),
classNames: {
thumb: componentClasses.sliderThumb,
mark: componentClasses.sliderMark,
},
}),
Input: {
@ -272,6 +274,13 @@ export const makeTheme = ({
baseVars['--button-color'] = 'var(--mantine-color-red-light-color)';
}
if (props.variant === 'subtle') {
baseVars['--button-bg'] = 'transparent';
baseVars['--button-hover'] = 'var(--color-bg-hover)';
baseVars['--button-color'] = 'var(--color-text)';
baseVars['--button-bd'] = 'none';
}
if (props.variant === 'link') {
baseVars['--button-bg'] = 'transparent';
baseVars['--button-hover'] = 'transparent';