tailwind-clamp 1.0.0 → 2.0.0
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/README.md +33 -78
- package/package.json +7 -5
- package/src/clamp.js +57 -0
- package/src/index.js +71 -267
- package/src/log.js +16 -0
- package/src/parse-value.js +66 -0
- package/src/resolve-property.js +302 -0
- package/src/utils.js +0 -82
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tailwind clamp
|
|
2
2
|
|
|
3
|
-
Tailwind CSS
|
|
3
|
+
Tailwind CSS plugin to use CSS `clamp` in your project. Enabling fluid interfaces using Tailwind syntax.
|
|
4
4
|
|
|
5
5
|
The plugin is based on the formula presented in this [article](https://chriskirknielsen.com/blog/modern-fluid-typography-with-clamp/)
|
|
6
6
|
|
|
@@ -8,9 +8,9 @@ The plugin is based on the formula presented in this [article](https://chriskirk
|
|
|
8
8
|
|
|
9
9
|
- Clamp values between a min and max viewport width, making it grow / shrink with the viewport.
|
|
10
10
|
- Possibility to use small to large, large to small, negative to positive, positive to negative and negative to negative values. (Negative values only work on properties that allow them, e.g. `margin`)
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
11
|
+
- Supports `px`, `rem` and `em` units.
|
|
12
|
+
- Support `text` values with multiple properties (`fontSize`, `lineHeight`, `letterSpacing`).
|
|
13
|
+
- Support using defined in the Tailwind CSS configuration file, arbitrary values or a combination.
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
@@ -20,107 +20,63 @@ Install the plugin from npm:
|
|
|
20
20
|
npm install nicolas-cusan/tailwind-clamp
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
### Predefine values in your config
|
|
26
|
-
|
|
27
|
-
The package provides two helper functions to help you define "clamped" values in your config:
|
|
28
|
-
|
|
29
|
-
#### `clamp(start, end, [minViewportWidth=375, maxViewportWidth=1440])`
|
|
30
|
-
|
|
31
|
-
##### Arguments
|
|
32
|
-
|
|
33
|
-
- `start` `{number}`: Value at `minViewportWidth` viewport size. The value is interpreted as pixels and outputted as `rem` in the generated CSS.
|
|
34
|
-
- `end` `{number}`: Value at `maxViewportWidth` viewport size. The value is interpreted as pixels and outputted as `rem` in the generated CSS.
|
|
35
|
-
- `[minViewportWidth=375]` `{number}`: Viewport size, where the clamp starts, defaults to `375`. The value is interpreted as pixels. Value should be smaller than `maxViewportWidth`.
|
|
36
|
-
- `[maxViewportWidth=1440]` `{number}`: Viewport size, where the clamp stops, defaults to `1440` The value is interpreted as pixels. Value should be smaller than `minViewportWidth`.
|
|
37
|
-
|
|
38
|
-
#### `clampFs(start, end, [tracking=null, minViewportWidth=375, maxViewportWidth=1440])`
|
|
39
|
-
|
|
40
|
-
##### Arguments
|
|
41
|
-
|
|
42
|
-
- `start` `{[fontSize: number, lineHeight: number]}`: Array of two numbers: `font-size` and `line-height` respectively at `minViewportWidth` viewport size. Both values are interpreted as pixels and outputted as `rem` in the generated CSS.
|
|
43
|
-
- `end` `{[fontSize: number, lineHeight: number]}`: Array of two numbers: `font-size` and `line-height` respectively at `maxViewportWidth` viewport size. Both values are interpreted as pixels and outputted as `rem` in the generated CSS.
|
|
44
|
-
- `[tracking=null]` `{string|null}`: `letter-spacing` setting, it is recommended to use the `em` unit as it proportional to the font size, e.g. `-0.01em`
|
|
45
|
-
- `[minViewportWidth=375]` `{number}`: Viewport size, where the clamp starts, defaults to `375`. The value is interpreted as pixels. Value should be smaller than `maxViewportWidth`.
|
|
46
|
-
- `[maxViewportWidth=1440]` `{number}`: Viewport size, where the clamp stops, defaults to `1440` The value is interpreted as pixels. Value should be smaller than `minViewportWidth`.
|
|
23
|
+
Add the plugin in your Tailwind CSS configuration file:
|
|
47
24
|
|
|
48
25
|
```js
|
|
49
26
|
// tailwind.config.js
|
|
50
|
-
const { setupClamp } = require('../src/utils.js');
|
|
51
|
-
|
|
52
|
-
const clampOptions = {
|
|
53
|
-
minViewportWidth: 375,
|
|
54
|
-
maxViewportWidth: 1440,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// Setup the clamp helper functions with the default min and max viewport sizes you want to use
|
|
58
|
-
const { clamp, clampFs } = setupClamp(options);
|
|
59
|
-
|
|
60
27
|
module.exports = {
|
|
61
28
|
theme: {
|
|
62
29
|
// ...
|
|
63
|
-
extend: {
|
|
64
|
-
spacing: {
|
|
65
|
-
// Use
|
|
66
|
-
grid: clamp(10, 20),
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
fontSize: {
|
|
70
|
-
base: clampFs([16, 20], [24, 28], '-0.01em'),
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
30
|
},
|
|
74
|
-
|
|
31
|
+
plugins: [
|
|
32
|
+
require('tailwind-clamp'),
|
|
33
|
+
// ...
|
|
34
|
+
],
|
|
75
35
|
};
|
|
76
36
|
```
|
|
77
37
|
|
|
78
|
-
###
|
|
38
|
+
### Configuration
|
|
79
39
|
|
|
80
|
-
The
|
|
40
|
+
The plugin allows two configuration options:
|
|
41
|
+
|
|
42
|
+
| Name | Description | Default value |
|
|
43
|
+
| ------------------ | ------------------------------------ | ------------- |
|
|
44
|
+
| `minViewportWidth` | Viewport size where the clamp starts | `375` |
|
|
45
|
+
| `maxViewportWidth` | Viewport size where the clamp end | `1440` |
|
|
81
46
|
|
|
82
47
|
```js
|
|
83
48
|
// tailwind.config.js
|
|
84
|
-
const clampOptions = {
|
|
85
|
-
minViewportWidth: 375,
|
|
86
|
-
maxViewportWidth: 1440,
|
|
87
|
-
};
|
|
88
|
-
|
|
89
49
|
module.exports = {
|
|
90
50
|
theme: {
|
|
91
51
|
// ...
|
|
92
52
|
},
|
|
93
53
|
plugins: [
|
|
94
|
-
require('tailwind-clamp')(
|
|
54
|
+
require('tailwind-clamp')({
|
|
55
|
+
minViewportWidth: 375,
|
|
56
|
+
maxViewportWidth: 1440,
|
|
57
|
+
}),
|
|
95
58
|
// ...
|
|
96
59
|
],
|
|
97
60
|
};
|
|
98
61
|
```
|
|
99
62
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
This plugin allows two configuration options:
|
|
103
|
-
|
|
104
|
-
| Name | Description | Default value |
|
|
105
|
-
| ------------------ | ------------------------------------ | ------------- |
|
|
106
|
-
| `minViewportWidth` | Viewport size where the clamp starts | `375` |
|
|
107
|
-
| `maxViewportWidth` | Viewport size where the clamp end | `1440` |
|
|
108
|
-
|
|
109
|
-
#### Using the plugin
|
|
63
|
+
## Usage
|
|
110
64
|
|
|
111
|
-
The arbitrary values syntax
|
|
65
|
+
The plugin relies on the arbitrary values syntax `clamp-[...]`. You need to pass at least three arguments separated by commas without whitespace, optionally you can also pass the `minViewportWidth` and the `maxViewportWidth`:
|
|
112
66
|
|
|
113
|
-
|
|
67
|
+
```
|
|
68
|
+
clamp-[<property>,<start>,<end>,[minViewportWidth,maxViewportWidth]]
|
|
69
|
+
```
|
|
114
70
|
|
|
115
|
-
|
|
71
|
+
### Arguments
|
|
116
72
|
|
|
117
|
-
- `property
|
|
118
|
-
- `start
|
|
119
|
-
- `end
|
|
120
|
-
- `[minViewportWidth=375]
|
|
121
|
-
- `[maxViewportWidth=1440]
|
|
73
|
+
- `property`: Property that the value should be applied to. See a list of all supported properties below.
|
|
74
|
+
- `start`: Value at `minViewportWidth` viewport size. It can be a key from your Tailwind CSS config file, a css value (`px`, `rem`, `em`) or a number (unit will be `px`), the unit will need to match `end`.
|
|
75
|
+
- `end`: Value at `maxViewportWidth` viewport size. It can be a key from your Tailwind CSS config file, a css value (`px`, `rem`, `em`) or a number (unit will be `px`), the unit will need to match `start`.
|
|
76
|
+
- `[minViewportWidth=375]`: Viewport size, where the clamp starts, defaults to `375`. Can be a key from `screens` a css value (`px`, `rem`, `em`) or a number (unit will be `px`), the unit will need to match `maxViewportWidth`. Value needs be smaller than `maxViewportWidth`.
|
|
77
|
+
- `[maxViewportWidth=1440]`: Viewport size, where the clamp stops, defaults to `1440`. Can be a key from `screens` a css value (`px`, `rem`, `em`) or a number (unit will be `px`), the unit will need to match `minViewportWidth`. Value needs to be larger than `minViewportWidth`.
|
|
122
78
|
|
|
123
|
-
|
|
79
|
+
### Examples
|
|
124
80
|
|
|
125
81
|
```html
|
|
126
82
|
<div class="clamp-[px,20,40] clamp-[py,10,18]">
|
|
@@ -137,7 +93,7 @@ The arbitrary values syntax for clamp requires at least three arguments separate
|
|
|
137
93
|
- `left`
|
|
138
94
|
- `right`
|
|
139
95
|
- `bottom`
|
|
140
|
-
- `text`
|
|
96
|
+
- `text` including `font-size`, `line-height` and `letter-spacing` if defined.
|
|
141
97
|
- `gap` including `gap-x`, `gap-y`.
|
|
142
98
|
- `w`
|
|
143
99
|
- `h`
|
|
@@ -157,6 +113,5 @@ The arbitrary values syntax for clamp requires at least three arguments separate
|
|
|
157
113
|
|
|
158
114
|
## Roadmap
|
|
159
115
|
|
|
160
|
-
- Support other units e.g `%`
|
|
161
116
|
- Support directional properties e.g. `ps`
|
|
162
117
|
- Add showcase
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwind-clamp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Tailwind CSS plugin to use CSS clamp in your projects",
|
|
5
5
|
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"dev": "next dev demo",
|
|
8
9
|
"build": "next build demo",
|
|
@@ -25,13 +26,14 @@
|
|
|
25
26
|
},
|
|
26
27
|
"homepage": "https://github.com/nicolas-cusan/tailwind-clamp#readme",
|
|
27
28
|
"dependencies": {
|
|
29
|
+
"chalk": "^5.3.0",
|
|
30
|
+
"next": "14.2.4",
|
|
28
31
|
"react": "^18",
|
|
29
|
-
"react-dom": "^18"
|
|
30
|
-
"next": "14.1.4"
|
|
32
|
+
"react-dom": "^18"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
|
-
"autoprefixer": "^10.
|
|
35
|
+
"autoprefixer": "^10.4.19",
|
|
34
36
|
"postcss": "^8",
|
|
35
|
-
"tailwindcss": "^3.
|
|
37
|
+
"tailwindcss": "^3.4.4"
|
|
36
38
|
}
|
|
37
39
|
}
|
package/src/clamp.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// https://chriskirknielsen.com/blog/modern-fluid-typography-with-clamp/
|
|
2
|
+
|
|
3
|
+
export const clamp = (
|
|
4
|
+
_start,
|
|
5
|
+
_end,
|
|
6
|
+
_minvw = { number: 375, unit: 'px' },
|
|
7
|
+
_maxvw = { number: 1440, unit: 'px' }
|
|
8
|
+
) => {
|
|
9
|
+
const unit = _start.unit;
|
|
10
|
+
const isPx = unit === 'px';
|
|
11
|
+
|
|
12
|
+
let start = _start.number;
|
|
13
|
+
let end = _end.number;
|
|
14
|
+
let negative = false;
|
|
15
|
+
|
|
16
|
+
let minvw = _minvw.number;
|
|
17
|
+
let maxvw = _maxvw.number;
|
|
18
|
+
|
|
19
|
+
if (_minvw.unit !== 'px' && isPx) {
|
|
20
|
+
minvw = _minvw.number * 16;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (_minvw.unit === 'px' && !isPx) {
|
|
24
|
+
minvw = _minvw.number / 16;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (_maxvw.unit !== 'px' && isPx) {
|
|
28
|
+
maxvw = _maxvw.number * 16;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (_maxvw.unit === 'px' && !isPx) {
|
|
32
|
+
maxvw = _maxvw.number / 16;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (end < start && start < 0 && end < 0) {
|
|
36
|
+
start = Math.abs(start);
|
|
37
|
+
end = Math.abs(end);
|
|
38
|
+
negative = true;
|
|
39
|
+
} else if (end < start && start > 0 && end > 0) {
|
|
40
|
+
start = start * -1;
|
|
41
|
+
end = end * -1;
|
|
42
|
+
negative = true;
|
|
43
|
+
} else if (end < start) {
|
|
44
|
+
start = Math.abs(start) * -1;
|
|
45
|
+
end = Math.abs(end);
|
|
46
|
+
negative = true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const slope = (end - start) / (maxvw - minvw);
|
|
50
|
+
const calc = `${(start - minvw * slope).toFixed(6)}${unit} + ${(
|
|
51
|
+
100 * slope
|
|
52
|
+
).toFixed(6)}vw`;
|
|
53
|
+
|
|
54
|
+
const value = `clamp(${start}${unit}, ${calc}, ${end}${unit})`;
|
|
55
|
+
|
|
56
|
+
return negative ? `calc(${value} * -1)` : value;
|
|
57
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,288 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import plugin from 'tailwindcss/plugin';
|
|
2
|
+
import { resolveProperty } from './resolve-property.js';
|
|
3
|
+
import { log } from './log.js';
|
|
4
|
+
import { parseValue, parseFontSizeValue, checkValues } from './parse-value.js';
|
|
5
|
+
import { clamp } from './clamp.js';
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
'translate(var(--tw-translate-x), var(--tw-translate-y))',
|
|
6
|
-
'rotate(var(--tw-rotate))',
|
|
7
|
-
'skewX(var(--tw-skew-x))',
|
|
8
|
-
'skewY(var(--tw-skew-y))',
|
|
9
|
-
'scaleX(var(--tw-scale-x))',
|
|
10
|
-
'scaleY(var(--tw-scale-y))',
|
|
11
|
-
].join(' ');
|
|
12
|
-
|
|
13
|
-
function resolveProperty(property, value) {
|
|
14
|
-
switch (property) {
|
|
15
|
-
case 'p':
|
|
16
|
-
return {
|
|
17
|
-
padding: value,
|
|
18
|
-
};
|
|
19
|
-
case 'pt':
|
|
20
|
-
return {
|
|
21
|
-
paddingTop: value,
|
|
22
|
-
};
|
|
23
|
-
case 'pb':
|
|
24
|
-
return {
|
|
25
|
-
paddingBottom: value,
|
|
26
|
-
};
|
|
27
|
-
case 'pl':
|
|
28
|
-
return {
|
|
29
|
-
paddingLeft: value,
|
|
30
|
-
};
|
|
31
|
-
case 'pr':
|
|
32
|
-
return {
|
|
33
|
-
paddingRight: value,
|
|
34
|
-
};
|
|
35
|
-
case 'px':
|
|
36
|
-
return {
|
|
37
|
-
paddingLeft: value,
|
|
38
|
-
paddingRight: value,
|
|
39
|
-
};
|
|
40
|
-
case 'py':
|
|
41
|
-
return {
|
|
42
|
-
paddingTop: value,
|
|
43
|
-
paddingBottom: value,
|
|
44
|
-
};
|
|
45
|
-
case 'm':
|
|
46
|
-
return {
|
|
47
|
-
margin: value,
|
|
48
|
-
};
|
|
49
|
-
case 'mt':
|
|
50
|
-
return {
|
|
51
|
-
marginTop: value,
|
|
52
|
-
};
|
|
53
|
-
case 'mb':
|
|
54
|
-
return {
|
|
55
|
-
marginBottom: value,
|
|
56
|
-
};
|
|
57
|
-
case 'ml':
|
|
58
|
-
return {
|
|
59
|
-
marginLeft: value,
|
|
60
|
-
};
|
|
61
|
-
case 'mr':
|
|
62
|
-
return {
|
|
63
|
-
marginRight: value,
|
|
64
|
-
};
|
|
65
|
-
case 'mx':
|
|
66
|
-
return {
|
|
67
|
-
marginLeft: value,
|
|
68
|
-
marginRight: value,
|
|
69
|
-
};
|
|
70
|
-
case 'my':
|
|
71
|
-
return {
|
|
72
|
-
marginTop: value,
|
|
73
|
-
marginBottom: value,
|
|
74
|
-
};
|
|
75
|
-
case 'inset':
|
|
76
|
-
return {
|
|
77
|
-
top: value,
|
|
78
|
-
left: value,
|
|
79
|
-
right: value,
|
|
80
|
-
bottom: value,
|
|
81
|
-
};
|
|
82
|
-
case 'top':
|
|
83
|
-
return {
|
|
84
|
-
top: value,
|
|
85
|
-
};
|
|
86
|
-
case 'left':
|
|
87
|
-
return {
|
|
88
|
-
left: value,
|
|
89
|
-
};
|
|
90
|
-
case 'right':
|
|
91
|
-
return {
|
|
92
|
-
right: value,
|
|
93
|
-
};
|
|
94
|
-
case 'bottom':
|
|
95
|
-
return {
|
|
96
|
-
bottom: value,
|
|
97
|
-
};
|
|
98
|
-
case 'text':
|
|
99
|
-
return {
|
|
100
|
-
fontSize: value,
|
|
101
|
-
};
|
|
102
|
-
case 'gap':
|
|
103
|
-
return {
|
|
104
|
-
gap: value,
|
|
105
|
-
};
|
|
106
|
-
case 'gap-x':
|
|
107
|
-
return {
|
|
108
|
-
columnGap: value,
|
|
109
|
-
};
|
|
110
|
-
case 'gap-y':
|
|
111
|
-
return {
|
|
112
|
-
rowGap: value,
|
|
113
|
-
};
|
|
114
|
-
case 'w':
|
|
115
|
-
return {
|
|
116
|
-
width: value,
|
|
117
|
-
};
|
|
118
|
-
case 'h':
|
|
119
|
-
return {
|
|
120
|
-
height: value,
|
|
121
|
-
};
|
|
122
|
-
case 'size':
|
|
123
|
-
return {
|
|
124
|
-
width: value,
|
|
125
|
-
height: value,
|
|
126
|
-
};
|
|
127
|
-
case 'min-w':
|
|
128
|
-
return {
|
|
129
|
-
minWidth: value,
|
|
130
|
-
};
|
|
131
|
-
case 'min-h':
|
|
132
|
-
return {
|
|
133
|
-
minHeight: value,
|
|
134
|
-
};
|
|
135
|
-
case 'max-w':
|
|
136
|
-
return {
|
|
137
|
-
maxWidth: value,
|
|
138
|
-
};
|
|
139
|
-
case 'max-h':
|
|
140
|
-
return {
|
|
141
|
-
maxHeight: value,
|
|
142
|
-
};
|
|
143
|
-
case 'rounded':
|
|
144
|
-
return {
|
|
145
|
-
borderRadius: value,
|
|
146
|
-
};
|
|
147
|
-
case 'rounded-t':
|
|
148
|
-
return {
|
|
149
|
-
borderTopLeftRadius: value,
|
|
150
|
-
borderTopRightRadius: value,
|
|
151
|
-
};
|
|
152
|
-
case 'rounded-r':
|
|
153
|
-
return {
|
|
154
|
-
borderTopRightRadius: value,
|
|
155
|
-
borderBottomRightRadius: value,
|
|
156
|
-
};
|
|
157
|
-
case 'rounded-b':
|
|
158
|
-
return {
|
|
159
|
-
borderBottomLeftRadius: value,
|
|
160
|
-
borderBottomRightRadius: value,
|
|
161
|
-
};
|
|
162
|
-
case 'rounded-l':
|
|
163
|
-
return {
|
|
164
|
-
borderTopLeftRadius: value,
|
|
165
|
-
borderBottomLeftRadius: value,
|
|
166
|
-
};
|
|
167
|
-
case 'rounded-tl':
|
|
168
|
-
return {
|
|
169
|
-
borderTopLeftRadius: value,
|
|
170
|
-
};
|
|
171
|
-
case 'rounded-tr':
|
|
172
|
-
return {
|
|
173
|
-
borderTopRightRadius: value,
|
|
174
|
-
};
|
|
175
|
-
case 'rounded-bl':
|
|
176
|
-
return {
|
|
177
|
-
borderBottomLeftRadius: value,
|
|
178
|
-
};
|
|
179
|
-
case 'rounded-br':
|
|
180
|
-
return {
|
|
181
|
-
borderBottomRightRadius: value,
|
|
182
|
-
};
|
|
183
|
-
case 'translate-x':
|
|
184
|
-
return {
|
|
185
|
-
'--tw-translate-x': value,
|
|
186
|
-
'@defaults transform': {},
|
|
187
|
-
transform: cssTransformValue,
|
|
188
|
-
};
|
|
189
|
-
case 'translate-y':
|
|
190
|
-
return {
|
|
191
|
-
'--tw-translate-y': value,
|
|
192
|
-
'@defaults transform': {},
|
|
193
|
-
transform: cssTransformValue,
|
|
194
|
-
};
|
|
195
|
-
case 'text-stroke':
|
|
196
|
-
return {
|
|
197
|
-
'-webkit-text-stroke': value,
|
|
198
|
-
textStroke: value,
|
|
199
|
-
};
|
|
200
|
-
case 'stroke':
|
|
201
|
-
return {
|
|
202
|
-
strokeWidth: value,
|
|
203
|
-
};
|
|
204
|
-
case 'leading':
|
|
205
|
-
return {
|
|
206
|
-
lineHeight: value,
|
|
207
|
-
};
|
|
208
|
-
case 'border':
|
|
209
|
-
return {
|
|
210
|
-
borderWidth: value,
|
|
211
|
-
};
|
|
212
|
-
case 'border-t':
|
|
213
|
-
return {
|
|
214
|
-
borderTopWidth: value,
|
|
215
|
-
};
|
|
216
|
-
case 'border-b':
|
|
217
|
-
return {
|
|
218
|
-
borderBottomWidth: value,
|
|
219
|
-
};
|
|
220
|
-
case 'border-l':
|
|
221
|
-
return {
|
|
222
|
-
borderLeftWidth: value,
|
|
223
|
-
};
|
|
224
|
-
case 'border-r':
|
|
225
|
-
return {
|
|
226
|
-
borderRightWidth: value,
|
|
227
|
-
};
|
|
228
|
-
case 'border-x':
|
|
229
|
-
return {
|
|
230
|
-
borderLeftWidth: value,
|
|
231
|
-
borderRightWidth: value,
|
|
232
|
-
};
|
|
233
|
-
case 'border-y':
|
|
234
|
-
return {
|
|
235
|
-
borderTopWidth: value,
|
|
236
|
-
borderBottomWidth: value,
|
|
237
|
-
};
|
|
238
|
-
case 'scroll-m':
|
|
239
|
-
return {
|
|
240
|
-
scrollMargin: value,
|
|
241
|
-
};
|
|
242
|
-
default:
|
|
243
|
-
return null;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
module.exports = plugin.withOptions(function (
|
|
7
|
+
export default plugin.withOptions(function (
|
|
248
8
|
options = {
|
|
249
9
|
minViewportWidth: 375,
|
|
250
10
|
maxViewportWidth: 1440,
|
|
251
11
|
}
|
|
252
12
|
) {
|
|
253
|
-
return function ({ matchUtilities, theme }) {
|
|
13
|
+
return function ({ matchUtilities, theme, config }) {
|
|
254
14
|
matchUtilities(
|
|
255
15
|
{
|
|
256
16
|
clamp: (value) => {
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
17
|
+
const args = value.split(',');
|
|
18
|
+
|
|
19
|
+
const minvw = parseValue(
|
|
20
|
+
config().theme.screens[args[3]] ||
|
|
21
|
+
args[3] ||
|
|
22
|
+
`${options.minViewportWidth}`
|
|
23
|
+
);
|
|
260
24
|
|
|
261
|
-
|
|
262
|
-
|
|
25
|
+
const maxvw = parseValue(
|
|
26
|
+
config().theme.screens[args[4]] ||
|
|
27
|
+
args[4] ||
|
|
28
|
+
`${options.maxViewportWidth}`
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (args.length < 3) {
|
|
32
|
+
log.error(
|
|
33
|
+
`The clamp utility requires at least 3 arguments: "clamp-[${value}]".`
|
|
34
|
+
);
|
|
35
|
+
return null;
|
|
263
36
|
}
|
|
264
37
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
38
|
+
const resolvedProp = resolveProperty(args[0]);
|
|
39
|
+
|
|
40
|
+
if (!resolvedProp) {
|
|
41
|
+
log.error(
|
|
42
|
+
`Property "${args[0]}" is not supported: "clamp-[${value}]".`
|
|
268
43
|
);
|
|
44
|
+
return null;
|
|
269
45
|
}
|
|
270
46
|
|
|
271
|
-
const
|
|
272
|
-
props[0],
|
|
273
|
-
clamp(
|
|
274
|
-
props[1],
|
|
275
|
-
props[2],
|
|
276
|
-
props[3] || options.minViewportWidth,
|
|
277
|
-
props[4] || options.maxViewportWidth
|
|
278
|
-
)
|
|
279
|
-
);
|
|
47
|
+
const { key, props } = resolvedProp;
|
|
280
48
|
|
|
281
|
-
|
|
282
|
-
|
|
49
|
+
// handle fontSize separately
|
|
50
|
+
if (key === 'fontSize') {
|
|
51
|
+
const start = parseFontSizeValue(
|
|
52
|
+
config().theme[key][args[1]] || args[1]
|
|
53
|
+
);
|
|
54
|
+
const end = parseFontSizeValue(
|
|
55
|
+
config().theme[key][args[2]] || args[2]
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const css = {};
|
|
59
|
+
|
|
60
|
+
Object.keys(start).forEach((k) => {
|
|
61
|
+
if (k in end && checkValues(start[k], end[k], value, k)) {
|
|
62
|
+
const val = clamp(start[k], end[k], minvw, maxvw);
|
|
63
|
+
css[k] = val;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return Object.keys(css).length > 0 ? css : null;
|
|
283
68
|
}
|
|
284
69
|
|
|
285
|
-
|
|
70
|
+
// handle other properties
|
|
71
|
+
const start = parseValue(config().theme[key][args[1]] || args[1]);
|
|
72
|
+
const end = parseValue(config().theme[key][args[2]] || args[2]);
|
|
73
|
+
|
|
74
|
+
if (!checkValues(start, end, value)) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const val = clamp(start, end, minvw, maxvw);
|
|
79
|
+
|
|
80
|
+
const css = props.reduce((acc, prop) => {
|
|
81
|
+
if (typeof prop === 'string') {
|
|
82
|
+
acc[prop] = val;
|
|
83
|
+
} else {
|
|
84
|
+
acc = { ...acc, ...prop };
|
|
85
|
+
}
|
|
86
|
+
return acc;
|
|
87
|
+
}, {});
|
|
88
|
+
|
|
89
|
+
return css;
|
|
286
90
|
},
|
|
287
91
|
},
|
|
288
92
|
{ values: theme('clamp') }
|
package/src/log.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
|
|
3
|
+
export const log = {
|
|
4
|
+
error() {
|
|
5
|
+
console.log(chalk.red(...arguments));
|
|
6
|
+
},
|
|
7
|
+
warn() {
|
|
8
|
+
console.log(chalk.yellow(...arguments));
|
|
9
|
+
},
|
|
10
|
+
info() {
|
|
11
|
+
console.log(chalk.blue(...arguments));
|
|
12
|
+
},
|
|
13
|
+
log() {
|
|
14
|
+
console.log(chalk.gray(...arguments));
|
|
15
|
+
},
|
|
16
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { log } from './log.js';
|
|
2
|
+
|
|
3
|
+
export const parseValue = (value) => {
|
|
4
|
+
const number = parseFloat(value);
|
|
5
|
+
let unit = 'unsupported';
|
|
6
|
+
|
|
7
|
+
if (/^\d+$/.test(value)) {
|
|
8
|
+
unit = 'px';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const match = value.match(/px|rem|em/);
|
|
12
|
+
if (match) {
|
|
13
|
+
unit = match[0];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return { number, unit };
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const parseFontSizeValue = (value) => {
|
|
20
|
+
const values = {};
|
|
21
|
+
if (typeof value === 'string') {
|
|
22
|
+
values.fontSize = parseValue(value);
|
|
23
|
+
} else if (Array.isArray(value)) {
|
|
24
|
+
values.fontSize = parseValue(value[0]);
|
|
25
|
+
if (typeof value[1] === 'string') {
|
|
26
|
+
values.lineHeight = parseValue(value[1]);
|
|
27
|
+
} else if (typeof value[1] === 'object') {
|
|
28
|
+
if ('lineHeight' in value[1]) {
|
|
29
|
+
values.lineHeight = parseValue(value[1].lineHeight);
|
|
30
|
+
}
|
|
31
|
+
if ('letterSpacing' in value[1]) {
|
|
32
|
+
values.letterSpacing = parseValue(value[1].letterSpacing);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return values;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const checkValues = (start, end, value, prop = null) => {
|
|
40
|
+
if (start.number === end.number) {
|
|
41
|
+
log.error(
|
|
42
|
+
`Same value for start an end${
|
|
43
|
+
prop ? ` (${prop})` : ''
|
|
44
|
+
}: "clamp-[${value}]".`
|
|
45
|
+
);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (start.unit !== end.unit) {
|
|
50
|
+
log.error(
|
|
51
|
+
`Units need to match${prop ? ` (${prop})` : ''}: "clamp-[${value}]".`
|
|
52
|
+
);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (start.unit === 'unsupported' || end.unit === 'unsupported') {
|
|
57
|
+
log.error(
|
|
58
|
+
`Only px, rem and em units are supported${
|
|
59
|
+
prop ? ` (${prop})` : ''
|
|
60
|
+
}: "clamp-[${value}]".`
|
|
61
|
+
);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return true;
|
|
66
|
+
};
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
const cssTransformValue = [
|
|
2
|
+
'translate(var(--tw-translate-x), var(--tw-translate-y))',
|
|
3
|
+
'rotate(var(--tw-rotate))',
|
|
4
|
+
'skewX(var(--tw-skew-x))',
|
|
5
|
+
'skewY(var(--tw-skew-y))',
|
|
6
|
+
'scaleX(var(--tw-scale-x))',
|
|
7
|
+
'scaleY(var(--tw-scale-y))',
|
|
8
|
+
].join(' ');
|
|
9
|
+
|
|
10
|
+
export const resolveProperty = (name) => {
|
|
11
|
+
switch (name) {
|
|
12
|
+
case 'p':
|
|
13
|
+
return {
|
|
14
|
+
key: 'padding',
|
|
15
|
+
props: ['padding'],
|
|
16
|
+
};
|
|
17
|
+
case 'pt':
|
|
18
|
+
return {
|
|
19
|
+
key: 'padding',
|
|
20
|
+
props: ['paddingTop'],
|
|
21
|
+
};
|
|
22
|
+
case 'pb':
|
|
23
|
+
return {
|
|
24
|
+
key: 'padding',
|
|
25
|
+
props: ['paddingBottom'],
|
|
26
|
+
};
|
|
27
|
+
case 'pl':
|
|
28
|
+
return {
|
|
29
|
+
key: 'padding',
|
|
30
|
+
props: ['paddingLeft'],
|
|
31
|
+
};
|
|
32
|
+
case 'pr':
|
|
33
|
+
return {
|
|
34
|
+
key: 'padding',
|
|
35
|
+
props: ['paddingRight'],
|
|
36
|
+
};
|
|
37
|
+
case 'px':
|
|
38
|
+
return {
|
|
39
|
+
key: 'padding',
|
|
40
|
+
props: ['paddingLeft', 'paddingRight'],
|
|
41
|
+
};
|
|
42
|
+
case 'py':
|
|
43
|
+
return {
|
|
44
|
+
key: 'padding',
|
|
45
|
+
props: ['paddingTop', 'paddingBottom'],
|
|
46
|
+
};
|
|
47
|
+
case 'm':
|
|
48
|
+
return {
|
|
49
|
+
key: 'margin',
|
|
50
|
+
props: ['margin'],
|
|
51
|
+
};
|
|
52
|
+
case 'mt':
|
|
53
|
+
return {
|
|
54
|
+
key: 'margin',
|
|
55
|
+
props: ['marginTop'],
|
|
56
|
+
};
|
|
57
|
+
case 'mb':
|
|
58
|
+
return {
|
|
59
|
+
key: 'margin',
|
|
60
|
+
props: ['marginBottom'],
|
|
61
|
+
};
|
|
62
|
+
case 'ml':
|
|
63
|
+
return {
|
|
64
|
+
key: 'margin',
|
|
65
|
+
props: ['marginLeft'],
|
|
66
|
+
};
|
|
67
|
+
case 'mr':
|
|
68
|
+
return {
|
|
69
|
+
key: 'margin',
|
|
70
|
+
props: ['marginRight'],
|
|
71
|
+
};
|
|
72
|
+
case 'mx':
|
|
73
|
+
return {
|
|
74
|
+
key: 'margin',
|
|
75
|
+
props: ['marginLeft', 'marginRight'],
|
|
76
|
+
};
|
|
77
|
+
case 'my':
|
|
78
|
+
return {
|
|
79
|
+
key: 'margin',
|
|
80
|
+
props: ['marginTop', 'marginBottom'],
|
|
81
|
+
};
|
|
82
|
+
case 'inset':
|
|
83
|
+
return {
|
|
84
|
+
key: 'inset',
|
|
85
|
+
props: ['top', 'left', 'right', 'bottom'],
|
|
86
|
+
};
|
|
87
|
+
case 'top':
|
|
88
|
+
return {
|
|
89
|
+
key: 'inset',
|
|
90
|
+
props: ['top'],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
case 'left':
|
|
94
|
+
return {
|
|
95
|
+
key: 'inset',
|
|
96
|
+
props: ['left'],
|
|
97
|
+
};
|
|
98
|
+
case 'right':
|
|
99
|
+
return {
|
|
100
|
+
key: 'inset',
|
|
101
|
+
props: ['right'],
|
|
102
|
+
};
|
|
103
|
+
case 'bottom':
|
|
104
|
+
return {
|
|
105
|
+
key: 'inset',
|
|
106
|
+
props: ['bottom'],
|
|
107
|
+
};
|
|
108
|
+
case 'text':
|
|
109
|
+
return {
|
|
110
|
+
key: 'fontSize',
|
|
111
|
+
props: ['fontSize'],
|
|
112
|
+
};
|
|
113
|
+
case 'gap':
|
|
114
|
+
return {
|
|
115
|
+
key: 'gap',
|
|
116
|
+
props: ['gap'],
|
|
117
|
+
};
|
|
118
|
+
case 'gap-x':
|
|
119
|
+
return {
|
|
120
|
+
key: 'gap',
|
|
121
|
+
props: ['columnGap'],
|
|
122
|
+
};
|
|
123
|
+
case 'gap-y':
|
|
124
|
+
return {
|
|
125
|
+
key: 'gap',
|
|
126
|
+
props: ['rowGap'],
|
|
127
|
+
};
|
|
128
|
+
case 'w':
|
|
129
|
+
return {
|
|
130
|
+
key: 'width',
|
|
131
|
+
props: ['width'],
|
|
132
|
+
};
|
|
133
|
+
case 'h':
|
|
134
|
+
return {
|
|
135
|
+
key: 'height',
|
|
136
|
+
props: ['height'],
|
|
137
|
+
};
|
|
138
|
+
case 'size':
|
|
139
|
+
return {
|
|
140
|
+
key: 'size',
|
|
141
|
+
props: ['width', 'height'],
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
case 'min-w':
|
|
145
|
+
return {
|
|
146
|
+
key: 'minWidth',
|
|
147
|
+
props: ['minWidth'],
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
case 'min-h':
|
|
151
|
+
return {
|
|
152
|
+
key: 'minHeight',
|
|
153
|
+
props: ['minHeight'],
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
case 'max-w':
|
|
157
|
+
return {
|
|
158
|
+
key: 'maxWidth',
|
|
159
|
+
props: ['maxWidth'],
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
case 'max-h':
|
|
163
|
+
return {
|
|
164
|
+
key: 'maxHeight',
|
|
165
|
+
props: ['maxHeight'],
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
case 'rounded':
|
|
169
|
+
return {
|
|
170
|
+
key: 'borderRadius',
|
|
171
|
+
props: ['borderRadius'],
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
case 'rounded-t':
|
|
175
|
+
return {
|
|
176
|
+
key: 'borderRadius',
|
|
177
|
+
props: ['borderTopLeftRadius', 'borderTopRightRadius'],
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
case 'rounded-r':
|
|
181
|
+
return {
|
|
182
|
+
key: 'borderRadius',
|
|
183
|
+
props: ['borderTopRightRadius', 'borderBottomRightRadius'],
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
case 'rounded-b':
|
|
187
|
+
return {
|
|
188
|
+
key: 'borderRadius',
|
|
189
|
+
props: ['borderBottomLeftRadius', 'borderBottomRightRadius'],
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
case 'rounded-l':
|
|
193
|
+
return {
|
|
194
|
+
key: 'borderRadius',
|
|
195
|
+
props: ['borderTopLeftRadius', 'borderBottomLeftRadius'],
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
case 'rounded-tl':
|
|
199
|
+
return {
|
|
200
|
+
key: 'borderRadius',
|
|
201
|
+
props: ['borderTopLeftRadius'],
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
case 'rounded-tr':
|
|
205
|
+
return {
|
|
206
|
+
key: 'borderRadius',
|
|
207
|
+
props: ['borderTopRightRadius'],
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
case 'rounded-bl':
|
|
211
|
+
return {
|
|
212
|
+
key: 'borderRadius',
|
|
213
|
+
props: ['borderBottomLeftRadius'],
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
case 'rounded-br':
|
|
217
|
+
return {
|
|
218
|
+
key: 'borderRadius',
|
|
219
|
+
props: ['borderBottomRightRadius'],
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
case 'translate-x':
|
|
223
|
+
return {
|
|
224
|
+
key: 'translate',
|
|
225
|
+
props: [
|
|
226
|
+
'--tw-translate-x',
|
|
227
|
+
{ '@defaults transform': {} },
|
|
228
|
+
{ transform: cssTransformValue },
|
|
229
|
+
],
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
case 'translate-y':
|
|
233
|
+
return {
|
|
234
|
+
key: 'translate',
|
|
235
|
+
props: [
|
|
236
|
+
'--tw-translate-y',
|
|
237
|
+
{ '@defaults transform': {} },
|
|
238
|
+
{ transform: cssTransformValue },
|
|
239
|
+
],
|
|
240
|
+
};
|
|
241
|
+
case 'stroke':
|
|
242
|
+
return {
|
|
243
|
+
key: 'strokeWidth',
|
|
244
|
+
props: ['strokeWidth'],
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
case 'leading':
|
|
248
|
+
return {
|
|
249
|
+
key: 'lineHeight',
|
|
250
|
+
props: ['lineHeight'],
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
case 'border':
|
|
254
|
+
return {
|
|
255
|
+
key: 'borderWidth',
|
|
256
|
+
props: ['borderWidth'],
|
|
257
|
+
};
|
|
258
|
+
case 'border-t':
|
|
259
|
+
return {
|
|
260
|
+
key: 'borderWidth',
|
|
261
|
+
props: ['borderTopWidth'],
|
|
262
|
+
};
|
|
263
|
+
case 'border-b':
|
|
264
|
+
return {
|
|
265
|
+
key: 'borderWidth',
|
|
266
|
+
props: ['borderBottomWidth'],
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
case 'border-l':
|
|
270
|
+
return {
|
|
271
|
+
key: 'borderWidth',
|
|
272
|
+
props: ['borderLeftWidth'],
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
case 'border-r':
|
|
276
|
+
return {
|
|
277
|
+
key: 'borderWidth',
|
|
278
|
+
props: ['borderRightWidth'],
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
case 'border-x':
|
|
282
|
+
return {
|
|
283
|
+
key: 'borderWidth',
|
|
284
|
+
props: ['borderLeftWidth', 'borderRightWidth'],
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
case 'border-y':
|
|
288
|
+
return {
|
|
289
|
+
key: 'borderWidth',
|
|
290
|
+
props: ['borderTopWidth', 'borderBottomWidth'],
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
case 'scroll-m':
|
|
294
|
+
return {
|
|
295
|
+
key: 'scrollMargin',
|
|
296
|
+
props: ['scrollMargin'],
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
default:
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
};
|
package/src/utils.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
// https://chriskirknielsen.com/blog/modern-fluid-typography-with-clamp/
|
|
2
|
-
|
|
3
|
-
const clamp = (_start, _end, minvw = 375, maxvw = 1440) => {
|
|
4
|
-
let start = _start;
|
|
5
|
-
let end = _end;
|
|
6
|
-
let negative = false;
|
|
7
|
-
|
|
8
|
-
if (_end < _start && _start < 0 && _end < 0) {
|
|
9
|
-
start = Math.abs(_start);
|
|
10
|
-
end = Math.abs(_end);
|
|
11
|
-
negative = true;
|
|
12
|
-
} else if (_end < _start && _start > 0 && _end > 0) {
|
|
13
|
-
start = _start * -1;
|
|
14
|
-
end = _end * -1;
|
|
15
|
-
negative = true;
|
|
16
|
-
} else if (_end < _start) {
|
|
17
|
-
start = Math.abs(_start) * -1;
|
|
18
|
-
end = Math.abs(_end);
|
|
19
|
-
negative = true;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const rem = (px) => `${px / 16}rem`;
|
|
23
|
-
const factor = (1 / (maxvw - minvw)) * (end - start);
|
|
24
|
-
const calc = `${rem(start - minvw * factor)} + ${100 * factor}vw`;
|
|
25
|
-
|
|
26
|
-
const value = `clamp(${rem(start)}, ${calc}, ${rem(end)})`;
|
|
27
|
-
|
|
28
|
-
return negative ? `calc(${value} * -1)` : value;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const clampFs = (start, end, tracking = null, minvw = 375, maxvw = 1440) => {
|
|
32
|
-
const [startFs, startLh] = start;
|
|
33
|
-
const [endFs, endLh] = end;
|
|
34
|
-
|
|
35
|
-
const sameLh =
|
|
36
|
-
(startFs == startLh && endFs === endLh) ||
|
|
37
|
-
startLh / startFs === endLh / endFs;
|
|
38
|
-
|
|
39
|
-
const settings = [
|
|
40
|
-
clamp(startFs, endFs, minvw, maxvw),
|
|
41
|
-
{
|
|
42
|
-
lineHeight: sameLh
|
|
43
|
-
? startLh / startFs
|
|
44
|
-
: clamp(startLh, endLh, minvw, maxvw),
|
|
45
|
-
},
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
if (tracking) {
|
|
49
|
-
settings[1].letterSpacing = tracking;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return settings;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const setupClamp = (
|
|
56
|
-
options = {
|
|
57
|
-
minViewportWidth: 375,
|
|
58
|
-
maxViewportWidth: 1440,
|
|
59
|
-
}
|
|
60
|
-
) => {
|
|
61
|
-
return {
|
|
62
|
-
clamp: (
|
|
63
|
-
start,
|
|
64
|
-
end,
|
|
65
|
-
minvw = options.minViewportWidth,
|
|
66
|
-
maxvw = options.maxViewportWidth
|
|
67
|
-
) => clamp(start, end, minvw, maxvw),
|
|
68
|
-
clampFs: (
|
|
69
|
-
start,
|
|
70
|
-
end,
|
|
71
|
-
tracking = null,
|
|
72
|
-
minvw = options.minViewportWidth,
|
|
73
|
-
maxvw = options.maxViewportWidth
|
|
74
|
-
) => clampFs(start, end, tracking, minvw, maxvw),
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
module.exports = {
|
|
79
|
-
clamp,
|
|
80
|
-
clampFs,
|
|
81
|
-
setupClamp,
|
|
82
|
-
};
|