Skip to content

Commit a0bf889

Browse files
authored
Merge pull request #7 from OSpoon/feature/ideas
LGTM
2 parents 3b94cf9 + fa0fe3a commit a0bf889

File tree

7 files changed

+83
-50
lines changed

7 files changed

+83
-50
lines changed

README.md

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,46 @@ npm install postcss postcss-dynamic-pixel --save-dev
4242

4343
```JavaScript
4444
// ./postcss.config.cjs
45-
const { dynamicPixel } = require('postcss-dynamic-pixel')
46-
4745
module.exports = {
48-
plugins: [
49-
dynamicPixel({
50-
idealViewportWidth: 750,
51-
currentViewportWidth: 100,
52-
minViewportWidth: 320,
53-
maxViewportWidth: 1440,
54-
})
55-
]
46+
plugins: {
47+
'postcss-dynamic-pixel': {
48+
idealViewportWidth: 750,
49+
currentViewportWidth: 100,
50+
minViewportWidth: 320,
51+
maxViewportWidth: 1440,
52+
},
53+
},
54+
}
55+
```
56+
57+
## All Options
58+
59+
```typescript
60+
export interface DynamicPixelOptions {
61+
/* 理想视窗宽度,设计稿宽度,按像素值设置,但省略单位(px) */
62+
idealViewportWidth?: number
63+
/* 当前视窗宽度,按视口值设置,但省略单位(vw) */
64+
currentViewportWidth?: number
65+
66+
/* 最小视窗宽度,按像素值设置,但省略单位(px) */
67+
minViewportWidth?: number
68+
/* 最大视窗宽度,按像素值设置,但省略单位(px) */
69+
maxViewportWidth?: number
70+
71+
/* 理想的字体大小,按像素值设置,但省略单位(px) */
72+
idealFontSize?: number
73+
74+
/* 是否替换原有值 */
75+
replace?: boolean
76+
77+
/* 跳过的属性列表 */
78+
skipProps?: string[]
79+
/* 跳过的选择器列表 */
80+
skipSelectors?: string[] | RegExp[]
81+
/* 是否处理媒体查询中的像素值 */
82+
mediaQuery?: boolean
83+
/* 排除文件列表 */
84+
exclude?: RegExp
5685
}
5786
```
5887

build.config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { join } from 'node:path'
2+
import { appendFileSync, rmSync } from 'node:fs'
13
import { defineBuildConfig } from 'unbuild'
24

