-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Created new base theme for Iris grid and mapped existing styles to it - Added color palettes to styleguide - IrisGrid now creates and resolves css variables when creating the default theme **Testing** - Easiest way to see the new color palettes is in the styleguide. - Iris Grid should look as it did before except for a few cases where the new color palette doesn't exactly align with the old one. aka. a color may have a subtle change in saturation but there shouldn't be any changes to the visual color. Current mapping of Bootstrap gray palette to new `--dh-color-gray` vars based on Don's POC. The Bootstrap variables will get updated in a future PR to pull from the new vars, but this is how things line up right now: <img width="350" alt="image" src="https://github.com/deephaven/web-client-ui/assets/1900643/ea9d3ea9-427c-4382-95ed-f0c47a16cd29"> BREAKING CHANGE: Enterprise will need ThemeProvider for the css variables to be available
- Loading branch information
Showing
22 changed files
with
758 additions
and
285 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
packages/code-studio/src/styleguide/ThemeColors.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
.themeColors { | ||
--swatch-height: 35px; | ||
--column-gap: 14px; | ||
|
||
display: grid; | ||
column-gap: var(--column-gap); | ||
// Add as many columns as will fit in the container each 210px wide. | ||
// Row height is set to the swatch height (35px) by dynamic `grid-row` style | ||
// attributes set in ThemeColors.tsx. | ||
grid-template-columns: repeat(auto-fit, 210px); | ||
|
||
.label { | ||
display: flex; | ||
align-items: end; | ||
justify-content: space-between; | ||
gap: 4px; | ||
height: var(--swatch-height); | ||
text-transform: capitalize; | ||
white-space: nowrap; | ||
} | ||
|
||
.swatch { | ||
display: flex; | ||
align-items: center; | ||
height: var(--swatch-height); | ||
justify-content: space-between; | ||
padding: 0 10px; | ||
|
||
span { | ||
overflow: hidden; | ||
white-space: nowrap; | ||
text-overflow: ellipsis; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
import React, { useMemo } from 'react'; | ||
import { Tooltip } from '@deephaven/components'; | ||
import { ColorUtils } from '@deephaven/utils'; | ||
import palette from '@deephaven/components/src/theme/theme-dark/theme-dark-palette.css?inline'; | ||
import semantic from '@deephaven/components/src/theme/theme-dark/theme-dark-semantic.css?inline'; | ||
import semanticEditor from '@deephaven/components/src/theme/theme-dark/theme-dark-semantic-editor.css?inline'; | ||
import semanticGrid from '@deephaven/components/src/theme/theme-dark/theme-dark-semantic-grid.css?inline'; | ||
import styles from './ThemeColors.module.scss'; | ||
|
||
// Group names are extracted from var names via a regex capture group. Most of | ||
// them work pretty well, but some need to be remapped to a more appropriate | ||
// group. | ||
const reassignVarGroups: Record<string, string> = { | ||
'--dh-color-black': 'gray', | ||
'--dh-color-white': 'gray', | ||
// Editor | ||
'--dh-color-editor-bg': 'editor', | ||
'--dh-color-editor-fg': 'editor', | ||
'--dh-color-editor-context-menu-bg': 'menus', | ||
'--dh-color-editor-context-menu-fg': 'menus', | ||
'--dh-color-editor-menu-selection-bg': 'menus', | ||
// Grid | ||
'--dh-color-grid-bg': 'grid', | ||
'--dh-color-grid-number-positive': 'Data Types', | ||
'--dh-color-grid-number-negative': 'Data Types', | ||
'--dh-color-grid-number-zero': 'Data Types', | ||
'--dh-color-grid-date': 'Data Types', | ||
'--dh-color-grid-string-null': 'Data Types', | ||
}; | ||
|
||
// Mappings of variable groups to rename | ||
const renameGroups = { | ||
editor: { | ||
line: 'editor', | ||
comment: 'code', | ||
string: 'code', | ||
number: 'code', | ||
delimiter: 'code', | ||
identifier: 'code', | ||
keyword: 'code', | ||
operator: 'code', | ||
storage: 'code', | ||
predefined: 'code', | ||
selection: 'state', | ||
focus: 'state', | ||
}, | ||
grid: { data: 'Data Bars', context: 'Context Menu' }, | ||
}; | ||
|
||
export function ThemeColors(): JSX.Element { | ||
const swatchDataGroups = useMemo( | ||
() => ({ | ||
'Theme Color Palette': buildColorGroups(palette, 1), | ||
'Semantic Colors': buildColorGroups(semantic, 1), | ||
'Editor Colors': buildColorGroups(semanticEditor, 2, renameGroups.editor), | ||
'Grid Colors': buildColorGroups(semanticGrid, 2, renameGroups.grid), | ||
}), | ||
[] | ||
); | ||
|
||
return ( | ||
<> | ||
{Object.entries(swatchDataGroups).map(([label, data]) => ( | ||
<div key={label}> | ||
<h2 className="ui-title">{label}</h2> | ||
<div className={styles.themeColors}> | ||
{Object.entries(data).map(([group, swatchData]) => ( | ||
<div | ||
key={group} | ||
// This is the secret sauce for filling columns. The height of | ||
// each swatch group spans multiple rows (the number of swatches | ||
// + 1 for the label). This causes the grid to create rows | ||
// based on the swatch height (35px), and each swatch (also the | ||
// group label) neatly fits in a grid cell. The grid will put a | ||
// group in each column and then wrap back around to the first | ||
// until all groups are placed. | ||
style={{ gridRow: `span ${swatchData.length + 1}` }} | ||
> | ||
<span className={styles.label}>{group}</span> | ||
{swatchData.map(({ name, value }) => ( | ||
<div | ||
key={name} | ||
className={styles.swatch} | ||
style={{ | ||
backgroundColor: value, | ||
color: `var(--dh-color-${contrastColor(value)})`, | ||
}} | ||
> | ||
<Tooltip> | ||
<div>{name}</div> | ||
<div>{value}</div> | ||
<div> | ||
{ColorUtils.normalizeCssColor(value).replace( | ||
/^(#[a-f0-9]{6})ff$/, | ||
'$1' | ||
)} | ||
</div> | ||
</Tooltip> | ||
<span>{name.replace('--dh-color-', '')}</span> | ||
{name.endsWith('-hue') ? <span>{value}</span> : null} | ||
</div> | ||
))} | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
))} | ||
</> | ||
); | ||
} | ||
|
||
export default ThemeColors; | ||
|
||
/** Return black or white contrast color */ | ||
function contrastColor(color: string): 'black' | 'white' { | ||
const rgba = ColorUtils.parseRgba(ColorUtils.asRgbOrRgbaString(color) ?? ''); | ||
if (rgba == null || rgba.a < 0.5) { | ||
return 'white'; | ||
} | ||
|
||
const { r, g, b } = rgba; | ||
const y = (299 * r + 587 * g + 114 * b) / 1000; | ||
return y >= 128 ? 'black' : 'white'; | ||
} | ||
|
||
/** Extract an array of { name, value } pairs for css variables in a given string */ | ||
function extractColorVars( | ||
styleText: string | ||
): { name: string; value: string }[] { | ||
const computedStyle = getComputedStyle(document.documentElement); | ||
|
||
return styleText | ||
.split('\n') | ||
.map(line => /^\s{2}(--dh-color-(?:[^:]+))/.exec(line)?.[1]) | ||
.filter(Boolean) | ||
.map(varName => | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
({ name: varName!, value: computedStyle.getPropertyValue(varName!)! }) | ||
); | ||
} | ||
|
||
/** Group color data based on capture group value */ | ||
function buildColorGroups( | ||
styleText: string, | ||
captureGroupI: number, | ||
groupRemap: Record<string, string> = {} | ||
): Record<string, { name: string; value: string }[]> { | ||
const swatchData = extractColorVars(styleText); | ||
|
||
const groupData = swatchData.reduce( | ||
(acc, { name, value }) => { | ||
const match = /^--dh-color-([^-]+)(?:-([^-]+))?/.exec(name); | ||
let group = | ||
reassignVarGroups[name] ?? | ||
match?.[captureGroupI] ?? | ||
match?.[1] ?? | ||
'???'; | ||
|
||
group = groupRemap[group] ?? group; | ||
|
||
if (acc[group] == null) { | ||
acc[group] = []; | ||
} | ||
|
||
// Add a spacer for black / white | ||
if (name === '--dh-color-black') { | ||
acc[group].push({ name: '', value: '' }); | ||
} | ||
|
||
acc[group].push({ name, value }); | ||
|
||
return acc; | ||
}, | ||
{} as Record<string, { name: string; value: string }[]> | ||
); | ||
|
||
return groupData; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.