Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@warp-ds/uno

Package Overview
Dependencies
Maintainers
1
Versions
135
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@warp-ds/uno - npm Package Compare versions

Comparing version 0.0.11 to 0.0.12

.github/workflows/lint.pr.yml

16

checkFabricClasses.js

@@ -1,12 +0,12 @@

import { createGenerator } from '@unocss/core'
import presetEngine from '#plugin'
import { buildList } from '@warp-ds/fabric-parity-checker'
import { createGenerator } from '@unocss/core';
import presetEngine from '#plugin';
import { buildList } from '@warp-ds/fabric-parity-checker';
const fabricClassListWithoutClassDots = buildList().map(e => e.replace('.', ''))
const fabricClassListWithoutClassDots = buildList().map(e => e.replace('.', ''));
const uno = createGenerator({ presets: [presetEngine()] })
const fabricClasses = await uno.generate(fabricClassListWithoutClassDots)
const uno = createGenerator({ presets: [presetEngine()] });
const fabricClasses = await uno.generate(fabricClassListWithoutClassDots);
fabricClassListWithoutClassDots.forEach(className => {
if (!fabricClasses.matched.has(className)) console.log("MISSING", className)
})
if (!fabricClasses.matched.has(className)) console.log("MISSING", className);
});
# These Fabric css rules will no longer be supported or need rethinking in Warp
### aspect ratio
- aspect-w and aspect-h are deprecated in favor of the aspect-1/1 form
- aspect-none - no support, not needed anymore since we have more responsive breakpoint support
### focus ring
- focus-ring :: prefer focusable
### Flex

@@ -4,0 +12,0 @@

@@ -1,1 +0,1 @@

import 'uno.css'
import 'uno.css';

@@ -1,9 +0,36 @@

import { createGenerator } from '@unocss/core'
import { presetWarp } from '#plugin'
import { parseArgs } from 'node:util';
import { createGenerator } from '@unocss/core';
import { presetWarp } from '#plugin';
const uno = createGenerator({ presets: [presetWarp()] })
const devClasses = ['!m-16', 'opacity-50']
const cliClasses = process.argv.slice(2)
const classes = cliClasses.length ? cliClasses : devClasses
const result = await uno.generate(classes)
console.log(result.css)
const {
values: { cliClasses, ...options },
} = parseArgs({
options: {
cliClasses: {
type: 'string',
short: 'c',
},
development: {
type: 'boolean',
},
externalClasses: {
type: 'boolean',
},
externalizeClasses: {
type: 'boolean',
},
usePixels: {
type: 'boolean',
},
usePreflight: {
type: 'boolean',
},
},
});
const uno = createGenerator({ presets: [presetWarp( options )] });
const devClasses = ['m-16!', 'opacity-50'];
const classes = cliClasses ?? devClasses;
const result = await uno.generate(classes);
console.log(result.css);
{
"name": "@warp-ds/uno",
"version": "0.0.11",
"version": "0.0.12",
"type": "module",

@@ -18,2 +18,3 @@ "exports": {

"#preflights": "./src/_preflights/index.js",
"#postprocess": "./src/postprocessor.js",
"#bounding": "./src/bounding.js",

@@ -27,3 +28,5 @@ "#bounds": "./src/bounds.js"

"build": "rollup -c",
"version": "pnpm test && pnpm build && pnpm publish"
"version": "pnpm test && pnpm build && pnpm publish",
"lint": "eslint . --fix",
"lint:check": "eslint ."
},

@@ -40,9 +43,14 @@ "keywords": [],

"@unocss/autocomplete": "^0.49.1",
"@warp-ds/eslint-config": "^0.0.1",
"drnm": "^0.9.0",
"rollup": "^3.12.0",
"eslint": "^8.34.0",
"rollup": "^3.15.0",
"unocss": "^0.49.4",
"uvu": "^0.5.6",
"vite": "^4.1.1",
"vitest": "^0.28.3"
"vitest": "^0.28.5"
},
"eslintConfig": {
"extends": "@warp-ds"
}
}

@@ -1,5 +0,37 @@

# checking fabric classes
# drive - an UnoCSS preset
## use
## plugin API
### usePreflight
- `boolean`
- Forces preflights to be included
### development
- `boolean`
- Will include preflights and base classes when true. These would be 'externalized' to Eik in production builds.
### usePixels
- `boolean`
- Internal use only, for use on sites that are incompatible with root REM/`font-size` changes
## migration development
## checking fabric classes
1. Check out the `parity` project from warp-ds, get dependencies for the project
2. Link to the `parity` project from the `plugin` folder (this folder): `pnpm link ../parity`
3. Run `node checkFabricClasses.js`
## generating warp classes using command line
Run `node dev.js` or `pnpm dev`
Usage: node dev.js [-c <string> | --cliClasses=<string>] [--usePixels] [--development] [--externalClasses] [--externalizeClasses] [--usePreflight]
Example: `node dev.js --usePixels --development --cliClasses=m-2`
! Do not use shortcut when passing negative values, e.g. `node dev.js --cliClasses='-m-2! gap-2'`

@@ -1,3 +0,3 @@

import { defineConfig } from 'rollup'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import { defineConfig } from 'rollup';
import { nodeResolve } from '@rollup/plugin-node-resolve';

@@ -8,5 +8,5 @@ export default defineConfig({

file: './dist/drive.js',
format: 'esm'
format: 'esm',
},
plugins: [nodeResolve()]
})
plugins: [nodeResolve()],
});

@@ -1,3 +0,3 @@

import { formVariables } from './formVariables.js'
import { formElements } from './form-elements.js'
import { formVariables } from './formVariables.js';
import { formElements } from './form-elements.js';

@@ -8,4 +8,4 @@ // TODO - the export here should probably be an artifact so we get rid of deps and cruft

getCSS() {
return formVariables + formElements
}
}
return formVariables + formElements;
},
};

@@ -31,5 +31,4 @@ export const formElements = `

/* FIXME */
.input::placeholder {
color: blue;
color: var(--w-text-color-placeholder, blue);
opacity: 1;

@@ -102,2 +101,2 @@ }

}
`
`;

@@ -1,9 +0,9 @@

import { svgToDataUri } from './svg-to-data-uri.js'
import { svgToDataUri } from './svg-to-data-uri.js';
const encode = svg => `url("${svgToDataUri(svg)}")`
const encode = svg => `url("${svgToDataUri(svg)}")`;
// NB: we can't (easily) use a CSSvar for stroke here - need to just standardize on a color
const selectChevron = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20"><path stroke="#333" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M6 8l4 4 4-4"/></svg>`
const checkMark = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="white"><path d="M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z"/></svg>`
const checkDash = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><path stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8h8"/></svg>`
const selectChevron = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20"><path stroke="#333" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M6 8l4 4 4-4"/></svg>`;
const checkMark = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="white"><path d="M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z"/></svg>`;
const checkDash = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><path stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8h8"/></svg>`;

@@ -36,2 +36,2 @@ // most of these will go away once we get semantic tokens

}
`
`;

@@ -5,3 +5,3 @@ const REGEX = {

quotes: /"/g,
}
};

@@ -25,8 +25,8 @@ const collapseWhitespace = (str) => str.trim().replace(REGEX.whitespace, ' ');

// Strip the Byte-Order Mark if the SVG has one
if (svgString.charCodeAt(0) === 0xfeff) svgString = svgString.slice(1)
if (svgString.charCodeAt(0) === 0xfeff) svgString = svgString.slice(1);
const body = collapseWhitespace(svgString).replace(REGEX.quotes, "'")
return 'data:image/svg+xml,' + dataURIPayload(body)
const body = collapseWhitespace(svgString).replace(REGEX.quotes, "'");
return 'data:image/svg+xml,' + dataURIPayload(body);
}
export const toSrcset = (svgString) => svgToDataUri(svgString).replace(/ /g, '%20')
export const toSrcset = (svgString) => svgToDataUri(svgString).replace(/ /g, '%20');

@@ -1,5 +0,5 @@

import { twReset } from './tw-reset.js'
import { formPreflight } from './forms/export.js'
import { transformBase } from './transform.js'
import { twReset } from './tw-reset.js';
import { formPreflight } from './forms/export.js';
import { transformBase } from './transform.js';
export const preflights = [twReset, transformBase, formPreflight]
export const preflights = [twReset, transformBase, formPreflight];

@@ -1,2 +0,2 @@

import { entriesToCss } from '@unocss/core'
import { entriesToCss } from '@unocss/core';

@@ -21,5 +21,5 @@ const transformBaseValues = {

getCSS() {
const css = entriesToCss(Object.entries(transformBaseValues))
return `*,::before,::after{${css}}`
}
}
const css = entriesToCss(Object.entries(transformBaseValues));
return `*,::before,::after{${css}}`;
},
};

@@ -360,3 +360,3 @@ export const twReset = {

}
`
}
`,
};

@@ -15,27 +15,2 @@ import { handler as h, makeGlobalStaticRules } from '#utils';

const listStyles = {
'disc': 'disc',
'circle': 'circle',
'square': 'square',
'decimal': 'decimal',
'zero-decimal': 'decimal-leading-zero'
}
export const listStyle = [
// base
[
/^list-(.+)$/,
([, alias]) => {
const style = listStyles[alias]
if (style) return { 'list-style-type': style }
},
{ autocomplete: `list-(${Object.keys(listStyles).join('|')})` }
],
// styles
['list-outside', { 'list-style-position': 'outside' }],
['list-inside', { 'list-style-position': 'inside' }],
['list-none', { 'list-style-type': 'none' }],
...makeGlobalStaticRules('list', 'list-style-type'),
]
export const overscrolls = [

@@ -54,3 +29,3 @@ ['overscroll-auto', { 'overscroll-behavior': 'auto' }],

...makeGlobalStaticRules('overscroll-y', 'overscroll-behavior-y'),
]
];

@@ -61,2 +36,2 @@ export const scrollBehaviors = [

...makeGlobalStaticRules('scroll', 'scroll-behavior'),
]
];

@@ -1,2 +0,4 @@

import { handler as h, directionMap, cornerMap } from "#utils";
import { escapeSelector } from '@unocss/core';
import { directionMap, cornerMap } from "#utils";
import { lineWidth } from '#theme';

@@ -25,2 +27,4 @@ const borderStyles = [

[/^border-([rltb])-(.+)$/, handlerBorderStyle],
// divide
[/^divide-([xy])-?(\d+)?-?(reverse)?$/, handlerDivideBorder, { autocomplete: `divide-<x|y>-(${Object.keys(lineWidth).join('|')})-(reverse)` }],
];

@@ -36,9 +40,7 @@

const v = theme.lineWidth?.[b ?? 1];
if (a in directionMap && v != null)
return directionMap[a].map((i) => [`border${i}-width`, v]);
if (a in directionMap && v != null) return directionMap[a].map((i) => [`border${i}-width`, v]);
}
function handlerBorderStyle([, a = "", s]) {
if (borderStyles.includes(s) && a in directionMap)
return directionMap[a].map((i) => [`border${i}-style`, s]);
if (borderStyles.includes(s) && a in directionMap) return directionMap[a].map((i) => [`border${i}-style`, s]);
}

@@ -52,8 +54,28 @@

[/^rounded-([bi][se]-[bi][se])(?:-(.+))?$/, handlerRounded],
]
];
function handlerRounded([, a = '', s], { theme }) {
const v = theme.borderRadius?.[s ?? 4];
if (a in cornerMap && v != null)
return cornerMap[a].map(i => [`border${i}-radius`, v]);
if (a in cornerMap && v != null) return cornerMap[a].map(i => [`border${i}-radius`, v]);
}
function handleDivideBorderSizes(direction, width, reverse, theme) {
const borderWidth = theme.lineWidth?.[width ?? 1];
if (direction in directionMap && borderWidth) {
return directionMap[direction].map((i) => {
const borderPosition = !!reverse ? 0 : 1;
if (i === directionMap[direction][borderPosition]) {
return `border${i}-width:0`;
}
return `border${i}-width:${borderWidth}`;
});
};
}
function handlerDivideBorder([_selector, direction = "", width, reverse], { theme }) {
const sizes = handleDivideBorderSizes(direction, width, reverse, theme)?.join(';');
if (sizes) {
const selector = escapeSelector(_selector);
return `.${selector}>*+*{${sizes}}`;
}
}

@@ -1,5 +0,15 @@

import { handler as h } from '#utils';
export const opacity = [
[/^opacity-?(\d+)$/, ([, d]) => ({ opacity: h.bracket.percent(d) })],
[/^opacity-(\d+)$/, ([, d], { theme }) => ({ opacity: theme.opacity[d] }), { autocomplete: 'opacity-${opacity}' }],
];
export const textColors = [
['text', { color: 'var(--w-text-color)' }],
['text-inverted', { color: 'var(--w-text-color-inverted)' }],
['text-inverted-subtle', { color: 'var(--w-text-color-inverted-subtle)' }],
['text-subtle', { color: 'var(--w-text-color-subtle)' }],
];
export const bgColors = [
['bg', { 'background-color': 'var(--w-background-color)' }],
['bg-subtle', { 'background-color': 'var(--w-background-color-subtle)' }],
];
export const textDecorations = [
[/^(underline|line-through)$/, ([, s]) => ({ 'text-decoration-line': s })],
['no-underline', { 'text-decoration': 'none' }],
[/^(underline|line-through)$/, ([, s]) => ({ 'text-decoration-line': s })],
['no-underline', { 'text-decoration': 'none' }],
];

@@ -1,3 +0,4 @@

import { handler as h } from '#utils'
import { globalKeywords, handler as h } from '#utils';
export const display = [

@@ -26,3 +27,3 @@ ['flex', { display: 'flex' }],

// unset, revert, inherit
[/^display-(.+)$/, ([, c]) => ({ display: h.bracket.cssvar.global(c) || c })],
]
[/^display-(.+)$/, ([, c]) => ({ display: h.cssvar.global(c) }), { autocomplete: `display-${globalKeywords.join('|')}` }],
];

@@ -1,6 +0,6 @@

import { handler as h } from '#utils'
import { bounded } from '#bounding'
import * as bounds from '#bounds'
import { handler as h } from '#utils';
import { bounded } from '#bounding';
import * as bounds from '#bounds';
const numericHandler = { handler: (d) => h.number(d) }
const numericHandler = { handler: (d) => h.number(d) };

@@ -25,5 +25,5 @@ export const flex = [

bounds.flexGrowShrink,
{ nullable: true, ...numericHandler }
{ nullable: true, ...numericHandler },
),
{ autocomplete: ['shrink-<num>'] }
{ autocomplete: ['shrink-<num>'] },
],

@@ -35,5 +35,5 @@ [

bounds.flexGrowShrink,
{ nullable: true, ...numericHandler }
{ nullable: true, ...numericHandler },
),
{ autocomplete: ['grow-<num>'] }
{ autocomplete: ['grow-<num>'] },
],

@@ -44,3 +44,3 @@ // TODO: needs tested

([, d], { theme }) => ({ 'flex-basis': theme.spacing?.[d] ?? h.auto.fraction(d) }),
{ autocomplete: ['basis-$spacing'] }
{ autocomplete: ['basis-$spacing'] },
],

@@ -56,2 +56,2 @@ // directions

['flex-nowrap', { 'flex-wrap': 'nowrap' }],
]
];

@@ -5,13 +5,13 @@ // TODO: use actual variables and values when those has been defined

'outline-offset': 'var(--w-outline-offset, 1px)',
}
};
const focusRingInsetStyle = {
'--w-outline-offset': '-3px',
}
};
export const focusRing = [
["focusable:focus", focusRingStyle],
["focusable:focus:not(:focus-visible)", { 'outline': 'none'}],
["focusable:focus:not(:focus-visible)", { 'outline': 'none' }],
["focusable:focus-visible", focusRingStyle],
["focusable-inset", { ... focusRingInsetStyle }],
];
const directions = {
'': '',
'x': 'column-',
'y': 'row-',
'': '',
'x': 'column-',
'y': 'row-',
};
const handleGap = ([, d = '', s], { theme }) => {
const v = theme.spacing?.[s];
const v = theme.spacing?.[s];
if (v != null) {
return {
[`${directions[d]}gap`]: v,
};
}
if (v != null) {
return {
[`${directions[d]}gap`]: v,
};
}
};
export const gap = [
[/^gap-?()(\d+)$/, handleGap, { autocomplete: ['gap-$spacing'] }],
[/^gap-([xy])-?(\d+)$/, handleGap, { autocomplete: ['gap-(x|y)-$spacing'] }],
[/^gap-?()(\d+)$/, handleGap, { autocomplete: ['gap-$spacing'] }],
[/^gap-([xy])-?(\d+)$/, handleGap, { autocomplete: ['gap-(x|y)-$spacing'] }],
];
import { handler as h } from '#utils';
import { bounded } from "#bounding"
import * as bounds from '#bounds'
import { bounded } from '#bounding';
import * as bounds from '#bounds';
const autoDirection = (prop) => {
switch (prop) {
case 'min': return 'min-content';
case 'max': return 'max-content';
case 'fr': return 'minmax(0,1fr)';
case 'auto': return 'auto';
case 'min':
return 'min-content';
case 'max':
return 'max-content';
case 'fr':
return 'minmax(0,1fr)';
case 'auto':
return 'auto';
}

@@ -16,4 +20,4 @@

const numericHandler = { handler: (d) => h.number.auto(d) }
const numericOrAutoHandler = { handler: (d) => h.number.auto(d) }
const numericHandler = { handler: (d) => h.number.auto(d) };
const numericOrAutoHandler = { handler: (d) => h.number.auto(d) };

@@ -31,4 +35,4 @@ export const grid = [

bounds.gridRow,
numericHandler
)
numericHandler,
),
],

@@ -40,5 +44,5 @@ [

bounds.gridCol,
numericHandler
numericHandler,
),
{ autocomplete: ['(row|col)-span-<num>'] }
{ autocomplete: ['(row|col)-span-<num>'] },
],

@@ -51,4 +55,4 @@ // starts & ends

bounds.gridRow,
numericOrAutoHandler
)
numericOrAutoHandler,
),
],

@@ -60,4 +64,4 @@ [

bounds.gridCol,
numericOrAutoHandler
)
numericOrAutoHandler,
),
],

@@ -69,4 +73,4 @@ [

bounds.gridRow,
numericOrAutoHandler
)
numericOrAutoHandler,
),
],

