Skip to content

Commit

Permalink
feat: attributify support
Browse files Browse the repository at this point in the history
  • Loading branch information
zguolee committed Aug 27, 2022
1 parent dd8d0ec commit f8105d0
Show file tree
Hide file tree
Showing 32 changed files with 776 additions and 383 deletions.
39 changes: 34 additions & 5 deletions README.md
Expand Up @@ -13,17 +13,46 @@ pnpm add unocss-applet -D # with pnpm
## Usage

```ts
import { defineConfig } from 'unocss'
import {
defineConfig,
presetAttributify,
presetIcons,
presetUno,
transformerDirectives,
transformerVariantGroup,
} from 'unocss'

import { presetApplet, presetRemToRpx, transformerRenameClass } from 'unocss-applet'
import {
presetApplet,
presetRemToRpx,
transformerApplet,
transformerAttributify,
} from 'unocss-applet'

const presets = []
const transformers = []

if (process.env.UNI_PLATFORM === 'h5') {
presets.push(presetUno())
presets.push(presetAttributify())
}
else {
presets.push(presetApplet())
presets.push(presetRemToRpx())

transformers.push(transformerApplet())
transformers.push(transformerAttributify())
}

export default defineConfig({
presets: [
presetApplet(),
presetRemToRpx(),
presetIcons(),
...presets,
],
transformers: [
transformerRenameClass(),
transformerDirectives(),
transformerVariantGroup(),
...transformers,
],
})
```
Expand Down
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -23,14 +23,15 @@
"@types/node": "^18.7.2",
"@unocss-applet/preset-applet": "workspace:*",
"@unocss-applet/preset-rem-to-rpx": "workspace:*",
"@unocss-applet/transformer-rename-class": "workspace:*",
"@unocss-applet/transformer-applet": "workspace:*",
"@unocss-applet/transformer-attributify": "workspace:*",
"bumpp": "^8.2.1",
"eslint": "^8.21.0",
"esno": "^0.16.3",
"rimraf": "^3.0.2",
"typescript": "^4.7.4",
"unbuild": "^0.8.8",
"unocss": "^0.45.7",
"unocss": "^0.45.13",
"unocss-applet": "workspace:*",
"vite": "^2.9.15",
"vitest": "^0.21.1"
Expand Down
6 changes: 3 additions & 3 deletions packages/preset-applet/package.json
Expand Up @@ -54,8 +54,8 @@
"stub": "unbuild --stub"
},
"dependencies": {
"@unocss/core": "0.45.7",
"@unocss/preset-mini": "0.45.7",
"@unocss/preset-wind": "0.45.7"
"@unocss/core": "0.45.13",
"@unocss/preset-mini": "0.45.13",
"@unocss/preset-wind": "0.45.13"
}
}
2 changes: 1 addition & 1 deletion packages/preset-rem-to-rpx/package.json
Expand Up @@ -37,6 +37,6 @@
"stub": "unbuild --stub"
},
"dependencies": {
"@unocss/core": "^0.45.7"
"@unocss/core": "^0.45.13"
}
}
@@ -1,13 +1,13 @@
# @unocss-applet/transformer-rename-class
# @unocss-applet/transformer-applet

Coverts class selector name to hash.

## Instal

```bash
npm i @unocss-applet/transformer-rename-class --save-dev # with npm
yarn add @unocss-applet/transformer-rename-class -D # with yarn
pnpm add @unocss-applet/transformer-rename-class -D # with pnpm
npm i @unocss-applet/transformer-applet --save-dev # with npm
yarn add @unocss-applet/transformer-applet -D # with yarn
pnpm add @unocss-applet/transformer-applet -D # with pnpm
```

## Usage
Expand All @@ -17,19 +17,19 @@ pnpm add @unocss-applet/transformer-rename-class -D # with pnpm
```ts
import { defineConfig } from 'unocss'

import transformerRenameClass from '@unocss-applet/transformer-rename-class'
import transformerApplet from '@unocss-applet/transformer-applet'

export default defineConfig({
// ...
transformers: [
transformerRenameClass(),
transformerApplet(),
],
})
```

## Type Declarations
```ts
export interface RenameClassOptions {
export interface TransformerAppletOptions {
/**
* Prefix for compile class name
* @default 'uno-'
Expand All @@ -46,29 +46,6 @@ export interface RenameClassOptions {
* @default 'applet_shortcuts'
*/
layer?: string

/**
* Enable rename class, only build applet should be true
* e.g. In uniapp `enableRename: !(process.env.UNI_PLATFORM === 'h5')` to disable rename class in h5
* @default true
*/
enableRename?: boolean

/**
* Separators to expand.
*
* ```
* foo-(bar baz) -> foo-bar foo-baz
* ^
* separator
* ```
*
* You may set it to `[':']` for strictness.
*
* @default [':', '-']
* @see https://github.com/unocss/unocss/pull/1231
*/
separators?: (':' | '-')[]
}
```

