feat(system): media and utils are now customizable!

This commit is contained in:
Junior Garcia 2022-10-23 22:13:05 -03:00
parent 4fe96c16d5
commit 4cd6786a93
6 changed files with 157 additions and 49 deletions

View File

@ -2,6 +2,7 @@ import React from "react";
import {Meta} from "@storybook/react";
import {Spacer} from "@nextui-org/spacer";
import {Lock, User, VolumeUp, Camera, Activity} from "@nextui-org/shared-icons";
import {NextUI, NextUIProvider, createTheme, PropertyValue} from "@nextui-org/system";
import {Avatar} from "../src";
@ -36,6 +37,42 @@ const Container = ({children}: any) => (
export const Simple = () => <Avatar text="Hello" />;
const userTheme = createTheme({
type: "light",
className: "user-theme",
media: {
xsMax: "(min-width: 320px) and (max-width: 540px)",
p1: "(min-width: 0px) and (max-width: 320px)",
},
utils: {
myUtility: (value: PropertyValue<"width">) => ({
display: "flex",
justifyContent: "center",
alignItems: "center",
width: `calc(${value} * 2)`,
height: `calc(${value} * 2)`,
}),
},
});
export const BreakpointTest = () => (
<NextUIProvider theme={userTheme}>
<NextUI.Div
css={{
"@bp1": {
bg: "red",
myUtility: "100px",
},
"@xsMax": {
bg: "blue",
},
}}
>
<Avatar text={nameUsers[0]} />
</NextUI.Div>
</NextUIProvider>
);
export const Default = () => {
return (
<>

View File

@ -149,13 +149,6 @@ export const defaultTokens = {
dropdownItem:
"background 0.12s ease, transform 0.12s ease, color 0.12s ease, box-shadow 0.12s ease 0s",
},
breakpoints: {
xs: "650px",
sm: "960px",
md: "1280px",
lg: "1400px",
xl: "1920px",
},
};
export const defaultColors = {
@ -246,21 +239,21 @@ export const defaultColors = {
};
export const defaultMedia = {
xs: `(min-width: ${defaultTokens.breakpoints.xs})`,
sm: `(min-width: ${defaultTokens.breakpoints.sm})`,
md: `(min-width: ${defaultTokens.breakpoints.md})`,
lg: `(min-width: ${defaultTokens.breakpoints.lg})`,
xl: `(min-width: ${defaultTokens.breakpoints.xl})`,
xsMin: `(min-width: ${defaultTokens.breakpoints.xs})`,
smMin: `(min-width: ${defaultTokens.breakpoints.sm})`,
mdMin: `(min-width: ${defaultTokens.breakpoints.md})`,
lgMin: `(min-width: ${defaultTokens.breakpoints.lg})`,
xlMin: `(min-width: ${defaultTokens.breakpoints.xl})`,
xsMax: `(max-width: ${defaultTokens.breakpoints.xs})`,
smMax: `(max-width: ${defaultTokens.breakpoints.sm})`,
mdMax: `(max-width: ${defaultTokens.breakpoints.md})`,
lgMax: `(max-width: ${defaultTokens.breakpoints.lg})`,
xlMax: `(max-width: ${defaultTokens.breakpoints.xl})`,
xs: "(min-width: 650px)",
sm: "(min-width: 960px)",
md: "(min-width: 1280px)",
lg: "(min-width: 1400px)",
xl: "(min-width: 1920px)",
xsMin: "(min-width: 650px)",
smMin: "(min-width: 960px)",
mdMin: "(min-width: 1280px)",
lgMin: "(min-width: 1400px)",
xlMin: "(min-width: 1920px)",
xsMax: "(max-width: 650px)",
smMax: "(max-width: 960px)",
mdMax: "(max-width: 1280px)",
lgMax: "(max-width: 1400px)",
xlMax: "(max-width: 1920px)",
motion: "(prefers-reduced-motion: reduce)",
safari: "not all and (min-resolution:.001dpcm)",
hover: "(any-hover: hover)",

View File

@ -1,9 +1,9 @@
export * from "./types";
export * from "./stitches.config";
export * from "./root";
export * from "./system";
export * from "./colors";
export * from "./utils";
export * from "./theme-provider";
export * from "./use-theme";
export * from "./css-baseline";
export * from "./system";
export * from "./root";
export * from "./theme-provider";
export * from "./stitches.config";
export * from "./use-theme";
export * from "./types";

View File

@ -1,12 +1,10 @@
import type * as Stitches from "@stitches/react";
import {createStitches} from "@stitches/react";
import {deepMerge} from "@nextui-org/shared-utils";
import commonTheme from "./common";
import lightTheme from "./light-theme";
import darkTheme from "./dark-theme";
import {Theme, BaseTheme} from "./types";
import {Theme, BaseTheme, ConfigType} from "./types";
export const getStitchesTheme = (targetTheme: BaseTheme): BaseTheme => {
return deepMerge(targetTheme, commonTheme.theme);
@ -38,23 +36,54 @@ export const {
},
});
export const createTheme = ({type, theme = {}, className}: Theme) => {
// mutators
export function setMedia<Media extends {} = {}>(media: ConfigType.Media<Media>): void {
config.media = {
...config.media,
...media,
};
}
export function setUtils<Utils extends {} = {}>(utils: ConfigType.Utils<Utils>): void {
config.utils = {
...config.utils,
...utils,
};
}
function setThemeMap<ThemeMap extends {} = {}>(themeMap: ConfigType.ThemeMap<ThemeMap>): void {
config.themeMap = {
...config.themeMap,
...themeMap,
};
}
export const createTheme = ({
type,
className,
theme = {},
media = {},
utils = {},
themeMap = {},
}: Theme) => {
if (!type) {
throw new Error("Theme type is required");
}
if (Object.keys(media).length > 0) {
setMedia(media);
}
if (Object.keys(utils).length > 0) {
setUtils(utils);
}
if (Object.keys(themeMap).length > 0) {
setThemeMap(themeMap);
}
return createThemeBase(
className || `${type}-theme`,
deepMerge(type === "dark" ? darkTheme : lightTheme, theme),
);
};
// stitches types
export type StitchesConfig = typeof config;
export type VariantProps<T> = Stitches.VariantProps<T>;
export type PropertyValue<T extends keyof Stitches.CSSProperties> = Stitches.PropertyValue<T>;
export type ScaleValue<T> = Stitches.ScaleValue<T>;
export type CSSProperties = Stitches.CSSProperties;
export type CSS = Stitches.CSS<StitchesConfig>;
export type StitchesTheme = typeof theme;
export type CSSComponent = typeof css;

View File

@ -1,8 +1,15 @@
import {StitchesTheme, createThemeBase} from "./stitches.config";
import type * as Stitches from "@stitches/react";
import {createThemeBase, config, theme, css} from "./stitches.config";
import commonTheme from "./common";
/** Configuration Interface */
declare namespace ConfigType {
export declare namespace ConfigType {
/** Media interface. */
export type Media<T = {}> = {
[name in keyof T]: T[name] extends string ? T[name] : string;
};
/** Theme interface. */
export type Theme<T = {}> = {
fonts?: {[token in number | string]: boolean | number | string};
@ -18,7 +25,6 @@ declare namespace ConfigType {
shadows?: {[token in number | string]: boolean | number | string};
dropShadows?: {[token in number | string]: boolean | number | string};
transitions?: {[token in number | string]: boolean | number | string};
breakpoints?: {[token in number | string]: boolean | number | string};
} & {
[Scale in keyof T]: {
[Token in keyof T[Scale]]: T[Scale][Token] extends boolean | number | string
@ -26,13 +32,40 @@ declare namespace ConfigType {
: boolean | number | string;
};
};
/** ThemeMap interface. */
export type ThemeMap<T = {}> = {
[Property in keyof T]: T[Property] extends string ? T[Property] : string;
};
/** Utility interface. */
export type Utils<T = {}> = {
[Property in keyof T]: T[Property] extends (value: infer V) => {}
?
| T[Property]
| ((value: V) => {
[K in keyof Stitches.CSSProperties]?: Stitches.CSSProperties[K] | V;
})
: never;
};
}
// stitches types
export type StitchesConfig = typeof config;
export type VariantProps<T> = Stitches.VariantProps<T>;
export type PropertyValue<T extends keyof Stitches.CSSProperties> = Stitches.PropertyValue<T>;
export type ScaleValue<T> = Stitches.ScaleValue<T>;
export type CSSProperties = Stitches.CSSProperties;
export type CSS = Stitches.CSS<StitchesConfig>;
export type StitchesTheme = typeof theme;
export type CSSComponent = typeof css;
// theme types
export type BaseTheme = ConfigType.Theme;
export type NextUITheme = StitchesTheme;
export type ThemeType = "dark" | "light";
export type CreateTheme = ReturnType<typeof createThemeBase>;
// tokens types
export type TokenKeyName = keyof typeof commonTheme["theme"];
export interface TokenValue {
@ -46,6 +79,9 @@ export type Theme = {
type?: ThemeType | string;
className?: string;
theme?: BaseTheme;
media?: ConfigType.Media;
utils?: ConfigType.Utils;
themeMap?: ConfigType.ThemeMap;
};
export type NextUIThemeContext = {

21
pnpm-lock.yaml generated
View File

@ -506,6 +506,7 @@ importers:
specifiers:
'@nextui-org/aria-utils': workspace:*
'@nextui-org/dom-utils': workspace:*
'@nextui-org/react-utils': workspace:*
'@nextui-org/shared-css': workspace:*
'@nextui-org/shared-utils': workspace:*
'@nextui-org/system': workspace:*
@ -520,6 +521,7 @@ importers:
dependencies:
'@nextui-org/aria-utils': link:../../utilities/aria-utils
'@nextui-org/dom-utils': link:../../utilities/dom-utils
'@nextui-org/react-utils': link:../../utilities/react-utils
'@nextui-org/shared-css': link:../../utilities/shared-css
'@nextui-org/shared-utils': link:../../utilities/shared-utils
'@nextui-org/system': link:../../core/system
@ -982,6 +984,21 @@ importers:
clean-package: 2.1.1
react: 17.0.2
packages/utilities/react-utils:
specifiers:
'@nextui-org/shared-utils': workspace:*
'@nextui-org/system': workspace:*
'@nextui-org/use-real-shape': workspace:*
clean-package: 2.1.1
react: ^17.0.2
dependencies:
'@nextui-org/shared-utils': link:../shared-utils
'@nextui-org/system': link:../../core/system
'@nextui-org/use-real-shape': link:../../hooks/use-real-shape
devDependencies:
clean-package: 2.1.1
react: 17.0.2
packages/utilities/shared-css:
specifiers:
clean-package: 2.1.1
@ -998,16 +1015,12 @@ importers:
packages/utilities/shared-utils:
specifiers:
'@nextui-org/system': workspace:*
'@nextui-org/use-real-shape': workspace:*
'@types/use-sync-external-store': ^0.0.3
clean-package: 2.1.1
deepmerge: 4.2.2
react: ^17.0.2
use-sync-external-store: ^1.2.0
dependencies:
'@nextui-org/system': link:../../core/system
'@nextui-org/use-real-shape': link:../../hooks/use-real-shape
deepmerge: 4.2.2
use-sync-external-store: 1.2.0_react@17.0.2
devDependencies: