mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(system): media and utils are now customizable!
This commit is contained in:
parent
4fe96c16d5
commit
4cd6786a93
@ -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 (
|
||||
<>
|
||||
|
||||
@ -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)",
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
21
pnpm-lock.yaml
generated
@ -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:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user