diff --git a/ui/.storybook/preview-head.html b/ui/.storybook/preview-head.html
index 05da1e9..fe4ffd0 100644
--- a/ui/.storybook/preview-head.html
+++ b/ui/.storybook/preview-head.html
@@ -1,3 +1,7 @@
+
\ No newline at end of file
+
diff --git a/ui/.storybook/preview.js b/ui/.storybook/preview.js
index b774878..6b02860 100644
--- a/ui/.storybook/preview.js
+++ b/ui/.storybook/preview.js
@@ -1,3 +1,10 @@
+import { dripStitches } from '../src/theme/stitches';
+import addons from '@storybook/addons';
+import { useEffect } from 'react';
+import { themes } from '@storybook/theming';
+
+const channel = addons.getChannel();
+
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
@@ -7,3 +14,35 @@ export const parameters = {
},
},
};
+
+const { darkTheme: darkThemeClassName } = dripStitches;
+
+export const decorators = [
+ (renderStory) => {
+ const { globalCss } = dripStitches;
+
+ const globalStyles = globalCss({
+ '*, html': {
+ 'font-family': 'Manrope',
+ },
+ body: {
+ backgroundColor: 'black',
+ },
+ });
+
+ globalStyles();
+
+ useEffect(() => {
+ function switchColorMode(isDarkMode) {
+ document.body.style.backgroundColor = isDarkMode ? 'black' : 'white';
+ document.body.classList.remove('light', darkThemeClassName);
+ document.body.classList.add(isDarkMode ? darkThemeClassName : 'light');
+ }
+
+ channel.on('DARK_MODE', switchColorMode);
+ return () => channel.off('DARK_MODE', switchColorMode);
+ }, []);
+
+ return renderStory();
+ },
+];
diff --git a/ui/src/theme/stitches/foundations/index.ts b/ui/src/theme/stitches/foundations/index.ts
index d757e0e..19acd07 100644
--- a/ui/src/theme/stitches/foundations/index.ts
+++ b/ui/src/theme/stitches/foundations/index.ts
@@ -1 +1,8 @@
+export * from './media';
export * from './colors';
+export * from './radii';
+export * from './shadows';
+export * from './sizes';
+export * from './spacing';
+export * from './typography';
+export * from './z-indices';
diff --git a/ui/src/theme/stitches/foundations/media.ts b/ui/src/theme/stitches/foundations/media.ts
new file mode 100644
index 0000000..116f217
--- /dev/null
+++ b/ui/src/theme/stitches/foundations/media.ts
@@ -0,0 +1,12 @@
+export const media = {
+ // Breakpoints
+ sm: '(min-width: 640px)',
+ md: '(min-width: 768px)',
+ lg: '(min-width: 1024px)',
+ xl: '(min-width: 1280px)',
+ '2xl': '(min-width: 1536px)',
+
+ // Motion and hover
+ motion: '(prefers-reduced-motion)',
+ hover: '(any-hover: hover)',
+};
diff --git a/ui/src/theme/stitches/foundations/radii.ts b/ui/src/theme/stitches/foundations/radii.ts
new file mode 100644
index 0000000..7a2f72a
--- /dev/null
+++ b/ui/src/theme/stitches/foundations/radii.ts
@@ -0,0 +1,8 @@
+export const radii = {
+ none: '0',
+ sm: '0.25rem', // 4px
+ md: '0.5rem', // 8px
+ lg: '0.75rem', // 12px
+ xl: '1rem', // 16px
+ full: '9999px',
+};
diff --git a/ui/src/theme/stitches/foundations/shadows.ts b/ui/src/theme/stitches/foundations/shadows.ts
new file mode 100644
index 0000000..d81a927
--- /dev/null
+++ b/ui/src/theme/stitches/foundations/shadows.ts
@@ -0,0 +1,11 @@
+//TODO: maybe we can use tailwind for this
+export const shadows = {
+ none: '0 0 #0000',
+ inner: 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
+ xs: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
+ sm: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
+ md: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
+ lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
+ xl: '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
+ ['2xl']: '0 25px 50px -12px rgb(0 0 0 / 0.25)',
+};
diff --git a/ui/src/theme/stitches/foundations/sizes.ts b/ui/src/theme/stitches/foundations/sizes.ts
new file mode 100644
index 0000000..65f0195
--- /dev/null
+++ b/ui/src/theme/stitches/foundations/sizes.ts
@@ -0,0 +1,22 @@
+import { spacing } from './spacing';
+
+export const sizes = {
+ ...spacing,
+ max: 'max-content',
+ min: 'min-content',
+ full: '100%',
+ '3xs': '14rem',
+ '2xs': '16rem',
+ xs: '20rem',
+ sm: '24rem',
+ md: '28rem',
+ lg: '32rem',
+ xl: '36rem',
+ '2xl': '42rem',
+ '3xl': '48rem',
+ '4xl': '56rem',
+ '5xl': '64rem',
+ '6xl': '72rem',
+ '7xl': '80rem',
+ '8xl': '90rem',
+};
diff --git a/ui/src/theme/stitches/foundations/spacing.ts b/ui/src/theme/stitches/foundations/spacing.ts
new file mode 100644
index 0000000..6432c69
--- /dev/null
+++ b/ui/src/theme/stitches/foundations/spacing.ts
@@ -0,0 +1,35 @@
+export const spacing = {
+ '0': '0px',
+ '0h': '0.125rem', // 2px
+ 1: '0.25rem', // 4px
+ '1h': '0.375rem', // 6px
+ 2: '0.5rem', // 8px
+ '2h': '0.625rem', // 10px
+ 3: '0.75rem', // 12px
+ '3h': '0.875rem', // 14px
+ 4: '1rem', // 16px
+ 5: '1.25rem', // 20px
+ 6: '1.5rem',
+ 7: '1.75rem',
+ 8: '2rem',
+ 9: '2.25rem',
+ 10: '2.5rem',
+ 12: '3rem',
+ 14: '3.5rem',
+ 16: '4rem',
+ 20: '5rem',
+ 24: '6rem',
+ 28: '7rem',
+ 32: '8rem',
+ 36: '9rem',
+ 40: '10rem',
+ 44: '11rem',
+ 48: '12rem',
+ 52: '13rem',
+ 56: '14rem',
+ 60: '15rem',
+ 64: '16rem',
+ 72: '18rem',
+ 80: '20rem',
+ 96: '24rem',
+};
diff --git a/ui/src/theme/stitches/foundations/typography.ts b/ui/src/theme/stitches/foundations/typography.ts
new file mode 100644
index 0000000..91e5ee2
--- /dev/null
+++ b/ui/src/theme/stitches/foundations/typography.ts
@@ -0,0 +1,62 @@
+export const typography = {
+ letterSpacings: {
+ tighter: '-0.05em',
+ tight: '-0.025em',
+ normal: '0',
+ wide: '0.025em',
+ wider: '0.05em',
+ widest: '0.1em',
+ },
+
+ lineHeights: {
+ normal: 'normal',
+ none: 1,
+ shorter: 1.25,
+ short: 1.375,
+ base: 1.5,
+ tall: 1.625,
+ taller: '2',
+ '3': '.75rem',
+ '4': '1rem',
+ '5': '1.25rem',
+ '6': '1.5rem',
+ '7': '1.75rem',
+ '8': '2rem',
+ '9': '2.25rem',
+ '10': '2.5rem',
+ },
+
+ fontWeights: {
+ hairline: 100,
+ thin: 200,
+ light: 300,
+ normal: 400,
+ medium: 500,
+ semibold: 600,
+ bold: 700,
+ extrabold: 800,
+ black: 900,
+ },
+
+ fonts: {
+ heading: `Manrope`,
+ body: `Manrope`,
+ mono: `Manrope`,
+ },
+
+ fontSizes: {
+ xs: '0.75rem', //12px
+ sm: '0.875rem', //14px
+ md: '1rem', //16px
+ lg: '1.125rem', //18px
+ xl: '1.25rem', //20px
+ '2xl': '1.5rem',
+ '3xl': '1.875rem',
+ '4xl': '2.25rem',
+ '5xl': '3rem',
+ '6xl': '3.75rem',
+ '7xl': '4.5rem',
+ '8xl': '6rem',
+ '9xl': '8rem',
+ },
+};
diff --git a/ui/src/theme/stitches/foundations/z-indices.ts b/ui/src/theme/stitches/foundations/z-indices.ts
new file mode 100644
index 0000000..bb07319
--- /dev/null
+++ b/ui/src/theme/stitches/foundations/z-indices.ts
@@ -0,0 +1,15 @@
+export const zIndices = {
+ hide: -1,
+ auto: 'auto',
+ base: 0,
+ docked: 10,
+ dropdown: 1000,
+ sticky: 1100,
+ banner: 1200,
+ overlay: 1300,
+ modal: 1400,
+ popover: 1500,
+ skipLink: 1600,
+ toast: 1700,
+ tooltip: 1800,
+};
diff --git a/ui/src/theme/stitches/index.ts b/ui/src/theme/stitches/index.ts
index 340fd15..8fe1080 100644
--- a/ui/src/theme/stitches/index.ts
+++ b/ui/src/theme/stitches/index.ts
@@ -1 +1,2 @@
export * from './themes';
+export * from './foundations';
diff --git a/ui/src/theme/stitches/themes.ts b/ui/src/theme/stitches/themes.ts
index ab380a5..b01cc8c 100644
--- a/ui/src/theme/stitches/themes.ts
+++ b/ui/src/theme/stitches/themes.ts
@@ -1,54 +1,125 @@
-import { createStitches } from '@stitches/react';
-import { darkColors } from './foundations';
+/* eslint-disable @typescript-eslint/ban-types */
+import { createStitches, DefaultThemeMap } from '@stitches/react';
+import type { ConfigType } from '@stitches/react/types/config';
-export const {
- styled,
- css,
- globalCss,
- keyframes,
- theme: darkTheme,
- createTheme,
- config,
-} = createStitches({
- theme: {
- colors: {
- ...darkColors,
+import { allToNegative } from '../../utils';
+import {
+ colors,
+ darkColors,
+ media as libMedia,
+ radii,
+ shadows,
+ sizes,
+ spacing,
+ typography,
+ zIndices,
+} from './foundations';
+import { utils as libUtils } from './utils';
+
+export interface CreateDripStitchesConfig<
+ Prefix,
+ Media,
+ Theme,
+ ThemeMap,
+ Utils
+> {
+ prefix?: ConfigType.Prefix;
+ media?: ConfigType.Media;
+ theme?: ConfigType.Theme;
+ themeMap?: ConfigType.ThemeMap;
+ utils?: ConfigType.Utils;
+}
+export const createDripStitches = <
+ Prefix extends string = '',
+ Media extends {} = {},
+ Theme extends {} = {},
+ ThemeMap extends {} = DefaultThemeMap,
+ Utils extends {} = {}
+>(
+ config?: CreateDripStitchesConfig
+) => {
+ const { prefix, theme, themeMap, utils, media } = config || {};
+
+ const _spacing = {
+ ...allToNegative(spacing),
+ ...spacing,
+ };
+
+ const _sizes = {
+ ...allToNegative(sizes),
+ ...sizes,
+ };
+
+ const { createTheme, ...otherStitches } = createStitches({
+ prefix: prefix || ('drip' as string),
+ media: {
+ ...libMedia,
+ ...(media || {}),
},
- space: {
- xs: '0.32rem',
- sm: '0.625rem',
- md: '1.25rem',
- lg: '2.375rem',
- xl: '4.75rem',
+ theme: {
+ colors: {
+ ...darkColors, // TODO: replace with light colors once it's done the light mode
+ ...(theme?.colors || {}),
+ },
+ space: {
+ ..._spacing,
+ ...(theme?.space || {}),
+ },
+ sizes: {
+ ..._sizes,
+ ...(theme?.sizes || {}),
+ },
+ fontWeights: {
+ ...typography.fontWeights,
+ ...(theme?.fontWeights || {}),
+ },
+ fonts: {
+ ...typography.fonts,
+ ...(theme?.fonts || {}),
+ },
+ letterSpacings: {
+ ...typography.letterSpacings,
+ ...(theme?.letterSpacings || {}),
+ },
+ lineHeights: {
+ ...typography.lineHeights,
+ ...(theme?.lineHeights || {}),
+ },
+ fontSizes: {
+ ...typography.fontSizes,
+ ...(theme?.fontSizes || {}),
+ },
+ radii: {
+ ...radii,
+ ...(theme?.radii || {}),
+ },
+ shadows: {
+ ...shadows,
+ ...(theme?.shadows || {}),
+ },
+ zIndices: {
+ ...zIndices,
+ ...(theme?.zIndices || {}),
+ },
+ ...(theme || {}),
},
- fontSizes: {
- sm: '0.75rem',
- md: '1rem',
- lg: '1.75rem',
- 'h-sm': '1rem',
- 'h-md': '1.5rem',
- 'h-lg': '2rem',
+ themeMap,
+ utils: {
+ ...libUtils,
+ ...(utils || {}),
},
- radii: {
- xs: '0.25rem',
- sm: '0.5rem',
- md: '0.75rem',
- lg: '1rem',
- xl: '1.5rem',
- full: '9999px',
- },
- borderWidths: {
- default: '1px',
- focus: '2px',
- },
- borderStyles: {
- default: 'solid',
- },
- },
- media: {
- sm: '(max-width: 640px)',
- md: '(max-width: 850px)',
- lg: '(max-width: 1140px)',
- large: '(min-width: 1140px)',
- },
-});
+ });
+
+ const darkTheme = createTheme({
+ colors: darkColors,
+ });
+
+ return {
+ createTheme,
+ darkTheme,
+ darkThemeSelector: `.${darkTheme} &`,
+ ...otherStitches,
+ };
+};
+
+export const dripStitches = createDripStitches();
diff --git a/ui/src/theme/stitches/utils.ts b/ui/src/theme/stitches/utils.ts
new file mode 100644
index 0000000..1bd2738
--- /dev/null
+++ b/ui/src/theme/stitches/utils.ts
@@ -0,0 +1,89 @@
+import Stitches from '@stitches/react';
+
+export const utils = {
+ p: (value: Stitches.PropertyValue<'padding'>) => ({
+ padding: value,
+ }),
+ pt: (value: Stitches.PropertyValue<'paddingTop'>) => ({
+ paddingTop: value,
+ }),
+ pr: (value: Stitches.PropertyValue<'paddingRight'>) => ({
+ paddingRight: value,
+ }),
+ pb: (value: Stitches.PropertyValue<'paddingBottom'>) => ({
+ paddingBottom: value,
+ }),
+ pl: (value: Stitches.PropertyValue<'paddingLeft'>) => ({
+ paddingLeft: value,
+ }),
+ px: (value: Stitches.PropertyValue<'paddingLeft'>) => ({
+ paddingLeft: value,
+ paddingRight: value,
+ }),
+ py: (value: Stitches.PropertyValue<'paddingTop'>) => ({
+ paddingTop: value,
+ paddingBottom: value,
+ }),
+
+ m: (value: Stitches.PropertyValue<'margin'>) => ({
+ margin: value,
+ }),
+ mt: (value: Stitches.PropertyValue<'marginTop'>) => ({
+ marginTop: value,
+ }),
+ mr: (value: Stitches.PropertyValue<'marginRight'>) => ({
+ marginRight: value,
+ }),
+ mb: (value: Stitches.PropertyValue<'marginBottom'>) => ({
+ marginBottom: value,
+ }),
+ ml: (value: Stitches.PropertyValue<'marginLeft'>) => ({
+ marginLeft: value,
+ }),
+ mx: (value: Stitches.PropertyValue<'marginLeft'>) => ({
+ marginLeft: value,
+ marginRight: value,
+ }),
+ my: (value: Stitches.PropertyValue<'marginTop'>) => ({
+ marginTop: value,
+ marginBottom: value,
+ }),
+
+ br: (value: Stitches.PropertyValue<'borderRadius'>) => ({
+ borderRadius: value,
+ }),
+ btrr: (value: Stitches.PropertyValue<'borderTopRightRadius'>) => ({
+ borderTopRightRadius: value,
+ }),
+ bbrr: (value: Stitches.PropertyValue<'borderBottomRightRadius'>) => ({
+ borderBottomRightRadius: value,
+ }),
+ bblr: (value: Stitches.PropertyValue<'borderBottomLeftRadius'>) => ({
+ borderBottomLeftRadius: value,
+ }),
+ btlr: (value: Stitches.PropertyValue<'borderTopLeftRadius'>) => ({
+ borderTopLeftRadius: value,
+ }),
+
+ ox: (value: Stitches.PropertyValue<'overflowX'>) => ({ overflowX: value }),
+ oy: (value: Stitches.PropertyValue<'overflowY'>) => ({ overflowY: value }),
+
+ userSelect: (value: Stitches.PropertyValue<'userSelect'>) => ({
+ WebkitUserSelect: value,
+ userSelect: value,
+ }),
+
+ size: (value: Stitches.PropertyValue<'width'>) => ({
+ width: value,
+ height: value,
+ }),
+
+ appearance: (value: Stitches.PropertyValue<'appearance'>) => ({
+ WebkitAppearance: value,
+ appearance: value,
+ }),
+ backgroundClip: (value: Stitches.PropertyValue<'backgroundClip'>) => ({
+ WebkitBackgroundClip: value,
+ backgroundClip: value,
+ }),
+};
diff --git a/ui/src/utils/index.ts b/ui/src/utils/index.ts
index c8707da..b43d013 100644
--- a/ui/src/utils/index.ts
+++ b/ui/src/utils/index.ts
@@ -1,2 +1,3 @@
export * from './format';
export * from './validation';
+export * from './object';
diff --git a/ui/src/utils/object.ts b/ui/src/utils/object.ts
new file mode 100644
index 0000000..e71e7a1
--- /dev/null
+++ b/ui/src/utils/object.ts
@@ -0,0 +1,11 @@
+type StringObject = { [key: string]: string };
+
+export const allToNegative = (obj: StringObject) => {
+ const negativeSpacing: StringObject = {};
+
+ for (const key in obj) {
+ negativeSpacing[`-${key}`] = `-${obj[key]}`;
+ }
+
+ return negativeSpacing;
+};