@@ -78,9 +82,13 @@ [

bounds.gridCol,
numericOrAutoHandler
numericOrAutoHandler,
),
{ autocomplete: ['(row|col)-(start|end)-<num>'] }
{ autocomplete: ['(row|col)-(start|end)-<num>'] },
],
// auto flows
[/^auto-rows-(.+)$/, ([, v]) => ({ 'grid-auto-rows': autoDirection(v) })],
[/^auto-cols-(.+)$/, ([, v]) => ({ 'grid-auto-columns': autoDirection(v) }), { autocomplete: ['auto-(rows|cols)-<num>'] }],
[
/^auto-cols-(.+)$/,
([, v]) => ({ 'grid-auto-columns': autoDirection(v) }),
{ autocomplete: ['auto-(rows|cols)-<num>'] },
],
['grid-flow-row', { 'grid-auto-flow': 'row' }],

@@ -90,9 +98,17 @@ ['grid-flow-col', { 'grid-auto-flow': 'column' }],

['grid-flow-row-dense', { 'grid-auto-flow': 'row dense' }],
['grid-flow-col-dense', { 'grid-auto-flow': 'col dense' }],
['grid-flow-col-dense', { 'grid-auto-flow': 'column dense' }],
// templates
[/^grid-rows-(.+)$/, ([, v]) => ({ 'grid-template-rows': h.bracket(v) })],
[/^grid-cols-(.+)$/, ([, v]) => ({ 'grid-template-columns': h.bracket(v) })],
[/^grid-rows-minmax-([\w.-]+)$/, ([, d]) => ({ 'grid-template-rows': `repeat(auto-fill,minmax(${d},1fr))` })],
[/^grid-cols-minmax-([\w.-]+)$/, ([, d]) => ({ 'grid-template-columns': `repeat(auto-fill,minmax(${d},1fr))` })],
[
/^grid-rows-minmax-([\w.-]+)$/,
([, d]) => ({ 'grid-template-rows': `repeat(auto-fill,minmax(${d},1fr))` }),
],
[
/^grid-cols-minmax-([\w.-]+)$/,
([, d]) => ({
'grid-template-columns': `repeat(auto-fill,minmax(${d},1fr))`,
}),
],
[
/^grid-rows-(\d+)$/,

@@ -102,4 +118,4 @@ bounded(

bounds.gridRow,
numericHandler
)
numericHandler,
),
],

@@ -111,5 +127,5 @@ [

bounds.gridCol,
numericHandler
numericHandler,
),
{ autocomplete: ['grid-(rows|cols)-<num>', 'grid-(rows|cols)-none'] }
{ autocomplete: ['grid-(rows|cols)-<num>', 'grid-(rows|cols)-none'] },
],

@@ -116,0 +132,0 @@ ['grid-rows-none', { 'grid-template-rows': 'none' }],

import * as align from "./align.js";
import * as aspectRatio from "./aspect-ratio.js";
import * as backgrounds from './background.js';
import * as behaviors from "./behaviors.js";

@@ -11,7 +13,9 @@ import * as border from "./border.js";

import * as grid from "./grid.js";
import * as internal from './internal.js';
import * as layout from "./layout.js";
import * as lineClamp from "./line-clamp.js";
import * as list from "./list.js";
import * as position from "./position.js";
import * as size from "./size.js"
import * as spaceMargin from './space-margin.js'
import * as size from "./size.js";
import * as spaceMargin from './space-margin.js';
import * as spacing from "./spacing.js";

@@ -21,7 +25,11 @@ import * as staticRules from "./static.js";

import * as transition from "./transition.js";
import * as table from "./table.js";
const ruleGroups = {
...align,
...aspectRatio,
...backgrounds,
...behaviors,
...border,
...table,
...color,

@@ -34,4 +42,6 @@ ...display,

...grid,
...internal,
...layout,
...lineClamp,
...list,
...position,

@@ -43,10 +53,12 @@ ...size,

...transform,
...transition
}
...transition,
};
export const rules = [
...Object.values(ruleGroups)
...Object.values(ruleGroups),
].flat(1);
export * from "./align.js";
export * from "./aspect-ratio.js";
export * from './background.js';
export * from "./behaviors.js";

@@ -61,10 +73,13 @@ export * from "./border.js";

export * from "./grid.js";
export * from './internal.js';
export * from "./layout.js";
export * from "./line-clamp.js"
export * from "./line-clamp.js";
export * from "./list.js";
export * from "./position.js";
export * from "./size.js";
export * from './space-margin.js'
export * from './space-margin.js';
export * from "./spacing.js";
export * from "./static.js";
export * from "./table.js";
export * from "./transform.js";
export * from "./transition.js";

@@ -17,4 +17,4 @@ const overflowValues = ["auto", "hidden", "visible", "scroll"];

([, d, v]) =>
overflowValues.includes(v) ? { [`overflow-${d}`]: v } : undefined,
(overflowValues.includes(v) ? { [`overflow-${d}`]: v } : undefined),
],
];

@@ -11,2 +11,2 @@ // TODO: can we get rid of box-orient and webkit-box?

}), { autocomplete: ['line-clamp-<num>'] }],
]
];
import { handler as h, insetMap, makeGlobalStaticRules } from '#utils';
import { bounded } from "#bounding";
import * as bounds from '#bounds'
import * as bounds from '#bounds';
import { warnOnce } from '@unocss/core';

@@ -13,117 +13,117 @@

export const orders = [
[
/^order-(\d+)$/,
bounded(
([, d]) => ({ 'order': h.number(d)}),
bounds.order,
numericHandler
),
{ autocomplete: 'order-<num>' }
],
['order-first', { order: '-9999' }],
['order-last', { order: '9999' }],
['order-none', { order: '0' }],
[
/^order-(\d+)$/,
bounded(
([, d]) => ({ 'order': h.number(d) }),
bounds.order,
numericHandler,
),
{ autocomplete: 'order-<num>' },
],
['order-first', { order: '-9999' }],
['order-last', { order: '9999' }],
['order-none', { order: '0' }],
];
export const justifies = [
// contents
['justify-start', { 'justify-content': 'flex-start' }],
['justify-end', { 'justify-content': 'flex-end' }],
['justify-center', { 'justify-content': 'center' }],
['justify-between', { 'justify-content': 'space-between' }],
['justify-around', { 'justify-content': 'space-around' }],
['justify-evenly', { 'justify-content': 'space-evenly' }],
...makeGlobalStaticRules('justify', 'justify-content'),
// contents
['justify-start', { 'justify-content': 'flex-start' }],
['justify-end', { 'justify-content': 'flex-end' }],
['justify-center', { 'justify-content': 'center' }],
['justify-between', { 'justify-content': 'space-between' }],
['justify-around', { 'justify-content': 'space-around' }],
['justify-evenly', { 'justify-content': 'space-evenly' }],
...makeGlobalStaticRules('justify', 'justify-content'),
// items
['justify-items-start', { 'justify-items': 'start' }],
['justify-items-end', { 'justify-items': 'end' }],
['justify-items-center', { 'justify-items': 'center' }],
['justify-items-stretch', { 'justify-items': 'stretch' }],
...makeGlobalStaticRules('justify-items'),
// items
['justify-items-start', { 'justify-items': 'start' }],
['justify-items-end', { 'justify-items': 'end' }],
['justify-items-center', { 'justify-items': 'center' }],
['justify-items-stretch', { 'justify-items': 'stretch' }],
...makeGlobalStaticRules('justify-items'),
// selfs
['justify-self-auto', { 'justify-self': 'auto' }],
['justify-self-start', { 'justify-self': 'start' }],
['justify-self-end', { 'justify-self': 'end' }],
['justify-self-center', { 'justify-self': 'center' }],
['justify-self-stretch', { 'justify-self': 'stretch' }],
...makeGlobalStaticRules('justify-self'),
]
// selfs
['justify-self-auto', { 'justify-self': 'auto' }],
['justify-self-start', { 'justify-self': 'start' }],
['justify-self-end', { 'justify-self': 'end' }],
['justify-self-center', { 'justify-self': 'center' }],
['justify-self-stretch', { 'justify-self': 'stretch' }],
...makeGlobalStaticRules('justify-self'),
];
export const alignments = [
// contents
['content-center', { 'align-content': 'center' }],
['content-start', { 'align-content': 'flex-start' }],
['content-end', { 'align-content': 'flex-end' }],
['content-between', { 'align-content': 'space-between' }],
['content-around', { 'align-content': 'space-around' }],
['content-evenly', { 'align-content': 'space-evenly' }],
...makeGlobalStaticRules('content', 'align-content'),
// contents
['content-center', { 'align-content': 'center' }],
['content-start', { 'align-content': 'flex-start' }],
['content-end', { 'align-content': 'flex-end' }],
['content-between', { 'align-content': 'space-between' }],
['content-around', { 'align-content': 'space-around' }],
['content-evenly', { 'align-content': 'space-evenly' }],
...makeGlobalStaticRules('content', 'align-content'),
// items
['items-start', { 'align-items': 'flex-start' }],
['items-end', { 'align-items': 'flex-end' }],
['items-center', { 'align-items': 'center' }],
['items-baseline', { 'align-items': 'baseline' }],
['items-stretch', { 'align-items': 'stretch' }],
...makeGlobalStaticRules('items', 'align-items'),
// items
['items-start', { 'align-items': 'flex-start' }],
['items-end', { 'align-items': 'flex-end' }],
['items-center', { 'align-items': 'center' }],
['items-baseline', { 'align-items': 'baseline' }],
['items-stretch', { 'align-items': 'stretch' }],
...makeGlobalStaticRules('items', 'align-items'),
// selfs
['self-auto', { 'align-self': 'auto' }],
['self-start', { 'align-self': 'flex-start' }],
['self-end', { 'align-self': 'flex-end' }],
['self-center', { 'align-self': 'center' }],
['self-stretch', { 'align-self': 'stretch' }],
['self-baseline', { 'align-self': 'baseline' }],
...makeGlobalStaticRules('self', 'align-self'),
]
// selfs
['self-auto', { 'align-self': 'auto' }],
['self-start', { 'align-self': 'flex-start' }],
['self-end', { 'align-self': 'flex-end' }],
['self-center', { 'align-self': 'center' }],
['self-stretch', { 'align-self': 'stretch' }],
['self-baseline', { 'align-self': 'baseline' }],
...makeGlobalStaticRules('self', 'align-self'),
];
export const placements = [
// contents
['place-content-center', { 'place-content': 'center' }],
['place-content-start', { 'place-content': 'start' }],
['place-content-end', { 'place-content': 'end' }],
['place-content-between', { 'place-content': 'space-between' }],
['place-content-around', { 'place-content': 'space-around' }],
['place-content-evenly', { 'place-content': 'space-evenly' }],
['place-content-stretch', { 'place-content': 'stretch' }],
...makeGlobalStaticRules('place-content'),
// contents
['place-content-center', { 'place-content': 'center' }],
['place-content-start', { 'place-content': 'start' }],
['place-content-end', { 'place-content': 'end' }],
['place-content-between', { 'place-content': 'space-between' }],
['place-content-around', { 'place-content': 'space-around' }],
['place-content-evenly', { 'place-content': 'space-evenly' }],
['place-content-baseline', { 'place-content': 'baseline' }],
['place-content-stretch', { 'place-content': 'stretch' }],
...makeGlobalStaticRules('place-content'),
// items
['place-items-start', { 'place-items': 'start' }],
['place-items-end', { 'place-items': 'end' }],
['place-items-center', { 'place-items': 'center' }],
['place-items-stretch', { 'place-items': 'stretch' }],
...makeGlobalStaticRules('place-items'),
// items
['place-items-start', { 'place-items': 'start' }],
['place-items-end', { 'place-items': 'end' }],
['place-items-center', { 'place-items': 'center' }],
['place-items-stretch', { 'place-items': 'stretch' }],
...makeGlobalStaticRules('place-items'),
// selfs
['place-self-auto', { 'place-self': 'auto' }],
['place-self-start', { 'place-self': 'start' }],
['place-self-end', { 'place-self': 'end' }],
['place-self-center', { 'place-self': 'center' }],
['place-self-stretch', { 'place-self': 'stretch' }],
...makeGlobalStaticRules('place-self'),
]
// selfs
['place-self-auto', { 'place-self': 'auto' }],
['place-self-start', { 'place-self': 'start' }],
['place-self-end', { 'place-self': 'end' }],
['place-self-center', { 'place-self': 'center' }],
['place-self-stretch', { 'place-self': 'stretch' }],
...makeGlobalStaticRules('place-self'),
];
function handleInsetValue(v, { theme }) {
return theme.spacing?.[v] ?? h.fraction.auto(v); // TODO: warn if no value
return theme.spacing?.[v] ?? h.fraction.auto(v); // TODO: warn if no value
}
function handleInsetValues([, d, v], ctx) {
const r = handleInsetValue(v, ctx);
if (r != null && d in insetMap)
return insetMap[d].map(i => [i.slice(1), r]);
const r = handleInsetValue(v, ctx);
if (r != null && d in insetMap) return insetMap[d].map(i => [i.slice(1), r]);
}
export const insets = [
[/^inset-(.+)$/, ([, v], ctx) => ({ inset: handleInsetValue(v, ctx) }),
{
autocomplete: [
'inset-$spacing',
'inset-<directions>-$spacing',
'(top|left|right|bottom)-$spacing',
],
},
],
[/^inset-([xy])-(.+)$/, handleInsetValues],
[/^(top|left|right|bottom)-(.+)$/, ([, d, v], ctx) => ({ [d]: handleInsetValue(v, ctx) })],
[/^inset-(.+)$/, ([, v], ctx) => ({ inset: handleInsetValue(v, ctx) }),
{
autocomplete: [
'inset-$spacing',
'inset-<directions>-$spacing',
'(top|left|right|bottom)-$spacing',
],
},
],
[/^inset-([xy])-(.+)$/, handleInsetValues],
[/^(top|left|right|bottom)-(.+)$/, ([, d, v], ctx) => ({ [d]: handleInsetValue(v, ctx) })],
];

@@ -146,4 +146,4 @@

function handleZIndexValue(v, { theme }) {
if (!theme.zIndex?.[v]) return warnOnce(`${v} is not allowed as z-index value`)
return theme.zIndex[v]
if (!theme.zIndex?.[v]) return warnOnce(`${v} is not allowed as z-index value`);
return theme.zIndex[v];
}

@@ -150,0 +150,0 @@

@@ -1,5 +0,10 @@

import { handler as h, resolveBreakpoints, resolveVerticalBreakpoints } from '#utils'
import { handler as h, resolveBreakpoints, resolveVerticalBreakpoints } from '#utils';
const sizeMapping = { h: 'height', w: 'width', };
const sizeMapping = { h: 'height', w: 'width' };
const getPropName = (minmax, hw) => `${minmax || ''}${sizeMapping[hw]}`;
const resolveArbitraryValues = (d, unit, context) => {
if (unit === "rem") return h.rem(`${d}${unit}`);
if (unit === "px" || context.theme.usingPixels) return h.px(d);
return h.rem(d);
};

@@ -28,4 +33,4 @@ function getSizeValue(minmax, hw, theme, prop) {

'(max|min)-(w|h)-$width|height|maxWidth|maxHeight|minWidth|minHeight',
]
}
],
},
],

@@ -43,14 +48,3 @@ [/^(min-|max-)?(h)-screen-(.+)$/, ([, m, w, s], context) => ({ [getPropName(m, w)]: resolveVerticalBreakpoints(context)?.[s] })],

}],
[/^(min-|max-)?([wh])-\[(\d+)(rem|px)?]$/, ([, minmax, wh, d, unit], context) => ({ [getPropName(minmax, wh)]: resolveArbitraryValues(d, unit, context) })],
];
function getAspectRatio(prop) {
if (/^\d+\/\d+$/.test(prop)) return prop;
switch (prop) {
case 'square': return '1/1';
case 'video': return '16/9';
}
return h.global.auto.number(prop);
}
export const aspectRatio = [
[/^aspect-(?:ratio-)?(.+)$/, ([, d]) => ({ 'aspect-ratio': getAspectRatio(d) }), { autocomplete: ['aspect-(square|video|ratio)', 'aspect-ratio-(square|video)'] }],
];

@@ -1,2 +0,2 @@

import { directionMap } from '#utils'
import { directionMap } from '#utils';

@@ -7,14 +7,14 @@ export const spaceMargins = [

[/^space-([xy])-reverse$/, ([, d]) => ({ [`--w-space-${d}-reverse`]: 1 })],
]
];
function handlerSpace([, d, s = 1], { theme }) {
const v = theme.spacing?.[s]
const v = theme.spacing?.[s];
if (v != null) {
const results = directionMap[d].map((item) => {
const key = `margin${item}`
const key = `margin${item}`;
const value = item.endsWith('right') || item.endsWith('bottom')
? `calc(${v} * var(--w-space-${d}-reverse))`
: `calc(${v} * calc(1 - var(--w-space-${d}-reverse)))`
return [key, value]
})
: `calc(${v} * calc(1 - var(--w-space-${d}-reverse)))`;
return [key, value];
});

@@ -25,5 +25,5 @@ if (results) {

...results,
]
];
}
}
}

@@ -1,2 +0,2 @@

import { directionSize } from '#utils'
import { directionSize } from '#utils';

@@ -10,3 +10,3 @@ // negatives come in via the negative variant

[/^p([rltb])-(.+)$/, directionSize('padding'), { autocomplete: '(m|p)<directions>-<num>' }],
]
];

@@ -17,2 +17,2 @@ export const margin = [

[/^m([rltb])-(.+)$/, directionSize('margin')],
]
];

@@ -42,3 +42,3 @@ import { globalKeywords, handler as h, makeGlobalStaticRules, positionMap } from '#utils';

/^whitespace-([-\w]+)$/,
([, v]) => ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces', ...globalKeywords].includes(v) ? { 'white-space': v } : undefined,
([, v]) => (['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces', ...globalKeywords].includes(v) ? { 'white-space': v } : undefined),
{ autocomplete: 'whitespace-(normal|nowrap|pre|pre-line|pre-wrap|break-spaces)' },

@@ -81,4 +81,4 @@ ],

export const fontSmoothings = [
['antialiased', { '-webkit-font-smoothing': 'antialiased', '-moz-osx-font-smoothing': 'grayscale', 'font-smoothing': 'grayscale', }],
['subpixel-antialiased', { '-webkit-font-smoothing': 'auto', '-moz-osx-font-smoothing': 'auto', 'font-smoothing': 'auto', }],
['antialiased', { '-webkit-font-smoothing': 'antialiased', '-moz-osx-font-smoothing': 'grayscale', 'font-smoothing': 'grayscale' }],
['subpixel-antialiased', { '-webkit-font-smoothing': 'auto', '-moz-osx-font-smoothing': 'auto', 'font-smoothing': 'auto' }],
];

@@ -113,3 +113,3 @@

],
]
];

@@ -119,3 +119,3 @@ export const isolations = [

['isolation-auto', { isolation: 'auto' }],
]
];