Expand Down
File renamed without changes.
@@ -1,16 +1,16 @@
{
"name": "@unocss-applet/transformer-rename-class",
"name": "@unocss-applet/transformer-applet",
"type": "module",
"version": "0.1.2",
"packageManager": "pnpm@7.2.1",
"description": "",
"author": "Neil Lee <zguolee@foxmail.com>",
"license": "MIT",
"homepage": "https://github.com/unocss-applet/unocss-applet/tree/main/packages/transformer-rename-class#readme",
"homepage": "https://github.com/unocss-applet/unocss-applet/tree/main/packages/transformer-applet#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/unocss-applet/unocss-applet.git",
"directory": "packages/transformer-rename-class"
"directory": "packages/transformer-applet"
},
"bugs": "https://github.com/unocss-applet/unocss-applet/issues",
"keywords": [
Expand All @@ -35,7 +35,7 @@
"stub": "unbuild --stub"
},
"dependencies": {
"@unocss/core": "^0.45.7"
"@unocss/core": "^0.45.13"
},
"devDependencies": {
"magic-string": "^0.26.2"
Expand Down
37 changes: 37 additions & 0 deletions packages/transformer-applet/src/compile.ts
@@ -0,0 +1,37 @@
import type { UnocssPluginContext } from 'unocss'
import type { TransformerAppletOptions } from './types'

export async function compileApplet(body: string, ctx: UnocssPluginContext, options: TransformerAppletOptions = {}): Promise<string[]> {
const {
classPrefix = 'uno-',
hashFn = hash,
layer = 'applet_shortcuts',
} = options

const { uno, tokens } = ctx
const replacements = []
const result = await Promise.all(body.split(/\s+/).filter(Boolean).map(async i => [i, !!await uno.parseToken(i)] as const))
const known = result.filter(([, matched]) => matched).map(([i]) => i)
const unknown = result.filter(([, matched]) => !matched).map(([i]) => i)
replacements.push(...unknown)
body = known.join(' ')
if (body) {
const hash = hashFn(body)
const className = `${classPrefix}${hash}`
replacements.unshift(className)
uno.config.shortcuts.push([className, body, { layer }])
tokens.add(className)
}
return replacements
}

export function hash(str: string) {
let i; let l
let hval = 0x811C9DC5

for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i)
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24)
}
return (`00000${(hval >>> 0).toString(36)}`).slice(-6)
}
79 changes: 79 additions & 0 deletions packages/transformer-applet/src/index.ts
@@ -0,0 +1,79 @@
import type { SourceCodeTransformer } from 'unocss'
import MagicString from 'magic-string'
import type { TransformerAppletOptions } from './types'
import { compileApplet } from './compile'

export default function transformerApplet(options: TransformerAppletOptions = {}): SourceCodeTransformer {
// Regular expression of characters to be escaped
const charReg = /[.:%!#()[\/\],]/

const classRE = /:?(hover-)?class=\".*?\"/g
const string1RE = /([']).*?(['])/g
const string2RE = /([\`]).*?([\`])/g

return {
name: 'transformer-applet',
enforce: 'pre',
async transform(s, _, ctx) {
const code = new MagicString(s.toString())
// process class
const classMatches = [...code.original.matchAll(classRE)]
for (const match of classMatches) {
// skip `... ? ... : ...`
if (/\?.*:/g.test(match[0]))
continue

// skip `... : ...`
if (/{.+:.+}/g.test(match[0]))
continue

const start = match.index!
const matchSplit = match[0].split('class=')

const body = matchSplit[1].slice(1, -1)

if (charReg.test(body)) {
const replacements = await compileApplet(body, ctx, options)
code.overwrite(start, start + match[0].length, `${matchSplit[0]}class="${replacements.join(' ')}"`)
}
}

// process string1
const string1Matches = [...code.original.matchAll(string1RE)]
for (const match of string1Matches) {
// There may be no need
// https://tailwindcss.com/docs/background-image#arbitrary-values
// skip all the image formats in HTML for bg-[url('...')]
if (/\.(png|jpg|jpeg|gif|svg)/g.test(match[0]))
continue
// skip http(s)://
if (/http(s)?:\/\//g.test(match[0]))
continue

const start = match.index!
const body = match[0].slice(1, -1)
if (charReg.test(body)) {
const replacements = await compileApplet(body, ctx, options)
code.overwrite(start, start + match[0].length, `'${replacements.join(' ')}'`)
}
}

// process string2
const string2Matches = [...code.original.matchAll(string2RE)]
for (const match of string2Matches) {
// skip `${...}`
if (/\$\{.*\}/g.test(match[0]))
continue

const start = match.index!
const body = match[0].slice(1, -1)
if (charReg.test(body)) {
const replacements = await compileApplet(body, ctx, options)
code.overwrite(start, start + match[0].length, `'${replacements.join(' ')}'`)
}
}
s.overwrite(0, s.original.length, code.toString())
},
}
}

18 changes: 18 additions & 0 deletions packages/transformer-applet/src/types.ts
@@ -0,0 +1,18 @@
export interface TransformerAppletOptions {
/**
* Prefix for compile class name
* @default 'uno-'
*/
classPrefix?: string

/**
* Hash function
*/
hashFn?: (str: string) => string

/**
* The layer name of generated rules
* @default 'applet_shortcuts'
*/
layer?: string
}
16 changes: 16 additions & 0 deletions packages/transformer-attributify/README.md
@@ -0,0 +1,16 @@
# @unocss-applet/transformer-attributify

Attributify Mode for [UnoCSS](https://github.com/unocss/unocss).

## Instal

```bash
npm i @unocss-applet/transformer-attributify --save-dev # with npm
yarn add @unocss-applet/transformer-attributify -D # with yarn
pnpm add @unocss-applet/transformer-attributify -D # with pnpm
```


## License

MIT License &copy; 2022-PRESENT [Neil Lee](https://github.com/zguolee)
16 changes: 16 additions & 0 deletions packages/transformer-attributify/build.config.ts
@@ -0,0 +1,16 @@
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
entries: [
'src/index',
],
clean: true,
declaration: true,
externals: [
'magic-string',
'unocss',
],
rollup: {
emitCJS: true,
},
})

0 comments on commit f8105d0

Please sign in to comment.