viewfx 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +21 -0
- package/README.es.md +111 -0
- package/README.md +111 -0
- package/package.json +57 -0
- package/src/compound.cjs +47 -0
- package/src/effects.cjs +232 -0
- package/src/engine.cjs +161 -0
- package/src/index.css +815 -0
- package/src/masks.cjs +99 -0
- package/src/masks.css +2 -0
- package/src/masks.js +97 -0
- package/src/mosaic.cjs +24 -0
- package/src/plugin.cjs +41 -0
- package/src/plugin.js +1 -0
- package/src/theme.json +43 -0
package/src/masks.cjs
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask shapes for the ViewFX Tailwind plugin.
|
|
3
|
+
*
|
|
4
|
+
* Declared as readable SVG and emitted as base64 custom properties
|
|
5
|
+
* (`pnpm emit:masks` → `src/masks.css`). Base64 matters: an SVG data URI
|
|
6
|
+
* containing a nested `url(#id)` filter reference breaks CSS minifiers
|
|
7
|
+
* when written literally into a stylesheet.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const svg = (viewBox, body) =>
|
|
11
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}">${body}</svg>`
|
|
12
|
+
|
|
13
|
+
const blur = (deviation) =>
|
|
14
|
+
`<defs><filter id="b"><feGaussianBlur stdDeviation="${deviation}"/></filter></defs>`
|
|
15
|
+
|
|
16
|
+
const MASK_SVG = {
|
|
17
|
+
circle: svg('0 0 40 40', '<circle cx="20" cy="20" r="20" fill="#fff"/>'),
|
|
18
|
+
|
|
19
|
+
'circle-blur': svg(
|
|
20
|
+
'0 0 40 40',
|
|
21
|
+
`${blur(2)}<circle cx="20" cy="20" r="18" fill="#fff" filter="url(#b)"/>`
|
|
22
|
+
),
|
|
23
|
+
|
|
24
|
+
'corner-tl': svg(
|
|
25
|
+
'0 0 40 40',
|
|
26
|
+
`${blur(0.6)}<circle cx="0" cy="0" r="40" fill="#fff" filter="url(#b)"/>`
|
|
27
|
+
),
|
|
28
|
+
|
|
29
|
+
'corner-tr': svg(
|
|
30
|
+
'0 0 40 40',
|
|
31
|
+
`${blur(0.6)}<circle cx="40" cy="0" r="40" fill="#fff" filter="url(#b)"/>`
|
|
32
|
+
),
|
|
33
|
+
|
|
34
|
+
'corner-bl': svg(
|
|
35
|
+
'0 0 40 40',
|
|
36
|
+
`${blur(0.6)}<circle cx="0" cy="40" r="40" fill="#fff" filter="url(#b)"/>`
|
|
37
|
+
),
|
|
38
|
+
|
|
39
|
+
'corner-br': svg(
|
|
40
|
+
'0 0 40 40',
|
|
41
|
+
`${blur(0.6)}<circle cx="40" cy="40" r="40" fill="#fff" filter="url(#b)"/>`
|
|
42
|
+
),
|
|
43
|
+
|
|
44
|
+
square: svg('0 0 40 40', '<rect width="40" height="40" fill="#fff"/>'),
|
|
45
|
+
|
|
46
|
+
soft: svg(
|
|
47
|
+
'0 0 40 40',
|
|
48
|
+
`${blur(1.4)}<ellipse cx="20" cy="20" rx="18" ry="16" fill="#fff" filter="url(#b)"/>`
|
|
49
|
+
),
|
|
50
|
+
|
|
51
|
+
diamond: svg('0 0 40 40', '<polygon points="20,0 40,20 20,40 0,20" fill="#fff"/>'),
|
|
52
|
+
|
|
53
|
+
hexagon: svg(
|
|
54
|
+
'0 0 100 100',
|
|
55
|
+
'<polygon points="50,0 93.3,25 93.3,75 50,100 6.7,75 6.7,25" fill="#fff"/>'
|
|
56
|
+
),
|
|
57
|
+
|
|
58
|
+
star: svg(
|
|
59
|
+
'0 0 100 100',
|
|
60
|
+
'<polygon points="50,0 61,35 95,35 68,57 79,91 50,70 21,91 32,57 5,35 39,35" fill="#fff"/>'
|
|
61
|
+
),
|
|
62
|
+
|
|
63
|
+
ink: svg(
|
|
64
|
+
'0 0 100 100',
|
|
65
|
+
'<defs><filter id="t">' +
|
|
66
|
+
'<feTurbulence type="fractalNoise" baseFrequency="0.045" numOctaves="4" result="n"/>' +
|
|
67
|
+
'<feDisplacementMap in="SourceGraphic" in2="n" scale="28" xChannelSelector="R" yChannelSelector="G"/>' +
|
|
68
|
+
'</filter></defs>' +
|
|
69
|
+
'<circle cx="50" cy="50" r="42" fill="#fff" filter="url(#t)"/>'
|
|
70
|
+
),
|
|
71
|
+
|
|
72
|
+
heart: svg(
|
|
73
|
+
'0 0 100 100',
|
|
74
|
+
'<path fill="#fff" d="M50 96C16 68 2 50 2 28 2 12 14 2 32 2c10 0 15 7 18 14 3-7 8-14 18-14 18 0 30 10 30 26 0 22-14 40-48 68Z"/>'
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function toBase64(markup) {
|
|
79
|
+
return Buffer.from(markup, 'utf8').toString('base64')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function maskVariables() {
|
|
83
|
+
const vars = {}
|
|
84
|
+
for (const [name, markup] of Object.entries(MASK_SVG)) {
|
|
85
|
+
vars[`--mask-${name}`] = `url("data:image/svg+xml;base64,${toBase64(markup)}")`
|
|
86
|
+
}
|
|
87
|
+
return vars
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** `:root` declaration block exposing every shape as `--mask-<name>`. */
|
|
91
|
+
function maskCustomProperties() {
|
|
92
|
+
const declarations = Object.entries(maskVariables())
|
|
93
|
+
.map(([name, value]) => `${name}:${value}`)
|
|
94
|
+
.join(';')
|
|
95
|
+
|
|
96
|
+
return `:root{${declarations}}`
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = { MASK_SVG, maskCustomProperties, maskVariables }
|
package/src/masks.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/* Generated by scripts/emit-masks.mjs — do not edit by hand. */
|
|
2
|
+
:root{--mask-circle:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iMjAiIGZpbGw9IiNmZmYiLz48L3N2Zz4=");--mask-circle-blur:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGRlZnM+PGZpbHRlciBpZD0iYiI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMiIvPjwvZmlsdGVyPjwvZGVmcz48Y2lyY2xlIGN4PSIyMCIgY3k9IjIwIiByPSIxOCIgZmlsbD0iI2ZmZiIgZmlsdGVyPSJ1cmwoI2IpIi8+PC9zdmc+");--mask-corner-tl:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGRlZnM+PGZpbHRlciBpZD0iYiI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC42Ii8+PC9maWx0ZXI+PC9kZWZzPjxjaXJjbGUgY3g9IjAiIGN5PSIwIiByPSI0MCIgZmlsbD0iI2ZmZiIgZmlsdGVyPSJ1cmwoI2IpIi8+PC9zdmc+");--mask-corner-tr:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGRlZnM+PGZpbHRlciBpZD0iYiI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC42Ii8+PC9maWx0ZXI+PC9kZWZzPjxjaXJjbGUgY3g9IjQwIiBjeT0iMCIgcj0iNDAiIGZpbGw9IiNmZmYiIGZpbHRlcj0idXJsKCNiKSIvPjwvc3ZnPg==");--mask-corner-bl:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGRlZnM+PGZpbHRlciBpZD0iYiI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC42Ii8+PC9maWx0ZXI+PC9kZWZzPjxjaXJjbGUgY3g9IjAiIGN5PSI0MCIgcj0iNDAiIGZpbGw9IiNmZmYiIGZpbHRlcj0idXJsKCNiKSIvPjwvc3ZnPg==");--mask-corner-br:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGRlZnM+PGZpbHRlciBpZD0iYiI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC42Ii8+PC9maWx0ZXI+PC9kZWZzPjxjaXJjbGUgY3g9IjQwIiBjeT0iNDAiIHI9IjQwIiBmaWxsPSIjZmZmIiBmaWx0ZXI9InVybCgjYikiLz48L3N2Zz4=");--mask-square:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHJlY3Qgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiBmaWxsPSIjZmZmIi8+PC9zdmc+");--mask-soft:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGRlZnM+PGZpbHRlciBpZD0iYiI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMS40Ii8+PC9maWx0ZXI+PC9kZWZzPjxlbGxpcHNlIGN4PSIyMCIgY3k9IjIwIiByeD0iMTgiIHJ5PSIxNiIgZmlsbD0iI2ZmZiIgZmlsdGVyPSJ1cmwoI2IpIi8+PC9zdmc+");--mask-diamond:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBvbHlnb24gcG9pbnRzPSIyMCwwIDQwLDIwIDIwLDQwIDAsMjAiIGZpbGw9IiNmZmYiLz48L3N2Zz4=");--mask-hexagon:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cG9seWdvbiBwb2ludHM9IjUwLDAgOTMuMywyNSA5My4zLDc1IDUwLDEwMCA2LjcsNzUgNi43LDI1IiBmaWxsPSIjZmZmIi8+PC9zdmc+");--mask-star:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cG9seWdvbiBwb2ludHM9IjUwLDAgNjEsMzUgOTUsMzUgNjgsNTcgNzksOTEgNTAsNzAgMjEsOTEgMzIsNTcgNSwzNSAzOSwzNSIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==");--mask-ink:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48ZmlsdGVyIGlkPSJ0Ij48ZmVUdXJidWxlbmNlIHR5cGU9ImZyYWN0YWxOb2lzZSIgYmFzZUZyZXF1ZW5jeT0iMC4wNDUiIG51bU9jdGF2ZXM9IjQiIHJlc3VsdD0ibiIvPjxmZURpc3BsYWNlbWVudE1hcCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJuIiBzY2FsZT0iMjgiIHhDaGFubmVsU2VsZWN0b3I9IlIiIHlDaGFubmVsU2VsZWN0b3I9IkciLz48L2ZpbHRlcj48L2RlZnM+PGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNDIiIGZpbGw9IiNmZmYiIGZpbHRlcj0idXJsKCN0KSIvPjwvc3ZnPg==");--mask-heart:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNTAgOTZDMTYgNjggMiA1MCAyIDI4IDIgMTIgMTQgMiAzMiAyYzEwIDAgMTUgNyAxOCAxNCAzLTcgOC0xNCAxOC0xNCAxOCAwIDMwIDEwIDMwIDI2IDAgMjItMTQgNDAtNDggNjhaIi8+PC9zdmc+")}
|
package/src/masks.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask shapes for the ViewFX Tailwind plugin.
|
|
3
|
+
*
|
|
4
|
+
* Declared as readable SVG and emitted as base64 custom properties
|
|
5
|
+
* (`pnpm emit:masks` → `src/masks.css`). Base64 matters: an SVG data URI
|
|
6
|
+
* containing a nested `url(#id)` filter reference breaks CSS minifiers
|
|
7
|
+
* when written literally into a stylesheet.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const svg = (viewBox, body) =>
|
|
11
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}">${body}</svg>`
|
|
12
|
+
|
|
13
|
+
const blur = (deviation) =>
|
|
14
|
+
`<defs><filter id="b"><feGaussianBlur stdDeviation="${deviation}"/></filter></defs>`
|
|
15
|
+
|
|
16
|
+
export const MASK_SVG = {
|
|
17
|
+
circle: svg('0 0 40 40', '<circle cx="20" cy="20" r="20" fill="#fff"/>'),
|
|
18
|
+
|
|
19
|
+
'circle-blur': svg(
|
|
20
|
+
'0 0 40 40',
|
|
21
|
+
`${blur(2)}<circle cx="20" cy="20" r="18" fill="#fff" filter="url(#b)"/>`
|
|
22
|
+
),
|
|
23
|
+
|
|
24
|
+
'corner-tl': svg(
|
|
25
|
+
'0 0 40 40',
|
|
26
|
+
`${blur(0.6)}<circle cx="0" cy="0" r="40" fill="#fff" filter="url(#b)"/>`
|
|
27
|
+
),
|
|
28
|
+
|
|
29
|
+
'corner-tr': svg(
|
|
30
|
+
'0 0 40 40',
|
|
31
|
+
`${blur(0.6)}<circle cx="40" cy="0" r="40" fill="#fff" filter="url(#b)"/>`
|
|
32
|
+
),
|
|
33
|
+
|
|
34
|
+
'corner-bl': svg(
|
|
35
|
+
'0 0 40 40',
|
|
36
|
+
`${blur(0.6)}<circle cx="0" cy="40" r="40" fill="#fff" filter="url(#b)"/>`
|
|
37
|
+
),
|
|
38
|
+
|
|
39
|
+
'corner-br': svg(
|
|
40
|
+
'0 0 40 40',
|
|
41
|
+
`${blur(0.6)}<circle cx="40" cy="40" r="40" fill="#fff" filter="url(#b)"/>`
|
|
42
|
+
),
|
|
43
|
+
|
|
44
|
+
square: svg('0 0 40 40', '<rect width="40" height="40" fill="#fff"/>'),
|
|
45
|
+
|
|
46
|
+
soft: svg(
|
|
47
|
+
'0 0 40 40',
|
|
48
|
+
`${blur(1.4)}<ellipse cx="20" cy="20" rx="18" ry="16" fill="#fff" filter="url(#b)"/>`
|
|
49
|
+
),
|
|
50
|
+
|
|
51
|
+
diamond: svg('0 0 40 40', '<polygon points="20,0 40,20 20,40 0,20" fill="#fff"/>'),
|
|
52
|
+
|
|
53
|
+
hexagon: svg(
|
|
54
|
+
'0 0 100 100',
|
|
55
|
+
'<polygon points="50,0 93.3,25 93.3,75 50,100 6.7,75 6.7,25" fill="#fff"/>'
|
|
56
|
+
),
|
|
57
|
+
|
|
58
|
+
star: svg(
|
|
59
|
+
'0 0 100 100',
|
|
60
|
+
'<polygon points="50,0 61,35 95,35 68,57 79,91 50,70 21,91 32,57 5,35 39,35" fill="#fff"/>'
|
|
61
|
+
),
|
|
62
|
+
|
|
63
|
+
ink: svg(
|
|
64
|
+
'0 0 100 100',
|
|
65
|
+
'<defs><filter id="t">' +
|
|
66
|
+
'<feTurbulence type="fractalNoise" baseFrequency="0.045" numOctaves="4" result="n"/>' +
|
|
67
|
+
'<feDisplacementMap in="SourceGraphic" in2="n" scale="28" xChannelSelector="R" yChannelSelector="G"/>' +
|
|
68
|
+
'</filter></defs>' +
|
|
69
|
+
'<circle cx="50" cy="50" r="42" fill="#fff" filter="url(#t)"/>'
|
|
70
|
+
),
|
|
71
|
+
|
|
72
|
+
heart: svg(
|
|
73
|
+
'0 0 100 100',
|
|
74
|
+
'<path fill="#fff" d="M50 96C16 68 2 50 2 28 2 12 14 2 32 2c10 0 15 7 18 14 3-7 8-14 18-14 18 0 30 10 30 26 0 22-14 40-48 68Z"/>'
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function toBase64(markup) {
|
|
79
|
+
return Buffer.from(markup, 'utf8').toString('base64')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function maskVariables() {
|
|
83
|
+
const vars = {}
|
|
84
|
+
for (const [name, markup] of Object.entries(MASK_SVG)) {
|
|
85
|
+
vars[`--mask-${name}`] = `url("data:image/svg+xml;base64,${toBase64(markup)}")`
|
|
86
|
+
}
|
|
87
|
+
return vars
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** `:root` declaration block exposing every shape as `--mask-<name>`. */
|
|
91
|
+
export function maskCustomProperties() {
|
|
92
|
+
const declarations = Object.entries(maskVariables())
|
|
93
|
+
.map(([name, value]) => `${name}:${value}`)
|
|
94
|
+
.join(';')
|
|
95
|
+
|
|
96
|
+
return `:root{${declarations}}`
|
|
97
|
+
}
|
package/src/mosaic.cjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** 8×8 lattice. Tiles bloom from each cell with a feathered edge. */
|
|
2
|
+
const PERIOD = '12.5%'
|
|
3
|
+
const CENTER = '6.25%'
|
|
4
|
+
const GROW = '8%'
|
|
5
|
+
const CORE = '6.6%'
|
|
6
|
+
|
|
7
|
+
const mosaicStripe = (axis) =>
|
|
8
|
+
`repeating-linear-gradient(${axis}#0000 0,#0000 calc(${CENTER} - var(--fx-mosaic) * ${GROW}),#fff calc(${CENTER} - var(--fx-mosaic) * ${CORE}),#fff calc(${CENTER} + var(--fx-mosaic) * ${CORE}),#0000 calc(${CENTER} + var(--fx-mosaic) * ${GROW}),#0000 ${PERIOD})`
|
|
9
|
+
|
|
10
|
+
const mosaicMaskImage = `${mosaicStripe('')},${mosaicStripe('90deg,')}`
|
|
11
|
+
|
|
12
|
+
const mosaicNewRoot = {
|
|
13
|
+
mask: 'none',
|
|
14
|
+
maskImage: mosaicMaskImage,
|
|
15
|
+
WebkitMaskImage: mosaicMaskImage,
|
|
16
|
+
maskSize: '100% 100%',
|
|
17
|
+
WebkitMaskSize: '100% 100%',
|
|
18
|
+
maskRepeat: 'no-repeat',
|
|
19
|
+
WebkitMaskRepeat: 'no-repeat',
|
|
20
|
+
maskComposite: 'intersect',
|
|
21
|
+
WebkitMaskComposite: 'source-in'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = { mosaicMaskImage, mosaicNewRoot }
|
package/src/plugin.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const plugin = require('tailwindcss/plugin')
|
|
2
|
+
const { engineBase } = require('./engine.cjs')
|
|
3
|
+
const effects = require('./effects.cjs')
|
|
4
|
+
const { registerCompound } = require('./compound.cjs')
|
|
5
|
+
const { duration, delay, steps } = require('./theme.json')
|
|
6
|
+
|
|
7
|
+
module.exports = plugin(
|
|
8
|
+
function viewfx({ addBase, addUtilities, matchUtilities, theme }) {
|
|
9
|
+
addBase(engineBase())
|
|
10
|
+
addUtilities(effects)
|
|
11
|
+
registerCompound({ matchUtilities })
|
|
12
|
+
|
|
13
|
+
matchUtilities(
|
|
14
|
+
{
|
|
15
|
+
'fx-duration': (value) => ({ '--fx-duration-override': value })
|
|
16
|
+
},
|
|
17
|
+
{ values: theme('fxDuration') }
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
matchUtilities(
|
|
21
|
+
{
|
|
22
|
+
'fx-delay': (value) => ({ '--fx-delay': value })
|
|
23
|
+
},
|
|
24
|
+
{ values: theme('fxDelay') }
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
matchUtilities(
|
|
28
|
+
{
|
|
29
|
+
'fx-steps': (value) => ({ '--fx-ease-override': `steps(${value})` })
|
|
30
|
+
},
|
|
31
|
+
{ values: theme('fxSteps') }
|
|
32
|
+
)
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
theme: {
|
|
36
|
+
fxDuration: duration,
|
|
37
|
+
fxDelay: delay,
|
|
38
|
+
fxSteps: steps
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
)
|
package/src/plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './plugin.cjs'
|
package/src/theme.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"duration": {
|
|
3
|
+
"none": "0ms",
|
|
4
|
+
"slower": "500ms",
|
|
5
|
+
"slow": "400ms",
|
|
6
|
+
"normal": "300ms",
|
|
7
|
+
"fast": "200ms",
|
|
8
|
+
"faster": "100ms",
|
|
9
|
+
"0": "0ms",
|
|
10
|
+
"100": "100ms",
|
|
11
|
+
"150": "150ms",
|
|
12
|
+
"200": "200ms",
|
|
13
|
+
"250": "250ms",
|
|
14
|
+
"300": "300ms",
|
|
15
|
+
"400": "400ms",
|
|
16
|
+
"500": "500ms",
|
|
17
|
+
"700": "700ms",
|
|
18
|
+
"800": "800ms",
|
|
19
|
+
"900": "900ms",
|
|
20
|
+
"1000": "1000ms"
|
|
21
|
+
},
|
|
22
|
+
"delay": {
|
|
23
|
+
"none": "0ms",
|
|
24
|
+
"0": "0ms",
|
|
25
|
+
"100": "100ms",
|
|
26
|
+
"150": "150ms",
|
|
27
|
+
"200": "200ms",
|
|
28
|
+
"250": "250ms",
|
|
29
|
+
"300": "300ms",
|
|
30
|
+
"400": "400ms",
|
|
31
|
+
"500": "500ms",
|
|
32
|
+
"700": "700ms",
|
|
33
|
+
"800": "800ms",
|
|
34
|
+
"900": "900ms",
|
|
35
|
+
"1000": "1000ms"
|
|
36
|
+
},
|
|
37
|
+
"steps": {
|
|
38
|
+
"none": "0",
|
|
39
|
+
"retro": "8",
|
|
40
|
+
"normal": "16",
|
|
41
|
+
"modern": "24"
|
|
42
|
+
}
|
|
43
|
+
}
|