@@ -132,5 +132,5 @@ export const objectPositions = [

[/^object-(.+)$/, ([, d]) => {
if (positionMap[d]) return { 'object-position': positionMap[d] }
if (positionMap[d]) return { 'object-position': positionMap[d] };
}, { autocomplete: `object-(${Object.keys(positionMap).join('|')})` }],
]
];

@@ -155,3 +155,3 @@ export const backgroundBlendModes = [

...makeGlobalStaticRules('bg-blend', 'background-blend'),
]
];

@@ -177,2 +177,2 @@ export const mixBlendModes = [

...makeGlobalStaticRules('mix-blend'),
]
];

@@ -42,3 +42,3 @@ import { handler as h, makeGlobalStaticRules, positionMap, xyzMap } from '#utils';

([, s]) => ({ 'transform-origin': positionMap[s] }),
{ autocomplete: [`origin-(${Object.keys(positionMap).join('|')})`, `origin-(${Object.keys(positionMap).join('|')})`] }
{ autocomplete: [`origin-(${Object.keys(positionMap).join('|')})`, `origin-(${Object.keys(positionMap).join('|')})`] },
],

@@ -90,4 +90,3 @@ // modifiers

};
}
else {
} else {
return {

@@ -94,0 +93,0 @@ '--w-rotate-x': 0,

@@ -7,4 +7,4 @@ import { globalKeywords, handler as h, makeGlobalStaticRules } from '#utils';

out: 'cubic-bezier(0, 0, 0.2, 1)',
'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)'
}
'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
};

@@ -39,3 +39,3 @@ const transitionPropertyGroup = {

([, d], { theme }) => ({ 'transition-duration': theme.duration?.[d || 'DEFAULT'] ?? h.time(d) }),
{ autocomplete: 'duration-$duration' }
{ autocomplete: 'duration-$duration' },
],

@@ -45,7 +45,7 @@ [

([, d], { theme }) => ({ 'transition-delay': theme.duration?.[d || 'DEFAULT'] ?? h.time(d) }),
{ autocomplete: 'delay-$duration' }
{ autocomplete: 'delay-$duration' },
],
[/^ease-(.+)$/,
([, d]) => ({ 'transition-timing-function': easings[d] }),
{ autocomplete: 'ease-(linear|in|out|in-out)' }
{ autocomplete: 'ease-(linear|in|out|in-out)' },
],

@@ -52,0 +52,0 @@ // props

@@ -8,188 +8,166 @@ import { escapeRegExp } from '@unocss/core';

