@cherrywind/flexible 0.0.2-beta → 0.0.2-beta.2
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 +66 -13
- package/README.zh-CN.md +67 -14
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +18 -8
- package/dist/index.js +22 -14
- package/dist/index.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ A lightweight and flexible layout system for responsive web design, inspired by
|
|
|
12
12
|
- 🎯 Customizable breakpoints
|
|
13
13
|
- 🎨 CSS variable support
|
|
14
14
|
- 🧹 Clean API with cleanup function
|
|
15
|
+
- ⚡ Immediate layout application
|
|
16
|
+
- 📐 Orientation change support
|
|
15
17
|
|
|
16
18
|
## Installation
|
|
17
19
|
|
|
@@ -44,8 +46,10 @@ import { flexible } from '@cherrywind/flexible';
|
|
|
44
46
|
|
|
45
47
|
const cleanup = flexible({
|
|
46
48
|
breakpoints: [1024, 768],
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
layouts: [375, 1024, 1920],
|
|
50
|
+
basicLayout: 1920,
|
|
51
|
+
immediate: true,
|
|
52
|
+
orientationchange: false,
|
|
49
53
|
scope: {
|
|
50
54
|
element: document.querySelector('.container'),
|
|
51
55
|
cssVarName: '--custom-rem'
|
|
@@ -65,22 +69,49 @@ interface FlexibleOptions {
|
|
|
65
69
|
*/
|
|
66
70
|
breakpoints?: number[];
|
|
67
71
|
/**
|
|
68
|
-
* An array of
|
|
72
|
+
* An array of layout widths that corresponds to breakpoints.
|
|
69
73
|
* Must have exactly one more item than breakpoints array.
|
|
74
|
+
* For example, if breakpoints is [768], layouts could be [375, 1920],
|
|
75
|
+
* where 375 is the width for viewport <= 768px and 1920 is for viewport > 768px.
|
|
70
76
|
*/
|
|
71
|
-
|
|
77
|
+
layouts?: number[];
|
|
72
78
|
/**
|
|
73
|
-
* The base
|
|
74
|
-
*
|
|
79
|
+
* The base layout width used as reference for calculations.
|
|
80
|
+
* Only effective when layouts is provided.
|
|
81
|
+
* Used as the baseline layout width for ratio calculations.
|
|
82
|
+
* Defaults to the last item in layouts array (layouts?.at(-1)),
|
|
83
|
+
* which typically represents the largest viewport width.
|
|
75
84
|
*/
|
|
76
|
-
|
|
85
|
+
basicLayout?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Whether to apply the layout immediately on initialization.
|
|
88
|
+
* Defaults to false.
|
|
89
|
+
*/
|
|
90
|
+
immediate?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Whether to listen for orientation change events.
|
|
93
|
+
* Defaults to true.
|
|
94
|
+
*/
|
|
95
|
+
orientationchange?: boolean;
|
|
77
96
|
/**
|
|
78
97
|
* Whether to set the CSS variable on a specific scope element.
|
|
98
|
+
* Defaults to false, which means setting the font size on the document element.
|
|
99
|
+
* If an object is provided, it can specify the element and CSS variable name.
|
|
79
100
|
*/
|
|
80
|
-
scope?:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
scope?:
|
|
102
|
+
| false
|
|
103
|
+
| {
|
|
104
|
+
/**
|
|
105
|
+
* The scope element to set the CSS variable on.
|
|
106
|
+
* Defaults to document.documentElement.
|
|
107
|
+
*/
|
|
108
|
+
element?: HTMLElement;
|
|
109
|
+
/**
|
|
110
|
+
* The CSS variable name to use for the base rem value.
|
|
111
|
+
* Defaults to "--local-scope-rem".
|
|
112
|
+
*/
|
|
113
|
+
cssVarName?: string;
|
|
114
|
+
};
|
|
84
115
|
}
|
|
85
116
|
```
|
|
86
117
|
|
|
@@ -115,8 +146,8 @@ import { flexible } from '@cherrywind/flexible';
|
|
|
115
146
|
|
|
116
147
|
const cleanup = flexible({
|
|
117
148
|
breakpoints: [1024, 768],
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
layouts: [375, 1024, 1920],
|
|
150
|
+
basicLayout: 1920
|
|
120
151
|
});
|
|
121
152
|
```
|
|
122
153
|
|
|
@@ -134,6 +165,28 @@ const cleanup = flexible({
|
|
|
134
165
|
});
|
|
135
166
|
```
|
|
136
167
|
|
|
168
|
+
### Immediate Layout Example
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { flexible } from '@cherrywind/flexible';
|
|
172
|
+
|
|
173
|
+
// Apply layout immediately without waiting for load event
|
|
174
|
+
const cleanup = flexible({
|
|
175
|
+
immediate: true
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Disable Orientation Change Example
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { flexible } from '@cherrywind/flexible';
|
|
183
|
+
|
|
184
|
+
// Disable orientation change handling
|
|
185
|
+
const cleanup = flexible({
|
|
186
|
+
orientationchange: false
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
137
190
|
## License
|
|
138
191
|
|
|
139
192
|
MIT
|
package/README.zh-CN.md
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
- 🎯 可自定义断点
|
|
13
13
|
- 🎨 支持 CSS 变量
|
|
14
14
|
- 🧹 提供清理函数的简洁 API
|
|
15
|
+
- ⚡ 支持立即应用布局
|
|
16
|
+
- 📐 支持屏幕方向变化
|
|
15
17
|
|
|
16
18
|
## 安装
|
|
17
19
|
|
|
@@ -44,8 +46,10 @@ import { flexible } from '@cherrywind/flexible';
|
|
|
44
46
|
|
|
45
47
|
const cleanup = flexible({
|
|
46
48
|
breakpoints: [1024, 768],
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
layouts: [375, 1024, 1920],
|
|
50
|
+
basicLayout: 1920,
|
|
51
|
+
immediate: true,
|
|
52
|
+
orientationchange: false,
|
|
49
53
|
scope: {
|
|
50
54
|
element: document.querySelector('.container'),
|
|
51
55
|
cssVarName: '--custom-rem'
|
|
@@ -65,22 +69,49 @@ interface FlexibleOptions {
|
|
|
65
69
|
*/
|
|
66
70
|
breakpoints?: number[];
|
|
67
71
|
/**
|
|
68
|
-
*
|
|
72
|
+
* 与断点对应的布局宽度数组。
|
|
69
73
|
* 数组长度必须比断点数组多一个。
|
|
74
|
+
* 例如,如果断点是 [768],布局可以是 [375, 1920],
|
|
75
|
+
* 其中 375 是视口宽度 <= 768px 时的宽度,1920 是视口宽度 > 768px 时的宽度。
|
|
70
76
|
*/
|
|
71
|
-
|
|
77
|
+
layouts?: number[];
|
|
72
78
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
79
|
+
* 用于计算的基础布局宽度。
|
|
80
|
+
* 仅在提供 layouts 时有效。
|
|
81
|
+
* 用作比例计算的基础布局宽度。
|
|
82
|
+
* 默认为 layouts 数组的最后一项(layouts?.at(-1)),
|
|
83
|
+
* 通常代表最大的视口宽度。
|
|
75
84
|
*/
|
|
76
|
-
|
|
85
|
+
basicLayout?: number;
|
|
86
|
+
/**
|
|
87
|
+
* 是否在初始化时立即应用布局。
|
|
88
|
+
* 默认为 false。
|
|
89
|
+
*/
|
|
90
|
+
immediate?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* 是否监听屏幕方向变化事件。
|
|
93
|
+
* 默认为 true。
|
|
94
|
+
*/
|
|
95
|
+
orientationchange?: boolean;
|
|
77
96
|
/**
|
|
78
97
|
* 是否在特定作用域元素上设置 CSS 变量。
|
|
98
|
+
* 默认为 false,表示在文档元素上设置字体大小。
|
|
99
|
+
* 如果提供对象,可以指定元素和 CSS 变量名。
|
|
79
100
|
*/
|
|
80
|
-
scope?:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
scope?:
|
|
102
|
+
| false
|
|
103
|
+
| {
|
|
104
|
+
/**
|
|
105
|
+
* 设置 CSS 变量的作用域元素。
|
|
106
|
+
* 默认为 document.documentElement。
|
|
107
|
+
*/
|
|
108
|
+
element?: HTMLElement;
|
|
109
|
+
/**
|
|
110
|
+
* 用于基础 rem 值的 CSS 变量名。
|
|
111
|
+
* 默认为 "--local-scope-rem"。
|
|
112
|
+
*/
|
|
113
|
+
cssVarName?: string;
|
|
114
|
+
};
|
|
84
115
|
}
|
|
85
116
|
```
|
|
86
117
|
|
|
@@ -115,8 +146,8 @@ import { flexible } from '@cherrywind/flexible';
|
|
|
115
146
|
|
|
116
147
|
const cleanup = flexible({
|
|
117
148
|
breakpoints: [1024, 768],
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
layouts: [375, 1024, 1920],
|
|
150
|
+
basicLayout: 1920
|
|
120
151
|
});
|
|
121
152
|
```
|
|
122
153
|
|
|
@@ -134,6 +165,28 @@ const cleanup = flexible({
|
|
|
134
165
|
});
|
|
135
166
|
```
|
|
136
167
|
|
|
168
|
+
### 立即应用布局示例
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { flexible } from '@cherrywind/flexible';
|
|
172
|
+
|
|
173
|
+
// 立即应用布局,不等待 load 事件
|
|
174
|
+
const cleanup = flexible({
|
|
175
|
+
immediate: true
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 禁用屏幕方向变化示例
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { flexible } from '@cherrywind/flexible';
|
|
183
|
+
|
|
184
|
+
// 禁用屏幕方向变化处理
|
|
185
|
+
const cleanup = flexible({
|
|
186
|
+
orientationchange: false
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
137
190
|
## 许可证
|
|
138
191
|
|
|
139
|
-
MIT
|
|
192
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=(f={})=>{const{breakpoints:u=[768],layouts:s,basicLayout:p,scope:c,immediate:l=!1,orientationchange:d=!0}=f,a=u.sort((e,o)=>e-o),n=s==null?void 0:s.sort((e,o)=>e-o),m=p??(n==null?void 0:n.at(-1)),v=e=>!n||!m?1:n.length-1===a.length?m/n[e]:1,t=()=>{const e=document.documentElement,o=e.clientWidth;let r=o/100;for(let i=0;i<a.length;i++)if(o<=a[i]){r=r*v(i);break}if(c){const{element:i=document.documentElement,cssVarName:w="--local-scope-rem"}=c;i.style.setProperty(w,r+"px")}else e.style.fontSize=r+"px"};return l?t():window.addEventListener("load",t),window.addEventListener("resize",t),d&&screen.orientation.addEventListener("change",t),()=>{l||window.removeEventListener("load",t),window.removeEventListener("resize",t),d&&screen.orientation.removeEventListener("change",t)}};exports.flexible=b;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * Options for the flexible layout function.\n */\nexport interface FlexibleOptions {\n /**\n * An array of breakpoints in pixels, from largest to smallest.\n * Defaults to [768].\n */\n breakpoints?: number[];\n /**\n * An array of layout widths that corresponds to breakpoints.\n * Must have exactly one more item than breakpoints array.\n * For example, if breakpoints is [768], layouts could be [375, 1920],\n * where 375 is the width for viewport <= 768px and 1920 is for viewport > 768px.\n */\n layouts?: number[];\n /**\n * The base layout width used as reference for calculations.\n * Only effective when layouts is provided.\n * Used as the baseline layout width for ratio calculations.\n * Defaults to the last item in layouts array (layouts?.at(-1)),\n * which typically represents the largest viewport width.\n */\n basicLayout?: number;\n /**\n * Whether to apply the layout immediately on initialization.\n * Defaults to false.\n */\n immediate?: boolean;\n /**\n * Whether to listen for orientation change events.\n * Defaults to true.\n */\n orientationchange?: boolean;\n\n /**\n * Whether to set the CSS variable on a specific scope element.\n * Defaults to false, which means setting the font size on the document element.\n * If an object is provided, it can specify the element and CSS variable name.\n */\n scope?:\n | false\n | {\n /**\n * The scope element to set the CSS variable on.\n * Defaults to document.documentElement.\n */\n element?: HTMLElement;\n /**\n * The CSS variable name to use for the base rem value.\n * Defaults to \"--local-scope-rem\".\n */\n cssVarName?: string;\n };\n}\n\n/**\n * Initializes a flexible layout system that sets a CSS variable for rem units\n * based on the viewport width and adaptively scales according to breakpoints.\n *\n * @param options - Configuration options for the flexible layout\n * @returns A cleanup function to remove event listeners\n */\nexport const flexible = (options: FlexibleOptions = {}): (() => void) => {\n const {\n breakpoints: propBreakpoints = [768],\n layouts: propLayouts,\n basicLayout: propBasicLayout,\n scope,\n immediate = false,\n orientationchange = true,\n } = options;\n // Sort breakpoints and layouts in ascending order\n const breakpoints = propBreakpoints.sort((a, b) => a - b);\n const layouts = propLayouts?.sort((a, b) => a - b);\n const basicLayout = propBasicLayout ?? layouts?.at(-1);\n\n /**\n * Calculate the ratio factor for a specific breakpoint\n * @param index - Breakpoint index\n * @returns The ratio factor, defaults to 1\n */\n const getBreakpointRatio = (index: number): number => {\n if (!layouts || !basicLayout) return 1;\n if (layouts.length - 1 === breakpoints.length) {\n return basicLayout / layouts[index];\n }\n return 1; // Default to ratio factor of 1\n };\n\n /**\n * Respond to window size changes and update CSS variable\n */\n const responsive = (): void => {\n const html = document.documentElement;\n const width = html.clientWidth;\n // 100rem = 100vw = design width\n let vw = width / 100;\n\n for (let i = 0; i < breakpoints.length; i++) {\n if (width <= breakpoints[i]) {\n // Should use layouts[i] as the base\n vw = vw * getBreakpointRatio(i);\n break;\n }\n }\n if (scope) {\n const { element = document.documentElement, cssVarName = '--local-scope-rem' } = scope;\n // Set the CSS variable --local-scope-rem for the element\n element.style.setProperty(cssVarName, vw + 'px');\n } else {\n html.style.fontSize = vw + 'px';\n }\n };\n\n if (immediate) {\n responsive();\n } else {\n window.addEventListener('load', responsive);\n }\n window.addEventListener('resize', responsive);\n if (orientationchange) {\n screen.orientation.addEventListener('change', responsive);\n }\n // Return cleanup function\n return () => {\n if (!immediate) {\n window.removeEventListener('load', responsive);\n }\n window.removeEventListener('resize', responsive);\n if (orientationchange) {\n screen.orientation.removeEventListener('change', responsive);\n }\n };\n};\n"],"names":["flexible","options","propBreakpoints","propLayouts","propBasicLayout","scope","immediate","orientationchange","breakpoints","a","b","layouts","basicLayout","getBreakpointRatio","index","responsive","html","width","vw","element","cssVarName"],"mappings":"gFA+DO,MAAMA,EAAW,CAACC,EAA2B,KAAqB,CACjE,KAAA,CACJ,YAAaC,EAAkB,CAAC,GAAG,EACnC,QAASC,EACT,YAAaC,EACb,MAAAC,EACA,UAAAC,EAAY,GACZ,kBAAAC,EAAoB,EAAA,EAClBN,EAEEO,EAAcN,EAAgB,KAAK,CAACO,EAAGC,IAAMD,EAAIC,CAAC,EAClDC,EAAUR,GAAA,YAAAA,EAAa,KAAK,CAACM,EAAGC,IAAMD,EAAIC,GAC1CE,EAAcR,IAAmBO,GAAA,YAAAA,EAAS,GAAG,KAO7CE,EAAsBC,GACtB,CAACH,GAAW,CAACC,EAAoB,EACjCD,EAAQ,OAAS,IAAMH,EAAY,OAC9BI,EAAcD,EAAQG,CAAK,EAE7B,EAMHC,EAAa,IAAY,CAC7B,MAAMC,EAAO,SAAS,gBAChBC,EAAQD,EAAK,YAEnB,IAAIE,EAAKD,EAAQ,IAEjB,QAAS,EAAI,EAAG,EAAIT,EAAY,OAAQ,IAClC,GAAAS,GAAST,EAAY,CAAC,EAAG,CAEtBU,EAAAA,EAAKL,EAAmB,CAAC,EAC9B,KAAA,CAGJ,GAAIR,EAAO,CACT,KAAM,CAAE,QAAAc,EAAU,SAAS,gBAAiB,WAAAC,EAAa,qBAAwBf,EAEjFc,EAAQ,MAAM,YAAYC,EAAYF,EAAK,IAAI,CAAA,MAE1CF,EAAA,MAAM,SAAWE,EAAK,IAE/B,EAEA,OAAIZ,EACSS,EAAA,EAEJ,OAAA,iBAAiB,OAAQA,CAAU,EAErC,OAAA,iBAAiB,SAAUA,CAAU,EACxCR,GACK,OAAA,YAAY,iBAAiB,SAAUQ,CAAU,EAGnD,IAAM,CACNT,GACI,OAAA,oBAAoB,OAAQS,CAAU,EAExC,OAAA,oBAAoB,SAAUA,CAAU,EAC3CR,GACK,OAAA,YAAY,oBAAoB,SAAUQ,CAAU,CAE/D,CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,20 +17,30 @@ export declare interface FlexibleOptions {
|
|
|
17
17
|
*/
|
|
18
18
|
breakpoints?: number[];
|
|
19
19
|
/**
|
|
20
|
-
* An array of
|
|
20
|
+
* An array of layout widths that corresponds to breakpoints.
|
|
21
21
|
* Must have exactly one more item than breakpoints array.
|
|
22
|
-
* For example, if breakpoints is [768],
|
|
22
|
+
* For example, if breakpoints is [768], layouts could be [375, 1920],
|
|
23
23
|
* where 375 is the width for viewport <= 768px and 1920 is for viewport > 768px.
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
layouts?: number[];
|
|
26
26
|
/**
|
|
27
|
-
* The base
|
|
28
|
-
* Only effective when
|
|
29
|
-
* Used as the baseline
|
|
30
|
-
* Defaults to the last item in
|
|
27
|
+
* The base layout width used as reference for calculations.
|
|
28
|
+
* Only effective when layouts is provided.
|
|
29
|
+
* Used as the baseline layout width for ratio calculations.
|
|
30
|
+
* Defaults to the last item in layouts array (layouts?.at(-1)),
|
|
31
31
|
* which typically represents the largest viewport width.
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
basicLayout?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to apply the layout immediately on initialization.
|
|
36
|
+
* Defaults to false.
|
|
37
|
+
*/
|
|
38
|
+
immediate?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Whether to listen for orientation change events.
|
|
41
|
+
* Defaults to true.
|
|
42
|
+
*/
|
|
43
|
+
orientationchange?: boolean;
|
|
34
44
|
/**
|
|
35
45
|
* Whether to set the CSS variable on a specific scope element.
|
|
36
46
|
* Defaults to false, which means setting the font size on the document element.
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
const
|
|
2
|
-
const {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
const h = (p = {}) => {
|
|
2
|
+
const {
|
|
3
|
+
breakpoints: f = [768],
|
|
4
|
+
layouts: s,
|
|
5
|
+
basicLayout: u,
|
|
6
|
+
scope: c,
|
|
7
|
+
immediate: l = !1,
|
|
8
|
+
orientationchange: d = !0
|
|
9
|
+
} = p, a = f.sort((e, o) => e - o), n = s == null ? void 0 : s.sort((e, o) => e - o), m = u ?? (n == null ? void 0 : n.at(-1)), v = (e) => !n || !m ? 1 : n.length - 1 === a.length ? m / n[e] : 1, t = () => {
|
|
10
|
+
const e = document.documentElement, o = e.clientWidth;
|
|
11
|
+
let r = o / 100;
|
|
12
|
+
for (let i = 0; i < a.length; i++)
|
|
13
|
+
if (o <= a[i]) {
|
|
14
|
+
r = r * v(i);
|
|
8
15
|
break;
|
|
9
16
|
}
|
|
10
|
-
if (
|
|
11
|
-
const { element:
|
|
12
|
-
|
|
17
|
+
if (c) {
|
|
18
|
+
const { element: i = document.documentElement, cssVarName: w = "--local-scope-rem" } = c;
|
|
19
|
+
i.style.setProperty(w, r + "px");
|
|
13
20
|
} else
|
|
14
|
-
|
|
21
|
+
e.style.fontSize = r + "px";
|
|
15
22
|
};
|
|
16
|
-
return window.addEventListener("load", t), window.addEventListener("resize", t),
|
|
17
|
-
window.removeEventListener("load", t), window.removeEventListener("resize", t),
|
|
23
|
+
return l ? t() : window.addEventListener("load", t), window.addEventListener("resize", t), d && screen.orientation.addEventListener("change", t), () => {
|
|
24
|
+
l || window.removeEventListener("load", t), window.removeEventListener("resize", t), d && screen.orientation.removeEventListener("change", t);
|
|
18
25
|
};
|
|
19
26
|
};
|
|
20
27
|
export {
|
|
21
|
-
|
|
28
|
+
h as flexible
|
|
22
29
|
};
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Options for the flexible layout function.\n */\nexport interface FlexibleOptions {\n /**\n * An array of breakpoints in pixels, from largest to smallest.\n * Defaults to [768].\n */\n breakpoints?: number[];\n /**\n * An array of layout widths that corresponds to breakpoints.\n * Must have exactly one more item than breakpoints array.\n * For example, if breakpoints is [768], layouts could be [375, 1920],\n * where 375 is the width for viewport <= 768px and 1920 is for viewport > 768px.\n */\n layouts?: number[];\n /**\n * The base layout width used as reference for calculations.\n * Only effective when layouts is provided.\n * Used as the baseline layout width for ratio calculations.\n * Defaults to the last item in layouts array (layouts?.at(-1)),\n * which typically represents the largest viewport width.\n */\n basicLayout?: number;\n /**\n * Whether to apply the layout immediately on initialization.\n * Defaults to false.\n */\n immediate?: boolean;\n /**\n * Whether to listen for orientation change events.\n * Defaults to true.\n */\n orientationchange?: boolean;\n\n /**\n * Whether to set the CSS variable on a specific scope element.\n * Defaults to false, which means setting the font size on the document element.\n * If an object is provided, it can specify the element and CSS variable name.\n */\n scope?:\n | false\n | {\n /**\n * The scope element to set the CSS variable on.\n * Defaults to document.documentElement.\n */\n element?: HTMLElement;\n /**\n * The CSS variable name to use for the base rem value.\n * Defaults to \"--local-scope-rem\".\n */\n cssVarName?: string;\n };\n}\n\n/**\n * Initializes a flexible layout system that sets a CSS variable for rem units\n * based on the viewport width and adaptively scales according to breakpoints.\n *\n * @param options - Configuration options for the flexible layout\n * @returns A cleanup function to remove event listeners\n */\nexport const flexible = (options: FlexibleOptions = {}): (() => void) => {\n const {\n breakpoints: propBreakpoints = [768],\n layouts: propLayouts,\n basicLayout: propBasicLayout,\n scope,\n immediate = false,\n orientationchange = true,\n } = options;\n // Sort breakpoints and layouts in ascending order\n const breakpoints = propBreakpoints.sort((a, b) => a - b);\n const layouts = propLayouts?.sort((a, b) => a - b);\n const basicLayout = propBasicLayout ?? layouts?.at(-1);\n\n /**\n * Calculate the ratio factor for a specific breakpoint\n * @param index - Breakpoint index\n * @returns The ratio factor, defaults to 1\n */\n const getBreakpointRatio = (index: number): number => {\n if (!layouts || !basicLayout) return 1;\n if (layouts.length - 1 === breakpoints.length) {\n return basicLayout / layouts[index];\n }\n return 1; // Default to ratio factor of 1\n };\n\n /**\n * Respond to window size changes and update CSS variable\n */\n const responsive = (): void => {\n const html = document.documentElement;\n const width = html.clientWidth;\n // 100rem = 100vw = design width\n let vw = width / 100;\n\n for (let i = 0; i < breakpoints.length; i++) {\n if (width <= breakpoints[i]) {\n // Should use layouts[i] as the base\n vw = vw * getBreakpointRatio(i);\n break;\n }\n }\n if (scope) {\n const { element = document.documentElement, cssVarName = '--local-scope-rem' } = scope;\n // Set the CSS variable --local-scope-rem for the element\n element.style.setProperty(cssVarName, vw + 'px');\n } else {\n html.style.fontSize = vw + 'px';\n }\n };\n\n if (immediate) {\n responsive();\n } else {\n window.addEventListener('load', responsive);\n }\n window.addEventListener('resize', responsive);\n if (orientationchange) {\n screen.orientation.addEventListener('change', responsive);\n }\n // Return cleanup function\n return () => {\n if (!immediate) {\n window.removeEventListener('load', responsive);\n }\n window.removeEventListener('resize', responsive);\n if (orientationchange) {\n screen.orientation.removeEventListener('change', responsive);\n }\n };\n};\n"],"names":["flexible","options","propBreakpoints","propLayouts","propBasicLayout","scope","immediate","orientationchange","breakpoints","a","b","layouts","basicLayout","getBreakpointRatio","index","responsive","html","width","vw","element","cssVarName"],"mappings":"AA+DO,MAAMA,IAAW,CAACC,IAA2B,OAAqB;AACjE,QAAA;AAAA,IACJ,aAAaC,IAAkB,CAAC,GAAG;AAAA,IACnC,SAASC;AAAA,IACT,aAAaC;AAAA,IACb,OAAAC;AAAA,IACA,WAAAC,IAAY;AAAA,IACZ,mBAAAC,IAAoB;AAAA,EAAA,IAClBN,GAEEO,IAAcN,EAAgB,KAAK,CAACO,GAAGC,MAAMD,IAAIC,CAAC,GAClDC,IAAUR,KAAA,gBAAAA,EAAa,KAAK,CAACM,GAAGC,MAAMD,IAAIC,IAC1CE,IAAcR,MAAmBO,KAAA,gBAAAA,EAAS,GAAG,MAO7CE,IAAqB,CAACC,MACtB,CAACH,KAAW,CAACC,IAAoB,IACjCD,EAAQ,SAAS,MAAMH,EAAY,SAC9BI,IAAcD,EAAQG,CAAK,IAE7B,GAMHC,IAAa,MAAY;AAC7B,UAAMC,IAAO,SAAS,iBAChBC,IAAQD,EAAK;AAEnB,QAAIE,IAAKD,IAAQ;AAEjB,aAAS,IAAI,GAAG,IAAIT,EAAY,QAAQ;AAClC,UAAAS,KAAST,EAAY,CAAC,GAAG;AAEtB,QAAAU,IAAAA,IAAKL,EAAmB,CAAC;AAC9B;AAAA,MAAA;AAGJ,QAAIR,GAAO;AACT,YAAM,EAAE,SAAAc,IAAU,SAAS,iBAAiB,YAAAC,IAAa,wBAAwBf;AAEjF,MAAAc,EAAQ,MAAM,YAAYC,GAAYF,IAAK,IAAI;AAAA,IAAA;AAE1C,MAAAF,EAAA,MAAM,WAAWE,IAAK;AAAA,EAE/B;AAEA,SAAIZ,IACSS,EAAA,IAEJ,OAAA,iBAAiB,QAAQA,CAAU,GAErC,OAAA,iBAAiB,UAAUA,CAAU,GACxCR,KACK,OAAA,YAAY,iBAAiB,UAAUQ,CAAU,GAGnD,MAAM;AACX,IAAKT,KACI,OAAA,oBAAoB,QAAQS,CAAU,GAExC,OAAA,oBAAoB,UAAUA,CAAU,GAC3CR,KACK,OAAA,YAAY,oBAAoB,UAAUQ,CAAU;AAAA,EAE/D;AACF;"}
|