Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@gnist/themes

Package Overview
Dependencies
Maintainers
4
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@gnist/themes - npm Package Compare versions

Comparing version
3.29.0
to
3.30.0-alpha.2
+22
-11
dist/atoms.css.js

@@ -1,15 +0,19 @@

import { globalStyle, style } from "@vanilla-extract/css";
import { globalStyle } from "@vanilla-extract/css";
import { createSprinkles, defineProperties } from "@vanilla-extract/sprinkles";
import { typography } from "./layers.css.js";
import { gnist, gnistStyle } from "./layers.css.js";
import { tokens } from "./tokens.css.js";
export const textContainer = style({});
export const textContainer = gnistStyle({});
globalStyle(`${textContainer} p, ${textContainer} ul, ${textContainer} ol`, {
marginTop: tokens.type.small.body.paragraphSpacing,
"@media": {
"screen and (min-width: 768px)": {
marginTop: tokens.type.medium.body.paragraphSpacing,
"@layer": {
[gnist]: {
marginTop: tokens.type.small.body.paragraphSpacing,
"@media": {
"screen and (min-width: 768px)": {
marginTop: tokens.type.medium.body.paragraphSpacing,
},
"screen and (min-width: 1024px)": {
marginTop: tokens.type.large.body.paragraphSpacing,
},
},
},
"screen and (min-width: 1024px)": {
marginTop: tokens.type.large.body.paragraphSpacing,
},
},

@@ -19,2 +23,3 @@ });

const responsiveProperties = defineProperties({
"@layer": gnist,
conditions: {

@@ -62,2 +67,3 @@ mobile: {},

const colorProperties = defineProperties({
"@layer": gnist,
properties: {

@@ -72,2 +78,3 @@ backgroundColor: color,

const radiusProperties = defineProperties({
"@layer": gnist,
properties: {

@@ -90,2 +97,3 @@ borderTopLeftRadius: radius,

const strokeProperties = defineProperties({
"@layer": gnist,
properties: {

@@ -108,2 +116,3 @@ borderTopWidth: stroke,

const elevationProperties = defineProperties({
"@layer": gnist,
properties: {

@@ -115,2 +124,3 @@ boxShadow: elevation,

const sizeProperties = defineProperties({
"@layer": gnist,
properties: {

@@ -139,3 +149,3 @@ width: size,

const responsiveTypeProperties = defineProperties({
"@layer": typography,
"@layer": gnist,
conditions: {

@@ -152,2 +162,3 @@ mobile: {},

const positionProperties = defineProperties({
"@layer": gnist,
properties: {

@@ -154,0 +165,0 @@ position: ["static", "relative", "absolute", "fixed", "sticky"],

@@ -0,2 +1,60 @@

import { ComplexStyleRule } from "@vanilla-extract/css";
import { RecipeVariants, RuntimeFn } from "@vanilla-extract/recipes";
/** @deprecated No longer used internally. Will be removed in next major version. */
export declare const typography: string;
/** @deprecated No longer used internally. Will be removed in next major version. */
export declare const framework: string;
export declare const gnist = "gnist";
/**
* A custom style() function that wraps all styles in @layer gnist { }.
* Has the same API as vanilla-extract's style() function.
*
* @example
* ```ts
* import { gnistStyle } from "@gnist/themes/layers.css.js";
*
* const myClass = gnistStyle({
* color: "red",
* padding: "10px",
* });
* ```
*/
export declare function gnistStyle(rule: ComplexStyleRule, debugId?: string): string;
type RecipeStyleRule = ComplexStyleRule | string;
type VariantDefinitions = Record<string, RecipeStyleRule>;
type BooleanMap<T> = T extends "true" | "false" ? boolean : T;
type VariantGroups = Record<string, VariantDefinitions>;
type VariantSelection<Variants extends VariantGroups> = {
[VariantGroup in keyof Variants]?: BooleanMap<keyof Variants[VariantGroup]> | undefined;
};
interface CompoundVariant<Variants extends VariantGroups> {
variants: VariantSelection<Variants>;
style: RecipeStyleRule;
}
type PatternOptions<Variants extends VariantGroups> = {
base?: RecipeStyleRule;
variants?: Variants;
defaultVariants?: VariantSelection<Variants>;
compoundVariants?: Array<CompoundVariant<Variants>>;
};
/**
* A custom recipe() function that wraps all styles in @layer gnist { }.
* Has the same API as @vanilla-extract/recipes' recipe() function.
*
* @example
* ```ts
* import { gnistRecipe } from "@gnist/themes/layers.css.js";
*
* const myRecipe = gnistRecipe({
* base: { padding: "10px" },
* variants: {
* color: {
* primary: { backgroundColor: "blue" },
* secondary: { backgroundColor: "gray" },
* },
* },
* });
* ```
*/
export declare function gnistRecipe<Variants extends VariantGroups>(options: PatternOptions<Variants>, debugId?: string): RuntimeFn<Variants>;
export type { RecipeVariants };

@@ -1,3 +0,130 @@

import { layer } from "@vanilla-extract/css";
import { layer, style, } from "@vanilla-extract/css";
import { recipe } from "@vanilla-extract/recipes";
/** @deprecated No longer used internally. Will be removed in next major version. */
export const typography = layer("typography");
/** @deprecated No longer used internally. Will be removed in next major version. */
export const framework = layer("framework");
export const gnist = "gnist";
/**
* Wraps a StyleRule object with the gnist layer.
* Preserves any existing @layer rules by merging them.
*/
function wrapInGnistLayer(rule) {
if (rule["@layer"]) {
// If there's already a @layer, we need to merge
const existingLayer = rule["@layer"];
return {
...rule,
"@layer": {
[gnist]: existingLayer,
},
};
}
return {
"@layer": {
[gnist]: rule,
},
};
}
/**
* Processes a ComplexStyleRule, wrapping StyleRule objects with the gnist layer.
* Handles strings (class names), arrays, and StyleRule objects.
*/
function processComplexStyleRule(rule) {
if (typeof rule === "string") {
// Class name string - pass through unchanged
return rule;
}
if (Array.isArray(rule)) {
// Recursively process array items
return rule.map((item) => item ? processComplexStyleRule(item) : item);
}
// It's a StyleRule object - wrap it
return wrapInGnistLayer(rule);
}
/**
* A custom style() function that wraps all styles in @layer gnist { }.
* Has the same API as vanilla-extract's style() function.
*
* @example
* ```ts
* import { gnistStyle } from "@gnist/themes/layers.css.js";
*
* const myClass = gnistStyle({
* color: "red",
* padding: "10px",
* });
* ```
*/
export function gnistStyle(rule, debugId) {
const processedRule = processComplexStyleRule(rule);
return style(processedRule, debugId);
}
/**
* Processes a RecipeStyleRule, wrapping StyleRule objects with the gnist layer.
* Strings (class names) pass through unchanged.
*/
function processRecipeStyleRule(rule) {
if (typeof rule === "string") {
// Class name string - pass through unchanged
return rule;
}
return processComplexStyleRule(rule);
}
/**
* Processes recipe variants, wrapping each variant's styles with the gnist layer.
*/
function processRecipeVariants(variants) {
const processed = {};
for (const [variantName, variantValues] of Object.entries(variants)) {
processed[variantName] = {};
for (const [valueName, styles] of Object.entries(variantValues)) {
processed[variantName][valueName] = processRecipeStyleRule(styles);
}
}
return processed;
}
/**
* Processes compound variants, wrapping each compound variant's style with the gnist layer.
*/
function processCompoundVariants(compoundVariants) {
return compoundVariants.map((cv) => ({
...cv,
style: processRecipeStyleRule(cv.style),
}));
}
/**
* A custom recipe() function that wraps all styles in @layer gnist { }.
* Has the same API as @vanilla-extract/recipes' recipe() function.
*
* @example
* ```ts
* import { gnistRecipe } from "@gnist/themes/layers.css.js";
*
* const myRecipe = gnistRecipe({
* base: { padding: "10px" },
* variants: {
* color: {
* primary: { backgroundColor: "blue" },
* secondary: { backgroundColor: "gray" },
* },
* },
* });
* ```
*/
export function gnistRecipe(options, debugId) {
const processedOptions = {};
if (options.base !== undefined) {
processedOptions.base = processRecipeStyleRule(options.base);
}
if (options.variants) {
processedOptions.variants = processRecipeVariants(options.variants);
}
if (options.defaultVariants) {
processedOptions.defaultVariants = options.defaultVariants;
}
if (options.compoundVariants) {
processedOptions.compoundVariants = processCompoundVariants(options.compoundVariants);
}
return recipe(processedOptions, debugId);
}

@@ -1,3 +0,4 @@

import { globalStyle, style } from "@vanilla-extract/css";
import { globalStyle } from "@vanilla-extract/css";
import { atoms } from "./atoms.css.js";
import { gnist, gnistStyle } from "./layers.css.js";
import { tokens } from "./tokens.css.js";

@@ -28,3 +29,3 @@ /**

}));
export const globalTextStyles = style([
export const globalTextStyles = gnistStyle([
atoms({ backgroundColor: "background", color: "on-background" }),

@@ -34,4 +35,8 @@ responsiveTypography.body,

globalStyle("p, ul, ol", {
margin: 0,
fontFamily: tokens.typeface.brand,
"@layer": {
[gnist]: {
margin: 0,
fontFamily: tokens.typeface.brand,
},
},
});
{
"name": "@gnist/themes",
"version": "3.29.0",
"version": "3.30.0-alpha.2",
"license": "UNLICENSED",

@@ -8,2 +8,6 @@ "description": "",

"exports": {
"./layers.css.js": {
"import": "./dist/layers.css.js",
"types": "./dist/layers.css.d.ts"
},
"./atoms.css.js": {

@@ -67,3 +71,3 @@ "import": "./dist/atoms.css.js",

},
"gitHead": "1b5b7189ae8c3576e8fec2c28f1d418667a544d4"
"gitHead": "a7a72c810de3a341dee37cad940f4a6e7bfb66be"
}

@@ -7,2 +7,55 @@ # Themes for @gnist/design-system

## CSS Layers
All styles produced by this library are wrapped in `@layer gnist { }`. This means consumers can override any design system style without specificity issues — unlayered styles always take precedence over layered styles.
To ensure correct layer ordering, add a `@layer` declaration at the top of your main CSS file (e.g. `globals.css`):
```css
@layer base, gnist;
```
This guarantees that `gnist` styles take precedence over `base` styles. Any global or reset CSS you write should be wrapped in `@layer base { }` so it doesn't unintentionally override design system styles:
```css
@layer base {
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
}
}
```
Styles written outside any `@layer` will still take the highest precedence, allowing you to override design system styles when needed.
## Development
When writing styles within the design system or gnist-app, use `gnistStyle` and `gnistRecipe` instead of vanilla-extract's `style` and `recipe`:
```ts
import { gnistStyle, gnistRecipe } from "@gnist/themes/layers.css.js";
const myClass = gnistStyle({ color: "red" });
const myRecipe = gnistRecipe({
base: { padding: "10px" },
variants: {
size: {
small: { fontSize: "12px" },
large: { fontSize: "18px" },
},
},
});
```
A lint rule enforces this — importing `style` from `@vanilla-extract/css` or `recipe` from `@vanilla-extract/recipes` will produce an error.
Note that `globalStyle` and `styleVariants` are not wrapped automatically and must be manually placed inside `@layer` when needed.
See DEVELOPMENT.md for more details.
## Overview

@@ -96,7 +149,7 @@

```ts
import { style } from "@vanilla-extract/css";
import { gnistStyle } from "@gnist/themes/layers.css.js";
import { tokens } from "@gnist/themes/tokens.css.js";
import { boxColors } from "@gnist/themes/colors.css.js";
const box = style([
const box = gnistStyle([
boxColors["primary-container"],

@@ -121,7 +174,7 @@ { borderWidth: tokens.stroke.medium },

```tsx
import { style } from "@vanilla-extract/css";
import { gnistStyle } from "@gnist/themes/layers.css.js";
import { atoms } from "@gnist/themes/atoms.css.js";
import { responsiveTypography } from "@gnist/themes/typography.css.js"
const someStyle = style([
const someStyle = gnistStyle([
atoms({ display: "flex", padding: "xs" }),

@@ -145,7 +198,7 @@ responsiveTypography.lead,

```ts
import { recipe } from "@vanilla-extract/recipes";
import { gnistRecipe } from "@gnist/themes/layers.css.js";
import { atoms } from "@gnist/themes/atoms.css.js";
import { densityTypography } from "@gnist/themes/typography.css.js";
const action = recipe({
const action = gnistRecipe({
base: atoms({ display: "block" }),

@@ -155,3 +208,3 @@ ...densityTypography.action,

const className = recipe({ density: "default" });
const className = action({ density: "default" });
```

@@ -162,7 +215,7 @@

```ts
import { recipe } from "@vanilla-extract/recipes";
import { gnistRecipe } from "@gnist/themes/layers.css.js";
import { atoms } from "@gnist/themes/atoms.css.js";
import { densityTypography } from "@gnist/themes/typography.css.js";
const box = recipe({
const box = gnistRecipe({
base: [atoms({ display: "block" })],

@@ -360,1 +413,2 @@ variants: {

**Note:** These tokens stay in sync with the vanilla-extract themes automatically when design tokens are updated from Figma.

Sorry, the diff of this file is not supported yet