export function hex2rgba(hex = '') {
const color = parseHexColor(hex);
if (color != null) {
const { components, alpha } = color;
if (alpha == null)
return components;
return [...components, alpha];
}
const color = parseHexColor(hex);
if (color != null) {
const { components, alpha } = color;
if (alpha == null) return components;
return [...components, alpha];
}
}
export function parseCssColor(str = '') {
const color = parseColor(str);
if (color == null || color === false)
return;
const { type: casedType, components, alpha } = color;
const type = casedType.toLowerCase();
if (components.length === 0)
return;
if (['rgba', 'hsla'].includes(type) && alpha == null)
return;
if (cssColorFunctions.includes(type) && ![1, 3].includes(components.length))
return;
return {
type,
components: components.map(c => typeof c === 'string' ? c.trim() : c),
alpha: typeof alpha === 'string' ? alpha.trim() : alpha,
};
const color = parseColor(str);
if (color == null || color === false) return;
const { type: casedType, components, alpha } = color;
const type = casedType.toLowerCase();
if (components.length === 0) return;
if (['rgba', 'hsla'].includes(type) && alpha == null) return;
if (cssColorFunctions.includes(type) && ![1, 3].includes(components.length)) return;
return {
type,
components: components.map(c => (typeof c === 'string' ? c.trim() : c)),
alpha: typeof alpha === 'string' ? alpha.trim() : alpha,
};
}
export function colorOpacityToString(color) {
const alpha = color.alpha ?? 1;
return typeof alpha === 'string' && alphaPlaceholders.includes(alpha) ? 1 : alpha;
const alpha = color.alpha ?? 1;
return typeof alpha === 'string' && alphaPlaceholders.includes(alpha) ? 1 : alpha;
}
export function colorToString(color, alphaOverride) {
if (typeof color === 'string')
return color.replace(alphaPlaceholdersRE, `${alphaOverride ?? 1}`);
const { components } = color;
let { alpha, type } = color;
alpha = alphaOverride ?? alpha;
type = type.toLowerCase();
// Comma separated functions
if (['hsla', 'hsl', 'rgba', 'rgb'].includes(type))
return `${type.replace('a', '')}a(${components.join(',')}${alpha == null ? '' : `,${alpha}`})`;
alpha = alpha == null ? '' : ` / ${alpha}`;
if (cssColorFunctions.includes(type))
return `${type}(${components.join(' ')}${alpha})`;
return `color(${type} ${components.join(' ')}${alpha})`;
if (typeof color === 'string') return color.replace(alphaPlaceholdersRE, `${alphaOverride ?? 1}`);
const { components } = color;
let { alpha, type } = color;
alpha = alphaOverride ?? alpha;
type = type.toLowerCase();
// Comma separated functions
if (['hsla', 'hsl', 'rgba', 'rgb'].includes(type)) return `${type.replace('a', '')}a(${components.join(',')}${alpha == null ? '' : `,${alpha}`})`;
alpha = alpha == null ? '' : ` / ${alpha}`;
if (cssColorFunctions.includes(type)) return `${type}(${components.join(' ')}${alpha})`;
return `color(${type} ${components.join(' ')}${alpha})`;
}
function parseColor(str) {
if (!str)
return;
let color = parseHexColor(str);
if (color != null)
return color;
color = cssColorKeyword(str);
if (color != null)
return color;
color = parseCssCommaColorFunction(str);
if (color != null)
return color;
color = parseCssSpaceColorFunction(str);
if (color != null)
return color;
color = parseCssColorFunction(str);
if (color != null)
return color;
if (!str) return;
let color = parseHexColor(str);
if (color != null) return color;
color = cssColorKeyword(str);
if (color != null) return color;
color = parseCssCommaColorFunction(str);
if (color != null) return color;
color = parseCssSpaceColorFunction(str);
if (color != null) return color;
color = parseCssColorFunction(str);
if (color != null) return color;
}
function parseHexColor(str) {
const [, body] = str.match(/^#([\da-f]+)$/i) || [];
if (!body)
return;
switch (body.length) {
case 3:
case 4:
const digits = Array.from(body, s => Number.parseInt(s, 16)).map(n => (n << 4) | n);
return {
type: 'rgb',
components: digits.slice(0, 3),
alpha: body.length === 3
? undefined
: Math.round(digits[3] / 255 * 100) / 100,
};
case 6:
case 8:
const value = Number.parseInt(body, 16);
return {
type: 'rgb',
components: body.length === 6
? [(value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF]
: [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF],
alpha: body.length === 6
? undefined
: Math.round((value & 0xFF) / 255 * 100) / 100,
};
}
const [, body] = str.match(/^#([\da-f]+)$/i) || [];
if (!body) return;
switch (body.length) {
case 3:
case 4:
const digits = Array.from(body, s => Number.parseInt(s, 16)).map(n => (n << 4) | n);
return {
type: 'rgb',
components: digits.slice(0, 3),
alpha: body.length === 3
? undefined
: Math.round(digits[3] / 255 * 100) / 100,
};
case 6:
case 8:
const value = Number.parseInt(body, 16);
return {
type: 'rgb',
components: body.length === 6
? [(value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF]
: [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF],
alpha: body.length === 6
? undefined
: Math.round((value & 0xFF) / 255 * 100) / 100,
};
}
}
function cssColorKeyword(str) {
const color = {
rebeccapurple: [102, 51, 153, 1],
}[str];
if (color != null) {
return {
type: 'rgb',
components: color.slice(0, 3),
alpha: color[3],
};
}
const color = {
rebeccapurple: [102, 51, 153, 1],
}[str];
if (color != null) {
return {
type: 'rgb',
components: color.slice(0, 3),
alpha: color[3],
};
}
}
function parseCssCommaColorFunction(color) {
const match = color.match(/^(rgb|rgba|hsl|hsla)\((.+)\)$/i);
if (!match)
return;
const [, type, componentString] = match;
// With min 3 (rgb) and max 4 (rgba), try to get 5 components
const components = getComponents(componentString, ',', 5);
if (components) {
if ([3, 4].includes(components.length)) {
return {
type,
components: components.slice(0, 3),
alpha: components[3],
};
}
else if (components.length !== 1) {
return false;
}
const match = color.match(/^(rgb|rgba|hsl|hsla)\((.+)\)$/i);
if (!match) return;
const [, type, componentString] = match;
// With min 3 (rgb) and max 4 (rgba), try to get 5 components
const components = getComponents(componentString, ',', 5);
if (components) {
if ([3, 4].includes(components.length)) {
return {
type,
components: components.slice(0, 3),
alpha: components[3],
};
} else if (components.length !== 1) {
return false;
}
}
}
const cssColorFunctionsRe = new RegExp(`^(${cssColorFunctions.join('|')})\\((.+)\\)$`, 'i');
function parseCssSpaceColorFunction(color) {
const match = color.match(cssColorFunctionsRe);
if (!match)
return;
const [, fn, componentString] = match;
const parsed = parseCssSpaceColorValues(`${fn} ${componentString}`);
if (parsed) {
const { alpha, components: [type, ...components] } = parsed;
return {
type,
components,
alpha,
};
}
const match = color.match(cssColorFunctionsRe);
if (!match) return;
const [, fn, componentString] = match;
const parsed = parseCssSpaceColorValues(`${fn} ${componentString}`);
if (parsed) {
const { alpha, components: [type, ...components] } = parsed;
return {
type,
components,
alpha,
};
}
}
function parseCssColorFunction(color) {
const match = color.match(/^color\((.+)\)$/);
if (!match)
return;
const parsed = parseCssSpaceColorValues(match[1]);
if (parsed) {
const { alpha, components: [type, ...components] } = parsed;
return {
type,
components,
alpha,
};
}
const match = color.match(/^color\((.+)\)$/);
if (!match) return;
const parsed = parseCssSpaceColorValues(match[1]);
if (parsed) {
const { alpha, components: [type, ...components] } = parsed;
return {
type,
components,
alpha,
};
}
}
function parseCssSpaceColorValues(componentString) {
const components = getComponents(componentString, ' ');
if (!components)
return;
let totalComponents = components.length;
// (fn 1 2 3 / 4)
if (components[totalComponents - 2] === '/') {
return {
components: components.slice(0, totalComponents - 2),
alpha: components[totalComponents - 1],
};
}
// (fn 1 2 3/ 4) or (fn 1 2 3 /4)
if (components[totalComponents - 2] != null && (components[totalComponents - 2].endsWith('/') || components[totalComponents - 1].startsWith('/'))) {
const removed = components.splice(totalComponents - 2);
components.push(removed.join(' '));
--totalComponents;
}
// maybe (fn 1 2 3/4)
const withAlpha = getComponents(components[totalComponents - 1], '/', 2);
if (!withAlpha)
return;
// without alpha
if (withAlpha.length === 1 || withAlpha[withAlpha.length - 1] === '')
return { components };
const alpha = withAlpha.pop();
components[totalComponents - 1] = withAlpha.join('/');
const components = getComponents(componentString, ' ');
if (!components) return;
let totalComponents = components.length;
// (fn 1 2 3 / 4)
if (components[totalComponents - 2] === '/') {
return {
components,
alpha,
components: components.slice(0, totalComponents - 2),
alpha: components[totalComponents - 1],
};
}
// (fn 1 2 3/ 4) or (fn 1 2 3 /4)
if (components[totalComponents - 2] != null && (components[totalComponents - 2].endsWith('/') || components[totalComponents - 1].startsWith('/'))) {
const removed = components.splice(totalComponents - 2);
components.push(removed.join(' '));
--totalComponents;
}
// maybe (fn 1 2 3/4)
const withAlpha = getComponents(components[totalComponents - 1], '/', 2);
if (!withAlpha) return;
// without alpha
if (withAlpha.length === 1 || withAlpha[withAlpha.length - 1] === '') return { components };
const alpha = withAlpha.pop();
components[totalComponents - 1] = withAlpha.join('/');
return {
components,
alpha,
};
}
import { isString } from '@unocss/core';
export function getComponent(str, open, close, separators) {
if (str === '') return;
if (isString(separators)) separators = [separators];
if (separators.length === 0) return;
const l = str.length;
let parenthesis = 0;
for (let i = 0; i < l; i++) {
switch (str[i]) {
case open:
parenthesis++;
break;
case close:
if (--parenthesis < 0) return;
break;
default:
for (const separator of separators) {
const separatorLength = separator.length;
if (separatorLength && separator === str.slice(i, i + separatorLength) && parenthesis === 0) {
if (i === 0 || i === l - separatorLength)
return;
return [
str.slice(0, i),
str.slice(i + separatorLength),
];
}
}
if (str === '') return;
if (isString(separators)) separators = [separators];
if (separators.length === 0) return;
const l = str.length;
let parenthesis = 0;
for (let i = 0; i < l; i++) {
switch (str[i]) {
case open:
parenthesis++;
break;
case close:
if (--parenthesis < 0) return;
break;
default:
for (const separator of separators) {
const separatorLength = separator.length;
if (separatorLength && separator === str.slice(i, i + separatorLength) && parenthesis === 0) {
if (i === 0 || i === l - separatorLength) return;
return [
str.slice(0, i),
str.slice(i + separatorLength),
];
}
}
}
return [ str, '', ];
}
return [str, ''];
}
export function getComponents(str, separators, limit) {
limit = limit ?? 10;
const components = [];
let i = 0;
while (str !== '') {
if (++i > limit) return;
const componentPair = getComponent(str, '(', ')', separators);
if (!componentPair) return;
const [component, rest] = componentPair;
components.push(component);
str = rest;
}
if (components.length > 0) return components;
limit = limit ?? 10;
const components = [];
let i = 0;
while (str !== '') {
if (++i > limit) return;
const componentPair = getComponent(str, '(', ')', separators);
if (!componentPair) return;
const [component, rest] = componentPair;
components.push(component);
str = rest;
}
if (components.length > 0) return components;
}

@@ -6,170 +6,148 @@ import { escapeSelector } from '@unocss/core';

const cssProps = [
// basic props
'color', 'border-color', 'background-color', 'flex-grow', 'flex', 'flex-shrink',
'caret-color', 'font', 'gap', 'opacity', 'visibility', 'z-index', 'font-weight',
'zoom', 'text-shadow', 'transform', 'box-shadow',
// positions
'background-position', 'left', 'right', 'top', 'bottom', 'object-position',
// sizes
'max-height', 'min-height', 'max-width', 'min-width', 'height', 'width',
'border-width', 'margin', 'padding', 'outline-width', 'outline-offset',
'font-size', 'line-height', 'text-indent', 'vertical-align',
'border-spacing', 'letter-spacing', 'word-spacing',
// enhances
'stroke', 'filter', 'backdrop-filter', 'fill', 'mask', 'mask-size', 'mask-border', 'clip-path', 'clip',
'border-radius',
// basic props
'color', 'border-color', 'background-color', 'flex-grow', 'flex', 'flex-shrink',
'caret-color', 'font', 'gap', 'opacity', 'visibility', 'z-index', 'font-weight',
'zoom', 'text-shadow', 'transform', 'box-shadow',
// positions
'background-position', 'left', 'right', 'top', 'bottom', 'object-position',
// sizes
'max-height', 'min-height', 'max-width', 'min-width', 'height', 'width',
'border-width', 'margin', 'padding', 'outline-width', 'outline-offset',
'font-size', 'line-height', 'text-indent', 'vertical-align',
'border-spacing', 'letter-spacing', 'word-spacing',
// enhances
'stroke', 'filter', 'backdrop-filter', 'fill', 'mask', 'mask-size', 'mask-border', 'clip-path', 'clip',
'border-radius',
];
function round(n) {
return n.toFixed(10).replace(/\.0+$/, '').replace(/(\.\d+?)0+$/, '$1');
return n.toFixed(10).replace(/\.0+$/, '').replace(/(\.\d+?)0+$/, '$1');
}
export function numberWithUnit(str) {
const match = str.match(numberWithUnitRE);
if (!match)
return;
const [, n, unit] = match;
const num = parseFloat(n);
if (unit && !Number.isNaN(num))
return `${round(num)}${unit}`;
const match = str.match(numberWithUnitRE);
if (!match) return;
const [, n, unit] = match;
const num = parseFloat(n);
if (unit && !Number.isNaN(num)) return `${round(num)}${unit}`;
}
export function auto(str) {
if (str === 'auto' || str === 'a')
return 'auto';
if (str === 'auto' || str === 'a') return 'auto';
}
export function rem(str) {
if (str.match(unitOnlyRE))
return `1${str}`;
const match = str.match(numberWithUnitRE);
if (!match)
return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num))
return unit ? `${round(num)}${unit}` : `${round(num / 10)}rem`;
if (str.match(unitOnlyRE)) return `1${str}`;
const match = str.match(numberWithUnitRE);
if (!match) return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num)) return unit ? `${round(num)}${unit}` : `${round(num / 10)}rem`;
}
export function px(str) {
if (str.match(unitOnlyRE))
return `1${str}`;
const match = str.match(numberWithUnitRE);
if (!match)
return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num))
return unit ? `${round(num)}${unit}` : `${round(num)}px`;
if (str.match(unitOnlyRE)) return `1${str}`;
const match = str.match(numberWithUnitRE);
if (!match) return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num)) return unit ? `${round(num)}${unit}` : `${round(num)}px`;
}
export function number(str) {
if (!numberRE.test(str))
return;
const num = parseFloat(str);
if (!Number.isNaN(num))
return round(num);
if (!numberRE.test(str)) return;
const num = parseFloat(str);
if (!Number.isNaN(num)) return round(num);
}
export function percent(str) {
if (str.endsWith('%'))
str = str.slice(0, -1);
const num = parseFloat(str);
if (!Number.isNaN(num))
return `${round(num / 100)}`;
if (str.endsWith('%')) str = str.slice(0, -1);
const num = parseFloat(str);
if (!Number.isNaN(num)) return `${round(num / 100)}`;
}
export function inverseFraction(str) {
if (str === 'full') return '100%';
const [left, right] = str.split('/');
const num = parseFloat(right) / parseFloat(left);
if (!Number.isNaN(num)) return `${round(num * 100)}%`;
}
export function fraction(str) {
if (str === 'full')
return '100%';
const [left, right] = str.split('/');
const num = parseFloat(left) / parseFloat(right);
if (!Number.isNaN(num))
return `${round(num * 100)}%`;
if (str === 'full') return '100%';
const [left, right] = str.split('/');
const num = parseFloat(left) / parseFloat(right);
if (!Number.isNaN(num)) return `${round(num * 100)}%`;
}
const bracketTypeRe = /^\[(color|length|position|quoted|string):/i;
function bracketWithType(str, requiredType) {
if (str && str.startsWith('[') && str.endsWith(']')) {
let base;
let hintedType;
const match = str.match(bracketTypeRe);
if (!match) {
base = str.slice(1, -1);
}
else {
if (!requiredType)
hintedType = match[1];
base = str.slice(match[0].length, -1);
}
if (!base)
return;
let curly = 0;
for (const i of base) {
if (i === '[') {
curly += 1;
}
else if (i === ']') {
curly -= 1;
if (curly < 0)
return;
}
}
if (curly)
return;
switch (hintedType) {
case 'string': return base
.replace(/(^|[^\\])_/g, '$1 ')
.replace(/\\_/g, '_');
case 'quoted': return base
.replace(/(^|[^\\])_/g, '$1 ')
.replace(/\\_/g, '_')
.replace(/(["\\])/g, '\\$1')
.replace(/^(.+)$/, '"$1"');
}
return base
.replace(/(url\(.*?\))/g, v => v.replace(/_/g, '\\_'))
.replace(/(^|[^\\])_/g, '$1 ')
.replace(/\\_/g, '_')
.replace(/(?:calc|clamp|max|min)\((.*)/g, (v) => {
return v.replace(/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 ');
});
if (str && str.startsWith('[') && str.endsWith(']')) {
let base;
let hintedType;
const match = str.match(bracketTypeRe);
if (!match) {
base = str.slice(1, -1);
} else {
if (!requiredType) hintedType = match[1];
base = str.slice(match[0].length, -1);
}
if (!base) return;
let curly = 0;
for (const i of base) {
if (i === '[') {
curly += 1;
} else if (i === ']') {
curly -= 1;
if (curly < 0) return;
}
}
if (curly) return;
switch (hintedType) {
case 'string': return base
.replace(/(^|[^\\])_/g, '$1 ')
.replace(/\\_/g, '_');
case 'quoted': return base
.replace(/(^|[^\\])_/g, '$1 ')
.replace(/\\_/g, '_')
.replace(/(["\\])/g, '\\$1')
.replace(/^(.+)$/, '"$1"');
}
return base
.replace(/(url\(.*?\))/g, v => v.replace(/_/g, '\\_'))
.replace(/(^|[^\\])_/g, '$1 ')
.replace(/\\_/g, '_')
.replace(/(?:calc|clamp|max|min)\((.*)/g, (v) => v.replace(/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 '));
}
}
export function bracket(str) {
return bracketWithType(str);
return bracketWithType(str);
}
export function bracketOfColor(str) {
return bracketWithType(str, 'color');
return bracketWithType(str, 'color');
}
export function bracketOfLength(str) {
return bracketWithType(str, 'length');
return bracketWithType(str, 'length');
}
export function bracketOfPosition(str) {
return bracketWithType(str, 'position');
return bracketWithType(str, 'position');
}
export function warpToken(str) {
if (str.match(/^\$\S/)) return `var(--w-${escapeSelector(str.slice(1))})`;
}
export function cssvar(str) {
if (str.match(/^\$\S/))
return `var(--${escapeSelector(str.slice(1))})`;
if (str.match(/^\$\S/)) return `var(--${escapeSelector(str.slice(1))})`;
}
export function time(str) {
const match = str.match(/^(-?[0-9.]+)(s|ms)?$/i);
if (!match)
return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num))
return unit ? `${round(num)}${unit}` : `${round(num)}ms`;
const match = str.match(/^(-?[0-9.]+)(s|ms)?$/i);
if (!match) return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num)) return unit ? `${round(num)}${unit}` : `${round(num)}ms`;
}
export function degree(str) {
const match = str.match(/^(-?[0-9.]+)(deg|rad|grad|turn)?$/i);
if (!match)
return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num))
return unit ? `${round(num)}${unit}` : `${round(num)}deg`;
const match = str.match(/^(-?[0-9.]+)(deg|rad|grad|turn)?$/i);
if (!match) return;
const [, n, unit] = match;
const num = parseFloat(n);
if (!Number.isNaN(num)) return unit ? `${round(num)}${unit}` : `${round(num)}deg`;
}
export function global(str) {
if (globalKeywords.includes(str))
return str;
if (globalKeywords.includes(str)) return str;
}
export function properties(str) {
if (str.split(',').every(prop => cssProps.includes(prop)))
return str;
if (str.split(',').every(prop => cssProps.includes(prop))) return str;
}
export function position(str) {
if (['top', 'left', 'right', 'bottom', 'center'].includes(str))
return str;
if (['top', 'left', 'right', 'bottom', 'center'].includes(str)) return str;
}

@@ -7,2 +7,2 @@ import { createValueHandler } from '@unocss/core';

export { valueHandlers };
export * from './regex.js'
export * from './regex.js';
export const directionMap = {
'l': ['-left'],
'r': ['-right'],
't': ['-top'],
'b': ['-bottom'],
's': ['-inline-start'],
'e': ['-inline-end'],
'x': ['-left', '-right'],
'y': ['-top', '-bottom'],
'': [''],
'bs': ['-block-start'],
'be': ['-block-end'],
'is': ['-inline-start'],
'ie': ['-inline-end'],
'block': ['-block-start', '-block-end'],
'inline': ['-inline-start', '-inline-end'],
'l': ['-left'],
'r': ['-right'],
't': ['-top'],
'b': ['-bottom'],
's': ['-inline-start'],
'e': ['-inline-end'],
'x': ['-left', '-right'],
'y': ['-top', '-bottom'],
'': [''],
'bs': ['-block-start'],
'be': ['-block-end'],
'is': ['-inline-start'],
'ie': ['-inline-end'],
'block': ['-block-start', '-block-end'],
'inline': ['-inline-start', '-inline-end'],
};
export const insetMap = {
...directionMap,
s: ['-inset-inline-start'],
e: ['-inset-inline-end'],
bs: ['-inset-block-start'],
be: ['-inset-block-end'],
is: ['-inset-inline-start'],
ie: ['-inset-inline-end'],
block: ['-inset-block-start', '-inset-block-end'],
inline: ['-inset-inline-start', '-inset-inline-end'],
...directionMap,
s: ['-inset-inline-start'],
e: ['-inset-inline-end'],
bs: ['-inset-block-start'],
be: ['-inset-block-end'],
is: ['-inset-inline-start'],
ie: ['-inset-inline-end'],
block: ['-inset-block-start', '-inset-block-end'],
inline: ['-inset-inline-start', '-inset-inline-end'],
};
export const cornerMap = {
'l': ['-top-left', '-bottom-left'],
'r': ['-top-right', '-bottom-right'],
't': ['-top-left', '-top-right'],
'b': ['-bottom-left', '-bottom-right'],
'tl': ['-top-left'],
'lt': ['-top-left'],
'tr': ['-top-right'],
'rt': ['-top-right'],
'bl': ['-bottom-left'],
'lb': ['-bottom-left'],
'br': ['-bottom-right'],
'rb': ['-bottom-right'],
'': [''],
'bs': ['-start-start', '-start-end'],
'be': ['-end-start', '-end-end'],
'is': ['-end-start', '-start-start'],
'ie': ['-start-end', '-end-end'],
'bs-is': ['-start-start'],
'is-bs': ['-start-start'],
'bs-ie': ['-start-end'],
'ie-bs': ['-start-end'],
'be-is': ['-end-start'],
'is-be': ['-end-start'],
'be-ie': ['-end-end'],
'ie-be': ['-end-end'],
'l': ['-top-left', '-bottom-left'],
'r': ['-top-right', '-bottom-right'],
't': ['-top-left', '-top-right'],
'b': ['-bottom-left', '-bottom-right'],
'tl': ['-top-left'],
'lt': ['-top-left'],
'tr': ['-top-right'],
'rt': ['-top-right'],
'bl': ['-bottom-left'],
'lb': ['-bottom-left'],
'br': ['-bottom-right'],
'rb': ['-bottom-right'],
'': [''],
'bs': ['-start-start', '-start-end'],
'be': ['-end-start', '-end-end'],
'is': ['-end-start', '-start-start'],
'ie': ['-start-end', '-end-end'],
'bs-is': ['-start-start'],
'is-bs': ['-start-start'],
'bs-ie': ['-start-end'],
'ie-bs': ['-start-end'],
'be-is': ['-end-start'],
'is-be': ['-end-start'],
'be-ie': ['-end-end'],
'ie-be': ['-end-end'],
};
export const xyzMap = {
'x': ['-x'],
'y': ['-y'],
'z': ['-z'],
'': ['-x', '-y'],
'x': ['-x'],
'y': ['-y'],
'z': ['-z'],
'': ['-x', '-y'],
};
const basePositionMap = [
'top',
'top center',
'top left',
'top right',
'bottom',
'bottom center',
'bottom left',
'bottom right',
'left',
'left center',
'left top',
'left bottom',
'right',
'right center',
'right top',
'right bottom',
'center',
'center top',
'center bottom',
'center left',
'center right',
'center center',
'top',
'top center',
'top left',
'top right',
'bottom',
'bottom center',
'bottom left',
'bottom right',
'left',
'left center',
'left top',
'left bottom',
'right',
'right center',
'right top',
'right bottom',
'center',
'center top',
'center bottom',
'center left',
'center right',
'center center',
];
export const positionMap = Object.assign({},
export const positionMap = Object.assign({},
// [{ top: 'top' }, { 'top-center': 'top center' }, ...]
...basePositionMap.map(p => ({ [p.replace(/ /, '-')]: p })),
// [{ t: 'top' }, { tc: 'top center' }, ...]
...basePositionMap.map(p => ({ [p.replace(/\b(\w)\w+/g, '$1').replace(/ /, '')]: p })));
...basePositionMap.map(p => ({ [p.replace(/ /, '-')]: p })),
// [{ t: 'top' }, { tc: 'top center' }, ...]
...basePositionMap.map(p => ({ [p.replace(/\b(\w)\w+/g, '$1').replace(/ /, '')]: p })));
export const globalKeywords = [
'inherit',
'initial',
'revert',
'revert-layer',
'unset',
'inherit',
'initial',
'revert',
'revert-layer',
'unset',
];
import { toArray, warnOnce } from '@unocss/core';
import { colorOpacityToString, colorToString, parseCssColor } from './colors.js'
import { handler as h } from './handlers/index.js'
import { directionMap, globalKeywords } from './mappings.js'
import { getComponents } from './getComponents.js'
import { colorOpacityToString, colorToString, parseCssColor } from './colors.js';
import { handler as h } from './handlers/index.js';
import { directionMap, globalKeywords } from './mappings.js';
import { getComponents } from './getComponents.js';

@@ -15,7 +15,7 @@ /**

export function directionSize(propertyPrefix) {
return ([_, direction, size], { theme }) => {
const v = theme.spacing?.[size] ?? h.global.auto(size);
if (!v) return warnOnce(`${propertyPrefix} not available in size ${size}`)
if (v != null) return directionMap[direction].map(i => [`${propertyPrefix}${i}`, v]);
};
return ([_, direction, size], { theme }) => {
const v = theme.spacing?.[size] ?? h.global.auto(size);
if (!v) return warnOnce(`${propertyPrefix} not available in size ${size}`);
if (v != null) return directionMap[direction].map(i => [`${propertyPrefix}${i}`, v]);
};
}

@@ -26,22 +26,21 @@ /**

function getThemeColor(theme, colors) {
let obj = theme.colors;
let index = -1;
for (const c of colors) {
index += 1;
if (obj && typeof obj !== 'string') {
const camel = colors.slice(index).join('-').replace(/(-[a-z])/g, n => n.slice(1).toUpperCase());
if (obj[camel])
return obj[camel];
if (obj[c]) {
obj = obj[c];
continue;
}
}
return undefined;
let obj = theme.colors;
let index = -1;
for (const c of colors) {
index += 1;
if (obj && typeof obj !== 'string') {
const camel = colors.slice(index).join('-').replace(/(-[a-z])/g, n => n.slice(1).toUpperCase());
if (obj[camel]) return obj[camel];
if (obj[c]) {
obj = obj[c];
continue;
}
}
return obj;
return undefined;
}
return obj;
}
export function splitShorthand(body, type) {
const split = body.split(/(?:\/|:)/)
const split = body.split(/(?:\/|:)/);

@@ -52,6 +51,6 @@ if (split[0] === `[${type}`) {

split[2],
]
];
}
return split
return split;
}

@@ -74,59 +73,49 @@

export function parseColor(body, theme) {
const split = body.split(/(?:\/|:)/);
let main, opacity;
if (split[0] === '[color') {
main = split.slice(0, 2).join(':');
opacity = split[2];
const split = body.split(/(?:\/|:)/);
let main, opacity;
if (split[0] === '[color') {
main = split.slice(0, 2).join(':');
opacity = split[2];
} else {
[main, opacity] = split;
}
const colors = main
.replace(/([a-z])([0-9])/g, '$1-$2')
.split(/-/g);
const [name] = colors;
if (!name) return;
let color;
const bracket = h.bracketOfColor(main);
const bracketOrMain = bracket || main;
if (bracketOrMain.match(/^#[\da-fA-F]+/g)) color = bracketOrMain;
else if (bracketOrMain.match(/^hex-[\da-fA-F]+/g)) color = `#${bracketOrMain.slice(4)}`;
else if (main.startsWith('$')) color = h.cssvar(main);
color = color || bracket;
let no = 'DEFAULT';
if (!color) {
let colorData;
const [scale] = colors.slice(-1);
if (scale.match(/^\d+$/)) {
no = scale;
colorData = getThemeColor(theme, colors.slice(0, -1));
if (!colorData || typeof colorData === 'string') color = undefined;
else color = colorData[no];
} else {
colorData = getThemeColor(theme, colors);
if (!colorData && colors.length <= 2) {
[, no = no] = colors;
colorData = getThemeColor(theme, [name]);
}
if (typeof colorData === 'string') color = colorData;
else if (no && colorData) color = colorData[no];
}
else {
[main, opacity] = split;
}
const colors = main
.replace(/([a-z])([0-9])/g, '$1-$2')
.split(/-/g);
const [name] = colors;
if (!name)
return;
let color;
const bracket = h.bracketOfColor(main);
const bracketOrMain = bracket || main;
if (bracketOrMain.match(/^#[\da-fA-F]+/g))
color = bracketOrMain;
else if (bracketOrMain.match(/^hex-[\da-fA-F]+/g))
color = `#${bracketOrMain.slice(4)}`;
else if (main.startsWith('$'))
color = h.cssvar(main);
color = color || bracket;
let no = 'DEFAULT';
if (!color) {
let colorData;
const [scale] = colors.slice(-1);
if (scale.match(/^\d+$/)) {
no = scale;
colorData = getThemeColor(theme, colors.slice(0, -1));
if (!colorData || typeof colorData === 'string')
color = undefined;
else
color = colorData[no];
}
else {
colorData = getThemeColor(theme, colors);
if (!colorData && colors.length <= 2) {
[, no = no] = colors;
colorData = getThemeColor(theme, [name]);
}
if (typeof colorData === 'string')
color = colorData;
else if (no && colorData)
color = colorData[no];
}
}
return {
opacity,
name,
no,
color,
cssColor: parseCssColor(color),
alpha: h.bracket.cssvar.percent(opacity ?? ''),
};
}
return {
opacity,
name,
no,
color,
cssColor: parseCssColor(color),
alpha: h.bracket.cssvar.percent(opacity ?? ''),
};
}

@@ -160,91 +149,83 @@ /**

export function colorResolver(property, varName, shouldPass) {
return ([, body], { theme }) => {
const data = parseColor(body, theme);
if (!data)
return;
const { alpha, color, cssColor } = data;
const css = {};
if (cssColor) {
if (alpha != null) {
css[property] = colorToString(cssColor, alpha);
}
else {
css[`--un-${varName}-opacity`] = colorOpacityToString(cssColor);
css[property] = colorToString(cssColor, `var(--un-${varName}-opacity)`);
}
}
else if (color) {
css[property] = colorToString(color, alpha);
}
if (shouldPass?.(css) !== false)
return css;
};
return ([, body], { theme }) => {
const data = parseColor(body, theme);
if (!data) return;
const { alpha, color, cssColor } = data;
const css = {};
if (cssColor) {
if (alpha != null) {
css[property] = colorToString(cssColor, alpha);
} else {
css[`--un-${varName}-opacity`] = colorOpacityToString(cssColor);
css[property] = colorToString(cssColor, `var(--un-${varName}-opacity)`);
}
} else if (color) {
css[property] = colorToString(color, alpha);
}
if (shouldPass?.(css) !== false) return css;
};
}
export function colorableShadows(shadows, colorVar) {
const colored = [];
shadows = toArray(shadows);
for (let i = 0; i < shadows.length; i++) {
// shadow values are between 3 to 6 terms including color
const components = getComponents(shadows[i], ' ', 6);
if (!components || components.length < 3)
return shadows;
const color = parseCssColor(components.pop());
if (color == null)
return shadows;
colored.push(`${components.join(' ')} var(${colorVar}, ${colorToString(color)})`);
}
return colored;
const colored = [];
shadows = toArray(shadows);
for (let i = 0; i < shadows.length; i++) {
// shadow values are between 3 to 6 terms including color
const components = getComponents(shadows[i], ' ', 6);
if (!components || components.length < 3) return shadows;
const color = parseCssColor(components.pop());
if (color == null) return shadows;
colored.push(`${components.join(' ')} var(${colorVar}, ${colorToString(color)})`);
}
return colored;
}
export function hasParseableColor(color, theme) {
return color != null && !!parseColor(color, theme)?.color;
return color != null && !!parseColor(color, theme)?.color;
}
export function resolveBreakpoints({ theme, generator }) {
let breakpoints;
if (generator.userConfig && generator.userConfig.theme)
breakpoints = generator.userConfig.theme.breakpoints;
if (!breakpoints)
breakpoints = theme.breakpoints;
return breakpoints;
let breakpoints;
if (generator.userConfig && generator.userConfig.theme) breakpoints = generator.userConfig.theme.breakpoints;
if (!breakpoints) breakpoints = theme.breakpoints;
return breakpoints;
}
export function resolveVerticalBreakpoints({ theme, generator }) {
let verticalBreakpoints;
if (generator.userConfig && generator.userConfig.theme)
verticalBreakpoints = generator.userConfig.theme.verticalBreakpoints;
if (!verticalBreakpoints)
verticalBreakpoints = theme.verticalBreakpoints;
return verticalBreakpoints;
let verticalBreakpoints;
if (generator.userConfig && generator.userConfig.theme) verticalBreakpoints = generator.userConfig.theme.verticalBreakpoints;
if (!verticalBreakpoints) verticalBreakpoints = theme.verticalBreakpoints;
return verticalBreakpoints;
}
export function makeGlobalStaticRules(prefix, property) {
return globalKeywords.map(keyword => [`${prefix}-${keyword}`, { [property ?? prefix]: keyword }]);
return globalKeywords.map(keyword => [`${prefix}-${keyword}`, { [property ?? prefix]: keyword }]);
}
export function getBracket(str, open, close) {
if (str === '')
return;
const l = str.length;
let parenthesis = 0;
let opened = false;
let openAt = 0;
for (let i = 0; i < l; i++) {
switch (str[i]) {
case open:
if (!opened) {
opened = true;
openAt = i;
}
parenthesis++;
break;
case close:
--parenthesis;
if (parenthesis < 0)
return;
if (parenthesis === 0) {
return [
str.slice(openAt, i + 1),
str.slice(i + 1),
str.slice(0, openAt),
];
}
break;
if (str === '') return;
const l = str.length;
let parenthesis = 0;
let opened = false;
let openAt = 0;
for (let i = 0; i < l; i++) {
switch (str[i]) {
case open:
if (!opened) {
opened = true;
openAt = i;
}
parenthesis++;
break;
case close:
--parenthesis;
if (parenthesis < 0) return;
if (parenthesis === 0) {
return [
str.slice(openAt, i + 1),
str.slice(i + 1),
str.slice(0, openAt),
];
}
break;
}
}
}
export function getNumericArrayInRange(first, last) {
return Array.from({ length: last - first + 1 }, (_, index) => first + index);
}

@@ -5,71 +5,70 @@ import { escapeRegExp } from '@unocss/core';

export const variantMatcher = (name, handler) => {
const re = new RegExp(`^${escapeRegExp(name)}[:-]`);
return {
name,
match(input) {
const match = input.match(re);
if (match) {
return {
matcher: input.slice(match[0].length),
handle: (input, next) => next({
...input,
...handler(input),
}),
};
}
},
autocomplete: `${name}:`,
};
const re = new RegExp(`^${escapeRegExp(name)}[:-]`);
return {
name,
match(input) {
const match = input.match(re);
if (match) {
return {
matcher: input.slice(match[0].length),
handle: (input, next) => next({
...input,
...handler(input),
}),
};
}
},
autocomplete: `${name}:`,
};
};
export const variantParentMatcher = (name, parent) => {
const re = new RegExp(`^${escapeRegExp(name)}[:-]`);
return {
name,
match(input) {
const match = input.match(re);
if (match) {
return {
matcher: input.slice(match[0].length),
handle: (input, next) => next({
...input,
parent: `${input.parent ? `${input.parent} $$ ` : ''}${parent}`,
}),
};
}
},
autocomplete: `${name}:`,
};
const re = new RegExp(`^${escapeRegExp(name)}[:-]`);
return {
name,
match(input) {
const match = input.match(re);
if (match) {
return {
matcher: input.slice(match[0].length),
handle: (input, next) => next({
...input,
parent: `${input.parent ? `${input.parent} $$ ` : ''}${parent}`,
}),
};
}
},
autocomplete: `${name}:`,
};
};
export const variantGetBracket = (prefix, matcher, separators) => {
if (matcher.startsWith(`${prefix}[`)) {
const [match, rest] = getBracket(matcher.slice(prefix.length), '[', ']') ?? [];
if (match && rest) {
for (const separator of separators) {
if (rest.startsWith(separator))
return [match, rest.slice(separator.length), separator];
}
return [match, rest, ''];
}
if (matcher.startsWith(`${prefix}[`)) {
const [match, rest] = getBracket(matcher.slice(prefix.length), '[', ']') ?? [];
if (match && rest) {
for (const separator of separators) {
if (rest.startsWith(separator)) return [match, rest.slice(separator.length), separator];
}
return [match, rest, ''];
}
}
};
export const variantGetParameter = (prefix, matcher, separators) => {
if (matcher.startsWith(prefix)) {
const body = variantGetBracket(prefix, matcher, separators);
if (body) {
const [label = '', rest = body[1]] = variantGetParameter('/', body[1], separators) ?? [];
return [body[0], rest, label];
}
for (const separator of separators.filter(x => x !== '/')) {
const pos = matcher.indexOf(separator, prefix.length);
if (pos !== -1) {
const labelPos = matcher.indexOf('/', prefix.length);
const unlabelled = labelPos === -1 || pos <= labelPos;
return [
matcher.slice(prefix.length, unlabelled ? pos : labelPos),
matcher.slice(pos + separator.length),
unlabelled ? '' : matcher.slice(labelPos + 1, pos),
];
}
}
if (matcher.startsWith(prefix)) {
const body = variantGetBracket(prefix, matcher, separators);
if (body) {
const [label = '', rest = body[1]] = variantGetParameter('/', body[1], separators) ?? [];
return [body[0], rest, label];
}
for (const separator of separators.filter(x => x !== '/')) {
const pos = matcher.indexOf(separator, prefix.length);
if (pos !== -1) {
const labelPos = matcher.indexOf('/', prefix.length);
const unlabelled = labelPos === -1 || pos <= labelPos;
return [
matcher.slice(prefix.length, unlabelled ? pos : labelPos),
matcher.slice(pos + separator.length),
unlabelled ? '' : matcher.slice(labelPos + 1, pos),
];
}
}
}
};

@@ -8,4 +8,4 @@ import {

variantPseudoClassesAndElements,
} from '@unocss/preset-mini/variants'
import { variantSpaceAndDivide } from './spaceAndDivide.js'
} from '@unocss/preset-mini/variants';
import { variantSpaceAndDivide } from './spaceAndDivide.js';

@@ -20,3 +20,3 @@ export const variants = [

...variantTaggedPseudoClasses({ attributifyPseudo: false }),
]
];

@@ -30,3 +30,3 @@ export {

variantSpaceAndDivide,
variantTaggedPseudoClasses
}
variantTaggedPseudoClasses,
};
// this lives in preset-wind and isn't explicitly exported
export const variantSpaceAndDivide = (matcher) => {
if (matcher.startsWith('_')) return
if (matcher.startsWith('_')) return;
if (/^space-?([xy])-?(-?.+)$/.test(matcher) || /divide-/.test(matcher)) {
return {
matcher,
selector: (input) => `${input}>:not([hidden])~:not([hidden])`
}
selector: (input) => `${input}>:not([hidden])~:not([hidden])`,
};
}
}
};

@@ -1,8 +0,8 @@

import { warnOnce } from '@unocss/core'
import { warnOnce } from '@unocss/core';
const inBounds = (v, bounds) => {
if (Number.isNaN(Number(v))) return true
return v >= bounds[0] && v <= bounds[1]
}
const notAvailable = (className, value) => `${className} is not available - this error message needs improvement`
if (Number.isNaN(Number(v))) return true;
return v >= bounds[0] && v <= bounds[1];
};
const notAvailable = (className, value) => `${className} is not available - this error message needs improvement`;

@@ -13,6 +13,6 @@ // we currently can't pass handler's as first-class functions because of something goofy in Uno

export const bounded = (cb, bounds, options = {}) => ([_, d]) => {
const val = options.handler?.(d)
if (options.nullable && !d) return cb([_, d])
if (!inBounds(val, bounds)) return warnOnce(notAvailable(_, d))
return cb([_, d])
}
const val = options.handler?.(d);
if (options.nullable && !d) return cb([_, d]);
if (!inBounds(val, bounds)) return warnOnce(notAvailable(_, d));
return cb([_, d]);
};
// grid
export const gridRow = [1,7]
export const gridCol = [1,13]
export const gridRow = [1,7];
export const gridCol = [1,13];
// flex
export const flexGrowShrink = [0, 5]
export const flexGrowShrink = [0, 5];
// position
export const order = [1, 12]
export const order = [1, 12];

@@ -1,5 +0,5 @@

export { theme } from '#theme'
export { rules } from '#rules'
export { variants } from '#variants'
export * as bounds from '#bounds'
export { theme } from '#theme';
export { rules } from '#rules';
export { variants } from '#variants';
export * as bounds from '#bounds';

@@ -1,13 +0,13 @@

import { preflights } from '#preflights'
import { rules } from '#rules'
import { variants } from '#variants'
import { useTheme } from '#theme'
import { preflights } from '#preflights';
import { rules } from '#rules';
import { variants } from '#variants';
import { useTheme } from '#theme';
import { postprocess } from '#postprocess';
const includePreflight = ['base', 'hyper']
/**
* @typedef PluginOptions
* @type {Object}
* @property {string} mode - one of X, Y, Z - modifies CSS output
* @property {boolean} development // not in use yet
* @property {boolean} usePreflight - force preflights to be included/excluded
* @property {boolean} externalizeClasses - force external or 'core' classes to be included/excluded
* @property {boolean} usePixels - use pixel spacing instead of rem

@@ -19,5 +19,6 @@ */

export function presetWarp (options = {}) {
const mode = options.mode ?? 'app'
const hasPreflight = options.usePreflight ?? includePreflight.includes(mode)
const theme = useTheme(options)
const hasPreflight = options.usePreflight ?? options.development;
const externalizeClasses = options.externalizeClasses ?? !options.development;
const externalClasses = options.externalClasses ?? []; // will possibly be our own list in the future
const theme = useTheme(options);
return {

@@ -28,6 +29,7 @@ name: '@warp-ds/uno',

variants,
preflights: hasPreflight ? preflights : []
}
preflights: hasPreflight ? preflights : [],
postprocess: postprocess(externalizeClasses, externalClasses),
};
}
export default presetWarp
export default presetWarp;

@@ -8,11 +8,11 @@ const breakpoints = {

lg: '990px',
}
};
const divideByTen = n => {
const roundedDecimal = Number((n / 10).toFixed(1)) // avoid any JS maths stupidity
return Math.round(roundedDecimal) === roundedDecimal ? Math.round(roundedDecimal) : roundedDecimal
}
export const spaceBase = [0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 44, 48, 56, 64, 80, 96, 112, 128, 144]
const spacingInPx = spaceBase.reduce((acc, e) => (acc[e] = `${e}px`, acc), {})
const spacingInRem = spaceBase.reduce((acc, e) => (acc[e] = `${divideByTen(e)}rem`, acc), {})
const roundedDecimal = Number((n / 10).toFixed(1)); // avoid any JS maths stupidity
return Math.round(roundedDecimal) === roundedDecimal ? Math.round(roundedDecimal) : roundedDecimal;
};
export const spaceBase = [0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 44, 48, 56, 64, 80, 96, 112, 128, 144];
const spacingInPx = spaceBase.reduce((acc, e) => (acc[e] = `${e}px`, acc), {});
const spacingInRem = spaceBase.reduce((acc, e) => (acc[e] = `${divideByTen(e)}rem`, acc), {});

@@ -26,5 +26,5 @@ const zIndex = {

50: "50",
}
};
const lineWidth = {
export const lineWidth = {
0: "0",

@@ -35,3 +35,3 @@ 1: "1px",

8: "8px",
}
};

@@ -46,14 +46,21 @@ const borderRadius = {

"full": "9999px",
}
};
export const durationBase = [75, 100, 150, 200, 300, 500, 700, 1000]
const duration = durationBase.reduce((acc, e) => (acc[e] = `${e}ms`, acc), {})
export const opacity = {
0: '0%',
25: '25%',
50: '50%',
100: '100%',
};
export const durationBase = [75, 100, 150, 200, 300, 500, 700, 1000];
const duration = durationBase.reduce((acc, e) => (acc[e] = `${e}ms`, acc), {});
export const useTheme = (opts = {}) => {
const baseSpacing = opts.usePixels ? spacingInPx : spacingInRem
const width = { ...baseSpacing, screen: '100vw' }
const height = { ...baseSpacing, screen: '100vh' }
const baseSpacing = opts.usePixels ? spacingInPx : spacingInRem;
const width = { ...baseSpacing, screen: '100vw' };
const height = { ...baseSpacing, screen: '100vh' };
return {
usingPixels: !!opts.pxSpacing,
usingPixels: !!opts.usePixels,
breakpoints,

@@ -71,4 +78,5 @@ borderRadius,

minHeight: height,
duration
}
}
duration,
opacity,
};
};

