Skip to content

Commit

Permalink
feat(cli, themebuilder): invalidate systemcolors as name for color (#…
Browse files Browse the repository at this point in the history
…3194)

Co-authored-by: Michael Marszalek <mimarz@gmail.com>
  • Loading branch information
Barsnes and mimarz authored Feb 26, 2025
1 parent 7f268d6 commit 8e91a6a
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-singers-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@digdir/designsystemet": patch
---

Invalidate system colors as color names (success, danger, warning, info, blue, green, orange, red, purple)
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const TableCard = () => {
</Search>
</div>
</div>
<Table data-size='sm' border>
<Table data-size='sm' border data-color='neutral'>
<Table.Head>
<Table.Row>
<Table.HeaderCell onClick={function Ya() {}} sort='none'>
Expand Down
35 changes: 31 additions & 4 deletions apps/theme/components/Sidebar/ColorPane/ColorPane.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RESERVED_COLORS } from '@digdir/designsystemet';
import {
Button,
Heading,
Expand All @@ -10,6 +11,7 @@ import { ColorPicker, type IColor } from 'react-color-palette';
import { useThemeStore } from '../../../store';

import cl from 'clsx/lite';
import { useState } from 'react';
import classes from './ColorPane.module.css';

type ColorPaneProps = {
Expand Down Expand Up @@ -38,13 +40,36 @@ export const ColorPane = ({
colorType,
}: ColorPaneProps) => {
const mainColors = useThemeStore((state) => state.colors.main);
const [colorError, setColorError] = useState('');

const disableRemoveButton = colorType === 'main' && mainColors.length === 1;

const getHeading = () => {
const t = colorType === 'main' ? 'hovedfarge' : 'støttefarge';
return type === 'addColor' ? 'Legg til ' + t : 'Rediger farge';
};

const checkNameIsValid = () => {
if (name === '') {
setColorError('Navnet på fargen kan ikke være tomt');
return false;
}

if (RESERVED_COLORS.includes(name.toLowerCase())) {
setColorError(
'Navnet på fargen kan ikke være det samme som våre systemfarger',
);
return false;
}
setColorError('');
return true;
};

const closeTab = () => {
setColorError('');
onClose();
};

return (
<div
className={cl(classes.colorPage, type.includes('Color') && classes.show)}
Expand All @@ -53,7 +78,7 @@ export const ColorPane = ({
<Button
data-size='sm'
variant='tertiary'
onClick={() => onClose()}
onClick={closeTab}
className={classes.back}
>
<ChevronLeftIcon title='a11y-title' fontSize='1.5rem' /> Gå tilbake
Expand Down Expand Up @@ -102,6 +127,8 @@ export const ColorPane = ({
.toLowerCase();
setName(value);
}}
onBlur={checkNameIsValid}
error={colorError}
/>
)}
<div className={classes.label}>Farge</div>
Expand All @@ -122,6 +149,8 @@ export const ColorPane = ({
data-size='sm'
color='neutral'
onClick={() => {
/* Check here as well to disable sending new color */
if (!checkNameIsValid()) return;
onPrimaryClicked(color.hex, name);
}}
>
Expand All @@ -132,9 +161,7 @@ export const ColorPane = ({
data-size='sm'
color='neutral'
variant='secondary'
onClick={() => {
onClose();
}}
onClick={closeTab}
>
Avbryt
</Button>
Expand Down
22 changes: 20 additions & 2 deletions packages/cli/bin/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as R from 'ramda';
import { z } from 'zod';
import { convertToHex } from '../src/colors/index.js';
import { RESERVED_COLORS } from '../src/colors/theme.js';
import { cliOptions } from '../src/tokens/create.js';

export function mapPathToOptionName(path: (string | number)[]) {
Expand All @@ -20,14 +21,31 @@ const hexPatterns = [
`#[0-9a-fA-F]{6}`,
`#[0-9a-fA-F]{8}`,
];
const reservedColorsPattern = `^(?!(?:${RESERVED_COLORS.join('|')})$)`;

export const colorRegex = new RegExp(`^${hexPatterns.join('|')}$`);

const colorSchema = z
.string({ description: 'A hex color, which is used for creating a color scale' })
.string({
description: `A hex color, which is used for creating a color scale. Invalid color names: ${RESERVED_COLORS.join(', ')}`,
})
.regex(colorRegex)
.transform(convertToHex);
const colorCategorySchema = z.record(colorSchema, { description: 'One or more color definitions' });

const colorCategorySchema = z
.record(
z.string().regex(new RegExp(reservedColorsPattern, 'i'), {
message: `Color names cannot include reserved names: ${RESERVED_COLORS.join(', ')}`,
}),
colorSchema,
{
description: 'One or more color definitions',
invalid_type_error: 'Color definitions must be hex color values',
},
)
.refine((colors) => !Object.keys(colors).some((key) => RESERVED_COLORS.includes(key.toLowerCase())), {
message: `Color names cannot include reserved names: ${RESERVED_COLORS.join(', ')}`,
});

const themeSchema = z.object(
{
Expand Down
13 changes: 13 additions & 0 deletions packages/cli/src/colors/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ import type { CssColor } from './types.js';
import type { Color, ColorNumber, ColorScheme, ThemeInfo } from './types.js';
import { getLightnessFromHex, getLuminanceFromLightness } from './utils.js';

export const RESERVED_COLORS = [
'neutral',
'success',
'warning',
'danger',
'info',
'blue',
'green',
'orange',
'purple',
'red',
];

/**
* Generates a color scale based on a base color and a color mode.
*
Expand Down

0 comments on commit 8e91a6a

Please sign in to comment.