@latte-macchiat-io/latte-vanilla-components 0.0.179 → 0.0.181

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@latte-macchiat-io/latte-vanilla-components",
3
- "version": "0.0.179",
3
+ "version": "0.0.181",
4
4
  "description": "Beautiful components for amazing projects, with a touch of Vanilla 🥤",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/index.ts CHANGED
@@ -86,11 +86,17 @@ export { type TextareaVariants } from './components/Form/TextField/Textarea/Text
86
86
 
87
87
  export { ToRemove } from './components/ToRemove/ToRemove';
88
88
 
89
- // Theme utilities
89
+ // Theme utilities
90
90
  export { createDarkTheme, createLightTheme, type ThemeOverrides } from './utils/theme';
91
+ export { createCustomLightTheme, createCustomDarkTheme, type ThemeOverrides as CustomThemeOverrides } from './utils/createCustomTheme';
92
+ export { createThemeOverride } from './utils/themeOverrides.css';
91
93
  // Theme contract and values
92
94
  export { themeContract } from './theme/contract.css';
93
95
  export { baseLightTheme, baseDarkTheme } from './theme/baseThemeValues';
94
96
 
97
+ // Pre-built themes (these actually generate CSS variables)
98
+ export { lightTheme } from './themes/light.css';
99
+ export { darkTheme } from './themes/dark.css';
100
+
95
101
  // Theme utilities
96
102
  export { createThemeOverride, getThemeContract, getThemeValues, toggleTheme, setTheme, getCurrentTheme, type ThemeValues } from './theme/utils';
@@ -0,0 +1,19 @@
1
+ import { createGlobalTheme } from '@vanilla-extract/css';
2
+ import { themeContract } from '../theme/contract.css';
3
+ import { baseDarkTheme } from '../theme/baseThemeValues';
4
+
5
+ // Create the dark theme at module level so Vanilla Extract can process it
6
+ export const darkTheme = createGlobalTheme('html[data-theme="dark"]', themeContract, {
7
+ colors: baseDarkTheme.colors,
8
+ space: baseDarkTheme.space,
9
+ radii: baseDarkTheme.radii,
10
+ fonts: baseDarkTheme.fonts,
11
+ maxWidth: `${baseDarkTheme.maxWidth}px`,
12
+ fontSizes: baseDarkTheme.fontSizes,
13
+ fontWeights: baseDarkTheme.fontWeights,
14
+ lineHeights: baseDarkTheme.lineHeights,
15
+ shadows: baseDarkTheme.shadows,
16
+ section: baseDarkTheme.section,
17
+ header: baseDarkTheme.header,
18
+ footer: baseDarkTheme.footer,
19
+ });
@@ -0,0 +1,19 @@
1
+ import { createGlobalTheme } from '@vanilla-extract/css';
2
+ import { themeContract } from '../theme/contract.css';
3
+ import { baseLightTheme } from '../theme/baseThemeValues';
4
+
5
+ // Create the light theme at module level so Vanilla Extract can process it
6
+ export const lightTheme = createGlobalTheme(':root', themeContract, {
7
+ colors: baseLightTheme.colors,
8
+ space: baseLightTheme.space,
9
+ radii: baseLightTheme.radii,
10
+ fonts: baseLightTheme.fonts,
11
+ maxWidth: `${baseLightTheme.maxWidth}px`,
12
+ fontSizes: baseLightTheme.fontSizes,
13
+ fontWeights: baseLightTheme.fontWeights,
14
+ lineHeights: baseLightTheme.lineHeights,
15
+ shadows: baseLightTheme.shadows,
16
+ section: baseLightTheme.section,
17
+ header: baseLightTheme.header,
18
+ footer: baseLightTheme.footer,
19
+ });
@@ -0,0 +1,52 @@
1
+ import { baseLightTheme, baseDarkTheme } from '../theme/baseThemeValues';
2
+
3
+ // Type for partial theme overrides
4
+ export type ThemeOverrides = {
5
+ colors?: Partial<typeof baseLightTheme.colors>;
6
+ space?: Partial<typeof baseLightTheme.space>;
7
+ radii?: Partial<typeof baseLightTheme.radii>;
8
+ fonts?: Partial<typeof baseLightTheme.fonts>;
9
+ maxWidth?: string;
10
+ fontSizes?: Partial<typeof baseLightTheme.fontSizes>;
11
+ fontWeights?: Partial<typeof baseLightTheme.fontWeights>;
12
+ lineHeights?: Partial<typeof baseLightTheme.lineHeights>;
13
+ shadows?: Partial<typeof baseLightTheme.shadows>;
14
+ section?: Partial<typeof baseLightTheme.section>;
15
+ header?: Partial<typeof baseLightTheme.header>;
16
+ footer?: Partial<typeof baseLightTheme.footer>;
17
+ };
18
+
19
+ // Utility to merge overrides with base theme
20
+ export const createCustomLightTheme = (overrides: ThemeOverrides = {}) => {
21
+ return {
22
+ colors: { ...baseLightTheme.colors, ...overrides.colors },
23
+ space: { ...baseLightTheme.space, ...overrides.space },
24
+ radii: { ...baseLightTheme.radii, ...overrides.radii },
25
+ fonts: { ...baseLightTheme.fonts, ...overrides.fonts },
26
+ maxWidth: overrides.maxWidth || `${baseLightTheme.maxWidth}px`,
27
+ fontSizes: { ...baseLightTheme.fontSizes, ...overrides.fontSizes },
28
+ fontWeights: { ...baseLightTheme.fontWeights, ...overrides.fontWeights },
29
+ lineHeights: { ...baseLightTheme.lineHeights, ...overrides.lineHeights },
30
+ shadows: { ...baseLightTheme.shadows, ...overrides.shadows },
31
+ section: { ...baseLightTheme.section, ...overrides.section },
32
+ header: { ...baseLightTheme.header, ...overrides.header },
33
+ footer: { ...baseLightTheme.footer, ...overrides.footer },
34
+ };
35
+ };
36
+
37
+ export const createCustomDarkTheme = (overrides: ThemeOverrides = {}) => {
38
+ return {
39
+ colors: { ...baseDarkTheme.colors, ...overrides.colors },
40
+ space: { ...baseDarkTheme.space, ...overrides.space },
41
+ radii: { ...baseDarkTheme.radii, ...overrides.radii },
42
+ fonts: { ...baseDarkTheme.fonts, ...overrides.fonts },
43
+ maxWidth: overrides.maxWidth || `${baseDarkTheme.maxWidth}px`,
44
+ fontSizes: { ...baseDarkTheme.fontSizes, ...overrides.fontSizes },
45
+ fontWeights: { ...baseDarkTheme.fontWeights, ...overrides.fontWeights },
46
+ lineHeights: { ...baseDarkTheme.lineHeights, ...overrides.lineHeights },
47
+ shadows: { ...baseDarkTheme.shadows, ...overrides.shadows },
48
+ section: { ...baseDarkTheme.section, ...overrides.section },
49
+ header: { ...baseDarkTheme.header, ...overrides.header },
50
+ footer: { ...baseDarkTheme.footer, ...overrides.footer },
51
+ };
52
+ };
@@ -1,4 +1,6 @@
1
+ import { createGlobalTheme } from '@vanilla-extract/css';
1
2
  import { baseDarkTheme, baseLightTheme } from '../theme/baseThemeValues';