@@ -1,19 +0,19 @@

import { createGenerator } from '@unocss/core'
import { beforeEach } from 'vitest'
import { presetWarp } from '#plugin'
import { createGenerator } from '@unocss/core';
import { beforeEach } from 'vitest';
import { presetWarp } from '#plugin';
export const getGenerator = (opts = {}) => createGenerator({ presets: [presetWarp(opts)] })
export const getGenerator = (opts = {}) => createGenerator({ presets: [presetWarp(opts)] });
export const setup = (opts = {}) => {
beforeEach(t => {
t.uno = getGenerator(opts)
})
}
t.uno = getGenerator(opts);
});
};
export const getFractions = (prefix, length = 6) => {
const numerator = Array.from({ length }).map((_, i) => i + 1)
const denomenator = Array.from({ length }).map((_, i) => i + 1)
const numerator = Array.from({ length }).map((_, i) => i + 1);
const denomenator = Array.from({ length }).map((_, i) => i + 1);
return numerator.flatMap(n => denomenator.map(d => {
if (n > d) return
return `${prefix}-${n}/${d}`
})).filter(Boolean)
}
if (n > d) return;
return `${prefix}-${n}/${d}`;
})).filter(Boolean);
};

@@ -1,16 +0,16 @@

import { setup } from './_helpers.js'
import { expect, test } from 'vitest'
import { setup } from './_helpers.js';
import { expect, test } from 'vitest';
setup()
setup();
test('appearance', async ({ uno }) => {
const { css } = await uno.generate('appearance-none')
const { css } = await uno.generate('appearance-none');
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.appearance-none{appearance:none;-webkit-appearance:none;}"
`)
})
`);
});
test('will-change', async ({ uno }) => {
const { css } = await uno.generate(['will-change-height', 'will-change-color'])
const { css } = await uno.generate(['will-change-height', 'will-change-color']);
expect(css).toMatchInlineSnapshot(`

@@ -20,18 +20,13 @@ "/* layer: default */

.will-change-height{will-change:height;}"
`)
})
`);
});
test('will-change', async ({ uno }) => {
const { css } = await uno.generate(['list-disc', 'list-circle', 'list-outside', 'list-inside', 'list-none'])
expect(css).toMatchSnapshot()
})
test('overscroll', async ({ uno }) => {
const classes = ['overscroll-auto', 'overscroll-contain', 'overscroll-none', 'overscroll-y-auto', 'overscroll-y-contain', 'overscroll-y-none', 'overscroll-x-auto', 'overscroll-x-contain', 'overscroll-x-none']
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['overscroll-auto', 'overscroll-contain', 'overscroll-none', 'overscroll-y-auto', 'overscroll-y-contain', 'overscroll-y-none', 'overscroll-x-auto', 'overscroll-x-contain', 'overscroll-x-none'];
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('scroll', async ({ uno }) => {
const { css } = await uno.generate(['scroll-auto', 'scroll-smooth'])
const { css } = await uno.generate(['scroll-auto', 'scroll-smooth']);
expect(css).toMatchInlineSnapshot(`

@@ -41,3 +36,3 @@ "/* layer: default */

.scroll-smooth{scroll-behavior:smooth;}"
`)
})
`);
});
import { setup } from "./_helpers.js";
import { describe, expect, test } from "vitest";
import { lineWidth } from '#theme';

@@ -84,2 +85,29 @@ setup();

});
test('supports divide borders between horizontal and stacked children', async ({ uno }) => {
const classes = Object.keys(lineWidth).map(width => [`divide-x-${width}`, `divide-y-${width}`]).flat();
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('supports divide borders between horizontal and stacked children in reverse order', async ({ uno }) => {
const classes = Object.keys(lineWidth).map(width => [`divide-x-${width}-reverse`, `divide-y-${width}-reverse`]).flat();
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('supports divide borders between horizontal and stacked children, default width', async ({ uno }) => {
const { css } = await uno.generate(['divide-x', 'divide-y', 'divide-x-reverse', 'divide-y-reverse']);
expect(css).toMatchSnapshot();
});
test('does not support divide borders when invalid width provided', async ({ uno }) => {
const classes = ['divide-x-10', 'divide-y-hej', 'divide-z-2-not-reverse'];
const { css } = await uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
});

@@ -86,0 +114,0 @@

@@ -8,3 +8,3 @@ import { setup } from "./_helpers.js";

test("supports underline and line-through", async (t) => {
const classes = ['underline', 'line-through']
const classes = ['underline', 'line-through'];

@@ -23,2 +23,2 @@ const { css } = await t.uno.generate(classes);

});
})
});

@@ -1,5 +0,5 @@

import { expect, test } from 'vitest'
import { expect, test } from 'vitest';
import { setup } from "./_helpers.js";
setup()
setup();

@@ -11,6 +11,6 @@ test("focus ring", async (t) => {

"focusable:focus-visible",
"focusable-inset"
]
"focusable-inset",
];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);

@@ -23,3 +23,3 @@ expect(css).toMatchInlineSnapshot(`

.focusable-inset{--w-outline-offset:-3px;}"
`)
})
`);
});

@@ -1,13 +0,11 @@

import { setup } from './_helpers.js'
import { spaceBase } from '#theme'
import { expect, test } from 'vitest'
import { setup } from './_helpers.js';
import { spaceBase } from '#theme';
import { expect, test } from 'vitest';
setup()
setup();
test('gap allows to render css based of all units in spaceBase', async (t) => {
const classes = spaceBase.map((spacingUnit) => {
return `gap-${spacingUnit}`
})
const classes = spaceBase.map((spacingUnit) => `gap-${spacingUnit}`);
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);

@@ -40,9 +38,9 @@ expect(css).toMatchInlineSnapshot(`

.gap-96{gap:9.6rem;}"
`)
})
`);
});
test("gap does not render css for invalid spacing units", async (t) => {
const { css } = await t.uno.generate(["gap-9999"])
const { css } = await t.uno.generate(["gap-9999"]);
expect(css).toMatchInlineSnapshot('""')
})
expect(css).toMatchInlineSnapshot('""');
});

@@ -1,36 +0,36 @@

