@latte-macchiat-io/latte-vanilla-components 0.0.325 → 0.0.327
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
@@ -6,9 +6,6 @@ import { queries } from '../../styles/mediaqueries';
|
|
6
6
|
import { themeContract } from '../../theme/contract.css';
|
7
7
|
|
8
8
|
import { generateResponsive } from '../../utils/generateResponsive';
|
9
|
-
import { generateResponsiveMedia } from '../../utils/generateResponsiveMedia';
|
10
|
-
import { generateResponsiveMediaCalc } from '../../utils/generateResponsiveMediaCalc';
|
11
|
-
import { mergeResponsiveMedias } from '../../utils/mergeResponsiveMedias';
|
12
9
|
|
13
10
|
export const carouselRecipe = recipe(
|
14
11
|
{
|
@@ -98,11 +95,9 @@ export const carouselNav = recipe(
|
|
98
95
|
pointerEvents: 'none',
|
99
96
|
justifyContent: 'flex-end',
|
100
97
|
|
101
|
-
'@media': {
|
102
|
-
|
103
|
-
|
104
|
-
}),
|
105
|
-
},
|
98
|
+
'@media': generateResponsive({
|
99
|
+
gap: themeContract.carousel.nav.gap,
|
100
|
+
}),
|
106
101
|
},
|
107
102
|
|
108
103
|
variants: {
|
@@ -122,14 +117,34 @@ export const carouselNav = recipe(
|
|
122
117
|
|
123
118
|
navPositionVertical: {
|
124
119
|
top: {
|
125
|
-
'@media':
|
120
|
+
'@media': generateResponsive(
|
121
|
+
{}, // pas de props "normales" ici
|
122
|
+
[
|
123
|
+
{
|
124
|
+
property: 'bottom',
|
125
|
+
base: '100%',
|
126
|
+
offset: themeContract.carousel.nav.positionVerticalOffset,
|
127
|
+
operator: '+',
|
128
|
+
},
|
129
|
+
]
|
130
|
+
),
|
126
131
|
},
|
127
132
|
center: {
|
128
133
|
top: '50%',
|
129
134
|
transform: 'translate(0%, -50%)',
|
130
135
|
},
|
131
136
|
bottom: {
|
132
|
-
'@media':
|
137
|
+
'@media': generateResponsive(
|
138
|
+
{}, // pas de props "normales" ici non plus
|
139
|
+
[
|
140
|
+
{
|
141
|
+
property: 'top',
|
142
|
+
base: '100%',
|
143
|
+
offset: themeContract.carousel.nav.positionVerticalOffset,
|
144
|
+
operator: '+',
|
145
|
+
},
|
146
|
+
]
|
147
|
+
),
|
133
148
|
},
|
134
149
|
},
|
135
150
|
},
|
@@ -167,12 +182,10 @@ export const carouselNavButton = style(
|
|
167
182
|
pointerEvents: 'none',
|
168
183
|
},
|
169
184
|
|
170
|
-
'@media': {
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
}),
|
175
|
-
},
|
185
|
+
'@media': generateResponsive({
|
186
|
+
width: themeContract.carousel.nav.width,
|
187
|
+
height: themeContract.carousel.nav.height,
|
188
|
+
}),
|
176
189
|
},
|
177
190
|
'carousel-nav-button'
|
178
191
|
);
|
@@ -214,12 +227,10 @@ export const carouselBullet = style(
|
|
214
227
|
transform: 'scale(1.2)',
|
215
228
|
},
|
216
229
|
|
217
|
-
'@media': {
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
}),
|
222
|
-
},
|
230
|
+
'@media': generateResponsive({
|
231
|
+
width: themeContract.carousel.bullet.width,
|
232
|
+
height: themeContract.carousel.bullet.height,
|
233
|
+
}),
|
223
234
|
},
|
224
235
|
'carousel-bullet'
|
225
236
|
);
|
@@ -1,17 +1,24 @@
|
|
1
|
+
// utils/generateResponsive.ts
|
1
2
|
import { queries } from '../styles/mediaqueries';
|
2
3
|
|
4
|
+
// Define the supported breakpoint keys
|
3
5
|
type BreakpointKey = 'mobile' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
6
|
+
|
7
|
+
// A responsive value can be a string, number, or anything with a toString method
|
4
8
|
type ResponsiveValue = string | number | { toString(): string };
|
9
|
+
|
10
|
+
// Map of breakpoint keys to responsive values
|
5
11
|
type BreakpointMap = Partial<Record<BreakpointKey, ResponsiveValue>>;
|
6
12
|
|
13
|
+
// Ordered list of breakpoints to iterate over
|
7
14
|
const BPS: BreakpointKey[] = ['mobile', 'sm', 'md', 'lg', 'xl', '2xl'];
|
8
15
|
|
9
16
|
/**
|
10
|
-
*
|
17
|
+
* Generates a fully responsive CSS object for Vanilla Extract
|
11
18
|
*
|
12
|
-
* @param props - normal CSS properties
|
13
|
-
* @param calcProps - optional array of calc() rules
|
14
|
-
* @returns object ready
|
19
|
+
* @param props - normal CSS properties, either a single value or responsive map
|
20
|
+
* @param calcProps - optional array of calc() rules for dynamic calculations
|
21
|
+
* @returns an object ready to use under `@media` in Vanilla Extract
|
15
22
|
*/
|
16
23
|
export function generateResponsive(
|
17
24
|
props: Record<string, ResponsiveValue | BreakpointMap>,
|
@@ -19,22 +26,25 @@ export function generateResponsive(
|
|
19
26
|
property: string;
|
20
27
|
base: ResponsiveValue | BreakpointMap;
|
21
28
|
offset: ResponsiveValue | BreakpointMap;
|
22
|
-
operator?: string; // + - * /
|
29
|
+
operator?: string; // + - * / etc.
|
23
30
|
}>
|
24
31
|
): Record<string, Record<string, string>> {
|
25
32
|
const result: Record<string, Record<string, string>> = {};
|
26
33
|
|
34
|
+
// Helper to convert a value to a proper CSS string
|
27
35
|
const toCssValue = (v: ResponsiveValue) => {
|
28
36
|
const s = String(v);
|
37
|
+
// If the value is a CSS variable, wrap it with var()
|
29
38
|
return s.startsWith('--') ? `var(${s})` : s;
|
30
39
|
};
|
31
40
|
|
32
|
-
// 1️⃣
|
41
|
+
// 1️⃣ Process normal CSS properties
|
33
42
|
for (const [cssProp, valOrMap] of Object.entries(props)) {
|
34
43
|
const isMapLike =
|
35
44
|
valOrMap && typeof valOrMap === 'object' && !Array.isArray(valOrMap) && Object.keys(valOrMap).some((k) => BPS.includes(k as BreakpointKey));
|
36
45
|
|
37
46
|
if (isMapLike) {
|
47
|
+
// Responsive map provided
|
38
48
|
const map = valOrMap as BreakpointMap;
|
39
49
|
for (const bp of BPS) {
|
40
50
|
const token = map[bp];
|
@@ -44,22 +54,34 @@ export function generateResponsive(
|
|
44
54
|
result[media][cssProp] = toCssValue(token);
|
45
55
|
}
|
46
56
|
} else {
|
57
|
+
// Single value, apply to all breakpoints
|
58
|
+
const token = valOrMap as ResponsiveValue;
|
47
59
|
for (const bp of BPS) {
|
48
60
|
const media = queries[bp as keyof typeof queries];
|
49
61
|
if (!result[media]) result[media] = {};
|
50
|
-
result[media][cssProp] = toCssValue(
|
62
|
+
result[media][cssProp] = toCssValue(token);
|
51
63
|
}
|
52
64
|
}
|
53
65
|
}
|
54
66
|
|
55
|
-
// 2️⃣
|
67
|
+
// 2️⃣ Process calc() properties if provided
|
56
68
|
if (calcProps) {
|
57
69
|
for (const { property, base, offset, operator = '+' } of calcProps) {
|
58
70
|
for (const bp of BPS) {
|
59
71
|
const media = queries[bp as keyof typeof queries];
|
60
|
-
|
61
|
-
|
72
|
+
|
73
|
+
// Safely extract the base value for the current breakpoint
|
74
|
+
const baseValue =
|
75
|
+
typeof base === 'object' && !Array.isArray(base) ? ((base as BreakpointMap)[bp] ?? Object.values(base as BreakpointMap)[0]) : base;
|
76
|
+
|
77
|
+
// Safely extract the offset value for the current breakpoint
|
78
|
+
const offsetValue =
|
79
|
+
typeof offset === 'object' && !Array.isArray(offset)
|
80
|
+
? ((offset as BreakpointMap)[bp] ?? Object.values(offset as BreakpointMap)[0])
|
81
|
+
: offset;
|
82
|
+
|
62
83
|
if (!result[media]) result[media] = {};
|
84
|
+
// Build the calc() CSS value
|
63
85
|
result[media][property] = `calc(${baseValue} ${operator} ${offsetValue})`;
|
64
86
|
}
|
65
87
|
}
|
@@ -1,32 +0,0 @@
|
|
1
|
-
import { queries } from '../styles/mediaqueries';
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Génère un objet @media pour Vanilla Extract avec des valeurs calculées (calc)
|
5
|
-
* Supporte les valeurs responsive issues du thème pour les deux opérandes.
|
6
|
-
*
|
7
|
-
* @param property - la propriété CSS (ex: 'top', 'bottom', 'marginTop'…)
|
8
|
-
* @param baseValue - soit une string, soit un objet responsive (themeContract.*)
|
9
|
-
* @param offsetValues - un objet responsive avec des offsets (ex: themeContract.carousel.nav.positionVerticalOffset)
|
10
|
-
* @param operator - opérateur de calcul ('+' ou '-') [par défaut '+']
|
11
|
-
* @returns Un objet directement utilisable dans `@media`
|
12
|
-
*/
|
13
|
-
export function generateResponsiveMediaCalc(
|
14
|
-
property: string,
|
15
|
-
baseValue: string | Record<string, string>,
|
16
|
-
offsetValues: Record<string, string>,
|
17
|
-
operator: string = '+'
|
18
|
-
) {
|
19
|
-
const result: Record<string, Record<string, string>> = {};
|
20
|
-
|
21
|
-
for (const [bp, query] of Object.entries(queries)) {
|
22
|
-
const base = typeof baseValue === 'string' ? baseValue : (baseValue[bp] ?? Object.values(baseValue)[0]); // fallback pour mobile
|
23
|
-
const offset = offsetValues[bp];
|
24
|
-
if (offset) {
|
25
|
-
result[query] = {
|
26
|
-
[property]: `calc(${base} ${operator} ${offset})`,
|
27
|
-
};
|
28
|
-
}
|
29
|
-
}
|
30
|
-
|
31
|
-
return result;
|
32
|
-
}
|
@@ -1,21 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Fusionne plusieurs objets responsive générés pour Vanilla Extract
|
3
|
-
* sans écraser les valeurs existantes des mêmes breakpoints.
|
4
|
-
*
|
5
|
-
* Exemple :
|
6
|
-
* mergeResponsiveMedias(a, b) => combine les clés communes
|
7
|
-
*/
|
8
|
-
export function mergeResponsiveMedias(...mediaObjects: Record<string, Record<string, string>>[]): Record<string, Record<string, string>> {
|
9
|
-
const merged: Record<string, Record<string, string>> = {};
|
10
|
-
|
11
|
-
for (const obj of mediaObjects) {
|
12
|
-
for (const [query, styles] of Object.entries(obj)) {
|
13
|
-
merged[query] = {
|
14
|
-
...(merged[query] || {}),
|
15
|
-
...styles,
|
16
|
-
};
|
17
|
-
}
|
18
|
-
}
|
19
|
-
|
20
|
-
return merged;
|
21
|
-
}
|