@vinicunca/unocss-preset 1.18.0 → 1.20.0

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.
@@ -1,8 +1,6 @@
1
- import { c as compressCSS } from '../shared/unocss-preset.Csuyh8w-.mjs';
2
- import '@unocss/core';
3
- import '@vinicunca/perkakas';
4
- import 'defu';
1
+ import { compressCSS } from "./utils-DFMuAdWB.js";
5
2
 
3
+ //#region src/presets/akar/index.ts
6
4
  const drawerAkarCss = `
7
5
  [data-akar-drawer] {
8
6
  touch-action: none;
@@ -261,14 +259,11 @@ const drawerAkarCss = `
261
259
  }
262
260
  }`;
263
261
  function presetAkar() {
264
- return {
265
- name: "unocss-preset-akar",
266
- preflights: [
267
- {
268
- getCSS: () => compressCSS(drawerAkarCss)
269
- }
270
- ]
271
- };
262
+ return {
263
+ name: "unocss-preset-akar",
264
+ preflights: [{ getCSS: () => compressCSS(drawerAkarCss) }]
265
+ };
272
266
  }
273
267
 
274
- export { presetAkar };
268
+ //#endregion
269
+ export { presetAkar };
@@ -0,0 +1,150 @@
1
+ import { layerMeta } from "./meta-hBxi8oC8.js";
2
+ import { h } from "@unocss/preset-mini/utils";
3
+
4
+ //#region src/presets/animation/animation.entity.ts
5
+ const CSS_VARIABLE_PREFIX = "--vin";
6
+ const ENTER_ANIMATION_NAME = "vin-in";
7
+ const EXIT_ANIMATION_NAME = "vin-out";
8
+
9
+ //#endregion
10
+ //#region src/presets/animation/animation.util.ts
11
+ function handleSlide(val, dir) {
12
+ let value = h.cssvar.fraction.rem(val || DEFAULT_SLIDE_TRANSLATE);
13
+ if (!value) return [];
14
+ if (!value.startsWith("var(--") && ["left", "top"].includes(dir ?? "")) {
15
+ if (value.startsWith("-")) value = value.slice(1);
16
+ else if (value !== "0") value = `-${value}`;
17
+ }
18
+ return [value, dir];
19
+ }
20
+
21
+ //#endregion
22
+ //#region src/presets/animation/animation.rule.ts
23
+ const DEFAULT_FADE_OPACITY = "0";
24
+ const DEFAULT_ZOOM_SCALE = "0";
25
+ const DEFAULT_SPIN_DEGREE = "30deg";
26
+ const DEFAULT_SLIDE_TRANSLATE = "100%";
27
+ const DIRECTIONS_AUTOCOMPLETE = "(t|b|l|r|top|bottom|left|right)";
28
+ const fadeRules = [[
29
+ /^fade-in(?:-(.+))?$/,
30
+ ([, op]) => ({ [`${CSS_VARIABLE_PREFIX}-enter-opacity`]: h.cssvar.percent(op || DEFAULT_FADE_OPACITY) }),
31
+ { autocomplete: "fade-(in|out)-<percent>" }
32
+ ], [/^fade-out(?:-(.+))?$/, ([, op]) => ({ [`${CSS_VARIABLE_PREFIX}-exit-opacity`]: h.cssvar.percent(op || DEFAULT_FADE_OPACITY) })]];
33
+ const zoomRules = [[
34
+ /^zoom-in(?:-(.+))?$/,
35
+ ([, scale]) => ({ [`${CSS_VARIABLE_PREFIX}-enter-scale`]: h.cssvar.fraction.percent(scale || DEFAULT_ZOOM_SCALE) }),
36
+ { autocomplete: "zoom-(in|out)-<percent>" }
37
+ ], [/^zoom-out(?:-(.+))?$/, ([, scale]) => ({ [`${CSS_VARIABLE_PREFIX}-exit-scale`]: h.cssvar.fraction.percent(scale || DEFAULT_ZOOM_SCALE) })]];
38
+ const spinRules = [[
39
+ /^spin-in(?:-(.+))?$/,
40
+ ([, deg]) => ({ [`${CSS_VARIABLE_PREFIX}-enter-rotate`]: h.cssvar.degree(deg || DEFAULT_SPIN_DEGREE) }),
41
+ {
42
+ autocomplete: "spin-(in|out)-<percent>",
43
+ layer: "animation"
44
+ }
45
+ ], [/^spin-out(?:-(.+))?$/, ([, deg]) => ({ [`${CSS_VARIABLE_PREFIX}-exit-rotate`]: h.cssvar.degree(deg || DEFAULT_SPIN_DEGREE) })]];
46
+ const slideRules = [[
47
+ /^slide-in(?:-from)?-([tblr]|top|bottom|left|right)(?:-(.+))?$/,
48
+ ([, dir, val]) => {
49
+ const [value, direction] = handleSlide(val, dir);
50
+ if (!value) return;
51
+ switch (direction) {
52
+ case "bottom":
53
+ case "top": return { [`${CSS_VARIABLE_PREFIX}-enter-translate-y`]: value };
54
+ case "left":
55
+ case "right": return { [`${CSS_VARIABLE_PREFIX}-enter-translate-x`]: value };
56
+ }
57
+ },
58
+ { autocomplete: [
59
+ `slide-(in|out)-${DIRECTIONS_AUTOCOMPLETE}-<percent>`,
60
+ `slide-(in|out)-${DIRECTIONS_AUTOCOMPLETE}-full`,
61
+ `slide-in-from-${DIRECTIONS_AUTOCOMPLETE}-<percent>`,
62
+ `slide-in-from-${DIRECTIONS_AUTOCOMPLETE}-full`
63
+ ] }
64
+ ], [
65
+ /^slide-out(?:-to)?-([tblr]|top|bottom|left|right)(?:-(.+))?$/,
66
+ ([, dir, val]) => {
67
+ const [value, direction] = handleSlide(val, dir);
68
+ if (!value) return;
69
+ switch (direction) {
70
+ case "bottom":
71
+ case "top": return { [`${CSS_VARIABLE_PREFIX}-exit-translate-y`]: value };
72
+ case "left":
73
+ case "right": return { [`${CSS_VARIABLE_PREFIX}-exit-translate-x`]: value };
74
+ }
75
+ },
76
+ { autocomplete: [`slide-out-to-${DIRECTIONS_AUTOCOMPLETE}-<percent>`, `slide-out-to-${DIRECTIONS_AUTOCOMPLETE}-full`] }
77
+ ]];
78
+ const animationRules = [
79
+ ...fadeRules,
80
+ ...zoomRules,
81
+ ...spinRules,
82
+ ...slideRules
83
+ ];
84
+ /**
85
+ * We need to add the layers into the rules.
86
+ * So we need to run this immediately.
87
+ */
88
+ for (const rule of animationRules) rule[2] = Object.assign(rule[2] || {}, layerMeta);
89
+
90
+ //#endregion
91
+ //#region src/presets/animation/animation.shortcut.ts
92
+ function animationShortcuts(options) {
93
+ function getSharedAnimationProperties() {
94
+ return {
95
+ "animation-duration": options.duration ? `${options.duration}${options.unit}` : "150ms",
96
+ ...options.delay && { "animation-delay": `${options.delay}${options.unit}` },
97
+ ...options.direction && { "animation-direction": options.direction },
98
+ ...options.fillMode && { "animation-fill-mode": options.fillMode },
99
+ ...options.iterationCount && { "animation-iteration-count": options.iterationCount },
100
+ ...options.playState && { "animation-play-state": options.playState },
101
+ ...options.timingFunction && { "animation-timing-function": options.timingFunction }
102
+ };
103
+ }
104
+ return [[
105
+ /^animate-in$/,
106
+ () => [`keyframes-${ENTER_ANIMATION_NAME}`, {
107
+ "animation-name": ENTER_ANIMATION_NAME,
108
+ ...getSharedAnimationProperties(),
109
+ [`${CSS_VARIABLE_PREFIX}-enter-opacity`]: "initial",
110
+ [`${CSS_VARIABLE_PREFIX}-enter-scale`]: "initial",
111
+ [`${CSS_VARIABLE_PREFIX}-enter-rotate`]: "initial",
112
+ [`${CSS_VARIABLE_PREFIX}-enter-translate-x`]: "initial",
113
+ [`${CSS_VARIABLE_PREFIX}-enter-translate-y`]: "initial"
114
+ }],
115
+ { autocomplete: "animate-in" }
116
+ ], [
117
+ /^animate-out$/,
118
+ () => [`keyframes-${EXIT_ANIMATION_NAME}`, {
119
+ "animation-name": EXIT_ANIMATION_NAME,
120
+ ...getSharedAnimationProperties(),
121
+ [`${CSS_VARIABLE_PREFIX}-exit-opacity`]: "initial",
122
+ [`${CSS_VARIABLE_PREFIX}-exit-scale`]: "initial",
123
+ [`${CSS_VARIABLE_PREFIX}-exit-rotate`]: "initial",
124
+ [`${CSS_VARIABLE_PREFIX}-exit-translate-x`]: "initial",
125
+ [`${CSS_VARIABLE_PREFIX}-exit-translate-y`]: "initial"
126
+ }],
127
+ { autocomplete: "animate-out" }
128
+ ]];
129
+ }
130
+
131
+ //#endregion
132
+ //#region src/presets/animation/animation.theme.ts
133
+ const animationTheme = { keyframes: {
134
+ [ENTER_ANIMATION_NAME]: `{from{opacity:var(${CSS_VARIABLE_PREFIX}-enter-opacity,1);transform:translate3d(var(${CSS_VARIABLE_PREFIX}-enter-translate-x,0),var(${CSS_VARIABLE_PREFIX}-enter-translate-y,0),0) scale3d(var(${CSS_VARIABLE_PREFIX}-enter-scale,1),var(${CSS_VARIABLE_PREFIX}-enter-scale,1),var(${CSS_VARIABLE_PREFIX}-enter-scale,1)) rotate(var(${CSS_VARIABLE_PREFIX}-enter-rotate,0))}}`,
135
+ [EXIT_ANIMATION_NAME]: `{to{opacity:var(${CSS_VARIABLE_PREFIX}-exit-opacity,1);transform:translate3d(var(${CSS_VARIABLE_PREFIX}-exit-translate-x,0),var(${CSS_VARIABLE_PREFIX}-exit-translate-y,0),0) scale3d(var(${CSS_VARIABLE_PREFIX}-exit-scale,1),var(${CSS_VARIABLE_PREFIX}-exit-scale,1),var(${CSS_VARIABLE_PREFIX}-exit-scale,1)) rotate(var(${CSS_VARIABLE_PREFIX}-exit-rotate,0))}}`
136
+ } };
137
+
138
+ //#endregion
139
+ //#region src/presets/animation/index.ts
140
+ function presetAnimation(options) {
141
+ return {
142
+ name: "unocss-preset-animation",
143
+ theme: { animation: animationTheme },
144
+ shortcuts: [...animationShortcuts(options)],
145
+ rules: [...animationRules]
146
+ };
147
+ }
148
+
149
+ //#endregion
150
+ export { presetAnimation };
@@ -0,0 +1,344 @@
1
+ //#region src/presets/fluid/utils/regex.util.ts
2
+ const REGEX_PATTERNS_NUMERIC_VALUES = "(?:--)?(-?\\d+)?(?:--)?(-?\\d+)?$";
3
+ const REGEX_PATTERNS_RANGE_VALUES = "(?:--)?(-?\\d+)?(?:-([a-zA-Z0-9]+))?$";
4
+ function extractValuesFromRegexMatch(match) {
5
+ const [utility, matchMin, matchMax, , predefinedRangeName] = match;
6
+ return {
7
+ utility,
8
+ matchMin,
9
+ matchMax,
10
+ predefinedRangeName
11
+ };
12
+ }
13
+
14
+ //#endregion
15
+ //#region src/presets/fluid/utils/parser.util.ts
16
+ function invertAndParseNumber(value) {
17
+ if (!value) return 0;
18
+ if (value.includes("-")) return Number.parseInt(value.replace("-", ""));
19
+ return -Number.parseInt(value);
20
+ }
21
+
22
+ //#endregion
23
+ //#region src/presets/fluid/utils/validation.util.ts
24
+ function validateUtilityRange({ range, utility, config }) {
25
+ if (!config.ranges) throw new Error(`[unocss-vinicunca fluid] (${utility}) Trying to use predefined range ${range} but no ranges are defined.`);
26
+ if (!config.ranges[range]) throw new Error(`[unocss-vinicunca fluid] (${utility}) Trying to use predefined range ${range} but it is not defined in ranges.`);
27
+ return true;
28
+ }
29
+ function validateUtilityName({ match, config }) {
30
+ const { utility, matchMin, matchMax, predefinedRangeName } = extractValuesFromRegexMatch(match);
31
+ if (!predefinedRangeName && matchMin && matchMax) return true;
32
+ try {
33
+ validateUtilityRange({
34
+ range: predefinedRangeName,
35
+ utility,
36
+ config
37
+ });
38
+ } catch (error) {
39
+ console.warn(error.message);
40
+ return false;
41
+ }
42
+ return true;
43
+ }
44
+
45
+ //#endregion
46
+ //#region src/presets/fluid/utils/rem.util.ts
47
+ function getRemMaxWidth(config) {
48
+ const maxWidth = config.extendMaxWidth || config.maxWidth;
49
+ if (config.useRemByDefault) return maxWidth;
50
+ else return maxWidth / config.remBase;
51
+ }
52
+ function getRemMinWidth(config) {
53
+ const minWidth = config.extendMinWidth || config.minWidth;
54
+ if (config.useRemByDefault) return minWidth;
55
+ else return minWidth / config.remBase;
56
+ }
57
+ function toRem(value, config) {
58
+ if (config.useRemByDefault) return value;
59
+ else return value / config.remBase;
60
+ }
61
+ /**
62
+ * Calculates the relative size based on the original viewport size and the new viewport size.
63
+ * This allows you to extend the min and max sizes of the fluid layout keeping the proportions.
64
+ * This function is used for the extendMinWidth and extendMaxWidth options.
65
+ * The result of this value is used to calculate the min and max values in rem when the viewport are extended.
66
+ */
67
+ function calculateRelativeSize({ originalViewPortMin, originalMinSize, originalMaxSize, originalViewPortMax, newViewPortSize }) {
68
+ const slope = (originalMaxSize - originalMinSize) / (originalViewPortMax - originalViewPortMin);
69
+ return slope * (newViewPortSize - originalViewPortMin) + originalMinSize;
70
+ }
71
+ /**
72
+ * Returns the min and max values in rem for the given match.
73
+ */
74
+ function extractRemBoundsFromMatch({ match, config }) {
75
+ let max, min;
76
+ const [utility, matchMin, matchMax, , predefinedRangeName] = match;
77
+ if (predefinedRangeName) {
78
+ validateUtilityRange({
79
+ range: predefinedRangeName,
80
+ utility,
81
+ config
82
+ });
83
+ const [minRange, maxRange] = config.ranges[predefinedRangeName];
84
+ min = toRem(minRange, config);
85
+ max = toRem(maxRange, config);
86
+ } else {
87
+ min = toRem(invertAndParseNumber(matchMin), config);
88
+ max = toRem(invertAndParseNumber(matchMax), config);
89
+ }
90
+ let relativeMin;
91
+ let relativeMax;
92
+ if (config.extendMinWidth) relativeMin = calculateRelativeSize({
93
+ originalViewPortMin: config.minWidth,
94
+ originalMinSize: min,
95
+ originalMaxSize: max,
96
+ originalViewPortMax: config.maxWidth,
97
+ newViewPortSize: config.extendMinWidth
98
+ });
99
+ if (config.extendMaxWidth) relativeMax = calculateRelativeSize({
100
+ originalViewPortMin: config.minWidth,
101
+ originalMinSize: min,
102
+ originalMaxSize: max,
103
+ originalViewPortMax: config.maxWidth,
104
+ newViewPortSize: config.extendMinWidth
105
+ });
106
+ return {
107
+ min: relativeMin ?? min,
108
+ max: relativeMax ?? max
109
+ };
110
+ }
111
+
112
+ //#endregion
113
+ //#region src/presets/fluid/utils/clamp.util.ts
114
+ /**
115
+ * Calculates the slope value for fluid.
116
+ *
117
+ * @param options - GetSlopeParams.
118
+ * @param options.min - The minimum value in the fluid range.
119
+ * @param options.max - The maximum value in the fluid range.
120
+ * @param options.config - Configuration object for additional settings.
121
+ *
122
+ * @returns The calculated slope value.
123
+ */
124
+ function getSlope({ min, max, config }) {
125
+ const remMaxWidth = getRemMaxWidth(config);
126
+ const remMinWidth = getRemMinWidth(config);
127
+ return (max - min) / (remMaxWidth - remMinWidth);
128
+ }
129
+ /**
130
+ * Calculates the intersection point for the fluid formula.
131
+ *
132
+ * @param options - GetIntersectionParams.
133
+ * @param options.min - The minimum value in the fluid range.
134
+ * @param options.slope - The slope value calculated for the fluid.
135
+ * @param options.minWidth - The minimum viewport width.
136
+ *
137
+ * @returns The calculated intersection point.
138
+ */
139
+ function getIntersection({ min, slope, minWidth }) {
140
+ return -minWidth * slope + min;
141
+ }
142
+ /**
143
+ * Calculates the slope percentage for the CSS 'clamp' function.
144
+ *
145
+ * @param options - GetSlopePercentageParams.
146
+ * @param options.min - The minimum value in the fluid range.
147
+ * @param options.max - The maximum value in the fluid range.
148
+ * @param options.config - Configuration object.
149
+ *
150
+ * @returns The slope value as a percentage for use in the 'clamp' function.
151
+ */
152
+ function getSlopePercentage({ min, max, config }) {
153
+ const slope = getSlope({
154
+ min,
155
+ max,
156
+ config
157
+ });
158
+ return slope * 100;
159
+ }
160
+ /**
161
+ * Generates a CSS 'clamp' function value for fluid.
162
+ *
163
+ * @param options - GetClampParams.
164
+ * @param options.min - The minimum value in the fluid range.
165
+ * @param options.max - The maximum value in the fluid range.
166
+ * @param options.config - Configuration object.
167
+ *
168
+ * @returns A string representing the CSS 'clamp' function.
169
+ */
170
+ function getClamp({ min, max, config }) {
171
+ const slope = getSlope({
172
+ min,
173
+ max,
174
+ config
175
+ });
176
+ const intersection = getIntersection({
177
+ min,
178
+ slope,
179
+ minWidth: getRemMinWidth(config)
180
+ });
181
+ const slopePercentage = getSlopePercentage({
182
+ min,
183
+ max,
184
+ config
185
+ });
186
+ const clampMin = Math.min(min, max);
187
+ const clampMax = Math.max(min, max);
188
+ return `clamp(${clampMin}rem, ${intersection.toFixed(4)}rem + ${slopePercentage.toFixed(4)}vw, ${clampMax}rem)`;
189
+ }
190
+ /**
191
+ * Generates a comment with the fluid values for the clamp CSS.
192
+ *
193
+ * @param options - GetClampCommentParams.
194
+ * @param options.match - The match array from the regex.
195
+ * @param options.config - Configuration object.
196
+ *
197
+ * @returns A string representing the comment for the 'clamp' function with fluid real values.
198
+ */
199
+ function getClampComment({ match, config }) {
200
+ if (!config.commentHelpers) return "";
201
+ const { predefinedRangeName, matchMin, matchMax } = extractValuesFromRegexMatch(match);
202
+ const predefinedRange = config.ranges && config.ranges[predefinedRangeName];
203
+ const isRem = config.useRemByDefault;
204
+ const min = predefinedRange ? predefinedRange[0] : -Number.parseInt(matchMin);
205
+ const max = predefinedRange ? predefinedRange[1] : -Number.parseInt(matchMax);
206
+ const unit = isRem ? "rem" : "px";
207
+ return `/* ${min}${unit} -> ${max}${unit} */`;
208
+ }
209
+
210
+ //#endregion
211
+ //#region src/presets/fluid/utils/constant.util.ts
212
+ const FLUID_UTILITIES = {
213
+ "fluid-text": "font-size",
214
+ "fluid-w": "width",
215
+ "fluid-min-w": "min-width",
216
+ "fluid-max-w": "max-width",
217
+ "fluid-h": "height",
218
+ "fluid-min-h": "min-height",
219
+ "fluid-max-h": "max-height",
220
+ "fluid-p": "padding",
221
+ "fluid-pt": "padding-top",
222
+ "fluid-pb": "padding-bottom",
223
+ "fluid-pl": "padding-left",
224
+ "fluid-pr": "padding-right",
225
+ "fluid-px": ["padding-left", "padding-right"],
226
+ "fluid-py": ["padding-top", "padding-bottom"],
227
+ "fluid-m": "margin",
228
+ "fluid-mt": "margin-top",
229
+ "fluid-mb": "margin-bottom",
230
+ "fluid-ml": "margin-left",
231
+ "fluid-mr": "margin-right",
232
+ "fluid-mx": ["margin-left", "margin-right"],
233
+ "fluid-my": ["margin-top", "margin-bottom"],
234
+ "fluid-gap": "gap",
235
+ "fluid-gap-x": "column-gap",
236
+ "fluid-gap-y": "row-gap",
237
+ "fluid-indent": "text-indent",
238
+ "fluid-scroll-m": "scroll-margin",
239
+ "fluid-scroll-mt": "scroll-margin-top",
240
+ "fluid-scroll-mb": "scroll-margin-bottom",
241
+ "fluid-scroll-ml": "scroll-margin-left",
242
+ "fluid-scroll-mr": "scroll-margin-right",
243
+ "fluid-scroll-mx": ["scroll-margin-left", "scroll-margin-right"],
244
+ "fluid-scroll-my": ["scroll-margin-top", "scroll-margin-bottom"],
245
+ "fluid-scroll-ms": "scroll-margin-inline-start",
246
+ "fluid-scroll-me": "scroll-margin-inline-end",
247
+ "fluid-scroll-p": "scroll-padding",
248
+ "fluid-scroll-pt": "scroll-padding-top",
249
+ "fluid-scroll-pb": "scroll-padding-bottom",
250
+ "fluid-scroll-pl": "scroll-padding-left",
251
+ "fluid-scroll-pr": "scroll-padding-right",
252
+ "fluid-scroll-px": ["scroll-padding-left", "scroll-padding-right"],
253
+ "fluid-scroll-py": ["scroll-padding-top", "scroll-padding-bottom"],
254
+ "fluid-scroll-ps": "scroll-padding-inline-start",
255
+ "fluid-scroll-pe": "scroll-padding-inline-end",
256
+ "fluid-leading": "line-height",
257
+ "fluid-top": "top",
258
+ "fluid-right": "right",
259
+ "fluid-bottom": "bottom",
260
+ "fluid-left": "left",
261
+ "fluid-inset": "inset",
262
+ "fluid-inset-x": ["left", "right"],
263
+ "fluid-inset-y": ["top", "bottom"]
264
+ };
265
+
266
+ //#endregion
267
+ //#region src/presets/fluid/utils/rule.util.ts
268
+ function buildSinglePropertyRule({ match, config, property }) {
269
+ if (!validateUtilityName({
270
+ match,
271
+ config
272
+ })) return "";
273
+ const { min, max } = extractRemBoundsFromMatch({
274
+ match,
275
+ config
276
+ });
277
+ return { [`${property}`]: getClamp({
278
+ min,
279
+ max,
280
+ config
281
+ }) + getClampComment({
282
+ match,
283
+ config
284
+ }) };
285
+ }
286
+ function buildMultiplePropertiesRule({ match, config, properties }) {
287
+ if (!validateUtilityName({
288
+ match,
289
+ config
290
+ }) || !Array.isArray(properties)) return "";
291
+ const { min, max } = extractRemBoundsFromMatch({
292
+ match,
293
+ config
294
+ });
295
+ const selectors = {};
296
+ properties.forEach((property) => {
297
+ selectors[property] = getClamp({
298
+ min,
299
+ max,
300
+ config
301
+ }) + getClampComment({
302
+ match,
303
+ config
304
+ });
305
+ });
306
+ return { ...selectors };
307
+ }
308
+ function buildRule({ name, properties, config }) {
309
+ const regexPattersNumericValues = `^${name}${REGEX_PATTERNS_NUMERIC_VALUES}`;
310
+ const regexPattersRangeValues = `^${name}${REGEX_PATTERNS_RANGE_VALUES}`;
311
+ const regexPattern = `${regexPattersNumericValues}|${regexPattersRangeValues}`;
312
+ const regex = new RegExp(regexPattern);
313
+ if (Array.isArray(properties)) return [[regex, (match) => buildMultiplePropertiesRule({
314
+ match,
315
+ config,
316
+ properties
317
+ })]];
318
+ else return [[regex, (match) => buildSinglePropertyRule({
319
+ match,
320
+ config,
321
+ property: properties
322
+ })]];
323
+ }
324
+ function buildFluidRules(config) {
325
+ return Object.entries(FLUID_UTILITIES).flatMap(([name, property]) => {
326
+ return buildRule({
327
+ name,
328
+ properties: property,
329
+ config
330
+ });
331
+ });
332
+ }
333
+
334
+ //#endregion
335
+ //#region src/presets/fluid/index.ts
336
+ function presetFluid(options) {
337
+ return {
338
+ name: "unocss-preset-fluid",
339
+ rules: [...buildFluidRules(options)]
340
+ };
341
+ }
342
+
343
+ //#endregion
344
+ export { presetFluid };