import { rules, display } from '#rules'
import { assert, expect, test } from 'vitest'
import { setup, getGenerator } from './_helpers.js'
import { createAutocomplete } from '@unocss/autocomplete'
import { rules, display } from '#rules';
import { assert, expect, test } from 'vitest';
import { setup, getGenerator } from './_helpers.js';
import { createAutocomplete } from '@unocss/autocomplete';
setup()
setup();
test('all static rules generate', async ({ uno }) => {
const staticClasses = rules.filter(r => typeof r[0] === 'string').map(r => r[0])
const generated = await uno.generate(staticClasses)
const staticClasses = rules.filter(r => typeof r[0] === 'string').map(r => r[0]);
const generated = await uno.generate(staticClasses);
// generated.matched is a Set
assert.equal(generated.matched.size, staticClasses.length)
})
assert.equal(generated.matched.size, staticClasses.length);
});
test('display rules are sane', async ({ uno }) => {
// filter 'hidden' because it doesn't map 1:1 with the CSS it generates
const displayClasses = display.filter(r => typeof r[0] === 'string').map(r => r[0]).filter(r => r !== 'hidden')
const buildDisplayRule = c => `display:${c};`
const displayExpectations = displayClasses.map(buildDisplayRule)
displayClasses.push('hidden', 'display-unset', 'display-revert', 'display-inherit')
displayExpectations.push(buildDisplayRule('none'), buildDisplayRule('unset'), buildDisplayRule('revert'), buildDisplayRule('inherit'))
const { css } = await uno.generate(displayClasses)
for (const expected of displayExpectations) assert.include(css, expected)
})
const displayClasses = display.filter(r => typeof r[0] === 'string').map(r => r[0]).filter(r => r !== 'hidden');
const buildDisplayRule = c => `display:${c};`;
const displayExpectations = displayClasses.map(buildDisplayRule);
displayClasses.push('hidden', 'display-unset', 'display-revert', 'display-inherit');
displayExpectations.push(buildDisplayRule('none'), buildDisplayRule('unset'), buildDisplayRule('revert'), buildDisplayRule('inherit'));
const { css } = await uno.generate(displayClasses);
for (const expected of displayExpectations) assert.include(css, expected);
});
test(`autocomplete doesn't throw`, async ({ uno }) => {
assert.doesNotThrow(() => {
const ac = createAutocomplete(uno)
ac.enumerate()
})
})
const ac = createAutocomplete(uno);
ac.enumerate();
});
});
test('can generate pixel values for theme', async () => {
const uno = getGenerator({ usePixels: true })
const { css } = await uno.generate(['pt-8', 'bottom-4', '-ml-32'])
const uno = getGenerator({ usePixels: true });
const { css } = await uno.generate(['pt-8', 'bottom-4', '-ml-32']);
expect(css).toMatchInlineSnapshot(`

@@ -41,3 +41,13 @@ "/* layer: default */

.-ml-32{margin-left:-32px;}"
`)
})
`);
});
test('it can externalize classes', async () => {
const uno = getGenerator({ externalizeClasses: true, externalClasses: ['p-16', '-ml-32'] });
const { css } = await uno.generate(['pt-8', 'bottom-4', '-ml-32']);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.bottom-4{bottom:0.4rem;}
.pt-8{padding-top:0.8rem;}"
`);
});

@@ -1,15 +0,121 @@

import { setup } from './_helpers.js'
import { assert, test } from 'vitest'
import { expect, test } from 'vitest';
import { gridCol, gridRow } from '#bounds';
import { getNumericArrayInRange } from '#utils';
import { setup } from './_helpers.js';
setup()
setup();
test('grid columns', async (t) => {
const staticNumbers = ['grid-cols-2', 'grid-cols-5']
const arbitrary = ['grid-cols-[200px_minmax(900px,_1fr)_100px]', 'grid-cols-[320px_1fr]']
const { css } = await t.uno.generate([staticNumbers, arbitrary].flat(Infinity))
const staticResult = n => `grid-template-columns:repeat(${n},minmax(0,1fr));`
assert.include(css, staticResult(2))
assert.include(css, staticResult(5))
assert.include(css, 'grid-template-columns:200px minmax(900px, 1fr) 100px;')
assert.include(css, 'grid-template-columns:320px 1fr;')
})
const columns = getNumericArrayInRange(gridCol[0], gridCol[1]);
const rows = getNumericArrayInRange(gridRow[0], gridRow[1]);
test('grid span', async (t) => {
const staticClasses = [
'col-auto',
'row-auto',
'col-span-full',
'row-span-full',
];
const artbitraryClassesRows = rows.map((num) => `row-span-${num}`);
const artbitraryClassesCols = columns.map((num) => `col-span-${num}`);
const { css } = await t.uno.generate([
...staticClasses,
...artbitraryClassesCols,
...artbitraryClassesRows,
]);
expect(css).toMatchSnapshot();
});
test('grid starts and ends', async (t) => {
const classesRows = rows.map((num) => [`row-start-${num}`, `row-end-${num}`]);
const classesCols = columns.map((num) => [`col-start-${num}`, `col-end-${num}`]);
const { css } = await t.uno.generate([...classesRows, ...classesCols].flat());
expect(css).toMatchSnapshot();
});
test('grid template columns with arbitrary values', async (t) => {
const arbitrary = [
'grid-cols-[200px_minmax(900px,_1fr)_100px]',
'grid-cols-[320px_1fr]',
'grid-cols-minmax-200px',
];
const { css } = await t.uno.generate(arbitrary);
expect(css).toMatchSnapshot();
});
test('grid template rows with arbitrary values', async (t) => {
const arbitrary = [
'grid-rows-[200px_repeat(auto-fill, 100px)_300px]',
'grid-rows-minmax-400px',
'grid-rows-minmax-400px',
];
const { css } = await t.uno.generate(arbitrary);
expect(css).toMatchSnapshot();
});
test('grid template rows and cols with not correct arbitrary values', async (t) => {
const arbitrary = [
'grid-cols-200px_minmax(900px,_1fr)_100px',
'grid-rows-200px_repeat(auto-fill, 100px)_300px',
'grid-rows-minmax-[200px-400px]',
];
const { css } = await t.uno.generate(arbitrary);
expect(css).toMatchInlineSnapshot('""');
});
test('grid auto flows', async (t) => {
const gridFlows = [
'auto-rows-auto',
'auto-rows-min',
'auto-rows-max',
'auto-rows-fr',
'auto-cols-auto',
'auto-cols-min',
'auto-cols-max',
'auto-cols-fr',
'grid-flow-row',
'grid-flow-col',
'grid-flow-dense',
'grid-flow-row-dense',
'grid-flow-col-dense',
];
const { css } = await t.uno.generate(gridFlows);
expect(css).toMatchSnapshot();
});
test('grid templates basic', async (t) => {
const classesRows = rows.map((num) => `grid-rows-${num}`);
const classesCols = columns.map((num) => `grid-cols-${num}`);
const { css } = await t.uno.generate([...classesCols, ...classesRows]);
expect(css).toMatchSnapshot();
});
test('grid styling is not created if out of range', async (t) => {
const outOfRangeRow = rows.length + 1;
const outOfRangeColumn = columns.length + 1;
const classes = [
`grid-rows-${outOfRangeRow}`,
`grid-columns-${outOfRangeColumn}`,
`row-span-${outOfRangeRow}`,
`col-span-${outOfRangeColumn}`,
`col-start-${outOfRangeColumn}`,
`col-end-${outOfRangeColumn}`,
`row-start-${outOfRangeRow}`,
`row-end-${outOfRangeRow}`,
];
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
test('grid templates none', async (t) => {
const classes = ['grid-rows-none', 'grid-cols-none'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});

@@ -9,2 +9,3 @@ import { setup } from "./_helpers.js";

const classes = [
"overflow-clip",
"overflow-auto",

@@ -11,0 +12,0 @@ "overflow-hidden",

@@ -1,48 +0,27 @@

import { setup } from './_helpers.js'
import { spaceBase } from '#theme'
import { globalKeywords } from "#utils"
import { describe, expect, test } from 'vitest'
import { setup } from './_helpers.js';
import { spaceBase } from '#theme';
import { globalKeywords } from "#utils";
import { describe, expect, test } from 'vitest';
setup()
setup();
describe("position", () => {
test("check static, fixed, absolute, relative and sticky values", async (t) => {
const classes = ["static", "fixed", "absolute", "relative", "sticky"]
const classes = ["static", "fixed", "absolute", "relative", "sticky"];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.absolute{position:absolute;}
.fixed{position:fixed;}
.relative{position:relative;}
.static{position:static;}
.sticky{position:sticky;}"
`)
})
})
expect(css).toMatchSnapshot();
});
});
describe('order', () => {
test('allows values 1 to 12', async (t) => {
const range = Array.from({ length: 12 }).map((_, i) => i + 1)
const classes = range.map(value => `order-${value}`)
const range = Array.from({ length: 12 }).map((_, i) => i + 1);
const classes = range.map(value => `order-${value}`);
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.order-1{order:1;}
.order-10{order:10;}
.order-11{order:11;}
.order-12{order:12;}
.order-2{order:2;}
.order-3{order:3;}
.order-4{order:4;}
.order-5{order:5;}
.order-6{order:6;}
.order-7{order:7;}
.order-8{order:8;}
.order-9{order:9;}"
`)
})
expect(css).toMatchSnapshot();
});

@@ -53,15 +32,10 @@ test('ensure -first, -last and -none is allowed and that the correct value is set', async (t) => {

["order-last"]: "9999",
["order-none"]: "0"
}
["order-none"]: "0",
};
const classes = Object.keys(styles)
const classes = Object.keys(styles);
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.order-first{order:-9999;}
.order-last{order:9999;}
.order-none{order:0;}"
`)
expect(css).toMatchSnapshot();
});

@@ -74,9 +48,8 @@

// Make sure to catch and verify those errors being trown
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
})
});
// justifies

@@ -86,94 +59,51 @@

test('check justify- classes and their expected justify-content values', async (t) => {
const classes = ['justify-start', 'justify-end','justify-center','justify-between', ',justify-around', 'justify-evenly']
const classes = ['justify-start', 'justify-end','justify-center','justify-between', ',justify-around', 'justify-evenly'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.justify-start{justify-content:flex-start;}
.justify-end{justify-content:flex-end;}
.justify-center{justify-content:center;}
.justify-between{justify-content:space-between;}
.justify-evenly{justify-content:space-evenly;}"
`);
})
expect(css).toMatchSnapshot();
});
test('check justify-items- classes and their expected justify-itemns values', async (t) => {
const classes = ['justify-items-start', 'justify-items-end', 'justify-items-center', 'justify-items-stretch']
const classes = ['justify-items-start', 'justify-items-end', 'justify-items-center', 'justify-items-stretch'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.justify-items-start{justify-items:start;}
.justify-items-end{justify-items:end;}
.justify-items-center{justify-items:center;}
.justify-items-stretch{justify-items:stretch;}"
`)
})
expect(css).toMatchSnapshot();
});
test('check justify-self- classes and their expected justify-self values', async (t) => {
const classes = ['justify-self-auto', 'justify-self-start', 'justify-self-end', 'justify-self-center', 'justify-self-stretch']
const classes = ['justify-self-auto', 'justify-self-start', 'justify-self-end', 'justify-self-center', 'justify-self-stretch'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.justify-self-auto{justify-self:auto;}
.justify-self-start{justify-self:start;}
.justify-self-end{justify-self:end;}
.justify-self-center{justify-self:center;}
.justify-self-stretch{justify-self:stretch;}"
`);
})
})
expect(css).toMatchSnapshot();
});
});
describe("alignments", () => {
test('check content- classes and their expected align-content values', async (t) => {
const classes = ['content-center', 'content-start', 'content-end', 'content-between', 'content-around', 'content-evenly']
const classes = ['content-center', 'content-start', 'content-end', 'content-between', 'content-around', 'content-evenly'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.content-center{align-content:center;}
.content-start{align-content:flex-start;}
.content-end{align-content:flex-end;}
.content-between{align-content:space-between;}
.content-around{align-content:space-around;}
.content-evenly{align-content:space-evenly;}"
`);
})
expect(css).toMatchSnapshot();
});
test('check items- classes and their expected align-items values', async (t) => {
const classes = ['items-start', 'items-end', 'items-center', 'items-baseline' ,'items-stretch']
const classes = ['items-start', 'items-end', 'items-center', 'items-baseline' ,'items-stretch'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.items-start{align-items:flex-start;}
.items-end{align-items:flex-end;}
.items-center{align-items:center;}
.items-baseline{align-items:baseline;}
.items-stretch{align-items:stretch;}"
`);
})
expect(css).toMatchSnapshot();
});
test('check self- classes and their expected align-self values', async (t) => {
const classes = ['self-auto', 'auto', 'self-start', 'flex-start', 'self-end', 'flex-end', 'self-center', 'center', 'self-stretch', 'stretch', 'self-baseline', 'baseline']
const classes = ['self-auto', 'auto', 'self-start', 'flex-start', 'self-end', 'flex-end', 'self-center', 'center', 'self-stretch', 'stretch', 'self-baseline', 'baseline'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.self-auto{align-self:auto;}
.self-start{align-self:flex-start;}
.self-end{align-self:flex-end;}
.self-center{align-self:center;}
.self-stretch{align-self:stretch;}
.self-baseline{align-self:baseline;}"
`);
})
})
expect(css).toMatchSnapshot();
});
});

@@ -185,47 +115,25 @@

test('check place-content- classes and their expected place-content values', async (t) => {
const classes = ['place-content-center', 'place-content-start', 'place-content-end', 'place-content-between', 'place-content-around', 'place-content-evenly', 'place-content-stretch']
const classes = ['place-content-center', 'place-content-start', 'place-content-end', 'place-content-between', 'place-content-around', 'place-content-evenly', 'place-content-stretch', 'place-content-baseline'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.place-content-center{place-content:center;}
.place-content-start{place-content:start;}
.place-content-end{place-content:end;}
.place-content-between{place-content:space-between;}
.place-content-around{place-content:space-around;}
.place-content-evenly{place-content:space-evenly;}
.place-content-stretch{place-content:stretch;}"
`)
})
expect(css).toMatchSnapshot();
});
test('check place-items- classes and their expected place-items values', async (t) => {
const classes = ['place-items-start', 'place-items-end' ,'place-items-center','place-items-stretch']
const classes = ['place-items-start', 'place-items-end' ,'place-items-center','place-items-stretch'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.place-items-start{place-items:start;}
.place-items-end{place-items:end;}
.place-items-center{place-items:center;}
.place-items-stretch{place-items:stretch;}"
`)
})
expect(css).toMatchSnapshot();
});
test('check place-self- classes and their expected place-self values', async (t) => {
const classes = ['place-self-auto', 'place-self-start', 'place-self-end', 'place-self-center', 'place-self-stretch']
const classes = ['place-self-auto', 'place-self-start', 'place-self-end', 'place-self-center', 'place-self-stretch'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.place-self-auto{place-self:auto;}
.place-self-start{place-self:start;}
.place-self-end{place-self:end;}
.place-self-center{place-self:center;}
.place-self-stretch{place-self:stretch;}"
`)
})
})
expect(css).toMatchSnapshot();
});
});

@@ -236,55 +144,8 @@ describe("global keywords", () => {

const classes = ["justify", "justify-items", "justify-self", "content", "items", "self", "place-content", "place-items", "place-self"]
.map(prefix => globalKeywords.map(keyword => `${prefix}-${keyword}`)).flat()
.map(prefix => globalKeywords.map(keyword => `${prefix}-${keyword}`)).flat();
const { css } = await uno.generate(classes)
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.justify-inherit{justify-content:inherit;}
.justify-initial{justify-content:initial;}
.justify-revert{justify-content:revert;}
.justify-revert-layer{justify-content:revert-layer;}
.justify-unset{justify-content:unset;}
.justify-items-inherit{justify-items:inherit;}
.justify-items-initial{justify-items:initial;}
.justify-items-revert{justify-items:revert;}
.justify-items-revert-layer{justify-items:revert-layer;}
.justify-items-unset{justify-items:unset;}
.justify-self-inherit{justify-self:inherit;}
.justify-self-initial{justify-self:initial;}
.justify-self-revert{justify-self:revert;}
.justify-self-revert-layer{justify-self:revert-layer;}
.justify-self-unset{justify-self:unset;}
.content-inherit{align-content:inherit;}
.content-initial{align-content:initial;}
.content-revert{align-content:revert;}
.content-revert-layer{align-content:revert-layer;}
.content-unset{align-content:unset;}
.items-inherit{align-items:inherit;}
.items-initial{align-items:initial;}
.items-revert{align-items:revert;}
.items-revert-layer{align-items:revert-layer;}
.items-unset{align-items:unset;}
.self-inherit{align-self:inherit;}
.self-initial{align-self:initial;}
.self-revert{align-self:revert;}
.self-revert-layer{align-self:revert-layer;}
.self-unset{align-self:unset;}
.place-content-inherit{place-content:inherit;}
.place-content-initial{place-content:initial;}
.place-content-revert{place-content:revert;}
.place-content-revert-layer{place-content:revert-layer;}
.place-content-unset{place-content:unset;}
.place-items-inherit{place-items:inherit;}
.place-items-initial{place-items:initial;}
.place-items-revert{place-items:revert;}
.place-items-revert-layer{place-items:revert-layer;}
.place-items-unset{place-items:unset;}
.place-self-inherit{place-self:inherit;}
.place-self-initial{place-self:initial;}
.place-self-revert{place-self:revert;}
.place-self-revert-layer{place-self:revert-layer;}
.place-self-unset{place-self:unset;}"
`)
})
})
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
});

@@ -296,80 +157,6 @@

const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.inset-0{inset:0rem;}
.inset-1{inset:0.1rem;}
.inset-10{inset:1rem;}
.inset-112{inset:11.2rem;}
.inset-12{inset:1.2rem;}
.inset-128{inset:12.8rem;}
.inset-14{inset:1.4rem;}
.inset-144{inset:14.4rem;}
.inset-16{inset:1.6rem;}
.inset-2{inset:0.2rem;}
.inset-20{inset:2rem;}
.inset-24{inset:2.4rem;}
.inset-28{inset:2.8rem;}
.inset-32{inset:3.2rem;}
.inset-4{inset:0.4rem;}
.inset-40{inset:4rem;}
.inset-44{inset:4.4rem;}
.inset-48{inset:4.8rem;}
.inset-56{inset:5.6rem;}
.inset-6{inset:0.6rem;}
.inset-64{inset:6.4rem;}
.inset-8{inset:0.8rem;}
.inset-80{inset:8rem;}
.inset-96{inset:9.6rem;}
.inset-x-0{left:0rem;right:0rem;}
.inset-x-1{left:0.1rem;right:0.1rem;}
.inset-x-10{left:1rem;right:1rem;}
.inset-x-112{left:11.2rem;right:11.2rem;}
.inset-x-12{left:1.2rem;right:1.2rem;}
.inset-x-128{left:12.8rem;right:12.8rem;}
.inset-x-14{left:1.4rem;right:1.4rem;}
.inset-x-144{left:14.4rem;right:14.4rem;}
.inset-x-16{left:1.6rem;right:1.6rem;}
.inset-x-2{left:0.2rem;right:0.2rem;}
.inset-x-20{left:2rem;right:2rem;}
.inset-x-24{left:2.4rem;right:2.4rem;}
.inset-x-28{left:2.8rem;right:2.8rem;}
.inset-x-32{left:3.2rem;right:3.2rem;}
.inset-x-4{left:0.4rem;right:0.4rem;}
.inset-x-40{left:4rem;right:4rem;}
.inset-x-44{left:4.4rem;right:4.4rem;}
.inset-x-48{left:4.8rem;right:4.8rem;}
.inset-x-56{left:5.6rem;right:5.6rem;}
.inset-x-6{left:0.6rem;right:0.6rem;}
.inset-x-64{left:6.4rem;right:6.4rem;}
.inset-x-8{left:0.8rem;right:0.8rem;}
.inset-x-80{left:8rem;right:8rem;}
.inset-x-96{left:9.6rem;right:9.6rem;}
.inset-y-0{top:0rem;bottom:0rem;}
.inset-y-1{top:0.1rem;bottom:0.1rem;}
.inset-y-10{top:1rem;bottom:1rem;}
.inset-y-112{top:11.2rem;bottom:11.2rem;}
.inset-y-12{top:1.2rem;bottom:1.2rem;}
.inset-y-128{top:12.8rem;bottom:12.8rem;}
.inset-y-14{top:1.4rem;bottom:1.4rem;}
.inset-y-144{top:14.4rem;bottom:14.4rem;}
.inset-y-16{top:1.6rem;bottom:1.6rem;}
.inset-y-2{top:0.2rem;bottom:0.2rem;}
.inset-y-20{top:2rem;bottom:2rem;}
.inset-y-24{top:2.4rem;bottom:2.4rem;}
.inset-y-28{top:2.8rem;bottom:2.8rem;}
.inset-y-32{top:3.2rem;bottom:3.2rem;}
.inset-y-4{top:0.4rem;bottom:0.4rem;}
.inset-y-40{top:4rem;bottom:4rem;}
.inset-y-44{top:4.4rem;bottom:4.4rem;}
.inset-y-48{top:4.8rem;bottom:4.8rem;}
.inset-y-56{top:5.6rem;bottom:5.6rem;}
.inset-y-6{top:0.6rem;bottom:0.6rem;}
.inset-y-64{top:6.4rem;bottom:6.4rem;}
.inset-y-8{top:0.8rem;bottom:0.8rem;}
.inset-y-80{top:8rem;bottom:8rem;}
.inset-y-96{top:9.6rem;bottom:9.6rem;}"
`);
})
expect(css).toMatchSnapshot();
});

