Skip to content

Commit

Permalink
feat(styles): add CSS var colors
Browse files Browse the repository at this point in the history
chore: fix usage of ESM module
  • Loading branch information
zettca authored and plagoa committed Dec 5, 2023
1 parent 3133853 commit 6d7444f
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 86 deletions.
30 changes: 26 additions & 4 deletions .storybook/decorators/withThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useState, useEffect, useMemo } from "react";
import { useState, useEffect, useRef } from "react";

import { addons } from "@storybook/addons";
import { Global } from "@storybook/theming";
import { Decorator } from "@storybook/react";

import { HvProvider } from "@hitachivantara/uikit-react-core";
import { HvVizProvider } from "@hitachivantara/uikit-react-viz";
Expand All @@ -11,14 +12,31 @@ import { getStoryStyles } from "../theme/styles/story";
import { ADDON_EVENT } from "../addons/theme-selector/constants";
import { getLocalTheme } from "../addons/theme-selector/utils";

const withThemeProvider = (story) => {
/** Return a `ref` that adds/removes `dark` class variant depending on `mode` */
const useDarkClass = <T extends HTMLElement = HTMLDivElement>(mode: string) => {
const ref = useRef<T>(null);

useEffect(() => {
if (mode === "wicked") {
ref.current?.classList.add("dark");
} else {
ref.current?.classList.remove("dark");
}
}, [mode]);

return ref;
};

const ThemeDecorator: Decorator = (story) => {
const initialTheme = getLocalTheme();

const [selectedTheme, setSelectedTheme] = useState(initialTheme);

const [theme, mode] = selectedTheme?.split("-") || ["ds5", "dawn"];
const base = theme === "ds3" ? ds3 : ds5;

const containerRef = useDarkClass(mode);

const storyStyles = getStoryStyles(base.colors.modes[mode].atmo2);

const switchTheme = ({ name }: Theme) => {
Expand All @@ -45,7 +63,11 @@ const withThemeProvider = (story) => {
colorMode={mode}
>
<HvVizProvider>
<div className="hv-story-sample" style={{ padding: 20 }}>
<div
ref={containerRef}
className="hv-story-sample"
style={{ padding: 20 }}
>
{story()}
</div>
</HvVizProvider>
Expand All @@ -54,4 +76,4 @@ const withThemeProvider = (story) => {
);
};

export default withThemeProvider;
export default ThemeDecorator;
4 changes: 2 additions & 2 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Preview } from "@storybook/react";
import DocsContainer from "./blocks/DocsContainer";
import { DocsPage } from "./blocks/DocsPage";
import withThemeProvider from "./decorators/withThemeProvider";
import ThemeDecorator from "./decorators/withThemeProvider";

import "uno.css";

Expand Down Expand Up @@ -66,5 +66,5 @@ export const parameters: Preview["parameters"] = {

export default {
parameters,
decorators: [withThemeProvider],
decorators: [ThemeDecorator],
} satisfies Preview;
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
HvBadge,
HvButton,
HvDropdown,
theme,
HvTypography,
} from "@hitachivantara/uikit-react-core";

<Meta title="Guides/Styling/Utility Classes" />
Expand Down Expand Up @@ -55,12 +55,12 @@ For more information, check out the [UnoCSS Vite documentation](https://unocss.d

## Usage

_**Note:**_ Usage of an [IDE plugin](https://unocss.dev/integrations/vscode) is recommended for a better developer experience.

To use the utility classes, simply add them to a component's `className` prop or to one of the `classes`' keys.
For a list of the available classes, check out the [Uno Preset documentation](https://unocss.dev/presets/uno#rules).
Using a [cheat sheet](https://tailwindcomponents.com/cheatsheet) can be useful to ease the learning curve of the classes.

_**Note:** The color utility classes depend on UI Kit's CSS variables, which means they can only be used inside `<HvProvider />`._

### Examples

#### Flex layouts, theme units
Expand All @@ -77,10 +77,11 @@ The utility classes integrate with the Design System theme for colors and sizing

<Canvas>
<Story name="Layout and theme">
<section className="flex flex-row w-400px justify-center gap-sm p-sm">
<section className="flex flex-row w-500px justify-center gap-sm p-sm">
<div className="w-10 h-10 rounded bg-positive" />
<div className="w-11 h-11 rounded bg-warning" />
<div className="w-12 h-12 rounded bg-negative" />
<div className="w-12 h-12 rounded bg-primary_20" />
</section>
</Story>
</Canvas>
Expand All @@ -89,11 +90,12 @@ The utility classes integrate with the Design System theme for colors and sizing

<Canvas>
<Story name="Breakpoints">
<section className="flex flex-col gap-xs text-atmo4">
<p className="sm:text-secondary">Breakpoint is SM+</p>
<p className="md:text-secondary">Breakpoint is MD+</p>
<p className="lg:text-secondary">Breakpoint is LG+</p>
<p className="xl:text-secondary">Breakpoint is XL+</p>
<section className="grid gap-xs grid-cols-4 md:grid-cols-6 lg:grid-cols-12">
{[...Array(12).keys()].map((i) => (
<div key={i} className="h-10 bg-atmo3 flex items-center justify-center">
<HvTypography variant="title3">{i + 1}</HvTypography>
</div>
))}
</section>
</Story>
</Canvas>
Expand Down
1 change: 1 addition & 0 deletions docs/overview/introduction/Introduction.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ NEXT UI Kit resources are distributed across multiple npm packages. This allows
- **Lab** - Contributed React components for the NEXT UI Kit.
- **Viz** - React visualizations for the NEXT Design System.
- **Code Editor** - React Monaco editor for the NEXT Design System.
- **UnoCSS Preset** - UnoCSS preset for styling with Utility Classes.

## Accessibility

Expand Down
33 changes: 27 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/core/src/components/Table/TableBody/TableBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface HvTableBodyProps

const tableSectionContext = {
type: "body",
filterClassName: "grid",
filterClassName: "_grid",
};

const defaultComponent = "tbody";
Expand Down
4 changes: 3 additions & 1 deletion packages/uno-preset/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
"@unocss/preset-uno": ">= 0.57.7"
},
"dependencies": {
"@hitachivantara/uikit-styles": "^5.16.3"
"@hitachivantara/uikit-styles": "^5.16.3",
"@unocss/preset-rem-to-px": "^0.57.7",
"unocss-preset-theme": "^0.11.0"
},
"devDependencies": {
"npm-run-all": "^4.1.5",
Expand Down
28 changes: 19 additions & 9 deletions packages/uno-preset/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
import { definePreset } from "@unocss/core";
import { UserConfig, definePreset, mergeConfigs } from "@unocss/core";
import { Theme, presetUno, PresetUnoOptions } from "@unocss/preset-uno";
import { presetRemToPx } from "@unocss/preset-rem-to-px";
// @ts-expect-error ignore CJS import ES module
import { presetTheme } from "unocss-preset-theme";

import { extendTheme } from "./theme";
import { extendTheme, themeModes } from "./theme";
import { rules } from "./rules";
import { remToPx } from "./utils";

export { remToPx, rules, extendTheme };
export { rules, extendTheme, themeModes };

export interface HvUnoOptions extends PresetUnoOptions {}

export const presetHv = definePreset<HvUnoOptions, Theme>((options) => {
const basePreset = presetUno(options);
const hvConfig: UserConfig<Theme> = {
extendTheme,
rules,
};

return {
...basePreset,
name: "@hitachivantara/uikit-uno-preset",
postprocess: [remToPx()],
extendTheme,
rules: [...basePreset.rules!, ...rules],
...mergeConfigs([
// base uno config
presetUno(options),
// convert rem to px & make 1 unit 8px (32px = 1rem => 1/4rem = 8px)
presetRemToPx({ baseFontSize: 32 }),
hvConfig,
// allows theme variants (light/dark) via CSS vars - aligned with UI Kit's
presetTheme<Theme>({ prefix: "--hv", theme: themeModes }),
]),
};
});
70 changes: 37 additions & 33 deletions packages/uno-preset/src/theme.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,39 @@
import type { Theme } from "@unocss/preset-uno";
import { ThemeExtender } from "@unocss/core";

import {
ds5 as hvTheme,
theme as hvThemeCssVars,
} from "@hitachivantara/uikit-styles";
import { ds5 as hvTheme } from "@hitachivantara/uikit-styles";

// #region HV utils
const { colors: colorVars } = hvThemeCssVars;
// #region theme conversion utils
const { dawn: defaultColors } = hvTheme.colors.modes;
const { base, ...hvSpacing } = hvTheme.space;

/** HV breakpoints with added `px` suffix */
const hvBreakpoints = Object.entries(hvTheme.breakpoints.values).map(
([key, value]) => [key, `${value}px`] as const
);
// #endregion

const borderRadius = {
DEFAULT: hvTheme.radii.round,
...hvTheme.radii,
};

const breakpoints = Object.fromEntries(hvBreakpoints);
const containers = Object.fromEntries(
hvBreakpoints.map(([k, v]) => [k, `(min-width: ${v})`])
);

const { base, ...hvSpacing } = hvTheme.space;
const spacing = {
DEFAULT: hvSpacing.sm,
...hvSpacing,
};

const hvZIndex = Object.entries(hvTheme.zIndices).map(
([key, value]) => [key, `${value}`] as const
);
const zIndex = Object.fromEntries(hvZIndex);
// #endregion

/** Extends the current theme with the NEXT Design System utilities */
export const extendTheme: ThemeExtender<Theme> = (baseTheme) => ({
...baseTheme,
borderRadius,
breakpoints,
containers,
spacing,
zIndex,

borderRadius: {
DEFAULT: hvTheme.radii.round,
...hvTheme.radii,
},
breakpoints: Object.fromEntries(hvBreakpoints),
containers: Object.fromEntries(
hvBreakpoints.map(([k, v]) => [k, `(min-width: ${v})`])
),
spacing: {
DEFAULT: hvSpacing.sm,
...hvSpacing,
},
zIndex: Object.fromEntries(hvZIndex),

// colors
colors: {
Expand All @@ -53,11 +43,11 @@ export const extendTheme: ThemeExtender<Theme> = (baseTheme) => ({
black: "#000000",
white: "#ffffff",
// using `theme` CSS vars for automatic theme switching, losing alpha + no HvProvider support
...colorVars,
...defaultColors,
},
accentColor: { DEFAULT: colorVars.primary },
textColor: { DEFAULT: colorVars.secondary },
backgroundColor: { DEFAULT: colorVars.backgroundColor },
accentColor: { DEFAULT: defaultColors.primary },
textColor: { DEFAULT: defaultColors.secondary },
backgroundColor: { DEFAULT: defaultColors.backgroundColor },

// typography
fontFamily: {
Expand All @@ -70,3 +60,17 @@ export const extendTheme: ThemeExtender<Theme> = (baseTheme) => ({
fontSize: { DEFAULT: hvTheme.fontSizes.base, ...hvTheme.fontSizes },
fontWeight: { DEFAULT: hvTheme.fontWeights.normal, ...hvTheme.fontWeights },
});

/** UI Kit theme mode variants */
export const themeModes = {
light: {
colors: {
...hvTheme.colors.modes.dawn,
},
},
dark: {
colors: {
...hvTheme.colors.modes.wicked,
},
},
};

0 comments on commit 6d7444f

Please sign in to comment.