feat: create custom preset for container at-rules
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
"@iconify-json/solar": "^1.1.9",
|
||||
"@types/node": "^20.12.12",
|
||||
"@unocss/cli": "^0.60.3",
|
||||
"@unocss/rule-utils": "^0.60.4",
|
||||
"unocss": "^0.60.3"
|
||||
}
|
||||
}
|
||||
|
||||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ devDependencies:
|
||||
'@unocss/cli':
|
||||
specifier: ^0.60.3
|
||||
version: 0.60.3
|
||||
'@unocss/rule-utils':
|
||||
specifier: ^0.60.4
|
||||
version: 0.60.4
|
||||
unocss:
|
||||
specifier: ^0.60.3
|
||||
version: 0.60.3(postcss@8.4.38)(vite@5.2.11)
|
||||
@@ -847,6 +850,10 @@ packages:
|
||||
resolution: {integrity: sha512-4bBX1pavDl2DSCozEII7bxYGT0IkyO7kKlUuCtooTePWyLjf2F7essdzHkJ00EpNR64kkebR9V0lqBMBo07VPw==}
|
||||
dev: true
|
||||
|
||||
/@unocss/core@0.60.4:
|
||||
resolution: {integrity: sha512-6tz8KTzC30oB0YikwRQoIpJ6Y6Dg+ZiK3NfCIsH+UX11bh2J2M53as2EL/5VQCqtiUn3YP0ZEzR2d1AWX78RCA==}
|
||||
dev: true
|
||||
|
||||
/@unocss/extractor-arbitrary-variants@0.60.3:
|
||||
resolution: {integrity: sha512-PnwNwkeAHmbJbrf5XN0xQG1KT1VQEye8neYn5yz1MHnT8Cj2nqjrqoCRGLCLhpOUg3/MNj+bpiA7hGnFbXWaCQ==}
|
||||
dependencies:
|
||||
@@ -950,6 +957,14 @@ packages:
|
||||
magic-string: 0.30.10
|
||||
dev: true
|
||||
|
||||
/@unocss/rule-utils@0.60.4:
|
||||
resolution: {integrity: sha512-7qUN33NM4T/IwWavm9VIOCZ2+4hLBc0YUGxcMNTDZSFQRQLkWe3N5dOlgwKXtMyMKatZfbIRUKVDUgvEefoCTA==}
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
'@unocss/core': 0.60.4
|
||||
magic-string: 0.30.10
|
||||
dev: true
|
||||
|
||||
/@unocss/scope@0.60.3:
|
||||
resolution: {integrity: sha512-uDUcBkFe8nRwNiU4YQyrOCjY7/+qFJI/Qr0eouMPOSEsQ6uIXQEWjykqUBJg2fvm0S2vbfBGO9tO/wCDIk5O3w==}
|
||||
dev: true
|
||||
|
||||
143
uno-utils.js
Normal file
143
uno-utils.js
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
This file is licensed under the MIT license provided down below:
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024-PRESENT Gustavo L. de Mello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This file has source code modified from the UnoCSS repository, licensed under the MIT
|
||||
license. A copy of the original licensed is provided here https://github.com/unocss/unocss/blob/main/LICENSE
|
||||
and down below:
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-PRESENT Anthony Fu <https://github.com/antfu>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @param {string} [requiredType]
|
||||
*
|
||||
* @license MIT
|
||||
* @author Anthony Fu <https://github.com/antfu>
|
||||
*/
|
||||
function bracketWithType(str, requiredType) {
|
||||
if (str && str.startsWith('[') && str.endsWith(']')) {
|
||||
/** @type {string | undefined } */
|
||||
let base
|
||||
/** @type {string | undefined } */
|
||||
let hintedType
|
||||
|
||||
const bracketTypeRe = /^\[(color|length|size|position|quoted|string):/i
|
||||
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
|
||||
|
||||
// test/preset-attributify.test.ts > fixture5
|
||||
if (base === '=""')
|
||||
return
|
||||
|
||||
if (base.startsWith('--'))
|
||||
base = `var(${base})`
|
||||
|
||||
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, (match) => {
|
||||
/** @type {string[]} */
|
||||
const vars = []
|
||||
return match
|
||||
.replace(/var\((--.+?)[,)]/g, (match, g1) => {
|
||||
vars.push(g1)
|
||||
return match.replace(g1, '--un-calc')
|
||||
})
|
||||
.replace(/(-?\d*\.?\d(?!-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 ')
|
||||
.replace(/--un-calc/g, () => /** @type {string} */(vars.shift()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
*
|
||||
* @license MIT
|
||||
* @author Anthony Fu <https://github.com/antfu>
|
||||
*/
|
||||
export function bracket(str) {
|
||||
return bracketWithType(str)
|
||||
}
|
||||
@@ -7,6 +7,95 @@ import {
|
||||
transformerDirectives,
|
||||
transformerVariantGroup,
|
||||
} from 'unocss';
|
||||
import { definePreset } from 'unocss';
|
||||
import { variantGetParameter } from '@unocss/rule-utils';
|
||||
|
||||
import * as utils from './uno-utils.js';
|
||||
|
||||
const presetContainers = definePreset(
|
||||
/**
|
||||
* @param {{ containers?: Record<string, string | number>}} [options={}]
|
||||
*/
|
||||
(options = {}) => {
|
||||
const defaultContainers = {
|
||||
'xs': '20rem',
|
||||
'sm': '24rem',
|
||||
'md': '28rem',
|
||||
'lg': '32rem',
|
||||
'xl': '36rem',
|
||||
'2xl': '42rem',
|
||||
'3xl': '48rem',
|
||||
'4xl': '56rem',
|
||||
'5xl': '64rem',
|
||||
'6xl': '72rem',
|
||||
'7xl': '80rem',
|
||||
};
|
||||
options.containers = {
|
||||
...defaultContainers,
|
||||
...Object.fromEntries(Object.entries(defaultContainers).map(e => [`h-${e[0]}`, e[1]])),
|
||||
...Object.fromEntries(Object.entries(defaultContainers).map(e => [`w-${e[0]}`, e[1]])),
|
||||
...options.containers,
|
||||
};
|
||||
/** @type {import('unocss').Preset} */
|
||||
const preset = {
|
||||
name: 'preset-containers',
|
||||
rules: [
|
||||
[/^@container(?:\/(\w+))?(?:-(normal|size))?$/, ([, l, v]) => {
|
||||
return {
|
||||
'container-type': v ?? 'inline-size',
|
||||
'container-name': l,
|
||||
}
|
||||
}],
|
||||
],
|
||||
variants: [
|
||||
{
|
||||
name: '@',
|
||||
match(matcher, ctx) {
|
||||
if (matcher.startsWith('@container')) {
|
||||
return matcher
|
||||
}
|
||||
const variant = variantGetParameter('@', matcher, ctx.generator.config.separators)
|
||||
if (variant) {
|
||||
const [match, rest, label] = variant;
|
||||
const unit = utils.bracket(match);
|
||||
console.log(match, rest, label)
|
||||
|
||||
/** @type {string | undefined } */
|
||||
let container;
|
||||
if (unit?.startsWith("h:")) {
|
||||
container = `(min-height: ${unit.replace('h:', '')})`
|
||||
} else if (unit?.startsWith("w:") || unit) {
|
||||
container = `(min-width: ${unit.replace('w:', '')})`
|
||||
} else {
|
||||
/** @type {string | number} */
|
||||
const size = options.containers?.[match] ?? '';
|
||||
container =
|
||||
`(${match.startsWith('h-') ? 'min-height' : 'min-width'}: ` +
|
||||
`${typeof size === 'number' ? `${size}px` : size})`
|
||||
}
|
||||
|
||||
if (!container) {
|
||||
return
|
||||
}
|
||||
|
||||
let order = (label ? 1000 : 2000) + Object.keys(options.containers ?? {}).indexOf(match);
|
||||
|
||||
return {
|
||||
matcher: rest,
|
||||
handle: (input, next) => next({
|
||||
...input,
|
||||
parent: `${input.parent ? `${input.parent} $$` : ''}@container${label ? ` ${label} ` : ''}${container}`,
|
||||
parentOrder: order,
|
||||
}),
|
||||
}
|
||||
}
|
||||
},
|
||||
multiPass: true,
|
||||
}
|
||||
],
|
||||
}
|
||||
return preset;
|
||||
})
|
||||
|
||||
export default defineConfig({
|
||||
theme: {
|
||||
@@ -16,6 +105,8 @@ export default defineConfig({
|
||||
'light-gray': '#9c9c9c',
|
||||
'gray': '#383838',
|
||||
'dark-gray': '#0c0c0c',
|
||||
'mauve': '#cba6f7',
|
||||
'yellow': '#f9e2af',
|
||||
},
|
||||
},
|
||||
cli: {
|
||||
@@ -28,6 +119,7 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
presetContainers(),
|
||||
presetIcons(),
|
||||
presetTypography(),
|
||||
presetUno(),
|
||||
|
||||
Reference in New Issue
Block a user