mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
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:
parent
1fb8e35501
commit
6c347a52c8
7 changed files with 118 additions and 18 deletions
10
.changeset/clickstack-color-tokens.md
Normal file
10
.changeset/clickstack-color-tokens.md
Normal 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
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
18
packages/app/src/theme/themes/components.module.scss
Normal file
18
packages/app/src/theme/themes/components.module.scss
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
Loading…
Reference in a new issue