@@ -379,80 +166,6 @@ test('check negative -inset- classes and their expected values', async (t) => {

const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.-inset-0{inset:-0rem;}
.-inset-1{inset:-0.1rem;}
.-inset-10{inset:-1rem;}
.-inset-112{inset:-11.2rem;}
.-inset-12{inset:-1.2rem;}
.-inset-128{inset:-12.8rem;}
.-inset-14{inset:-1.4rem;}
.-inset-144{inset:-14.4rem;}
.-inset-16{inset:-1.6rem;}
.-inset-2{inset:-0.2rem;}
.-inset-20{inset:-2rem;}
.-inset-24{inset:-2.4rem;}
.-inset-28{inset:-2.8rem;}
.-inset-32{inset:-3.2rem;}
.-inset-4{inset:-0.4rem;}
.-inset-40{inset:-4rem;}
.-inset-44{inset:-4.4rem;}
.-inset-48{inset:-4.8rem;}
.-inset-56{inset:-5.6rem;}
.-inset-6{inset:-0.6rem;}
.-inset-64{inset:-6.4rem;}
.-inset-8{inset:-0.8rem;}
.-inset-80{inset:-8rem;}
.-inset-96{inset:-9.6rem;}
.-inset-x-0{left:-0rem;right:-0rem;}
.-inset-x-1{left:-0.1rem;right:-0.1rem;}
.-inset-x-10{left:-1rem;right:-1rem;}
.-inset-x-112{left:-11.2rem;right:-11.2rem;}
.-inset-x-12{left:-1.2rem;right:-1.2rem;}
.-inset-x-128{left:-12.8rem;right:-12.8rem;}
.-inset-x-14{left:-1.4rem;right:-1.4rem;}
.-inset-x-144{left:-14.4rem;right:-14.4rem;}
.-inset-x-16{left:-1.6rem;right:-1.6rem;}
.-inset-x-2{left:-0.2rem;right:-0.2rem;}
.-inset-x-20{left:-2rem;right:-2rem;}
.-inset-x-24{left:-2.4rem;right:-2.4rem;}
.-inset-x-28{left:-2.8rem;right:-2.8rem;}
.-inset-x-32{left:-3.2rem;right:-3.2rem;}
.-inset-x-4{left:-0.4rem;right:-0.4rem;}
.-inset-x-40{left:-4rem;right:-4rem;}
.-inset-x-44{left:-4.4rem;right:-4.4rem;}
.-inset-x-48{left:-4.8rem;right:-4.8rem;}
.-inset-x-56{left:-5.6rem;right:-5.6rem;}
.-inset-x-6{left:-0.6rem;right:-0.6rem;}
.-inset-x-64{left:-6.4rem;right:-6.4rem;}
.-inset-x-8{left:-0.8rem;right:-0.8rem;}
.-inset-x-80{left:-8rem;right:-8rem;}
.-inset-x-96{left:-9.6rem;right:-9.6rem;}
.-inset-y-0{top:-0rem;bottom:-0rem;}
.-inset-y-1{top:-0.1rem;bottom:-0.1rem;}
.-inset-y-10{top:-1rem;bottom:-1rem;}
.-inset-y-112{top:-11.2rem;bottom:-11.2rem;}
.-inset-y-12{top:-1.2rem;bottom:-1.2rem;}
.-inset-y-128{top:-12.8rem;bottom:-12.8rem;}
.-inset-y-14{top:-1.4rem;bottom:-1.4rem;}
.-inset-y-144{top:-14.4rem;bottom:-14.4rem;}
.-inset-y-16{top:-1.6rem;bottom:-1.6rem;}
.-inset-y-2{top:-0.2rem;bottom:-0.2rem;}
.-inset-y-20{top:-2rem;bottom:-2rem;}
.-inset-y-24{top:-2.4rem;bottom:-2.4rem;}
.-inset-y-28{top:-2.8rem;bottom:-2.8rem;}
.-inset-y-32{top:-3.2rem;bottom:-3.2rem;}
.-inset-y-4{top:-0.4rem;bottom:-0.4rem;}
.-inset-y-40{top:-4rem;bottom:-4rem;}
.-inset-y-44{top:-4.4rem;bottom:-4.4rem;}
.-inset-y-48{top:-4.8rem;bottom:-4.8rem;}
.-inset-y-56{top:-5.6rem;bottom:-5.6rem;}
.-inset-y-6{top:-0.6rem;bottom:-0.6rem;}
.-inset-y-64{top:-6.4rem;bottom:-6.4rem;}
.-inset-y-8{top:-0.8rem;bottom:-0.8rem;}
.-inset-y-80{top:-8rem;bottom:-8rem;}
.-inset-y-96{top:-9.6rem;bottom:-9.6rem;}"
`);
})
expect(css).toMatchSnapshot();
});

@@ -462,211 +175,15 @@ test('check top-, left-, right-, bottom- classes and their expected values', async (t) => {

const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.bottom-0{bottom:0rem;}
.bottom-1{bottom:0.1rem;}
.bottom-10{bottom:1rem;}
.bottom-112{bottom:11.2rem;}
.bottom-12{bottom:1.2rem;}
.bottom-128{bottom:12.8rem;}
.bottom-14{bottom:1.4rem;}
.bottom-144{bottom:14.4rem;}
.bottom-16{bottom:1.6rem;}
.bottom-2{bottom:0.2rem;}
.bottom-20{bottom:2rem;}
.bottom-24{bottom:2.4rem;}
.bottom-28{bottom:2.8rem;}
.bottom-32{bottom:3.2rem;}
.bottom-4{bottom:0.4rem;}
.bottom-40{bottom:4rem;}
.bottom-44{bottom:4.4rem;}
.bottom-48{bottom:4.8rem;}
.bottom-56{bottom:5.6rem;}
.bottom-6{bottom:0.6rem;}
.bottom-64{bottom:6.4rem;}
.bottom-8{bottom:0.8rem;}
.bottom-80{bottom:8rem;}
.bottom-96{bottom:9.6rem;}
.left-0{left:0rem;}
.left-1{left:0.1rem;}
.left-10{left:1rem;}
.left-112{left:11.2rem;}
.left-12{left:1.2rem;}
.left-128{left:12.8rem;}
.left-14{left:1.4rem;}
.left-144{left:14.4rem;}
.left-16{left:1.6rem;}
.left-2{left:0.2rem;}
.left-20{left:2rem;}
.left-24{left:2.4rem;}
.left-28{left:2.8rem;}
.left-32{left:3.2rem;}
.left-4{left:0.4rem;}
.left-40{left:4rem;}
.left-44{left:4.4rem;}
.left-48{left:4.8rem;}
.left-56{left:5.6rem;}
.left-6{left:0.6rem;}
.left-64{left:6.4rem;}
.left-8{left:0.8rem;}
.left-80{left:8rem;}
.left-96{left:9.6rem;}
.right-0{right:0rem;}
.right-1{right:0.1rem;}
.right-10{right:1rem;}
.right-112{right:11.2rem;}
.right-12{right:1.2rem;}
.right-128{right:12.8rem;}
.right-14{right:1.4rem;}
.right-144{right:14.4rem;}
.right-16{right:1.6rem;}
.right-2{right:0.2rem;}
.right-20{right:2rem;}
.right-24{right:2.4rem;}
.right-28{right:2.8rem;}
.right-32{right:3.2rem;}
.right-4{right:0.4rem;}
.right-40{right:4rem;}
.right-44{right:4.4rem;}
.right-48{right:4.8rem;}
.right-56{right:5.6rem;}
.right-6{right:0.6rem;}
.right-64{right:6.4rem;}
.right-8{right:0.8rem;}
.right-80{right:8rem;}
.right-96{right:9.6rem;}
.top-0{top:0rem;}
.top-1{top:0.1rem;}
.top-10{top:1rem;}
.top-112{top:11.2rem;}
.top-12{top:1.2rem;}
.top-128{top:12.8rem;}
.top-14{top:1.4rem;}
.top-144{top:14.4rem;}
.top-16{top:1.6rem;}
.top-2{top:0.2rem;}
.top-20{top:2rem;}
.top-24{top:2.4rem;}
.top-28{top:2.8rem;}
.top-32{top:3.2rem;}
.top-4{top:0.4rem;}
.top-40{top:4rem;}
.top-44{top:4.4rem;}
.top-48{top:4.8rem;}
.top-56{top:5.6rem;}
.top-6{top:0.6rem;}
.top-64{top:6.4rem;}
.top-8{top:0.8rem;}
.top-80{top:8rem;}
.top-96{top:9.6rem;}"
`);
})
expect(css).toMatchSnapshot();
});
test('check negative -top-, -left-, -right-, -bottom- classes and their expected values', async (t) => {
const classes = spaceBase.map((n) => ([`-top-${n}`,`-left-${n}`,`-right-${n}`,`-bottom-${n}`])).flat()
const classes = spaceBase.map((n) => ([`-top-${n}`,`-left-${n}`,`-right-${n}`,`-bottom-${n}`])).flat();
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.-bottom-0{bottom:-0rem;}
.-bottom-1{bottom:-0.1rem;}
.-bottom-10{bottom:-1rem;}
.-bottom-112{bottom:-11.2rem;}
.-bottom-12{bottom:-1.2rem;}
.-bottom-128{bottom:-12.8rem;}
.-bottom-14{bottom:-1.4rem;}
.-bottom-144{bottom:-14.4rem;}
.-bottom-16{bottom:-1.6rem;}
.-bottom-2{bottom:-0.2rem;}
.-bottom-20{bottom:-2rem;}
.-bottom-24{bottom:-2.4rem;}
.-bottom-28{bottom:-2.8rem;}
.-bottom-32{bottom:-3.2rem;}
.-bottom-4{bottom:-0.4rem;}
.-bottom-40{bottom:-4rem;}
.-bottom-44{bottom:-4.4rem;}
.-bottom-48{bottom:-4.8rem;}
.-bottom-56{bottom:-5.6rem;}
.-bottom-6{bottom:-0.6rem;}
.-bottom-64{bottom:-6.4rem;}
.-bottom-8{bottom:-0.8rem;}
.-bottom-80{bottom:-8rem;}
.-bottom-96{bottom:-9.6rem;}
.-left-0{left:-0rem;}
.-left-1{left:-0.1rem;}
.-left-10{left:-1rem;}
.-left-112{left:-11.2rem;}
.-left-12{left:-1.2rem;}
.-left-128{left:-12.8rem;}
.-left-14{left:-1.4rem;}
.-left-144{left:-14.4rem;}
.-left-16{left:-1.6rem;}
.-left-2{left:-0.2rem;}
.-left-20{left:-2rem;}
.-left-24{left:-2.4rem;}
.-left-28{left:-2.8rem;}
.-left-32{left:-3.2rem;}
.-left-4{left:-0.4rem;}
.-left-40{left:-4rem;}
.-left-44{left:-4.4rem;}
.-left-48{left:-4.8rem;}
.-left-56{left:-5.6rem;}
.-left-6{left:-0.6rem;}
.-left-64{left:-6.4rem;}
.-left-8{left:-0.8rem;}
.-left-80{left:-8rem;}
.-left-96{left:-9.6rem;}
.-right-0{right:-0rem;}
.-right-1{right:-0.1rem;}
.-right-10{right:-1rem;}
.-right-112{right:-11.2rem;}
.-right-12{right:-1.2rem;}
.-right-128{right:-12.8rem;}
.-right-14{right:-1.4rem;}
.-right-144{right:-14.4rem;}
.-right-16{right:-1.6rem;}
.-right-2{right:-0.2rem;}
.-right-20{right:-2rem;}
.-right-24{right:-2.4rem;}
.-right-28{right:-2.8rem;}
.-right-32{right:-3.2rem;}
.-right-4{right:-0.4rem;}
.-right-40{right:-4rem;}
.-right-44{right:-4.4rem;}
.-right-48{right:-4.8rem;}
.-right-56{right:-5.6rem;}
.-right-6{right:-0.6rem;}
.-right-64{right:-6.4rem;}
.-right-8{right:-0.8rem;}
.-right-80{right:-8rem;}
.-right-96{right:-9.6rem;}
.-top-0{top:-0rem;}
.-top-1{top:-0.1rem;}
.-top-10{top:-1rem;}
.-top-112{top:-11.2rem;}
.-top-12{top:-1.2rem;}
.-top-128{top:-12.8rem;}
.-top-14{top:-1.4rem;}
.-top-144{top:-14.4rem;}
.-top-16{top:-1.6rem;}
.-top-2{top:-0.2rem;}
.-top-20{top:-2rem;}
.-top-24{top:-2.4rem;}
.-top-28{top:-2.8rem;}
.-top-32{top:-3.2rem;}
.-top-4{top:-0.4rem;}
.-top-40{top:-4rem;}
.-top-44{top:-4.4rem;}
.-top-48{top:-4.8rem;}
.-top-56{top:-5.6rem;}
.-top-6{top:-0.6rem;}
.-top-64{top:-6.4rem;}
.-top-8{top:-0.8rem;}
.-top-80{top:-8rem;}
.-top-96{top:-9.6rem;}"
`);
})
})
expect(css).toMatchSnapshot();
});
});

@@ -676,48 +193,25 @@ // floats

test("check float classes and corresponding values", async (t) => {
const classes = ["float-left", "float-right", "float-none"]
const classes = ["float-left", "float-right", "float-none"];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.float-left{float:left;}
.float-right{float:right;}
.float-none{float:none;}"
`)
})
expect(css).toMatchSnapshot();
});
test("check clear classes and corresponding values", async (t) => {
const classes = ["clear-left", "clear-right", "clear-both", "clear-none"]
const classes = ["clear-left", "clear-right", "clear-both", "clear-none"];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.clear-left{clear:left;}
.clear-right{clear:right;}
.clear-both{clear:both;}
.clear-none{clear:none;}"
`)
})
expect(css).toMatchSnapshot();
});
test("float and clear should work with global keywords", async (t) => {
const classes = ["float", "clear"].map(prefix => globalKeywords.map(keyword => `${prefix}-${keyword}`)).flat()
const classes = ["float", "clear"].map(prefix => globalKeywords.map(keyword => `${prefix}-${keyword}`)).flat();
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.float-inherit{float:inherit;}
.float-initial{float:initial;}
.float-revert{float:revert;}
.float-revert-layer{float:revert-layer;}
.float-unset{float:unset;}
.clear-inherit{clear:inherit;}
.clear-initial{clear:initial;}
.clear-revert{clear:revert;}
.clear-revert-layer{clear:revert-layer;}
.clear-unset{clear:unset;}"
`)
})
})
expect(css).toMatchSnapshot();
});
});

@@ -728,34 +222,20 @@ // z-index

