unframer 1.5.0 → 1.7.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/README.md +33 -11
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +14 -1
- package/dist/cli.test.js.map +1 -1
- package/dist/css.d.ts +27 -0
- package/dist/css.d.ts.map +1 -0
- package/dist/css.js +158 -0
- package/dist/css.js.map +1 -0
- package/dist/exporter.d.ts +5 -6
- package/dist/exporter.d.ts.map +1 -1
- package/dist/exporter.js +77 -78
- package/dist/exporter.js.map +1 -1
- package/dist/react.d.ts +5 -10
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +7 -89
- package/dist/react.js.map +1 -1
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +11 -0
- package/dist/utils.js.map +1 -0
- package/framer-fixed/dist/framer.js +2 -2
- package/package.json +2 -1
- package/src/cli.test.ts +36 -6
- package/src/cli.tsx +3 -2
- package/src/css.ts +194 -0
- package/src/exporter.ts +119 -91
- package/src/react.tsx +11 -108
- package/src/utils.ts +11 -0
package/README.md
CHANGED
|
@@ -46,14 +46,12 @@ Download framer components as simple files
|
|
|
46
46
|
1. Import the component inside your `jsx` files, for example
|
|
47
47
|
|
|
48
48
|
```tsx
|
|
49
|
+
import './framer/styles.cs' // load base Framer styles
|
|
49
50
|
import Menu from './framer/menus'
|
|
50
|
-
import { FramerStyles } from 'unframer'
|
|
51
51
|
|
|
52
52
|
export default function App() {
|
|
53
53
|
return (
|
|
54
54
|
<div>
|
|
55
|
-
{/* Injects fonts and other framer utility styles */}
|
|
56
|
-
<FramerStyles Components={[Menu]} />
|
|
57
55
|
<Menu componentVariable='some variable' />
|
|
58
56
|
</div>
|
|
59
57
|
)
|
|
@@ -63,14 +61,12 @@ export default function App() {
|
|
|
63
61
|
## Using responsive variants
|
|
64
62
|
|
|
65
63
|
```tsx
|
|
64
|
+
import './framer/styles.cs'
|
|
66
65
|
import Logos from './framer/logos'
|
|
67
|
-
import { FramerStyles } from 'unframer'
|
|
68
66
|
|
|
69
67
|
export default function App() {
|
|
70
68
|
return (
|
|
71
69
|
<div>
|
|
72
|
-
{/* Injects fonts and other framer utility styles */}
|
|
73
|
-
<FramerStyles Components={[Logos]} />
|
|
74
70
|
{/* Changes component variant based on breakpoint */}
|
|
75
71
|
<Logos.Responsive
|
|
76
72
|
variants={{
|
|
@@ -91,14 +87,12 @@ You can use `className` or `style` props to style your components
|
|
|
91
87
|
Notice that you will often need to use `!important` to override styles already defined in framer like `width` and `height`
|
|
92
88
|
|
|
93
89
|
```tsx
|
|
90
|
+
import './framer/styles.cs'
|
|
94
91
|
import Logos from './framer/logos'
|
|
95
|
-
import { FramerStyles } from 'unframer'
|
|
96
92
|
|
|
97
93
|
export default function App() {
|
|
98
94
|
return (
|
|
99
95
|
<div>
|
|
100
|
-
{/* Injects fonts and other framer utility styles */}
|
|
101
|
-
<FramerStyles Components={[Logos]} />
|
|
102
96
|
{/* Changes component variant based on breakpoint */}
|
|
103
97
|
<Logos.responsive
|
|
104
98
|
className='!w-full'
|
|
@@ -113,6 +107,31 @@ export default function App() {
|
|
|
113
107
|
}
|
|
114
108
|
```
|
|
115
109
|
|
|
110
|
+
## Sizing components
|
|
111
|
+
|
|
112
|
+
Framer components can have a fixed size, this comes from the root element in the Framer component editor. To override this size you will need to use the `style` prop or use a class with high specificity.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import './framer/styles.cs'
|
|
116
|
+
import Logos from './framer/logos'
|
|
117
|
+
|
|
118
|
+
export default function App() {
|
|
119
|
+
return (
|
|
120
|
+
<div>
|
|
121
|
+
<Logos.responsive
|
|
122
|
+
className='!w-full' // use !important to override framer default size
|
|
123
|
+
style={{ width: '100%' }} // or use style prop, which has higher specificity than the Framer class
|
|
124
|
+
variants={{
|
|
125
|
+
lg: 'Desktop',
|
|
126
|
+
md: 'Tablet',
|
|
127
|
+
base: 'Mobile',
|
|
128
|
+
}}
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
116
135
|
## Supported component props
|
|
117
136
|
|
|
118
137
|
`unframer` will add TypeScript definitions for your Framer components props and variables, some example variables you can use are:
|
|
@@ -128,7 +147,6 @@ export default function App() {
|
|
|
128
147
|
|
|
129
148
|
Known limitations:
|
|
130
149
|
|
|
131
|
-
|
|
132
150
|
- Color styles (also known as tokens) can get out of sync with your Framer project, if this happen you will have to find the corresponding css variable (in the form of `--token-xxxx`) in the component code and define it in your CSS, for example:
|
|
133
151
|
|
|
134
152
|
```css
|
|
@@ -137,7 +155,11 @@ Known limitations:
|
|
|
137
155
|
}
|
|
138
156
|
```
|
|
139
157
|
|
|
140
|
-
-
|
|
158
|
+
- Links to Framer pages won't work, this is because links to Framer pages are encoded with opaque ids. Instead you should
|
|
159
|
+
|
|
160
|
+
1. use link variables
|
|
161
|
+
1. absolute links (starting with https://, not links to other Framer pages).
|
|
162
|
+
1. append a query when creating a link (for example instead of writing `/home` you write `/home?` and don't press enter, this will preserve the link as it is)
|
|
141
163
|
|
|
142
164
|
- Internationalization is not supported
|
|
143
165
|
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAaA,eAAO,MAAM,GAAG,mBAAQ,CAAA"}
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bundle
|
|
1
|
+
import { bundle } from './exporter.js';
|
|
2
2
|
import JSON from 'json5';
|
|
3
3
|
import { setMaxListeners } from 'events';
|
|
4
4
|
import chokidar from 'chokidar';
|
|
@@ -7,6 +7,7 @@ import { findUp } from 'find-up';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
const configName = 'unframer.json';
|
|
9
9
|
import { cac } from 'cac';
|
|
10
|
+
import { logger } from './utils.js';
|
|
10
11
|
export const cli = cac();
|
|
11
12
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
12
13
|
cli.command('', 'Run unframer')
|
|
@@ -119,7 +120,7 @@ async function processConfig({ config, watch, signal, }) {
|
|
|
119
120
|
}
|
|
120
121
|
catch (e) {
|
|
121
122
|
if (signal) {
|
|
122
|
-
logger.log('Error processing config', e.
|
|
123
|
+
logger.log('Error processing config', e.stack);
|
|
123
124
|
return;
|
|
124
125
|
}
|
|
125
126
|
throw e;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"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"}
|
package/dist/cli.test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import tmp from 'tmp';
|
|
2
2
|
import { test, expect } from 'vitest';
|
|
3
|
-
import { bundle, componentCamelCase, extractTokenInfo } from './exporter.js';
|
|
3
|
+
import { bundle, componentCamelCase, extractTokenInfo, findRelativeLinks, } from './exporter.js';
|
|
4
4
|
test('componentCamelCase', () => {
|
|
5
5
|
expect(componentCamelCase('logo-ticker')).toMatchInlineSnapshot(`"LogoTickerFramerComponent"`);
|
|
6
6
|
expect(componentCamelCase('Logo-Ticker')).toMatchInlineSnapshot(`"LogoTickerFramerComponent"`);
|
|
@@ -8,6 +8,19 @@ test('componentCamelCase', () => {
|
|
|
8
8
|
expect(componentCamelCase('nav')).toMatchInlineSnapshot(`"NavFramerComponent"`);
|
|
9
9
|
expect(componentCamelCase('framer_nav')).toMatchInlineSnapshot(`"FramerNavFramerComponent"`);
|
|
10
10
|
});
|
|
11
|
+
test('findRelativeLinks', () => {
|
|
12
|
+
expect(findRelativeLinks(`
|
|
13
|
+
some code
|
|
14
|
+
href: { pathVariables: { m3uy2HDcr: m3uy2HDcry78Q_MgWu2, }, webPageId: 'MREmP2Mxd', },
|
|
15
|
+
other code
|
|
16
|
+
webPageId: 'another id', webPageId: 'xxx',
|
|
17
|
+
`)).toMatchInlineSnapshot(`
|
|
18
|
+
[
|
|
19
|
+
2,
|
|
20
|
+
4,
|
|
21
|
+
]
|
|
22
|
+
`);
|
|
23
|
+
});
|
|
11
24
|
test('extractTokenInfo', async () => {
|
|
12
25
|
const str = `
|
|
13
26
|
some other code
|
package/dist/cli.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,
|
|
1
|
+
{"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":"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"}
|
package/dist/css.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ComponentFont } from './framer.js';
|
|
2
|
+
export declare const breakpointSizes: {
|
|
3
|
+
readonly base: 0;
|
|
4
|
+
readonly sm: 320;
|
|
5
|
+
readonly md: 768;
|
|
6
|
+
readonly lg: 960;
|
|
7
|
+
readonly xl: 1200;
|
|
8
|
+
readonly '2xl': 1536;
|
|
9
|
+
};
|
|
10
|
+
export type ComponentFontBundle = {
|
|
11
|
+
/**
|
|
12
|
+
* This flag specifies whether the font bundle includes the specific font
|
|
13
|
+
* weights of Framer’s Inter font that the component uses. New smart
|
|
14
|
+
* components do that (which means we can emit CSS only for Inter fonts that
|
|
15
|
+
* are actually used); older smart components don’t (which means some places
|
|
16
|
+
* will emit CSS for all Inter fonts if this flag is not set).
|
|
17
|
+
* https://www.notion.so/framer/RFC-ComponentFont-v2-d5fd3e822fb049ffb6971554ab0e4e42
|
|
18
|
+
*/
|
|
19
|
+
explicitInter: boolean;
|
|
20
|
+
fileName?: string;
|
|
21
|
+
fonts: ComponentFont[];
|
|
22
|
+
};
|
|
23
|
+
export declare function logFontsUsage(fontsBundles: ComponentFontBundle[]): string;
|
|
24
|
+
export declare function getFontsStyles(_fontsDefs: ComponentFontBundle[]): string;
|
|
25
|
+
export declare const breakpointsStyles: string;
|
|
26
|
+
export declare function groupBy<T>(arr: T[], key: (x: T) => string): Map<string, T[]>;
|
|
27
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAA;AAcV,MAAM,MAAM,mBAAmB,GAAG;IAC9B;;;;;;;OAOG;IACH,aAAa,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,aAAa,EAAE,CAAA;CACzB,CAAA;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,mBAAmB,EAAE,UAuBhE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,mBAAmB,EAAE,UAwD/D;AAED,eAAO,MAAM,iBAAiB,QAwD7B,CAAA;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,oBAUzD"}
|
package/dist/css.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import dedent from 'dedent';
|
|
2
|
+
export const breakpointSizes = {
|
|
3
|
+
base: 0,
|
|
4
|
+
sm: 320,
|
|
5
|
+
md: 768,
|
|
6
|
+
lg: 960,
|
|
7
|
+
xl: 1200,
|
|
8
|
+
'2xl': 1536,
|
|
9
|
+
};
|
|
10
|
+
function deduplicateByKey(arr, key) {
|
|
11
|
+
let map = new Map();
|
|
12
|
+
for (let item of arr) {
|
|
13
|
+
let value = key(item);
|
|
14
|
+
if (map.has(value)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
map.set(value, item);
|
|
18
|
+
}
|
|
19
|
+
return Array.from(map.values());
|
|
20
|
+
}
|
|
21
|
+
export function logFontsUsage(fontsBundles) {
|
|
22
|
+
if (!fontsBundles.length) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
let familyToFilenames = new Map();
|
|
26
|
+
for (let fontDefBundle of fontsBundles) {
|
|
27
|
+
let filename = fontDefBundle.fileName;
|
|
28
|
+
for (let font of fontDefBundle.fonts) {
|
|
29
|
+
if (familyToFilenames.has(font.family)) {
|
|
30
|
+
familyToFilenames.get(font.family).add(filename);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
familyToFilenames.set(font.family, new Set([filename]));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
let str = `There are ${familyToFilenames.size} fonts used:\n`;
|
|
38
|
+
for (let [family, filenames] of familyToFilenames.entries()) {
|
|
39
|
+
str += `${JSON.stringify(family)}, used by\n`;
|
|
40
|
+
for (let filename of filenames) {
|
|
41
|
+
str += ` - ${filename}\n`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return str;
|
|
45
|
+
}
|
|
46
|
+
export function getFontsStyles(_fontsDefs) {
|
|
47
|
+
if (!_fontsDefs.length) {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
let urlToFilenames = new Map();
|
|
51
|
+
for (let fontDefBundle of _fontsDefs) {
|
|
52
|
+
let filename = fontDefBundle.fileName;
|
|
53
|
+
for (let font of fontDefBundle.fonts) {
|
|
54
|
+
if (urlToFilenames.has(font.url)) {
|
|
55
|
+
urlToFilenames.get(font.url).add(filename);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
urlToFilenames.set(font.url, new Set([filename]));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const allFonts = deduplicateByKey(_fontsDefs.flatMap((x) => x.fonts), (x) => x?.url).filter((x) => x.url);
|
|
63
|
+
// group fonts by the filenames users
|
|
64
|
+
const grouped = groupBy(allFonts, (x) => {
|
|
65
|
+
return [...(urlToFilenames.get(x.url) || [])].sort().join(', ');
|
|
66
|
+
});
|
|
67
|
+
let str = '\n\n';
|
|
68
|
+
for (let [groupComment, fonts] of grouped.entries()) {
|
|
69
|
+
fonts = sortByKey(fonts, (x) => x.url);
|
|
70
|
+
str += `/* used by ${groupComment} */\n`;
|
|
71
|
+
str +=
|
|
72
|
+
'\n' +
|
|
73
|
+
fonts
|
|
74
|
+
.map((x) => {
|
|
75
|
+
let str = '';
|
|
76
|
+
str += dedent `
|
|
77
|
+
@font-face {
|
|
78
|
+
font-family: '${x.family}';
|
|
79
|
+
src: url(${x.url});\n`;
|
|
80
|
+
if (x.style) {
|
|
81
|
+
str += ` font-style: ${x.style};\n`;
|
|
82
|
+
}
|
|
83
|
+
if (x.weight) {
|
|
84
|
+
str += ` font-weight: ${x.weight};\n`;
|
|
85
|
+
}
|
|
86
|
+
if (x.unicodeRange) {
|
|
87
|
+
str += ` unicodeRange: ${x.unicodeRange};\n`;
|
|
88
|
+
}
|
|
89
|
+
str += `}\n`;
|
|
90
|
+
return str;
|
|
91
|
+
})
|
|
92
|
+
.join('\n') +
|
|
93
|
+
'\n';
|
|
94
|
+
}
|
|
95
|
+
return str;
|
|
96
|
+
}
|
|
97
|
+
export const breakpointsStyles = /* css */ `
|
|
98
|
+
/* Base */
|
|
99
|
+
@media (min-width: ${breakpointSizes.base}px) and (max-width: ${breakpointSizes.sm - 1}px) {
|
|
100
|
+
.unframer-hidden.unframer-base {
|
|
101
|
+
display: contents;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Small */
|
|
106
|
+
@media (min-width: ${breakpointSizes.sm}px) and (max-width: ${breakpointSizes.md - 1}px) {
|
|
107
|
+
.unframer-hidden.unframer-sm {
|
|
108
|
+
display: contents;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Medium */
|
|
113
|
+
@media (min-width: ${breakpointSizes.md}px) and (max-width: ${breakpointSizes.lg - 1}px) {
|
|
114
|
+
.unframer-hidden.unframer-md {
|
|
115
|
+
display: contents;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Large */
|
|
120
|
+
@media (min-width: ${breakpointSizes.lg}px) and (max-width: ${breakpointSizes.xl - 1}px) {
|
|
121
|
+
.unframer-hidden.unframer-lg {
|
|
122
|
+
display: contents;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* Extra Large */
|
|
127
|
+
@media (min-width: ${breakpointSizes.xl}px) and (max-width: ${breakpointSizes['2xl'] - 1}px) {
|
|
128
|
+
.unframer-hidden.unframer-xl {
|
|
129
|
+
display: contents;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* 2 Extra Large */
|
|
134
|
+
@media (min-width: ${breakpointSizes['2xl']}px) {
|
|
135
|
+
.unframer-hidden.unframer-2xl {
|
|
136
|
+
display: contents;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.unframer-hidden {
|
|
141
|
+
display: none;
|
|
142
|
+
}
|
|
143
|
+
`;
|
|
144
|
+
export function groupBy(arr, key) {
|
|
145
|
+
const map = new Map();
|
|
146
|
+
for (let item of arr) {
|
|
147
|
+
const k = key(item);
|
|
148
|
+
if (!map.has(k)) {
|
|
149
|
+
map.set(k, []);
|
|
150
|
+
}
|
|
151
|
+
map.get(k)?.push(item);
|
|
152
|
+
}
|
|
153
|
+
return map;
|
|
154
|
+
}
|
|
155
|
+
function sortByKey(arr, key) {
|
|
156
|
+
return arr.slice().sort((a, b) => key(a).localeCompare(key(b)));
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=css.js.map
|
package/dist/css.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.js","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"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"}
|
package/dist/exporter.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Plugin } from 'esbuild';
|
|
2
2
|
import { PropertyControls } from '../framer-fixed/dist/framer.js';
|
|
3
|
-
|
|
4
|
-
log(...args: any[]): void;
|
|
5
|
-
error(...args: any[]): void;
|
|
6
|
-
};
|
|
3
|
+
import { ComponentFontBundle } from './css.js';
|
|
7
4
|
export declare function bundle({ cwd: out, watch, components, signal, }: {
|
|
8
5
|
cwd?: string | undefined;
|
|
9
6
|
watch?: boolean | undefined;
|
|
@@ -12,7 +9,10 @@ export declare function bundle({ cwd: out, watch, components, signal, }: {
|
|
|
12
9
|
}): Promise<void>;
|
|
13
10
|
export declare function findRelativeLinks(text: string): number[];
|
|
14
11
|
export declare function extractPropControlsSafe(text: any, name: any): Promise<PropertyControls<any, any> | undefined>;
|
|
15
|
-
export declare function extractPropControlsUnsafe(filename: any, name: any): Promise<
|
|
12
|
+
export declare function extractPropControlsUnsafe(filename: any, name: any): Promise<{
|
|
13
|
+
propertyControls?: PropertyControls;
|
|
14
|
+
fonts?: ComponentFontBundle[];
|
|
15
|
+
}>;
|
|
16
16
|
export declare function propControlsToType(controls: PropertyControls, fileName: any): string;
|
|
17
17
|
export declare function parsePropertyControls(code: string): string | null;
|
|
18
18
|
export declare function esbuildPluginBundleDependencies({ signal, }: {
|
|
@@ -24,7 +24,6 @@ export declare function resolveRedirect({ redirectCache, signal, url, }: {
|
|
|
24
24
|
signal?: AbortSignal;
|
|
25
25
|
}): Promise<any>;
|
|
26
26
|
export declare function recursiveResolveRedirect(url?: string, signal?: AbortSignal): Promise<string | undefined>;
|
|
27
|
-
export declare function deduplicateByKey<T>(key: keyof T, arr: (T | undefined)[]): any[];
|
|
28
27
|
type TokenInfo = {
|
|
29
28
|
tokenName: string;
|
|
30
29
|
metadata?: Record<string, any>;
|
package/dist/exporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA0C,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA0C,MAAM,SAAS,CAAA;AAOxE,OAAO,EAIH,gBAAgB,EAEnB,MAAM,gCAAgC,CAAA;AAKvC,OAAO,EACH,mBAAmB,EAKtB,MAAM,UAAU,CAAA;AAcjB,wBAAsB,MAAM,CAAC,EACzB,GAAG,EAAE,GAAQ,EACb,KAAa,EACb,UAAyC,EACzC,MAA6C,GAChD;;;;;CAAA,iBAkRA;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,YAY7C;AAED,wBAAsB,uBAAuB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,mDAmCvD;AAmGD,wBAAsB,yBAAyB,CAC3C,QAAQ,KAAA,EACR,IAAI,KAAA,GACL,OAAO,CAAC;IACP,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,KAAK,CAAC,EAAE,mBAAmB,EAAE,CAAA;CAChC,CAAC,CAsBD;AAWD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,KAAA,UA4FtE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,iBAqCjD;AAWD,wBAAgB,+BAA+B,CAAC,EAC5C,MAA6C,GAChD;;CAAA,UA0IA;AAED,wBAAsB,eAAe,CAAC,EAClC,aAAa,EACb,MAAM,EACN,GAAG,GACN,EAAE;IACC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,aAAa,CAAC,EAAE,GAAG,CAAA;IACnB,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB,gBAkBA;AAED,wBAAsB,wBAAwB,CAC1C,GAAG,CAAC,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,+BAkBvB;AAgCD,KAAK,SAAS,GAAG;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE9B,YAAY,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CA2D1D;AASD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,UAS7C"}
|
package/dist/exporter.js
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
import { transform, context } from 'esbuild';
|
|
2
|
+
import { Sema } from 'async-sema';
|
|
2
3
|
import dprint from 'dprint-node';
|
|
3
|
-
import pico from 'picocolors';
|
|
4
4
|
import { polyfillNode } from 'esbuild-plugin-polyfill-node';
|
|
5
|
-
import { ControlType, } from '../framer-fixed/dist/framer.js';
|
|
5
|
+
import { ControlType, combinedCSSRules, } from '../framer-fixed/dist/framer.js';
|
|
6
6
|
import { fetch as _fetch } from 'native-fetch';
|
|
7
7
|
import fs from 'fs';
|
|
8
8
|
import path from 'path';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
log(...args) {
|
|
14
|
-
console.log(prefix, ...args);
|
|
15
|
-
},
|
|
16
|
-
error(...args) {
|
|
17
|
-
console.error([prefix, ...args].map((x) => pico.red(x)).join(' '));
|
|
18
|
-
},
|
|
19
|
-
};
|
|
9
|
+
import { exec } from 'child_process';
|
|
10
|
+
import { breakpointsStyles, getFontsStyles, groupBy, logFontsUsage, } from './css.js';
|
|
11
|
+
import dedent from 'dedent';
|
|
12
|
+
import { logger } from './utils.js';
|
|
20
13
|
const fetchWithRetry = retryTwice(_fetch);
|
|
21
14
|
function validateUrl(url) {
|
|
22
15
|
try {
|
|
@@ -125,27 +118,60 @@ export async function bundle({ cwd: out = '', watch = false, components = {}, si
|
|
|
125
118
|
logger.log(`writing`, path.relative(out, file.path));
|
|
126
119
|
fs.writeFileSync(resultPathAbs, codeNew, 'utf-8');
|
|
127
120
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
121
|
+
let allFonts = [];
|
|
122
|
+
const sema = new Sema(10);
|
|
123
|
+
const packageJson = path.resolve(out, 'package.json');
|
|
124
|
+
fs.writeFileSync(packageJson, JSON.stringify({ type: 'module' }), 'utf-8');
|
|
125
|
+
try {
|
|
126
|
+
await Promise.all(result.outputFiles.map(async (file) => {
|
|
127
|
+
try {
|
|
128
|
+
await sema.acquire();
|
|
129
|
+
const name = path
|
|
130
|
+
.basename(file.path)
|
|
131
|
+
.replace(/\.js$/, '');
|
|
132
|
+
const resultPathAbs = path.resolve(out, file.path);
|
|
133
|
+
if (!components[name]) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
logger.log(`extracting types for ${name}`);
|
|
137
|
+
const { propertyControls, fonts } = await extractPropControlsUnsafe(resultPathAbs, name);
|
|
138
|
+
if (!propertyControls) {
|
|
139
|
+
logger.log(`no property controls found for ${name}`);
|
|
140
|
+
}
|
|
141
|
+
allFonts.push(...(fonts || []).map((x) => ({
|
|
142
|
+
...x,
|
|
143
|
+
fileName: path.basename(file.path),
|
|
144
|
+
})));
|
|
145
|
+
const types = propControlsToType(propertyControls, name);
|
|
146
|
+
// name = 'framer-' + name
|
|
147
|
+
// logger.log('name', name)
|
|
148
|
+
fs.writeFileSync(path.resolve(out, `${name}.d.ts`), types);
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
sema.release();
|
|
152
|
+
}
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
fs.rmSync(packageJson);
|
|
143
157
|
}
|
|
158
|
+
const cssString = '/* This css file has all the necessary styles to run all your components */\n' +
|
|
159
|
+
breakpointsStyles +
|
|
160
|
+
'\n\n' +
|
|
161
|
+
combinedCSSRules
|
|
162
|
+
.map((x) => (x?.startsWith(' ') ? dedent(x) : x))
|
|
163
|
+
.join('\n') +
|
|
164
|
+
getFontsStyles(allFonts);
|
|
165
|
+
fs.writeFileSync(path.resolve(out, 'styles.css'), cssString, 'utf-8');
|
|
166
|
+
logFontsUsage(allFonts)
|
|
167
|
+
.split('\n')
|
|
168
|
+
.forEach((x) => logger.log(x));
|
|
144
169
|
const outFiles = result.outputFiles
|
|
145
170
|
.map((x) => path.resolve(out, x.path))
|
|
146
171
|
.concat([
|
|
147
172
|
path.resolve(out, 'meta.json'),
|
|
148
173
|
path.resolve(out, 'tokens.css'),
|
|
174
|
+
path.resolve(out, 'styles.css'),
|
|
149
175
|
])
|
|
150
176
|
.concat(result.outputFiles.map((x) => path.resolve(out, x.path.replace('.js', '.d.ts'))));
|
|
151
177
|
const filesToDelete = prevFiles.filter((x) => !outFiles.includes(x));
|
|
@@ -161,7 +187,9 @@ export async function bundle({ cwd: out = '', watch = false, components = {}, si
|
|
|
161
187
|
if (watch) {
|
|
162
188
|
logger.log('waiting for components or config changes');
|
|
163
189
|
}
|
|
164
|
-
const tokensCss =
|
|
190
|
+
const tokensCss = "/* This css file contains your color variables, sometimes these get desynced when updated in Framer so it's good that you copy and paste this snippet into your app css */\n" +
|
|
191
|
+
'/* Bug: https://www.framer.community/c/bugs/color-style-unlinks-when-copying-component-between-projects-resulting-in-potential-value-discrepancy */\n' +
|
|
192
|
+
getTokensCss({ out, result });
|
|
165
193
|
fs.writeFileSync(path.resolve(out, 'tokens.css'), tokensCss, 'utf-8');
|
|
166
194
|
}
|
|
167
195
|
if (!watch) {
|
|
@@ -213,17 +241,15 @@ function decapitalize(str) {
|
|
|
213
241
|
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
214
242
|
}
|
|
215
243
|
export function findRelativeLinks(text) {
|
|
216
|
-
// regex to match these objects, could be in different lines or formatted, webPageId is the key element
|
|
217
|
-
// href: { webPageId: 'someId' }
|
|
218
244
|
const regex = /webPageId:\s+/g;
|
|
219
|
-
const matches = text.matchAll(regex);
|
|
220
|
-
// get line number for each match
|
|
221
245
|
const lines = text.split('\n');
|
|
222
|
-
const lineNumbers =
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
246
|
+
const lineNumbers = new Set();
|
|
247
|
+
for (let i = 0; i < lines.length; i++) {
|
|
248
|
+
if (regex.test(lines[i])) {
|
|
249
|
+
lineNumbers.add(i);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return [...lineNumbers];
|
|
227
253
|
}
|
|
228
254
|
export async function extractPropControlsSafe(text, name) {
|
|
229
255
|
try {
|
|
@@ -330,26 +356,20 @@ function getTokensCss({ out, result, }) {
|
|
|
330
356
|
return tokensCss;
|
|
331
357
|
}
|
|
332
358
|
export async function extractPropControlsUnsafe(filename, name) {
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
let propCode = `JSON.stringify(x.default?.propertyControls || null, null, 2)`;
|
|
338
|
-
// propCode = `x.default`
|
|
339
|
-
const code = `import(${JSON.stringify(filename)}).then(x => { console.log(${JSON.stringify(delimiter)}); console.log(${propCode})
|
|
359
|
+
const delimiter = '__delimiter__';
|
|
360
|
+
let propCode = `JSON.stringify({propertyControls: x.default?.propertyControls, fonts: x?.default?.fonts } || {}, null, 2)`;
|
|
361
|
+
// propCode = `x.default`
|
|
362
|
+
const code = `import(${JSON.stringify(filename)}).then(x => { console.log(${JSON.stringify(delimiter)}); console.log(${propCode})
|
|
340
363
|
})`;
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
finally {
|
|
351
|
-
fs.rmSync(packageJson);
|
|
352
|
-
}
|
|
364
|
+
let stdout = await new Promise((res, rej) => exec(`node --input-type=module -e '${code}'`, (err, stdout) => {
|
|
365
|
+
if (err) {
|
|
366
|
+
return rej(err);
|
|
367
|
+
}
|
|
368
|
+
res(stdout);
|
|
369
|
+
}));
|
|
370
|
+
stdout = stdout.split(delimiter)[1];
|
|
371
|
+
// console.log(stdout)
|
|
372
|
+
return safeJsonParse(stdout);
|
|
353
373
|
}
|
|
354
374
|
function safeJsonParse(text) {
|
|
355
375
|
try {
|
|
@@ -678,16 +698,6 @@ function retryTwice(fn) {
|
|
|
678
698
|
}
|
|
679
699
|
};
|
|
680
700
|
}
|
|
681
|
-
export function deduplicateByKey(key, arr) {
|
|
682
|
-
const map = new Map();
|
|
683
|
-
for (let item of arr) {
|
|
684
|
-
if (!item) {
|
|
685
|
-
continue;
|
|
686
|
-
}
|
|
687
|
-
map.set(item?.[key], item);
|
|
688
|
-
}
|
|
689
|
-
return Array.from(map.values());
|
|
690
|
-
}
|
|
691
701
|
export function extractTokenInfo(code) {
|
|
692
702
|
const lines = code.split('\n');
|
|
693
703
|
const tokenLines = lines.filter((line) => line.includes('var(--token'));
|
|
@@ -750,17 +760,6 @@ function splitOnce(str, separator) {
|
|
|
750
760
|
}
|
|
751
761
|
return [str.slice(0, index), str.slice(index + 1)];
|
|
752
762
|
}
|
|
753
|
-
function groupBy(arr, key) {
|
|
754
|
-
const map = new Map();
|
|
755
|
-
for (let item of arr) {
|
|
756
|
-
const k = key(item);
|
|
757
|
-
if (!map.has(k)) {
|
|
758
|
-
map.set(k, []);
|
|
759
|
-
}
|
|
760
|
-
map.get(k)?.push(item);
|
|
761
|
-
}
|
|
762
|
-
return map;
|
|
763
|
-
}
|
|
764
763
|
export function componentCamelCase(str) {
|
|
765
764
|
if (!str) {
|
|
766
765
|
return 'FramerComponent';
|