Skip to content

Commit

Permalink
feat(preset-tagify): new preset (#1010)
Browse files Browse the repository at this point in the history
  • Loading branch information
zojize committed May 29, 2022
1 parent a8d3c07 commit 896dad3
Show file tree
Hide file tree
Showing 23 changed files with 406 additions and 2 deletions.
5 changes: 4 additions & 1 deletion .vscode/settings.json
Expand Up @@ -4,5 +4,8 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": false
"editor.formatOnSave": false,
"cSpell.words": [
"tagify"
]
}
1 change: 1 addition & 0 deletions alias.ts
Expand Up @@ -13,6 +13,7 @@ export const alias: Record<string, string> = {
'@unocss/preset-attributify': r('./packages/preset-attributify/src/'),
'@unocss/preset-icons': r('./packages/preset-icons/src/'),
'@unocss/preset-mini': r('./packages/preset-mini/src/'),
'@unocss/preset-tagify': r('./packages/preset-tagify/src/'),
'@unocss/preset-typography': r('./packages/preset-typography/src/'),
'@unocss/preset-uno': r('./packages/preset-uno/src/'),
'@unocss/preset-web-fonts': r('./packages/preset-web-fonts/src/'),
Expand Down
3 changes: 2 additions & 1 deletion interactive/guides/packages.md
Expand Up @@ -7,7 +7,8 @@
| [@unocss/preset-uno](https://github.com/unocss/unocss/tree/main/packages/preset-uno) | The default preset |
| [@unocss/preset-mini](https://github.com/unocss/unocss/tree/main/packages/preset-mini) | The minimal but essential rules and variants |
| [@unocss/preset-wind](https://github.com/unocss/unocss/tree/main/packages/preset-wind) | Tailwind / Windi CSS compact preset |
| [@unocss/preset-attributify](https://github.com/unocss/unocss/tree/main/packages/preset-attributify) | Enables Attributify Mode for other rules |
| [@unocss/preset-attributify](https://github.com/unocss/unocss/tree/main/packages/preset-attributify) | Enables Attributify Mode for other rules |
| [@unocss/preset-tagify](https://github.com/unocss/unocss/tree/main/packages/preset-tagify) | Enables Tagify Mode for other rules |
| [@unocss/preset-icons](https://github.com/unocss/unocss/tree/main/packages/preset-icons) | Pure CSS Icons solution powered by Iconify |
| [@unocss/preset-web-fonts](https://github.com/unocss/unocss/tree/main/packages/preset-web-fonts) | Web fonts (Google Fonts, etc.) support |
| [@unocss/preset-typography](https://github.com/unocss/unocss/tree/main/packages/preset-typography) | The typography preset |
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -52,6 +52,7 @@
"@unocss/preset-attributify": "workspace:*",
"@unocss/preset-icons": "workspace:*",
"@unocss/preset-mini": "workspace:*",
"@unocss/preset-tagify": "workspace:*",
"@unocss/preset-typography": "workspace:*",
"@unocss/preset-uno": "workspace:*",
"@unocss/preset-web-fonts": "workspace:*",
Expand Down
1 change: 1 addition & 0 deletions packages/README.md
Expand Up @@ -9,6 +9,7 @@
| [@unocss/preset-mini](./preset-mini) | The minimal but essential rules and variants |||
| [@unocss/preset-wind](./preset-wind) | Tailwind / Windi CSS compact preset |||
| [@unocss/preset-attributify](./preset-attributify) | Enables Attributify Mode for other rules || No |
| [@unocss/preset-tagify](./preset-tagify) | Enables Tagify Mode for other rules || No |
| [@unocss/preset-icons](./preset-icons) | Pure CSS Icons solution powered by Iconify || No |
| [@unocss/preset-web-fonts](./preset-web-fonts) | Web fonts (Google Fonts, etc.) support || No |
| [@unocss/preset-typography](./preset-typography) | The typography preset || No |
Expand Down
1 change: 1 addition & 0 deletions packages/nuxt/package.json
Expand Up @@ -44,6 +44,7 @@
"@unocss/core": "workspace:*",
"@unocss/preset-attributify": "workspace:*",
"@unocss/preset-icons": "workspace:*",
"@unocss/preset-tagify": "workspace:*",
"@unocss/preset-typography": "workspace:*",
"@unocss/preset-uno": "workspace:*",
"@unocss/preset-web-fonts": "workspace:*",
Expand Down
2 changes: 2 additions & 0 deletions packages/nuxt/src/options.ts
Expand Up @@ -3,6 +3,7 @@ import presetAttributify from '@unocss/preset-attributify'
import presetIcons from '@unocss/preset-icons'
import presetWebFonts from '@unocss/preset-web-fonts'
import presetTypography from '@unocss/preset-typography'
import presetTagify from '@unocss/preset-tagify'
import presetWind from '@unocss/preset-wind'
import type { UnocssNuxtOptions } from './types'

Expand All @@ -12,6 +13,7 @@ export function resolveOptions(options: UnocssNuxtOptions) {
const presetMap = {
uno: presetUno,
attributify: presetAttributify,
tagify: presetTagify,
icons: presetIcons,
webFonts: presetWebFonts,
typography: presetTypography,
Expand Down
8 changes: 8 additions & 0 deletions packages/nuxt/src/types.ts
Expand Up @@ -4,6 +4,7 @@ import type { AttributifyOptions } from '@unocss/preset-attributify'
import type { IconsOptions } from '@unocss/preset-icons'
import type { WebFontsOptions } from '@unocss/preset-web-fonts'
import type { TypographyOptions } from '@unocss/preset-typography'
import type { TagifyOptions } from '@unocss/preset-tagify'
import type { PresetWindOptions } from '@unocss/preset-wind'

export interface UnocssNuxtOptions extends UserConfig {
Expand Down Expand Up @@ -43,6 +44,13 @@ export interface UnocssNuxtOptions extends UserConfig {
*/
attributify?: boolean | AttributifyOptions

/**
* Enable tagify mode and the options of it
* Only works when `presets` is not specified
* @default false
*/
tagify?: boolean | TagifyOptions

/**
* Enable icons preset and the options of it
* Only works when `presets` is not specified
Expand Down
22 changes: 22 additions & 0 deletions packages/preset-tagify/LICENSE
@@ -0,0 +1,22 @@
MIT License

Copyright (c) 2022-PRESENT Jeff Zou <https://github.com/zojize>
Copyright (c) 2022-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.
77 changes: 77 additions & 0 deletions packages/preset-tagify/README.md
@@ -0,0 +1,77 @@
# @unocss/preset-tagify

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

## Installation

```bash
npm i -D @unocss/preset-tagify
```

```ts
import preseTagify from '@unocss/preset-tagify'

Unocss({
presets: [
presetTagify({ /* options */ }),
// ...other presets
],
})
```

## Tagify Mode

This preset can come in handy when you only need a single unocss rule to be apply on an element.

```html
<span class="text-red"> red text </span>
<div class="flex"> flexbox </div>
I'm feeling <span class="i-line-md-emoji-grin"></span> today!
```

With tagify mode, you can embed CSS styles into HTML tags:

```html
<text-red> red text </text-red>
<flex> flexbox </flex>
I'm feeling <i-line-md-emoji-grin> </i-line-md-emoji-grin> today!
```

The HTML above works exactly as you would expect.

## With Prefix

```js
presetTagify({
prefix: 'un-'
})
```

```html
<!-- this will be matched -->
<un-flex> </un-flex>
<!-- this will not be matched -->
<flex> </flex>
```

## Extra Properties

You can inject extra properties to the matched rules:

```js
presetTagify({
// adds display: inline-block to matched icons
extraProperties: matched => matched.startsWith('i-')
? { display: 'inline-block' }
: { }
})
presetTagify({
// extraProperties can also be a plain object
extraProperties: { display: 'block' }
})
```

## License

MIT License &copy; 2022-PRESENT [Jeff Zou](https://github.com/zojize)
MIT License &copy; 2022-PRESENT [Anthony Fu](https://github.com/antfu)
12 changes: 12 additions & 0 deletions packages/preset-tagify/build.config.ts
@@ -0,0 +1,12 @@
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
entries: [
'src/index',
],
clean: true,
declaration: true,
rollup: {
emitCJS: true,
},
})
42 changes: 42 additions & 0 deletions packages/preset-tagify/package.json
@@ -0,0 +1,42 @@
{
"name": "@unocss/preset-tagify",
"version": "0.34.1",
"description": "Tagify preset for UnoCSS",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
"homepage": "https://github.com/unocss/unocss/tree/main/packages/transformer-variant-group#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/unocss/unocss.git",
"directory": "packages/transformer-variant-group"
},
"bugs": {
"url": "https://github.com/unocss/unocss/issues"
},
"keywords": [
"unocss",
"unocss-preset"
],
"sideEffects": false,
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "unbuild",
"stub": "unbuild --stub"
},
"dependencies": {
"@unocss/core": "workspace:*"
}
}
22 changes: 22 additions & 0 deletions packages/preset-tagify/src/extractor.ts
@@ -0,0 +1,22 @@
import type { Extractor } from '@unocss/core'
import type { TagifyOptions } from './types'

export const MARKER = '__TAGIFY__'
export const htmlTagRE = /<([\w\d-:]+)/g

export const extractorTagify = (options: TagifyOptions): Extractor => {
const {
prefix = '',
} = options

return {
name: 'tagify',
extract({ code }) {
return new Set(
Array.from(code.matchAll(htmlTagRE))
.filter(({ 1: match }) => match.startsWith(prefix))
.map(([, matched]) => `${MARKER}${matched}`),
)
},
}
}
33 changes: 33 additions & 0 deletions packages/preset-tagify/src/index.ts
@@ -0,0 +1,33 @@
import type { Preset } from '@unocss/core'
import { extractorSplit } from '@unocss/core'
import type { TagifyOptions } from './types'
import { extractorTagify } from './extractor'
import { variantTagify } from './variant'

export * from './extractor'
export * from './types'
export * from './variant'

const preset = (options: TagifyOptions = {}): Preset => {
const {
defaultExtractor = true,
} = options

const variants = [
variantTagify(options),
]
const extractors = [
extractorTagify(options),
]

if (defaultExtractor)
extractors.push(extractorSplit)

return {
name: '@unocss/preset-tagify',
variants,
extractors,
}
}

export default preset
19 changes: 19 additions & 0 deletions packages/preset-tagify/src/types.ts
@@ -0,0 +1,19 @@
export interface TagifyOptions {
/**
* The prefix to use for the tagify variant.
*/
prefix?: string

/**
* Extra CSS properties to apply to matched rules
*/
extraProperties?:
| Record<string, string>
| ((matched: string) => Partial<Record<string, string>>)

/**
* Enable default extractor
* @default true
*/
defaultExtractor?: boolean
}
31 changes: 31 additions & 0 deletions packages/preset-tagify/src/variant.ts
@@ -0,0 +1,31 @@
import type { VariantHandler, VariantObject } from '@unocss/core'
import type { TagifyOptions } from './types'
import { MARKER } from './extractor'

export const variantTagify = (options: TagifyOptions): VariantObject => {
const { extraProperties } = options
const prefix = `${MARKER}${options.prefix ?? ''}`

return {
name: 'tagify',
match(input) {
if (!input.startsWith(prefix))
return

const matcher = input.slice(prefix.length)
const handler: VariantHandler = {
matcher,
selector: i => i.slice(MARKER.length + 1),
}

if (extraProperties) {
if (typeof extraProperties === 'function')
handler.body = entries => [...entries, ...Object.entries(extraProperties(matcher) ?? {})]
else
handler.body = entries => [...entries, ...Object.entries(extraProperties)]
}

return handler
},
}
}
1 change: 1 addition & 0 deletions packages/unocss/build.config.ts
Expand Up @@ -7,6 +7,7 @@ export default defineBuildConfig({
'src/preset-uno',
'src/preset-icons',
'src/preset-attributify',
'src/preset-tagify',
'src/preset-web-fonts',
'src/preset-typography',
'src/preset-wind',
Expand Down
6 changes: 6 additions & 0 deletions packages/unocss/package.json
Expand Up @@ -33,6 +33,11 @@
"import": "./dist/preset-attributify.mjs",
"require": "./dist/preset-attributify.cjs"
},
"./preset-tagify": {
"types": "./dist/preset-tagify.d.ts",
"import": "./dist/preset-tagify.mjs",
"require": "./dist/preset-tagify.cjs"
},
"./preset-icons": {
"types": "./dist/preset-icons.d.ts",
"import": "./dist/preset-icons.mjs",
Expand Down Expand Up @@ -89,6 +94,7 @@
"@unocss/preset-attributify": "workspace:*",
"@unocss/preset-icons": "workspace:*",
"@unocss/preset-mini": "workspace:*",
"@unocss/preset-tagify": "workspace:*",
"@unocss/preset-typography": "workspace:*",
"@unocss/preset-uno": "workspace:*",
"@unocss/preset-web-fonts": "workspace:*",
Expand Down
1 change: 1 addition & 0 deletions packages/unocss/src/index.ts
Expand Up @@ -3,6 +3,7 @@ import type { UserConfig } from '@unocss/core'
export * from '@unocss/core'
export { default as presetUno } from '@unocss/preset-uno'
export { default as presetAttributify } from '@unocss/preset-attributify'
export { default as presetTagify } from '@unocss/preset-tagify'
export { default as presetIcons } from '@unocss/preset-icons'
export { default as presetWebFonts } from '@unocss/preset-web-fonts'
export { default as presetTypography } from '@unocss/preset-typography'
Expand Down
1 change: 1 addition & 0 deletions packages/unocss/src/preset-tagify.ts
@@ -0,0 +1 @@
export * from '@unocss/preset-attributify'

0 comments on commit 896dad3

Please sign in to comment.