test("check z- classes and their expected values", async (t) => {
const validLevels = [0, 10, 20, 30, 40, 50]
const positiveClasses = validLevels.map(i => `z-${i}`)
const negativeClasses = validLevels.map(i => `-z-${i}`)
const validLevels = [0, 10, 20, 30, 40, 50];
const positiveClasses = validLevels.map(i => `z-${i}`);
const negativeClasses = validLevels.map(i => `-z-${i}`);
const { css } = await t.uno.generate([...positiveClasses, ...negativeClasses, 'z-auto'])
const { css } = await t.uno.generate([...positiveClasses, ...negativeClasses, 'z-auto']);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.-z-10{z-index:-10;}
.-z-20{z-index:-20;}
.-z-30{z-index:-30;}
.-z-40{z-index:-40;}
.-z-50{z-index:-50;}
.z-0{z-index:0;}
.z-10{z-index:10;}
.z-20{z-index:20;}
.z-30{z-index:30;}
.z-40{z-index:40;}
.z-50{z-index:50;}
.z-auto{z-index:auto;}"
`)
})
expect(css).toMatchSnapshot();
});
test("skip invalid classes", async (t) => {
const classes = ['z-none', 'z-2', '-z-9999']
const classes = ['z-none', 'z-2', '-z-9999'];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""')
})
})
expect(css).toMatchInlineSnapshot('""');
});
});

@@ -766,27 +246,16 @@ // box-sizing

test("check box- classes and corresponding values", async (t) => {
const classes = ["box-border", "box-content"]
const classes = ["box-border", "box-content"];
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.box-border{box-sizing:border-box;}
.box-content{box-sizing:content-box;}"
`)
})
expect(css).toMatchSnapshot();
});
test("box- classes should work with global keywords", async (t) => {
const classes = ["box"].map(prefix => globalKeywords.map(keyword => `${prefix}-${keyword}`)).flat()
const classes = ["box"].map(prefix => globalKeywords.map(keyword => `${prefix}-${keyword}`)).flat();
const { css } = await t.uno.generate(classes)
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.box-inherit{box-sizing:inherit;}
.box-initial{box-sizing:initial;}
.box-revert{box-sizing:revert;}
.box-revert-layer{box-sizing:revert-layer;}
.box-unset{box-sizing:unset;}"
`)
})
})
expect(css).toMatchSnapshot();
});
});

@@ -1,60 +0,259 @@

import { setup, getFractions } from './_helpers.js'
import { spaceBase } from '#theme'
import { describe, expect, test } from 'vitest'
import { setup, getFractions, getGenerator } from './_helpers.js';
import { spaceBase } from '#theme';
import { describe, expect, test } from 'vitest';
setup()
setup();
const getSpecialSuffixes = (prefix) => ['full', 'fit', 'min', 'max', 'screen'].map(e => `${prefix}-${e}`)
const getSpecialSuffixes = (prefix) => ['full', 'fit', 'min', 'max', 'screen'].map(e => `${prefix}-${e}`);
describe('width and height', () => {
test('width', async ({ uno }) => {
const classes = spaceBase.map(e => `w-${e}`)
classes.push(...getSpecialSuffixes('w'))
classes.push(...getFractions('w'))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = spaceBase.map(e => `w-${e}`);
classes.push(...getSpecialSuffixes('w'));
classes.push(...getFractions('w'));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('height', async ({ uno }) => {
const classes = spaceBase.map(e => `h-${e}`)
classes.push(...getSpecialSuffixes('h'))
classes.push(...getFractions('h'))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
})
const classes = spaceBase.map(e => `h-${e}`);
classes.push(...getSpecialSuffixes('h'));
classes.push(...getFractions('h'));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
});
describe('max width and height', () => {
test('max-width', async ({ uno }) => {
const classes = spaceBase.map(e => `max-w-${e}`)
classes.push(...getSpecialSuffixes('max-w'))
classes.push(...getFractions('max-w'))
classes.push('max-w-prose')
classes.push('max-w-none')
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = spaceBase.map(e => `max-w-${e}`);
classes.push(...getSpecialSuffixes('max-w'));
classes.push(...getFractions('max-w'));
classes.push('max-w-prose');
classes.push('max-w-none');
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-height', async ({ uno }) => {
const classes = spaceBase.map(e => `max-h-${e}`)
classes.push(...getSpecialSuffixes('max-h'))
classes.push(...getFractions('max-h'))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
})
const classes = spaceBase.map(e => `max-h-${e}`);
classes.push(...getSpecialSuffixes('max-h'));
classes.push(...getFractions('max-h'));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
});
describe('min width and height', () => {
test('min-width', async ({ uno }) => {
const classes = spaceBase.map(e => `min-w-${e}`)
classes.push(...getSpecialSuffixes('min-w'))
classes.push(...getFractions('min-w'))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = spaceBase.map(e => `min-w-${e}`);
classes.push(...getSpecialSuffixes('min-w'));
classes.push(...getFractions('min-w'));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-height', async ({ uno }) => {
const classes = spaceBase.map(e => `min-h-${e}`)
classes.push(...getSpecialSuffixes('min-h'))
classes.push(...getFractions('min-h'))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
})
const classes = spaceBase.map(e => `min-h-${e}`);
classes.push(...getSpecialSuffixes('min-h'));
classes.push(...getFractions('min-h'));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
});
describe("width and height with arbitrary values", () => {
test('width with rem values', async (t) => {
const classes = ['w-[20000]', 'w-[99999]', 'w-[378]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('width with rem unit', async (t) => {
const classes = ['w-[20000rem]', 'w-[99999rem]', 'w-[378rem]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('width with pixel values', async () => {
const classes = ['w-[20000]', 'w-[99999]', 'w-[378]'];
const uno = getGenerator({ usePixels: true });
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('width with pixel unit', async (t) => {
const classes = ['w-[20000px]', 'w-[99999px]', 'w-[378px]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('width with invalid value', async (t) => {
const classes = ['w-20000', 'w-99999', 'w-378', 'w-[20000a]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
test('height with rem values', async (t) => {
const classes = ['h-[20000]', 'h-[99999]', 'h-[378]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('height with rem unit', async (t) => {
const classes = ['h-[20000rem]', 'h-[99999rem]', 'h-[378rem]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('height with pixel values', async () => {
const classes = ['h-[20000]', 'h-[99999]', 'h-[378]'];
const uno = getGenerator({ usePixels: true });
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('height with pixel unit', async (t) => {
const classes = ['h-[20000px]', 'h-[99999px]', 'h-[378px]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('height with invalid value', async (t) => {
const classes = ['h-20000', 'h-99999', 'h-378', 'h-[20000a]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
});
describe("min width and height with arbitrary values", () => {
test('min-width with rem values', async (t) => {
const classes = ['min-w-[20000]', 'min-w-[99999]', 'min-w-[378]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-width with rem unit', async (t) => {
const classes = ['min-w-[20000rem]', 'min-w-[99999rem]', 'min-w-[378rem]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-width with pixel values', async () => {
const classes = ['min-w-[20000]', 'min-w-[99999]', 'min-w-[378]'];
const uno = getGenerator({ usePixels: true });
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-width with pixel unit', async (t) => {
const classes = ['min-w-[20000px]', 'min-w-[99999px]', 'min-w-[378px]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-width with invalid value', async (t) => {
const classes = ['min-w-20000', 'min-w-99999', 'min-w-378', 'min-w-[20000a]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
test('min-height with rem values', async (t) => {
const classes = ['min-h-[20000]', 'min-h-[99999]', 'min-h-[378]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-height with rem unit', async (t) => {
const classes = ['min-h-[20000rem]', 'min-h-[99999rem]', 'min-h-[378rem]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-height with pixel values', async () => {
const classes = ['min-h-[20000]', 'min-h-[99999]', 'min-h-[378]'];
const uno = getGenerator({ usePixels: true });
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-height with pixel unit', async (t) => {
const classes = ['min-h-[20000px]', 'min-h-[99999px]', 'min-h-[378px]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('min-height with invalid value', async (t) => {
const classes = ['min-h-20000', 'min-h-99999', 'min-h-378', 'min-h-[20000a]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
});
describe("max width and height with arbitrary values", () => {
test('max-width with rem values', async (t) => {
const classes = ['max-w-[20000]', 'max-w-[99999]', 'max-w-[378]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-width with rem unit', async (t) => {
const classes = ['max-w-[20000rem]', 'max-w-[99999rem]', 'max-w-[378rem]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-width with pixel values', async () => {
const classes = ['max-w-[20000]', 'max-w-[99999]', 'max-w-[378]'];
const uno = getGenerator({ usePixels: true });
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-width with pixel unit', async (t) => {
const classes = ['max-w-[20000px]', 'max-w-[99999px]', 'max-w-[378px]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-width with invalid value', async (t) => {
const classes = ['max-w-20000', 'max-w-99999', 'max-w-378', 'max-w-[20000a]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
test('max-height with rem values', async (t) => {
const classes = ['max-h-[20000]', 'max-h-[99999]', 'max-h-[378]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-height with rem unit', async (t) => {
const classes = ['max-h-[20000rem]', 'max-h-[99999rem]', 'max-h-[378rem]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-height with pixel values', async () => {
const classes = ['max-h-[20000]', 'max-h-[99999]', 'max-h-[378]'];
const uno = getGenerator({ usePixels: true });
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-height with pixel unit', async (t) => {
const classes = ['max-h-[20000px]', 'max-h-[99999px]', 'max-h-[378px]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('max-height with invalid value', async (t) => {
const classes = ['max-h-20000', 'max-h-99999', 'max-h-378', 'max-h-[20000a]'];
const { css } = await t.uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
});

@@ -1,19 +0,19 @@

import { setup } from './_helpers.js'
import { spaceBase } from '#theme'
import { expect, test } from 'vitest'
import { setup } from './_helpers.js';
import { spaceBase } from '#theme';
import { expect, test } from 'vitest';
setup()
setup();
test('space-x', async ({ uno }) => {
const classes = spaceBase.map(e => `space-x-${e}`)
classes.push('space-x', 'space-x-reverse')
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = spaceBase.map(e => `space-x-${e}`);
classes.push('space-x', 'space-x-reverse');
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('space-y', async ({ uno }) => {
const classes = spaceBase.map(e => `space-y-${e}`)
classes.push('space-y', 'space-y-reverse')
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = spaceBase.map(e => `space-y-${e}`);
classes.push('space-y', 'space-y-reverse');
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});

@@ -1,9 +0,9 @@

import { expect, test } from 'vitest'
import { setup } from './_helpers.js'
import { expect, test } from 'vitest';
import { setup } from './_helpers.js';
setup()
setup();
test('padding works', async ({ uno }) => {
const classes = ['p-8', 'px-2', 'py-4', 'pl-32', 'pr-16', 'pb-8', 'pt-16']
const { css } = await uno.generate(classes)
const classes = ['p-8', 'px-2', 'py-4', 'pl-32', 'pr-16', 'pb-8', 'pt-16'];
const { css } = await uno.generate(classes);
expect(css).toMatchInlineSnapshot(`

@@ -18,14 +18,14 @@ "/* layer: default */

.pt-16{padding-top:1.6rem;}"
`)
})
`);
});
test('padding skips bad values', async ({ uno }) => {
const classes = ['p-7', 'px-3', 'py-5', 'pl-33', 'pr-19', 'pb-9', 'pt-17']
const { css } = await uno.generate(classes)
expect(css).toMatchInlineSnapshot('""')
})
const classes = ['p-7', 'px-3', 'py-5', 'pl-33', 'pr-19', 'pb-9', 'pt-17'];
const { css } = await uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});
test('margin works', async ({ uno }) => {
const classes = ['m-8', 'mx-2', 'my-4', 'ml-32', 'mr-16', 'mb-8', 'mt-16', '-m-8', 'm-auto', 'ml-auto']
const { css } = await uno.generate(classes)
const classes = ['m-8', 'mx-2', 'my-4', 'ml-32', 'mr-16', 'mb-8', 'mt-16', '-m-8', 'm-auto', 'ml-auto'];
const { css } = await uno.generate(classes);
expect(css).toMatchInlineSnapshot(`

@@ -43,9 +43,9 @@ "/* layer: default */

.mt-16{margin-top:1.6rem;}"
`)
})
`);
});
test('margin skips bad values', async ({ uno }) => {
const classes = ['m-7', 'mx-3', 'my-5', 'ml-33', 'mr-19', 'mb-9', 'mt-17', '-m-11']
const { css } = await uno.generate(classes)
expect(css).toMatchInlineSnapshot('""')
})
const classes = ['m-7', 'mx-3', 'my-5', 'ml-33', 'mr-19', 'mb-9', 'mt-17', '-m-11'];
const { css } = await uno.generate(classes);
expect(css).toMatchInlineSnapshot('""');
});

@@ -1,13 +0,27 @@

import { setup } from './_helpers.js'
import { expect, test } from 'vitest'
import * as staticRules from '../src/_rules/static.js'
import { setup } from './_helpers.js';
import { expect, test, describe } from 'vitest';
import { positionMap } from '#utils';
import * as staticRules from '../src/_rules/static.js';
// TODO: change this to a subpath import when this lands
// https://github.com/vitejs/vite/pull/7770
setup()
setup();
test('static rules do static things', async ({ uno }) => {
const staticClasses = Object.values(staticRules).flat().filter(rule => typeof rule[0] === 'string').map(rule => rule[0])
const { css } = await uno.generate(staticClasses)
expect(css).toMatchSnapshot()
})
const staticClasses = Object.values(staticRules).flat().filter(rule => typeof rule[0] === 'string').map(rule => rule[0]);
const { css } = await uno.generate(staticClasses);
expect(css).toMatchSnapshot();
});
describe('static rules for object position', () => {
test('supports all predefined values in the position map', async ({ uno }) => {
const staticClasses = Object.keys(positionMap).map(position => `object-${position}`);
const { css } = await uno.generate(staticClasses);
expect(css).toMatchSnapshot();
});
test('do not support invalid values', async ({ uno }) => {
const staticClasses = ['object-position', 'object-right-left'];
const { css } = await uno.generate(staticClasses);
expect(css).toMatchInlineSnapshot('""');
});
});

@@ -1,44 +0,44 @@

import { setup, getFractions } from './_helpers.js'
import { expect, test } from 'vitest'
import { positionMap } from '#utils'
import { spaceBase } from '#theme'
import { setup, getFractions } from './_helpers.js';
import { expect, test } from 'vitest';
import { positionMap } from '#utils';
import { spaceBase } from '#theme';
setup()
setup();
test('origin', async ({ uno }) => {
const classes = Object.keys(positionMap).map(e => `origin-${e}`)
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = Object.keys(positionMap).map(e => `origin-${e}`);
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('translate', async ({ uno }) => {
const classes = ['full', ...spaceBase].flatMap(e => ([`translate-x-${e}`, `translate-y-${e}`]))
classes.push(...getFractions('translate-x'))
classes.push(...getFractions('translate-y'))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['full', ...spaceBase].flatMap(e => ([`translate-x-${e}`, `translate-y-${e}`]));
classes.push(...getFractions('translate-x'));
classes.push(...getFractions('translate-y'));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('rotate', async ({ uno }) => {
const classes = [0, 1, 2, 3, 6, 12, 45, 90, 180].map(e => `rotate-${e}`)
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = [0, 1, 2, 3, 6, 12, 45, 90, 180].map(e => `rotate-${e}`);
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('skew', async ({ uno }) => {
const classes = [0, 1, 2, 3, 6, 12].flatMap(e => ([`skew-y-${e}`, `skew-x-${e}`]))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = [0, 1, 2, 3, 6, 12].flatMap(e => ([`skew-y-${e}`, `skew-x-${e}`]));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('scale', async ({ uno }) => {
const classes = [0, 50, 75, 90, 100, 105, 110, 125, 150].flatMap(e => ([`scale-${e}`, `scale-x-${e}`, `scale-y-${e}`]))
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = [0, 50, 75, 90, 100, 105, 110, 125, 150].flatMap(e => ([`scale-${e}`, `scale-x-${e}`, `scale-y-${e}`]));
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('transform', async ({ uno }) => {
const classes = ['transform', 'transform-cpu', 'transform-gpu', 'transform-none']
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['transform', 'transform-cpu', 'transform-gpu', 'transform-none'];
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});

@@ -1,29 +0,29 @@

import { setup } from './_helpers.js'
import { expect, test } from 'vitest'
import { durationBase } from '#theme'
import { setup } from './_helpers.js';
import { expect, test } from 'vitest';
import { durationBase } from '#theme';
setup()
setup();
test('transition', async ({ uno }) => {
const classes = ['none', 'all', 'colors', 'opacity', 'shadow', 'transform'].map(e => `transition-${e}`)
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['none', 'all', 'colors', 'opacity', 'shadow', 'transform'].map(e => `transition-${e}`);
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('duration', async ({ uno }) => {
const classes = durationBase.map(e => `duration-${e}`)
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = durationBase.map(e => `duration-${e}`);
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('delay', async ({ uno }) => {
const classes = durationBase.map(e => `delay-${e}`)
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = durationBase.map(e => `delay-${e}`);
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('ease', async ({ uno }) => {
const classes = ['linear', 'in', 'out', 'in-out'].map(e => `ease-${e}`)
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['linear', 'in', 'out', 'in-out'].map(e => `ease-${e}`);
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});

@@ -1,28 +0,28 @@

import { setup } from './_helpers.js'
import { describe, expect, test } from 'vitest'
import { setup } from './_helpers.js';
import { describe, expect, test } from 'vitest';
setup()
setup();
describe('variants', () => {
test('negative', async ({ uno }) => {
const classes = ['-inset-16', '-mt-32', '-bottom-1/2']
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['-inset-16', '-mt-32', '-bottom-1/2'];
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('breakpoints', async ({ uno }) => {
const classes = ['md:mt-32', 'at-md:mt-32', 'lt-md:mt-32']
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['md:mt-32', 'at-md:mt-32', 'lt-md:mt-32'];
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('important', async ({ uno }) => {
const classes = ['!mb-32', '!sm:mt-32', '!md:-bottom-1/2']
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['!mb-32', '!sm:mt-32', '!md:-bottom-1/2'];
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
test('pseudo', async ({ uno }) => {
const classes = ['last:mb-0', 'before:p-32', 'focus:border', 'group', 'group-hover:p-16', 'group/llama', 'group-hover/llama:m-32']
const { css } = await uno.generate(classes)
expect(css).toMatchSnapshot()
})
const classes = ['last:mb-0', 'before:p-32', 'focus:border', 'group', 'group-hover:p-16', 'group/llama', 'group-hover/llama:m-32'];
const { css } = await uno.generate(classes);
expect(css).toMatchSnapshot();
});
// space/divide variant is already tested by the space/divide classes
})
});

@@ -1,24 +0,24 @@

import { defineConfig } from 'vitest/config'
import drnm from 'drnm'
import path from 'node:path'
import fs from 'node:fs'
import UnoCSS from 'unocss/vite'
import { presetWarp } from '#plugin'
import { defineConfig } from 'vitest/config';
import drnm from 'drnm';
import path from 'node:path';
import fs from 'node:fs';
import UnoCSS from 'unocss/vite';
import { presetWarp } from '#plugin';
const __workdir = drnm(import.meta.url)
const pkg = JSON.parse(fs.readFileSync(path.join(__workdir, './package.json')))
const __workdir = drnm(import.meta.url);
const pkg = JSON.parse(fs.readFileSync(path.join(__workdir, './package.json')));
const alias = Object.entries(pkg.imports).reduce((acc, [k, v]) => {
acc[k] = path.resolve(path.join(__workdir, '.', v))
return acc
}, {})
acc[k] = path.resolve(path.join(__workdir, '.', v));
return acc;
}, {});
export default defineConfig({
plugins: [
UnoCSS({ presets: [presetWarp({ usePreflight: true })] })
UnoCSS({ presets: [presetWarp({ usePreflight: true })] }),
],
test: {
include: ['./test/*.js'],
exclude: ['./test/_*']
exclude: ['./test/_*'],
},
resolve: { alias }
})
resolve: { alias },
});

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc