@kalink-ui/seedly 0.29.0 → 0.30.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# @kalink-ui/seedly
|
|
2
2
|
|
|
3
|
+
## 0.30.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e257be4: feat(styles): add dynamic fluid scale helpers
|
|
8
|
+
|
|
9
|
+
New
|
|
10
|
+
- `getInterpolationFor(value, options)`: per-value exponential mapping from a mobile range to a desktop range.
|
|
11
|
+
- `toFluidClamp([min, max], options)`: build a viewport-based CSS `clamp()` with `interpolateFrom`/`interpolateTo` (defaults `23.5` and `80`).
|
|
12
|
+
- `toFluidClampFor(value, options)`: convenience to compute the mapped max and format a `clamp()` in one step.
|
|
13
|
+
|
|
14
|
+
Updates
|
|
15
|
+
- Storybook theme now uses the new helpers and no longer depends on an interpolation variable.
|
|
16
|
+
|
|
17
|
+
Usage
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import {
|
|
21
|
+
getInterpolationFor,
|
|
22
|
+
toFluidClampFor,
|
|
23
|
+
} from '@kalink-ui/seedly/styles';
|
|
24
|
+
|
|
25
|
+
const mapped = getInterpolationFor(12, {
|
|
26
|
+
lowMin: 12,
|
|
27
|
+
lowMax: 64,
|
|
28
|
+
highMin: 12,
|
|
29
|
+
highMax: 200,
|
|
30
|
+
exponent: 2,
|
|
31
|
+
rounding: 'none',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const clamp = toFluidClampFor(12, {
|
|
35
|
+
lowMin: 12,
|
|
36
|
+
lowMax: 64,
|
|
37
|
+
highMin: 12,
|
|
38
|
+
highMax: 200,
|
|
39
|
+
exponent: 2,
|
|
40
|
+
rounding: 'none',
|
|
41
|
+
// optional overrides
|
|
42
|
+
interpolateFrom: 23.5,
|
|
43
|
+
interpolateTo: 80,
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 0.29.1
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- 174eb5b: Correctly apply auto layout when defined
|
|
52
|
+
|
|
3
53
|
## 0.29.0
|
|
4
54
|
|
|
5
55
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kalink-ui/seedly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "A set of components for building UIs with React and TypeScript",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"vite": "^6.3.5",
|
|
44
44
|
"vite-tsconfig-paths": "^5.1.4",
|
|
45
45
|
"vitest": "^3.2.3",
|
|
46
|
-
"@kalink-ui/
|
|
47
|
-
"@kalink-ui/
|
|
46
|
+
"@kalink-ui/typescript-config": "0.4.0",
|
|
47
|
+
"@kalink-ui/eslint-config": "0.10.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@vanilla-extract/css": "^1.17.1",
|
|
@@ -172,7 +172,7 @@ const gridColumnsStyles = Object.fromEntries(
|
|
|
172
172
|
{ '@layer': Record<string, { gridTemplateColumns: string }> }
|
|
173
173
|
>;
|
|
174
174
|
|
|
175
|
-
export const
|
|
175
|
+
export const autoLayoutStyles = {
|
|
176
176
|
fill: {
|
|
177
177
|
'@layer': {
|
|
178
178
|
[components]: {
|
|
@@ -226,7 +226,7 @@ export const gridRecipe = recipe({
|
|
|
226
226
|
/**
|
|
227
227
|
* Whether to use auto-fill (default) or auto-fit
|
|
228
228
|
*/
|
|
229
|
-
|
|
229
|
+
autoLayout: autoLayoutStyles,
|
|
230
230
|
|
|
231
231
|
/**
|
|
232
232
|
* Grid item alignment along inline axis
|
|
@@ -274,8 +274,8 @@ export const columnsAt = createResponsiveVariants({
|
|
|
274
274
|
media: defaultMedia,
|
|
275
275
|
});
|
|
276
276
|
|
|
277
|
-
export const
|
|
278
|
-
styles:
|
|
277
|
+
export const autoLayoutAt = createResponsiveVariants({
|
|
278
|
+
styles: autoLayoutStyles,
|
|
279
279
|
media: defaultMedia,
|
|
280
280
|
});
|
|
281
281
|
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
alignContentAt,
|
|
5
5
|
alignItemsAt,
|
|
6
6
|
columnsAt,
|
|
7
|
-
|
|
7
|
+
autoLayoutAt,
|
|
8
8
|
gridRecipe,
|
|
9
9
|
justifyContentAt,
|
|
10
10
|
justifyItemsAt,
|
|
@@ -20,7 +20,7 @@ export const gridResponsive = responsiveRecipe({
|
|
|
20
20
|
columnSpacing: columnSpacingAt,
|
|
21
21
|
rowSpacing: rowSpacingAt,
|
|
22
22
|
columns: columnsAt,
|
|
23
|
-
|
|
23
|
+
autoLayout: autoLayoutAt,
|
|
24
24
|
justifyItems: justifyItemsAt,
|
|
25
25
|
alignItems: alignItemsAt,
|
|
26
26
|
justifyContent: justifyContentAt,
|
|
@@ -30,18 +30,16 @@ type GridProps<TUse extends ElementType> = PolymorphicComponentProps<TUse> &
|
|
|
30
30
|
*
|
|
31
31
|
* https://every-layout.dev/layouts/grid/
|
|
32
32
|
*/
|
|
33
|
-
export function Grid<TUse extends ElementType>({
|
|
34
|
-
minSize,
|
|
35
|
-
className,
|
|
36
|
-
...props
|
|
37
|
-
}: GridProps<TUse>) {
|
|
33
|
+
export function Grid<TUse extends ElementType>(props: GridProps<TUse>) {
|
|
38
34
|
const {
|
|
39
35
|
use: Comp = 'div',
|
|
36
|
+
minSize,
|
|
37
|
+
className,
|
|
40
38
|
spacing,
|
|
41
39
|
columnSpacing,
|
|
42
40
|
rowSpacing,
|
|
43
41
|
columns = { xs: 4, md: 8, lg: 12 },
|
|
44
|
-
|
|
42
|
+
autoLayout,
|
|
45
43
|
justifyItems,
|
|
46
44
|
alignItems,
|
|
47
45
|
justifyContent,
|
|
@@ -56,8 +54,8 @@ export function Grid<TUse extends ElementType>({
|
|
|
56
54
|
spacing,
|
|
57
55
|
columnSpacing,
|
|
58
56
|
rowSpacing,
|
|
59
|
-
columns,
|
|
60
|
-
|
|
57
|
+
columns: autoLayout ? undefined : columns,
|
|
58
|
+
autoLayout,
|
|
61
59
|
justifyItems,
|
|
62
60
|
alignItems,
|
|
63
61
|
justifyContent,
|
package/src/styles/index.ts
CHANGED
|
@@ -34,3 +34,13 @@ export {
|
|
|
34
34
|
} from './responsive';
|
|
35
35
|
|
|
36
36
|
export { breakpoints, screen, type BreakpointKey } from './breakpoints';
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
getInterpolationFor,
|
|
40
|
+
toFluidClamp,
|
|
41
|
+
toFluidClampFor,
|
|
42
|
+
type Interval,
|
|
43
|
+
type ExponentialScaleOptions,
|
|
44
|
+
type DynamicInterpolationOptions,
|
|
45
|
+
type FluidClampOptions,
|
|
46
|
+
} from './scale';
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export type Interval = [number, number];
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Common easing/rounding options used by the interpolation helpers.
|
|
5
|
+
* Note: `minStep` is ignored in single-value mapping but kept for backward
|
|
6
|
+
* compatibility of the public types.
|
|
7
|
+
*/
|
|
8
|
+
export interface ExponentialScaleOptions {
|
|
9
|
+
exponent?: number; // 1 = linear, >1 = ease-in, <1 = ease-out
|
|
10
|
+
minStep?: number; // kept for compatibility; not used by per-value mapping
|
|
11
|
+
rounding?: 'none' | 'round' | 'floor' | 'ceil';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface DynamicInterpolationOptions extends ExponentialScaleOptions {
|
|
15
|
+
lowMin: number;
|
|
16
|
+
lowMax: number;
|
|
17
|
+
highMin: number;
|
|
18
|
+
highMax: number;
|
|
19
|
+
clampInput?: boolean; // clamp input inside [lowMin, lowMax]
|
|
20
|
+
ensureGteInput?: boolean; // ensure output >= input
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface FluidClampOptions {
|
|
24
|
+
unit?: 'rem' | 'px';
|
|
25
|
+
baseFontSize?: number; // px per rem when unit is 'rem'
|
|
26
|
+
interpolateFrom?: number; // defaults to 23.5 (in `unit`)
|
|
27
|
+
interpolateTo?: number; // defaults to 80 (in `unit`)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Format a `[min, max]` pair into a CSS clamp() with viewport-based interpolation:
|
|
32
|
+
* clamp(min, calc(min + (max - min) * ((100vw - from) / (to - from))), max)
|
|
33
|
+
*
|
|
34
|
+
* - `from`/`to` default to 23.5 and 80 (in the selected `unit`).
|
|
35
|
+
* - `unit` may be 'rem' (default) or 'px'. When 'rem', values are converted from px
|
|
36
|
+
* using `baseFontSize` (default 16).
|
|
37
|
+
*/
|
|
38
|
+
export function toFluidClamp(
|
|
39
|
+
[min, max]: Interval,
|
|
40
|
+
options: FluidClampOptions = {},
|
|
41
|
+
): string {
|
|
42
|
+
const unit = options.unit ?? 'rem';
|
|
43
|
+
const base = options.baseFontSize ?? 16;
|
|
44
|
+
const from = options.interpolateFrom ?? 23.5;
|
|
45
|
+
const to = options.interpolateTo ?? 80;
|
|
46
|
+
|
|
47
|
+
const toUnit = (px: number): number => {
|
|
48
|
+
if (unit === 'px') {
|
|
49
|
+
return px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return px / base;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const minU = toUnit(min);
|
|
56
|
+
const maxU = toUnit(max);
|
|
57
|
+
const diffU = maxU - minU;
|
|
58
|
+
|
|
59
|
+
const interp = `((100vw - ${from}${unit}) / (${to} - ${from}))`;
|
|
60
|
+
|
|
61
|
+
return `clamp(${minU}${unit}, calc(${minU}${unit} + (${diffU} * ${interp})), ${maxU}${unit})`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Batch scale helpers were removed in favor of per-value mapping.
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Map a single `value` from [lowMin, lowMax] to [highMin, highMax] using
|
|
68
|
+
* exponential easing. Optionally rounds, clamps input, and ensures the output
|
|
69
|
+
* is not below the input (enabled by default).
|
|
70
|
+
*/
|
|
71
|
+
export function getInterpolationFor(
|
|
72
|
+
value: number,
|
|
73
|
+
{
|
|
74
|
+
lowMin,
|
|
75
|
+
lowMax,
|
|
76
|
+
highMin,
|
|
77
|
+
highMax,
|
|
78
|
+
exponent = 2,
|
|
79
|
+
rounding = 'round',
|
|
80
|
+
clampInput = true,
|
|
81
|
+
ensureGteInput = true,
|
|
82
|
+
}: DynamicInterpolationOptions,
|
|
83
|
+
): number {
|
|
84
|
+
if (lowMax === lowMin) {
|
|
85
|
+
throw new Error('getInterpolationFor: lowMin and lowMax must differ.');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const clamp = (v: number, min: number, max: number): number => {
|
|
89
|
+
if (v < min) {
|
|
90
|
+
return min;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (v > max) {
|
|
94
|
+
return max;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return v;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const round = (v: number): number => {
|
|
101
|
+
if (rounding === 'none') {
|
|
102
|
+
return v;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (rounding === 'floor') {
|
|
106
|
+
return Math.floor(v);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (rounding === 'ceil') {
|
|
110
|
+
return Math.ceil(v);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return Math.round(v);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const input = clampInput ? clamp(value, lowMin, lowMax) : value;
|
|
117
|
+
|
|
118
|
+
const t = (input - lowMin) / (lowMax - lowMin);
|
|
119
|
+
const eased = Math.pow(t, exponent);
|
|
120
|
+
const mapped = highMin + eased * (highMax - highMin);
|
|
121
|
+
|
|
122
|
+
let result = round(mapped);
|
|
123
|
+
|
|
124
|
+
if (ensureGteInput && result < input) {
|
|
125
|
+
result = input;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface FluidClampForOptions
|
|
132
|
+
extends DynamicInterpolationOptions,
|
|
133
|
+
FluidClampOptions {}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Convenience to produce a CSS clamp() for a single `value` by first computing
|
|
137
|
+
* its mapped high value via `getInterpolationFor`, then formatting with
|
|
138
|
+
* `toFluidClamp` using viewport interpolation.
|
|
139
|
+
*/
|
|
140
|
+
export function toFluidClampFor(
|
|
141
|
+
value: number,
|
|
142
|
+
{ unit = 'rem', baseFontSize = 16, ...opts }: FluidClampForOptions,
|
|
143
|
+
): string {
|
|
144
|
+
return toFluidClamp([value, getInterpolationFor(value, opts)], {
|
|
145
|
+
unit,
|
|
146
|
+
baseFontSize,
|
|
147
|
+
...opts,
|
|
148
|
+
});
|
|
149
|
+
}
|