framercode 0.1.0 → 0.1.1
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/dist/react.js +37 -2
- package/package.json +37 -37
package/dist/react.js
CHANGED
|
@@ -40,6 +40,40 @@ const subscribeResize = (callback) => {
|
|
|
40
40
|
window.addEventListener('resize', callback);
|
|
41
41
|
return () => window.removeEventListener('resize', callback);
|
|
42
42
|
};
|
|
43
|
+
const TITLE_WIDTHS = {
|
|
44
|
+
desktop: 1200,
|
|
45
|
+
laptop: 1024,
|
|
46
|
+
tablet: 810,
|
|
47
|
+
phone: 390,
|
|
48
|
+
};
|
|
49
|
+
const BREAKPOINT_ORDER = ['base', 'sm', 'md', 'lg', 'xl', '2xl'];
|
|
50
|
+
// Fallback when the export carried no breakpoint widths: the module's own
|
|
51
|
+
// variant control (options + optionTitles like "Desktop"/"Phone") is mapped
|
|
52
|
+
// to Framer's standard breakpoint widths.
|
|
53
|
+
function variantsFromControls(Component) {
|
|
54
|
+
const variant = Component?.propertyControls?.variant;
|
|
55
|
+
if (!variant || !Array.isArray(variant.options))
|
|
56
|
+
return {};
|
|
57
|
+
const titles = Array.isArray(variant.optionTitles) ? variant.optionTitles : [];
|
|
58
|
+
const entries = [];
|
|
59
|
+
variant.options.forEach((option, i) => {
|
|
60
|
+
if (typeof option !== 'string')
|
|
61
|
+
return;
|
|
62
|
+
const width = TITLE_WIDTHS[String(titles[i] ?? '').trim().toLowerCase()];
|
|
63
|
+
if (!width)
|
|
64
|
+
return;
|
|
65
|
+
const bp = breakpointForWidth(width);
|
|
66
|
+
if (bp && !entries.some(([existing]) => existing === bp))
|
|
67
|
+
entries.push([bp, option]);
|
|
68
|
+
});
|
|
69
|
+
if (entries.length === 0)
|
|
70
|
+
return {};
|
|
71
|
+
entries.sort((a, b) => BREAKPOINT_ORDER.indexOf(a[0]) - BREAKPOINT_ORDER.indexOf(b[0]));
|
|
72
|
+
const map = { base: entries[0][1] };
|
|
73
|
+
for (const [bp, option] of entries)
|
|
74
|
+
map[bp] = option;
|
|
75
|
+
return map;
|
|
76
|
+
}
|
|
43
77
|
/**
|
|
44
78
|
* Renders the variant of a component matching the current viewport width.
|
|
45
79
|
* All variants are rendered hidden via `.framercode-hidden` and the active one is
|
|
@@ -48,10 +82,11 @@ const subscribeResize = (callback) => {
|
|
|
48
82
|
export function WithFramerBreakpoints({ Component, variants, ...rest }) {
|
|
49
83
|
// getServerSnapshot returns '' so SSR/hydration match (server renders all).
|
|
50
84
|
const current = useSyncExternalStore(subscribeResize, () => breakpointForWidth(window.innerWidth) ?? '', () => '');
|
|
51
|
-
|
|
85
|
+
const effectiveVariants = isEmpty(variants) ? variantsFromControls(Component) : variants;
|
|
86
|
+
if (isEmpty(effectiveVariants)) {
|
|
52
87
|
return _jsx(Component, { ...rest });
|
|
53
88
|
}
|
|
54
|
-
const filled = fillBreakpoints(
|
|
89
|
+
const filled = fillBreakpoints(effectiveVariants);
|
|
55
90
|
const groups = new Map();
|
|
56
91
|
for (const bp of Object.keys(filled)) {
|
|
57
92
|
const variant = filled[bp];
|
package/package.json
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "framercode",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "Run Framer components exported by Framer Code in your own React app. Minimal runtime, no lock-in.",
|
|
6
|
-
"sideEffects": false,
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"main": "./dist/index.js",
|
|
9
|
-
"types": "./dist/index.d.ts",
|
|
10
|
-
"exports": {
|
|
11
|
-
".": {
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
13
|
-
"default": "./dist/index.js"
|
|
14
|
-
},
|
|
15
|
-
"./styles/*": {
|
|
16
|
-
"default": "./dist/styles/*"
|
|
17
|
-
},
|
|
18
|
-
"./package.json": "./package.json"
|
|
19
|
-
},
|
|
20
|
-
"files": [
|
|
21
|
-
"dist"
|
|
22
|
-
],
|
|
23
|
-
"scripts": {
|
|
24
|
-
"build": "tsc -p tsconfig.json && node scripts/postbuild.mjs",
|
|
25
|
-
"check-types": "tsc -p tsconfig.json --noEmit"
|
|
26
|
-
},
|
|
27
|
-
"peerDependencies": {
|
|
28
|
-
"react": "^18 || ^19",
|
|
29
|
-
"react-dom": "^18 || ^19"
|
|
30
|
-
},
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"@types/react": "^18",
|
|
33
|
-
"@types/react-dom": "^18",
|
|
34
|
-
"react": "^18",
|
|
35
|
-
"react-dom": "^18",
|
|
36
|
-
"typescript": "^5.9"
|
|
37
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "framercode",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Run Framer components exported by Framer Code in your own React app. Minimal runtime, no lock-in.",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./styles/*": {
|
|
16
|
+
"default": "./dist/styles/*"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -p tsconfig.json && node scripts/postbuild.mjs",
|
|
25
|
+
"check-types": "tsc -p tsconfig.json --noEmit"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": "^18 || ^19",
|
|
29
|
+
"react-dom": "^18 || ^19"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/react": "^18",
|
|
33
|
+
"@types/react-dom": "^18",
|
|
34
|
+
"react": "^18",
|
|
35
|
+
"react-dom": "^18",
|
|
36
|
+
"typescript": "^5.9"
|
|
37
|
+
}
|
|
38
38
|
}
|