Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(preset-tagify): new preset #1010

Merged
merged 10 commits into from May 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zojize I have added your credit here. I will merge this for now, feel free to send another PR if you'd like to adjust this part. Thanks!

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'