3
+ import { themeContract } from '../theme/contract.css';
2
4
 
3
5
  // Type for partial theme overrides
4
6
  export type ThemeOverrides = {
@@ -6,19 +8,19 @@ export type ThemeOverrides = {
6
8
  space?: Partial<typeof baseLightTheme.space>;
7
9
  radii?: Partial<typeof baseLightTheme.radii>;
8
10
  fonts?: Partial<typeof baseLightTheme.fonts>;
9
- maxWidth?: string;
11
+ maxWidth?: Partial<typeof baseLightTheme.maxWidth>;
10
12
  fontSizes?: Partial<typeof baseLightTheme.fontSizes>;
11
- fontWeights?: Partial<typeof baseLightTheme.fontWeights>;
12
- lineHeights?: Partial<typeof baseLightTheme.lineHeights>;
13
- shadows?: Partial<typeof baseLightTheme.shadows>;
14
- section?: Partial<typeof baseLightTheme.section>;
15
- header?: Partial<typeof baseLightTheme.header>;
16
- footer?: Partial<typeof baseLightTheme.footer>;
13
+ fontWeights?: Partial<typeof baseLightTheme.fontSizes>;
14
+ lineHeights?: Partial<typeof baseLightTheme.fontSizes>;
15
+ shadows?: Partial<typeof baseLightTheme.fontSizes>;
16
+ section?: Partial<typeof baseLightTheme.fontSizes>;
17
+ header?: Partial<typeof baseLightTheme.fontSizes>;
18
+ footer?: Partial<typeof baseLightTheme.fontSizes>;
17
19
  };
18
20
 
19
- // Utility to create a theme object with partial overrides over light theme base
20
- const createAppTheme = (overrides: ThemeOverrides = {}) => {
21
- return {
21
+ // Utility to create a theme with partial overrides over light theme base
22
+ const createAppTheme = (selector: string, overrides: ThemeOverrides = {}) => {
23
+ return createGlobalTheme(selector, themeContract, {
22
24
  colors: {
23
25
  ...baseLightTheme.colors,
24
26
  ...overrides.colors,
@@ -35,7 +37,7 @@ const createAppTheme = (overrides: ThemeOverrides = {}) => {
35
37
  ...baseLightTheme.fonts,
36
38
  ...overrides.fonts,
37
39
  },
38
- maxWidth: overrides.maxWidth || `${baseLightTheme.maxWidth}px`,
40
+ maxWidth: `${baseLightTheme.maxWidth || overrides.maxWidth}`,
39
41
  fontSizes: {
40
42
  ...baseLightTheme.fontSizes,
41
43
  ...overrides.fontSizes,
@@ -64,12 +66,12 @@ const createAppTheme = (overrides: ThemeOverrides = {}) => {
64
66
  ...baseLightTheme.footer,
65
67
  ...overrides.footer,
66
68
  },
67
- };
69
+ });
68
70
  };
69
71
 
70
- // Utility to create a theme object with partial overrides over dark theme base
71
- const createAppDarkTheme = (overrides: ThemeOverrides = {}) => {
72
- return {
72
+ // Utility to create a theme with partial overrides over dark theme base
73
+ const createAppDarkTheme = (selector: string, overrides: ThemeOverrides = {}) => {
74
+ return createGlobalTheme(selector, themeContract, {
73
75
  colors: {
74
76
  ...baseDarkTheme.colors,
75
77
  ...overrides.colors,
@@ -115,15 +117,15 @@ const createAppDarkTheme = (overrides: ThemeOverrides = {}) => {
115
117
  ...baseDarkTheme.footer,
116
118
  ...overrides.footer,
117
119
  },
118
- };
120
+ });
119
121
  };
120
122
 
121
- // Returns theme object for light theme - consuming app must call createGlobalTheme
123
+ // Convenience function for light theme (extends base light theme)
122
124
  export const createLightTheme = (overrides: ThemeOverrides = {}) => {
123
- return createAppTheme(overrides);
125
+ return createAppTheme('html', overrides);
124
126
  };
125
127
 
126
- // Returns theme object for dark theme - consuming app must call createGlobalTheme
128
+ // Convenience function for dark theme (extends base dark theme)
127
129
  export const createDarkTheme = (overrides: ThemeOverrides = {}) => {
128
- return createAppDarkTheme(overrides);
129
- };
130
+ return createAppDarkTheme('html[data-theme="dark"]', overrides);
131
+ };
@@ -0,0 +1,10 @@
1
+ import { createGlobalTheme, createThemeContract } from '@vanilla-extract/css';
2
+ import { themeContract } from '../theme/contract.css';
3
+
4
+ // Create a higher-specificity theme that can override the base themes
5
+ export const themeOverrides = createThemeContract(themeContract);
6
+
7
+ // Export a utility to create override themes with custom selectors
8
+ export const createThemeOverride = (selector: string, values: Partial<typeof themeContract>) => {
9
+ return createGlobalTheme(selector, themeContract, values as any);
10
+ };
@@ -1,15 +0,0 @@
1
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2
- const deepMergeObjects = (obj1: any, obj2: any) => {
3
- for (const key in obj2) {
4
- if (obj2.hasOwnProperty(key)) {
5
- if (obj2[key] instanceof Object && obj1[key] instanceof Object) {
6
- obj1[key] = deepMergeObjects(obj1[key], obj2[key]);
7
- } else {
8
- obj1[key] = obj2[key];
9
- }
10
- }
11
- }
12
- return obj1;
13
- };
14
-
15
- export default deepMergeObjects;
@@ -1,30 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
-
3
- import { breakpoints } from '../assets/styles/mediaqueries';
4
-
5
- type BreakpointKey = keyof typeof breakpoints;
6
-
7
- export function useBreakpointKey(): number {
8
- const [breakpoint, setBreakpoint] = useState<BreakpointKey>('mobile');
9
-
10
- useEffect(() => {
11
- function handleResize() {
12
- const width = window.innerWidth;
13
-
14
- if (width >= breakpoints['2xl']) setBreakpoint('2xl');
15
- else if (width >= breakpoints.xl) setBreakpoint('xl');
16
- else if (width >= breakpoints.lg) setBreakpoint('lg');
17
- else if (width >= breakpoints.md) setBreakpoint('md');
18
- else if (width >= breakpoints.sm) setBreakpoint('sm');
19
- else setBreakpoint('mobile');
20
- }
21
-
22
- handleResize(); // init au mount
23
- window.addEventListener('resize', handleResize);
24
- return () => window.removeEventListener('resize', handleResize);
25
- }, []);
26
-
27
- // Map Breakpoint → Index numérique
28
- const order: BreakpointKey[] = ['mobile', 'sm', 'md', 'lg', 'xl', '2xl'];
29
- return order.indexOf(breakpoint);
30
- }
@@ -1,37 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
-
3
- function useWindowSize() {
4
- // Initialize state with undefined width/height so server and client renders match
5
- // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
6
- const [windowSize, setWindowSize] = useState<{
7
- width: undefined | number;
8
- height: undefined | number;
9
- }>({
10
- width: undefined,
11
- height: undefined,
12
- });
13
-
14
- useEffect(() => {
15
- // only execute all the code below in client side
16
- // Handler to call on window resize
17
- function handleResize() {
18
- // Set window width/height to state
19
- setWindowSize({
20
- width: window.innerWidth,
21
- height: window.innerHeight,
22
- });
23
- }
24
-
25
- // Add event listener
26
- window.addEventListener('resize', handleResize);
27
-
28
- // Call handler right away so state gets updated with initial window size
29
- handleResize();
30
-
31
- // Remove event listener on cleanup
32
- return () => window.removeEventListener('resize', handleResize);
33
- }, []); // Empty array ensures that effect is only run on mount
34
- return windowSize;
35
- }
36
-
37
- export default useWindowSize;