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 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
- - Instead of using relative links to your Framer components you should either use link variables or absolute links (starting with https://, not links to other Framer pages). This is because links to Framer pages are encoded with opaque ids.
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":"AAYA,eAAO,MAAM,GAAG,mBAAQ,CAAA"}
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, logger } from './exporter.js';
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.message);
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":"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"}
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
@@ -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,EAAE,MAAM,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAE5E,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAC5B,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC,qBAAqB,CAAC,6BAA6B,CAAC,CAAA;IAC9F,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC,qBAAqB,CAAC,6BAA6B,CAAC,CAAA;IAC9F,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,CAAA;IACjF,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,sBAAsB,CAAC,CAAA;IAC/E,MAAM,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,qBAAqB,CAAC,4BAA4B,CAAC,CAAA;AAChG,CAAC,CAAC,CAAA;AAEF,IAAI,CACA,kBAAkB,EAClB,KAAK,IAAI,EAAE;IACP,MAAM,GAAG,GAAG;;;;;;;;;;SAUX,CAAA;IACD,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IACpC,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAqCpC,CAAC,CAAA;AACN,CAAC,EACD,IAAI,GAAG,EAAE,CACZ,CAAA;AACD,IAAI,CACA,yBAAyB,EACzB,KAAK,IAAI,EAAE;IACP,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAA;IAC5D,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IACrC,MAAM,GAAG,GACL,+DAA+D,CAAA;IACnE,MAAM,MAAM,CAAC;QACT,UAAU,EAAE;YACR,MAAM,EAAE,GAAG;SACd;QACD,GAAG,EAAE,UAAU;KAClB,CAAC,CAAA;AACN,CAAC,EACD,IAAI,GAAG,EAAE,CACZ,CAAA;AACD,IAAI,CACA,UAAU,EACV,KAAK,IAAI,EAAE;IACP,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAA;IAC5D,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IACrC,MAAM,GAAG,GAAG,wDAAwD,CAAA;IACpE,MAAM,MAAM,CAAC;QACT,UAAU,EAAE;YACR,IAAI,EAAE,GAAG;SACZ;QACD,GAAG,EAAE,UAAU;KAClB,CAAC,CAAA;AACN,CAAC,EACD,IAAI,GAAG,EAAE,CACZ,CAAA;AACD,IAAI,CACA,uBAAuB,EACvB,KAAK,IAAI,EAAE;IACP,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAA;IAC5D,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IACrC,MAAM,GAAG,GACL,qEAAqE,CAAA;IACzE,MAAM,MAAM,CAAC;QACT,UAAU,EAAE;YACR,KAAK,EAAE,GAAG;SACb;QACD,GAAG,EAAE,UAAU;KAClB,CAAC,CAAA;AACN,CAAC,EACD,IAAI,GAAG,EAAE,CACZ,CAAA"}
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.js","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,6 @@
1
1
  import { Plugin } from 'esbuild';
2
2
  import { PropertyControls } from '../framer-fixed/dist/framer.js';
3
- export declare const logger: {
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<any>;
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>;
@@ -1 +1 @@
1
- {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA0C,MAAM,SAAS,CAAA;AAQxE,OAAO,EAGH,gBAAgB,EACnB,MAAM,gCAAgC,CAAA;AAQvC,eAAO,MAAM,MAAM;;;CAOlB,CAAA;AAYD,wBAAsB,MAAM,CAAC,EACzB,GAAG,EAAE,GAAQ,EACb,KAAa,EACb,UAAyC,EACzC,MAA6C,GAChD;;;;;CAAA,iBA+NA;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,YAY7C;AAED,wBAAsB,uBAAuB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,mDAmCvD;AAmGD,wBAAsB,yBAAyB,CAAC,QAAQ,KAAA,EAAE,IAAI,KAAA,gBA2B7D;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,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,SASvE;AAED,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;AAqBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,UAS7C"}
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 { execSync } from 'child_process';
10
- const __dirname = path.dirname(new URL(import.meta.url).pathname);
11
- const prefix = '[unframer]';
12
- export const logger = {
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
- for (let file of result.outputFiles) {
129
- const name = path.basename(file.path).replace(/\.js$/, '');
130
- const resultPathAbs = path.resolve(out, file.path);
131
- if (!components[name]) {
132
- continue;
133
- }
134
- logger.log(`extracting types for ${name}`);
135
- const propControls = await extractPropControlsUnsafe(resultPathAbs, name);
136
- if (!propControls) {
137
- logger.log(`no property controls found for ${name}`);
138
- }
139
- const types = propControlsToType(propControls, name);
140
- // name = 'framer-' + name
141
- // logger.log('name', name)
142
- fs.writeFileSync(path.resolve(out, `${name}.d.ts`), types);
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 = getTokensCss({ out, result });
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 = Array.from(matches, (match) => {
223
- const index = lines.findIndex((line) => line.includes(match[0]));
224
- return index;
225
- });
226
- return lineNumbers;
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 packageJson = path.resolve(path.dirname(filename), 'package.json');
334
- try {
335
- fs.writeFileSync(packageJson, JSON.stringify({ type: 'module' }), 'utf-8');
336
- const delimiter = '__delimiter__';
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
- const res = execSync(`node --input-type=module -e '${code}'`);
342
- let stdout = res.toString();
343
- stdout = stdout.split(delimiter)[1];
344
- // console.log(stdout)
345
- return safeJsonParse(stdout);
346
- }
347
- catch (e) {
348
- logger.error(`Cannot get property controls for ${name}`, e.stack);
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';