npm.io
7.4.0 • Published 2d ago

@gnist/design-system

Licence
UNLICENSED
Version
7.4.0
Deps
13
Size
4.1 MB
Vulns
0
Weekly
0

Multi-brand React component library for Møller

@gnist/design-system is a React component library containing reusable, multi-brand GUI building blocks for applications in the Møller ecosystem.

For instructions on developing components, see the Development docs.

Consuming the library

The library is published as @gnist/design-system in the public npm registry. The prefix @moller is an npm scope associated with our organization on npm

Installing the library

Run the command

npm install @gnist/design-system @gnist/themes

Using the library

To use the library, the vanilla-extract plugin needs to be used.

Vite

For Vite 8, you need

npm install -D @vanilla-extract/vite-plugin @vanilla-extract/rollup-plugin

Your vite.config.ts might look like this:

// vite.config.ts

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { vanillaExtractPlugin as vanillaExtractRollupPlugin } from "@vanilla-extract/rollup-plugin";
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [react(), vanillaExtractPlugin()],
    optimizeDeps: {
        // Gnist publishes JS that imports vanilla-extract .css.js files,
        // so force those packages through Vite 8 prebundling.
        include: ["@gnist/design-system", "@gnist/design-system/**/*"],
        rolldownOptions: {
            plugins: [
                // Handle vanilla-extract file scopes during dep optimization.
                vanillaExtractRollupPlugin({ unstable_injectFilescopes: true }),
            ],
        },
    },
});

In the application entrypoint, import the required global styles and choose a theme

// app.tsx

import { LocalizationProvider } from "@gnist/design-system";
// Import one or more of these themes
import { bilholdLight } from "@gnist/themes/themes/bilholdLight.css.js";
import { gumpen } from "@gnist/themes/themes/gumpen.css.js";
import { brandless } from "@gnist/themes/themes/brandless.css.js";
import { mollerBil } from "@gnist/themes/themes/mollerBil.css.js";
import { skoda } from "@gnist/themes/themes/skoda.css.js";
import { vw } from "@gnist/themes/themes/vw.css.js";
import { dahles } from "@gnist/themes/themes/dahles.css.js";
import { autoria } from "@gnist/themes/themes/autoria.css.js";
import { audi } from "@gnist/themes/themes/audi.css.js";
import { cupra } from "@gnist/themes/themes/cupra.css.js";
// Import global styles
import { globalTextStyles } from "@gnist/themes/typography.css";
// Import necessary fonts (one or more, dependent on which themes are in use)
import "@gnist/design-system/fonts/moller";
import "@gnist/design-system/fonts/bilhold";
import "@gnist/design-system/fonts/skoda";
import "@gnist/design-system/fonts/gumpen";
import "@gnist/design-system/fonts/VW";
import "@gnist/design-system/fonts/dahles";
import "@gnist/design-system/fonts/autoria";
import "@gnist/design-system/fonts/audi";
import "@gnist/design-system/fonts/cupra";
import "@gnist/design-system/fonts/tools";

// Apply the theme
document.body.classList.add(bilholdLight);

// Apply global styles
globalTextStyles.forEach((c) => {
    document.body.classList.add(c);
});

export const App: React.FC = () => {
    return (
        <LocalizationProvider language="en">
            {/* ...the rest of your app here...*/}
        </LocalizationProvider>
    );
};

Note: The brandless and gnist themes are for internal use only. Both use the "Geist" font family, so if you are using either of these themes, import @gnist/design-system/fonts/tools as your font.

Next.js projects

If you are setting up in a Next.js project, the procedure is quite the same.

You will need to install and use @vanilla-extract/next-plugin:

npm install -D @vanilla-extract/next-plugin

With this setup, your next.config.mjs might look like this:

// next.config.mjs

import { createVanillaExtractPlugin } from "@vanilla-extract/next-plugin";
const withVanillaExtract = createVanillaExtractPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {};

export default withVanillaExtract(nextConfig);

If you are running a React version 18 project, you will also need to add this to your tsconfig.json for it to work with this React 17 library.

// tsconfig.json

"paths": {
     ...
      "react": [ "./node_modules/@types/react"]
    }

Then add the styling to your layout.tsx file. It might look like this:

// layout.tsx

import { bilholdLight } from "@gnist/themes/themes/bilholdLight.css.js";
import { globalTextStyles } from "@gnist/themes/typography.css.js";
import "@gnist/design-system/fonts/bilhold";

const bodyClassList = [bilholdLight, ...globalTextStyles];

export default function RootLayout({
    children,
}: {
    children: React.ReactNode;
}) {
    return (
        <html lang="en">
            <body className={bodyClassList.join(" ")}>{children}</body>
        </html>
    );
}
Using components

Finally, import components from @gnist/design-system:

// index.tsx

import { PrimaryButton } from "@gnist/design-system";

export default function Home() {
    return <PrimaryButton>Hello</PrimaryButton>;
}
Pages Router

If you are running Pages Router, add transpilePackages to next.config.mjs so that Vanilla Extract is applied to the library code:

// next.config.mjs
const nextConfig = {
    transpilePackages: ["@gnist/design-system", "@gnist/themes"],
};

As Pages Router does not have layout.tsx, you need to split the setup between pages/_document.tsx and pages/_app.tsx.

_document.tsx runs once on the server. Use a named import here to get the theme class for :

// _document.tsx

import { bilholdLight } from "@gnist/themes/themes/bilholdLight.css.js";
import { globalTextStyles } from "@gnist/themes/typography.css.js";
import "@gnist/design-system/fonts/bilhold";

const bodyClassList = [bilholdLight, ...globalTextStyles];

export default function RootLayout({
    children,
}: {
    children: React.ReactNode;
}) {
    return (
        <html lang="en">
            <body className={bodyClassList.join(" ")}>{children}</body>
        </html>
    );
}

_app.tsx runs on every route change. Here you must use side-effect imports for the same theme and typography so the CSS actually ends up in the client bundle:

// _app.tsx

import { LocalizationProvider } from "@gnist/design-system";

// Fonts matching your chosen theme
import "@gnist/design-system/fonts/bilhold";

// Side-effect imports to include CSS/tokens in client bundle
import "@gnist/themes/themes/bilholdLight.css.js";
import "@gnist/themes/typography.css.js";


export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    // Wrap app in LocalizationProvider
    <LocalizationProvider language="en">
      <Component {...pageProps} />
    </LocalizationProvider>
  );
}

This ensures:

_document.tsx sets the correct theme class on and .

_app.tsx loads the theme’s CSS variables and typography tokens into the client bundle.

Migrating from @moller/design-system

If you are migrating from the old component library @moller/design.system, please see the migration guide.