35
export default defineBuildConfig({
@@ -8,6 +10,17 @@ export default defineBuildConfig({
810
clean: true,
911
rollup: {
1012
emitCJS: true,
13+
esbuild: {
14+
minify: true,
15+
},
1116
},
1217
externals: ['postcss'],
18+
hooks: {
19+
'build:done': (ctx) => {
20+
['index.d.cts', 'index.d.mts', 'index.mjs'].forEach((file) => {
21+
rmSync(join(ctx.options.outDir, file))
22+
})
23+
appendFileSync(join(ctx.options.outDir, 'index.cjs'), `module.exports.postcss = true;`)
24+
},
25+
},
1326
})

package-lock.json

Lines changed: 6 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,14 @@
1111
"url": "git+https://github.com/OSpoon/postcss-dynamic-pixel.git"
1212
},
1313
"bugs": "https://github.com/OSpoon/postcss-dynamic-pixel/issues",
14-
"keywords": [],
14+
"keywords": ["postcss-plugin", "postcss", "pixel", "responsive", "px"],
1515
"sideEffects": false,
1616
"exports": {
1717
".": {
1818
"types": "./dist/index.d.ts",
19-
"import": "./dist/index.mjs",
2019
"require": "./dist/index.cjs"
2120
}
2221
},
23-
"main": "./dist/index.mjs",
24-
"module": "./dist/index.mjs",
2522
"types": "./dist/index.d.ts",
2623
"typesVersions": {
2724
"*": {
@@ -47,6 +44,9 @@
4744
"prepare": "simple-git-hooks",
4845
"example": "vite --open"
4946
},
47+
"peerDependencies": {
48+
"postcss": "^8.0.0"
49+
},
5050
"optionalDependencies": {
5151
"@rollup/rollup-linux-x64-gnu": "^4.13.0"
5252
},
@@ -59,7 +59,6 @@
5959
"eslint": "^8.51.0",
6060
"esno": "^0.17.0",
6161
"lint-staged": "^14.0.1",
62-
"postcss": "^8.4.35",
6362
"release-it": "^16.1.5",
6463
"rimraf": "^5.0.5",
6564
"simple-git-hooks": "^2.9.0",

postcss.config.cjs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
const { dynamicPixel } = require('./dist/index.cjs')
2-
31
module.exports = {
4-
plugins: [
5-
dynamicPixel({
2+
plugins: {
3+
'postcss-dynamic-pixel': {
64
idealViewportWidth: 750,
75
currentViewportWidth: 100,
86
minViewportWidth: 320,
97
maxViewportWidth: 1440,
10-
}),
11-
],
8+
},
9+
},
1210
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ function skipFiles(rule: Rule | undefined, exclude: RegExp | undefined) {
8787
return exclude.test(file)
8888
}
8989

90-
export function dynamicPixel(opts?: DynamicPixelOptions): Plugin {
90+
export default function dynamicPixel(opts?: DynamicPixelOptions): Plugin {
9191
const options = Object.assign({}, defaultOptions, opts)
9292
return {
9393
postcssPlugin: 'postcss-dynamic-pixel',

test/index.test.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,76 @@
11
import postcss from 'postcss'
22
import { describe, expect, it } from 'vitest'
3-
import { dynamicPixel } from '../src'
3+
import dynamicPixel from '../src'
44

55
describe('should all pass 😄', () => {
66
it('should replace all px with the formula', async () => {
77
const result = await postcss([dynamicPixel()]).process(`h1 { margin: 0 0 20px; font-size: 32px; line-height: 2; letter-spacing: 1px; }`)
8-
expect(result.css).toMatchInlineSnapshot('"h1 { margin: 0 0 calc( 20 * (clamp(768px, 100vw, 2560px) / 1920) ); font-size: calc( 32 * (clamp(768px, 100vw, 2560px) / 1920) ); line-height: 2; letter-spacing: calc( 1 * (clamp(768px, 100vw, 2560px) / 1920) ); }"')
8+
expect(result.css).toEqual('h1 { margin: 0 0 calc( 20 * (clamp(768px, 100vw, 2560px) / 1920) ); font-size: calc( 32 * (clamp(768px, 100vw, 2560px) / 1920) ); line-height: 2; letter-spacing: calc( 1 * (clamp(768px, 100vw, 2560px) / 1920) ); }')
99
})
1010

1111
it('should remain unitless if 0', async () => {
1212
const result = await postcss([dynamicPixel()]).process(`.rule { font-size: 0px; font-size: 0; }`)
13-
expect(result.css).toMatchInlineSnapshot('".rule { font-size: 0; font-size: 0; }"')
13+
expect(result.css).toEqual('.rule { font-size: 0; font-size: 0; }')
1414
})
1515

1616
it('should not replace units inside mediaQueries by default', async () => {
1717
const result = await postcss([dynamicPixel()]).process(`@media (min-width: 500px) { .rule { font-size: 16px } }`)
18-
expect(result.css).toMatchInlineSnapshot('"@media (min-width: 500px) { .rule { font-size: 16px } }"')
18+
expect(result.css).toEqual('@media (min-width: 500px) { .rule { font-size: 16px } }')
1919
})
2020

2121
it('should not replace values in double quotes or single quotes', async () => {
2222
const result = await postcss([dynamicPixel()]).process(`.rule { content: \'16px\'; font-family: "16px"; font-size: 16px; }`)
23-
expect(result.css).toMatchInlineSnapshot('".rule { content: \'16px\'; font-family: \\"16px\\"; font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }"')
23+
expect(result.css).toEqual('.rule { content: \'16px\'; font-family: \"16px\"; font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }')
2424
})
2525

2626
it('should not replace values in `url()`', async () => {
2727
const result = await postcss([dynamicPixel()]).process(`.rule { background: url(16px.jpg); font-size: 16px; }`)
28-
expect(result.css).toMatchInlineSnapshot('".rule { background: url(16px.jpg); font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }"')
28+
expect(result.css).toEqual('.rule { background: url(16px.jpg); font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }')
2929
})
3030

3131
it('should not replace values with an uppercase P or X', async () => {
3232
const result = await postcss([dynamicPixel()]).process(`.rule { margin: 12px calc(100% - 14PX); height: calc(100% - 20px); font-size: 12Px; line-height: 16px; }`)
33-
expect(result.css).toMatchInlineSnapshot('".rule { margin: calc( 12 * (clamp(768px, 100vw, 2560px) / 1920) ) calc(100% - 14PX); height: calc(100% - calc( 20 * (clamp(768px, 100vw, 2560px) / 1920) )); font-size: 12Px; line-height: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }"')
33+
expect(result.css).toEqual('.rule { margin: calc( 12 * (clamp(768px, 100vw, 2560px) / 1920) ) calc(100% - 14PX); height: calc(100% - calc( 20 * (clamp(768px, 100vw, 2560px) / 1920) )); font-size: 12Px; line-height: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }')
3434
})
3535

3636
it('should ignore non px values by default', async () => {
3737
const result = await postcss([dynamicPixel()]).process(`.rule { font-size: 2em }`)
38-
expect(result.css).toMatchInlineSnapshot('".rule { font-size: 2em }"')
38+
expect(result.css).toEqual('.rule { font-size: 2em }')
3939
})
4040

4141
it('should ignore selectors in the selector black list', async () => {
4242
const result = await postcss([dynamicPixel({
4343
skipSelectors: ['.rule2'],
4444
})]).process(`.rule { font-size: 15px } .rule2 { font-size: 15px }`)
45-
expect(result.css).toMatchInlineSnapshot('".rule { font-size: calc( 15 * (clamp(768px, 100vw, 2560px) / 1920) ) } .rule2 { font-size: 15px }"')
45+
expect(result.css).toEqual('.rule { font-size: calc( 15 * (clamp(768px, 100vw, 2560px) / 1920) ) } .rule2 { font-size: 15px }')
4646
})
4747

4848
it('should ignore every selector with `body$`', async () => {
4949
const result = await postcss([dynamicPixel({
5050
skipSelectors: ['body$'],
5151
})]).process(`body { font-size: 16px; } .class-body$ { font-size: 16px; } .simple-class { font-size: 16px; }`)
52-
expect(result.css).toMatchInlineSnapshot('"body { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); } .class-body$ { font-size: 16px; } .simple-class { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }"')
52+
expect(result.css).toEqual('body { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); } .class-body$ { font-size: 16px; } .simple-class { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }')
5353
})
5454

5555
it('should only ignore exactly `body`', async () => {
5656
const result = await postcss([dynamicPixel({
5757
skipSelectors: [/^body$/],
5858
})]).process(`body { font-size: 16px; } .class-body { font-size: 16px; } .simple-class { font-size: 16px; }`)
59-
expect(result.css).toMatchInlineSnapshot('"body { font-size: 16px; } .class-body { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); } .simple-class { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }"')
59+
expect(result.css).toEqual('body { font-size: 16px; } .class-body { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); } .simple-class { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); }')
6060
})
6161

6262
it('should replace px inside media queries if opts.mediaQuery', async () => {
6363
const result = await postcss([dynamicPixel({
6464
mediaQuery: true,
6565
})]).process(`@media (min-width: 500px) { .rule { font-size: 16px } }`)
66-
expect(result.css).toMatchInlineSnapshot('"@media (min-width: 500px) { .rule { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ) } }"')
66+
expect(result.css).toEqual('@media (min-width: 500px) { .rule { font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ) } }')
6767
})
6868

6969
it('should not replace px inside media queries if not opts.mediaQuery', async () => {
7070
const result = await postcss([dynamicPixel({
7171
mediaQuery: false,
7272
})]).process(`@media (min-width: 500px) { .rule { font-size: 16px } }`)
73-
expect(result.css).toMatchInlineSnapshot('"@media (min-width: 500px) { .rule { font-size: 16px } }"')
73+
expect(result.css).toEqual('@media (min-width: 500px) { .rule { font-size: 16px } }')
7474
})
7575

7676
it('when using regex at the time, the style should not be overwritten.', async () => {
@@ -79,7 +79,7 @@ describe('should all pass 😄', () => {
7979
})]).process(`.rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }`, {
8080
from: '/node_modules/main.css',
8181
})
82-
expect(result.css).toMatchInlineSnapshot('".rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }"')
82+
expect(result.css).toEqual('.rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }')
8383
})
8484

8585
it('when using regex at the time, the style should be overwritten.', async () => {
@@ -88,11 +88,11 @@ describe('should all pass 😄', () => {
8888
})]).process(`.rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }`, {
8989
from: '/example/main.css',
9090
})
91-
expect(result.css).toMatchInlineSnapshot('".rule { border: calc( 1 * (clamp(768px, 100vw, 2560px) / 1920) ) solid #000; font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); margin: calc( 1 * (clamp(768px, 100vw, 2560px) / 1920) ) calc( 10 * (clamp(768px, 100vw, 2560px) / 1920) ); }"')
91+
expect(result.css).toEqual('.rule { border: calc( 1 * (clamp(768px, 100vw, 2560px) / 1920) ) solid #000; font-size: calc( 16 * (clamp(768px, 100vw, 2560px) / 1920) ); margin: calc( 1 * (clamp(768px, 100vw, 2560px) / 1920) ) calc( 10 * (clamp(768px, 100vw, 2560px) / 1920) ); }')
9292
})
9393

9494
it('empty template', async () => {
9595
const result = await postcss([dynamicPixel()]).process(``)
96-
expect(result.css).toMatchInlineSnapshot('""')
96+
expect(result.css).toEqual('')
9797
})
9898
})

0 commit comments

Comments
 (0)