+
);
diff --git a/src/interface/base/Tabs.tsx b/src/interface/base/Tabs.tsx
new file mode 100644
index 00000000..ad5c00f2
--- /dev/null
+++ b/src/interface/base/Tabs.tsx
@@ -0,0 +1,18 @@
+import {h} from 'preact';
+import {Root, List, Trigger, Content} from '@radix-ui/react-tabs';
+
+export function Tabs(props: any) {
+ return
;
+}
+
+export function Bar(props: any) {
+ return
;
+}
+
+export function Link(props: any) {
+ return
;
+}
+
+export function Tab(props: any) {
+ return
;
+}
diff --git a/src/interface/hooks/useComponent.ts b/src/interface/hooks/useComponent.ts
index 384ef4a6..326901f4 100644
--- a/src/interface/hooks/useComponent.ts
+++ b/src/interface/hooks/useComponent.ts
@@ -1,9 +1,8 @@
-import {useState, useEffect} from 'react';
+import {useState, useEffect} from 'preact/hooks';
import {EditorComponent} from 'types/editor';
-export function useComponent() {
+export function useComponent(): EditorComponent {
const [component, setComponent] = useState
(null);
-
useEffect(() => {
const onMessage = (e: MessageEvent) => {
if (e.data?.pluginMessage?.type === 'code')
@@ -12,6 +11,5 @@ export function useComponent() {
addEventListener('message', onMessage);
return () => removeEventListener('message', onMessage);
}, []);
-
return component;
}
diff --git a/src/interface/hooks/useDarkMode.ts b/src/interface/hooks/useDarkMode.ts
index abda1993..b63de9d6 100644
--- a/src/interface/hooks/useDarkMode.ts
+++ b/src/interface/hooks/useDarkMode.ts
@@ -1,15 +1,13 @@
-import {useRef, useState, useEffect} from 'react';
+import {useRef, useState, useEffect} from 'preact/hooks';
-export function useDarkMode() {
+export function useDarkMode(): boolean {
const htmlRef = useRef(document.body.parentElement);
const [isDark, setDark] = useState(htmlRef.current.classList.contains('figma-dark'));
-
useEffect(() => {
const $ = new MutationObserver(() =>
setDark(htmlRef.current.classList.contains('figma-dark')));
$.observe(htmlRef.current, {attributes: true});
return () => $.disconnect();
}, []);
-
return isDark;
}
diff --git a/src/interface/hooks/useEditor.ts b/src/interface/hooks/useEditor.ts
index 30bb1082..85e8b515 100644
--- a/src/interface/hooks/useEditor.ts
+++ b/src/interface/hooks/useEditor.ts
@@ -1,6 +1,6 @@
-import {useEffect} from 'react';
+import {useEffect} from 'preact/hooks';
import {useMonaco} from '@monaco-editor/react';
-import schemaSettings from 'templates/schema.json';
+import schemaSettings from 'templates/settings/schema.json';
// import AutoImport, {regexTokeniser} from '@blitz/monaco-auto-import'
// import {AutoTypings, LocalStorageCache} from 'monaco-editor-auto-typings';
@@ -41,9 +41,9 @@ export function useEditor(settings: Settings, links?: EditorLinks, libs?: Editor
// Setup typescript user options + libraries
useEffect(() => {
const typescript = monaco?.languages.typescript.typescriptDefaults;
- typescript?.setCompilerOptions(settings.display.editor.compiler);
- typescript?.setInlayHintsOptions(settings.display.editor.inlayHints);
- typescript?.setDiagnosticsOptions(settings.display.editor.diagnostics);
+ typescript?.setCompilerOptions(settings.monaco.compiler);
+ typescript?.setInlayHintsOptions(settings.monaco.inlayHints);
+ typescript?.setDiagnosticsOptions(settings.monaco.diagnostics);
if (libs) {
typescript?.setExtraLibs(libs);
libs.forEach((lib) => {
diff --git a/src/interface/hooks/useExport.ts b/src/interface/hooks/useExport.ts
index 992abc79..717ddef8 100644
--- a/src/interface/hooks/useExport.ts
+++ b/src/interface/hooks/useExport.ts
@@ -1,7 +1,7 @@
-import {useEffect} from 'react';
+import {useEffect} from 'preact/hooks';
import {downloadZip} from 'client-zip';
-export function useExport() {
+export function useExport(): void {
useEffect(() => {
const onMessage = (e: MessageEvent) => {
if (e.data?.pluginMessage?.type === 'compile') {
@@ -14,7 +14,7 @@ export function useExport() {
}, []);
}
-async function saveFiles(project: string, files: string[][], theme: string) {
+async function saveFiles(project: string, files: string[][], theme: string): Promise {
const lastModified = new Date();
const payload: {name: string, lastModified: Date, input: string}[] = [];
payload.push({name: 'theme.ts', lastModified, input: theme});
diff --git a/src/interface/hooks/usePreview.ts b/src/interface/hooks/usePreview.ts
index 0d51345d..63778c7c 100644
--- a/src/interface/hooks/usePreview.ts
+++ b/src/interface/hooks/usePreview.ts
@@ -1,52 +1,40 @@
-import {useState, useEffect} from 'react';
-import {build} from 'utils/esbuild';
+import {useState, useEffect} from 'preact/hooks';
+import {build} from 'common/esbuild';
import type {Settings} from 'types/settings';
import type {EditorComponent} from 'types/editor';
-export function usePreview(component: EditorComponent, settings: Settings) {
+export function usePreview(component: EditorComponent, settings: Settings): string {
const [output, setOutput] = useState('');
-
useEffect(() => {
if (!component) return;
-
+
+ const tag = '<' + component.name + ' ' + component.props + '/>';
+
const appCode = component.preview
.replace(/import theme from ["']\.\/theme['"];/g, '')
.replace(/import\s*\{\s*(\w+)\s*\}\s*from\s*['"](\.\/\w+\.tsx?)['"]\s*;/g, '');
const entryPoint = `
- import {useEffect, useState} from 'react';
import {AppRegistry} from 'react-native';
- import {TransformWrapper, TransformComponent} from 'react-zoom-pan-pinch';
+ import {useEffect, useState} from 'react';
${appCode}
- function Preview() {
- return (
-
- ${'<' + component.name + ' ' + component.props + '/>'}
-
- );
- }
-
function Main() {
- return (
-
-
-
- );
+ return ${tag}
}
- AppRegistry.registerComponent('preview', () => Main);
- AppRegistry.runApplication('preview', {
- rootTag: document.getElementById('preview'),
+ AppRegistry.registerComponent('main', () => Main);
+ AppRegistry.runApplication('main', {
+ rootTag: document.getElementById('component'),
});
`;
build(entryPoint, settings)
.then(res => setOutput(res.code
- .replace('stdin_default as default', '')
+ .replace(/stdin_default as default\,?/, '')
.replace('var stdin_default', 'var theme')))
.catch(err => setOutput(err.toString()));
diff --git a/src/interface/hooks/useSettings.ts b/src/interface/hooks/useSettings.ts
index 2d9866ab..17ffc9c3 100644
--- a/src/interface/hooks/useSettings.ts
+++ b/src/interface/hooks/useSettings.ts
@@ -1,16 +1,22 @@
-import {useRef, useState, useCallback, useEffect} from 'react';
+import {useRef, useState, useCallback, useEffect, MutableRef} from 'preact/hooks';
import defaultConfig from 'config';
import type {Settings} from 'types/settings';
-const indent = defaultConfig.output?.format?.indentNumberOfSpaces || 2;
+const indent = defaultConfig?.writer?.indentNumberOfSpaces || 2;
const configRaw = JSON.stringify(defaultConfig, undefined, indent);
-export function useSettings() {
+export type SettingsData = {
+ config: Settings;
+ raw: string;
+ locked: MutableRef;
+ update: (payload: string, force?: boolean) => void;
+}
+
+export function useSettings(): SettingsData {
const locked = useRef(false);
const [raw, setRaw] = useState(configRaw);
const [config, setConfig] = useState(defaultConfig);
-
const update = useCallback((payload: string, force?: boolean) => {
if (!force && locked.current) return;
let decoded: Settings;
diff --git a/src/interface/hooks/useTheme.ts b/src/interface/hooks/useTheme.ts
index 5cfb7439..49a85d8e 100644
--- a/src/interface/hooks/useTheme.ts
+++ b/src/interface/hooks/useTheme.ts
@@ -1,8 +1,7 @@
-import {useState, useEffect} from 'react';
+import {useState, useEffect} from 'preact/hooks';
-export function useTheme() {
+export function useTheme(): string {
const [theme, setTheme] = useState(null);
-
useEffect(() => {
const onMessage = (e: MessageEvent) => {
if (e.data?.pluginMessage?.type === 'theme')
@@ -11,6 +10,5 @@ export function useTheme() {
addEventListener('message', onMessage);
return () => removeEventListener('message', onMessage);
}, []);
-
return theme;
}
diff --git a/src/interface/styles/theme.css b/src/interface/styles/default.css
similarity index 69%
rename from src/interface/styles/theme.css
rename to src/interface/styles/default.css
index 239d292c..8b49b82a 100644
--- a/src/interface/styles/theme.css
+++ b/src/interface/styles/default.css
@@ -62,6 +62,72 @@
--font-letter-spacing-neg-xlarge: -.001em;
}
+html, body {
+ margin: 0;
+ background-color: var(--figma-color-bg);
+ font-family: var(--font-stack);
+ font-size: var(--font-size-xsmall);
+ color: var(--figma-color-text);
+}
+
+#create-figma-plugin {
+ display: flex;
+ overflow: hidden;
+ height: 100%;
+}
+
+.expand {
+ flex: 1;
+}
+
+.tabs {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ flex: 1;
+}
+
+.bar {
+ padding: 4px 5px;
+ border-bottom: 1px solid var(--figma-color-border);
+ z-index: 5;
+ display: flex;
+ flex-direction: row;
+}
+
+.tab {
+ font-family: var(--font-stack);
+ font-size: var(--font-size-xsmall);
+ line-height: var(--font-line-height);
+ letter-spacing: var(--font-letter-spacing-pos-xsmall);
+ font-weight: 500;
+ background: none;
+ color: #b3b3b3;
+ padding: 0 8px;
+ height: 32;
+ border: 0;
+ border-radius: 2px;
+}
+
+.tab.icon {
+ width: 32;
+ padding: 0;
+ opacity: 0.6;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.tab[data-state="active"] {
+ font-weight: 600;
+ color: var(--figma-color-text);
+}
+
+.tab.icon[data-state="active"] {
+ background-color: var(--figma-color-bg-pressed);
+ opacity: 1;
+}
+
@font-face {
font-family: "Inter";
font-weight: 400;
@@ -82,12 +148,3 @@
font-style: normal;
src: url(https://rsms.me/inter/font-files/Inter-SemiBold.woff2?v=3.7) format("woff2"), url(https://rsms.me/inter/font-files/Inter-SemiBold.woff2?v=3.7) format("woff");
}
-
-@keyframes rotating {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
diff --git a/src/interface/styles/default.css.d.ts b/src/interface/styles/default.css.d.ts
new file mode 100644
index 00000000..48657a73
--- /dev/null
+++ b/src/interface/styles/default.css.d.ts
@@ -0,0 +1,10 @@
+declare const styles: {
+ readonly "create-figma-plugin": string;
+ readonly "expand": string;
+ readonly "tabs": string;
+ readonly "bar": string;
+ readonly "tab": string;
+ readonly "icon": string;
+};
+export = styles;
+
diff --git a/src/interface/styles/figma.css b/src/interface/styles/figma.css
deleted file mode 100644
index 21c1ae36..00000000
--- a/src/interface/styles/figma.css
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Inputs */
-
-.button {
- display: flex;
- flex-shrink: 0;
- align-items: center;
- height: var(--size-medium);
- padding: 0 var(--size-xsmall) 0 var(--size-xsmall);
- font-size: var(--font-size-xsmall);
- font-family: var(--font-stack);
- font-weight: var(--font-weight-medium);
- letter-spacing: var(--font-letter-spacing-neg-small);
- line-height: var(--font-line-height);
- color: var(--figma-color-text-onbrand);
- background-color: var(--figma-color-bg-brand);
- border-radius: var(--border-radius-large);
- border: 2px solid transparent;
- text-decoration: none;
- user-select: none;
- outline: none;
-}
-
-.button:active {
- background-color: var(--figma-color-bg-brand-pressed);
-}
-
-/* Tabs */
-
-.tabs {
- display: flex;
- flex-direction: column;
- flex: 1;
-}
-
-.bar {
- padding: 4px 5px;
- border-bottom: 1px solid var(--figma-color-border);
- z-index: 5;
- display: flex;
- flex-direction: row;
-}
-
-.tab {
- font-family: var(--font-stack);
- font-size: var(--font-size-xsmall);
- line-height: var(--font-line-height);
- letter-spacing: var(--font-letter-spacing-pos-xsmall);
- font-weight: 500;
- background: none;
- color: #b3b3b3;
- padding: 0 8px;
- height: 32;
- border: 0;
- border-radius: 2px;
-}
-
-.tab.icon {
- width: 32;
- padding: 0;
- opacity: 0.6;
-}
-
-.tab[data-state="active"] {
- font-weight: 600;
- color: var(--figma-color-text);
-}
-
-.tab.icon[data-state="active"] {
- background-color: var(--figma-color-bg-pressed);
- opacity: 1;
-}
-
-/* Radios */
-
-.radio-group {
- margin-bottom: 20px;
- margin-left: 6px;
-}
-
-.radio-group > label {
- user-select: none;
- display: block;
- padding: 4px 0;
-}
-
-input[type="radio"] {
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- border: 2px solid #bbb;
- border-radius: 50%;
- width: 1.2em;
- height: 1.2em;
- margin-right: 0.6em;
- position: relative;
- top: 0.3em;
-}
-
-input[type="radio"]:checked::before {
- content: '';
- display: block;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background-color: var(--figma-color-bg-brand);
- width: 0.6em;
- height: 0.6em;
- border-radius: 50%;
-}
\ No newline at end of file
diff --git a/src/interface/styles/global.css b/src/interface/styles/plugin.css
similarity index 82%
rename from src/interface/styles/global.css
rename to src/interface/styles/plugin.css
index 4638d95b..a0a6ed1d 100644
--- a/src/interface/styles/global.css
+++ b/src/interface/styles/plugin.css
@@ -1,30 +1,9 @@
-/* General */
-
-html, body {
- margin: 0;
- background-color: var(--figma-color-bg);
- font-family: var(--font-stack);
- font-size: var(--font-size-xsmall);
- color: var(--figma-color-text);
-}
-
iframe {
border: 0;
height: 100%;
width: 100%;
}
-h4 {
- margin-bottom: 0.5em;
-}
-
-#app {
- height: 100%;
- display: flex;
-}
-
-/* Utilities */
-
.center {
display: flex;
align-items: center;
@@ -32,24 +11,21 @@ h4 {
justify-content: center;
}
-.expand {
- flex: 1;
-}
-
.fill {
- height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 1;
+ margin-top: 41px;
+ background-color: var(--figma-color-bg);
}
.page {
padding: 0.5em 1.3em;
}
-/* Components */
-
-.editor {
- height: 100%;
-}
-
.loading {
display: block;
width: 24px;
@@ -58,3 +34,12 @@ h4 {
animation: rotating 1.0s linear infinite;
background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M4.848%209.74l.477.15-.477-.15zm2.622-3.08a.5.5%200%200%200-.617-.787l.617.787zm10.677%201.99a7%207%200%200%201%20.838%203.803l.998.065a8%208%200%200%200-.958-4.346l-.878.478zm.838%203.803a7%207%200%200%201-1.324%203.662l.81.588a8%208%200%200%200%201.513-4.186l-.998-.065zm-1.324%203.662a7%207%200%200%201-3.076%202.388l.37.93a8%208%200%200%200%203.515-2.729l-.81-.588zm-3.076%202.388a7%207%200%200%201-3.876.375l-.184.983a8%208%200%200%200%204.43-.428l-.37-.93zm-3.876.375a7%207%200%200%201-3.477-1.755l-.68.732a8%208%200%200%200%203.973%202.005l.184-.983zm-3.477-1.755a7%207%200%200%201-2.001-3.341l-.967.255a8%208%200%200%200%202.287%203.818l.68-.732zm-2-3.34a7%207%200%200%201%20.094-3.893l-.954-.3a8%208%200%200%200-.107%204.449l.967-.255zm.094-3.893c.323-1.024.863-1.835%201.326-2.394.23-.278.44-.49.6-.632l.175-.157.044-.037c.01-.008.01-.008-.298-.402l-.31-.393-.026.02-.06.05-.21.2c-.175.165-.413.407-.674.722-.52.627-1.137%201.55-1.5%202.73l.954.3z%22%20fill%3D%22%23a5a5a5%22%2F%3E%3C%2Fsvg%3E");
}
+
+@keyframes rotating {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
diff --git a/src/interface/styles/plugin.css.d.ts b/src/interface/styles/plugin.css.d.ts
new file mode 100644
index 00000000..17f2892f
--- /dev/null
+++ b/src/interface/styles/plugin.css.d.ts
@@ -0,0 +1,9 @@
+declare const styles: {
+ readonly "center": string;
+ readonly "fill": string;
+ readonly "page": string;
+ readonly "loading": string;
+ readonly "rotating": string;
+};
+export = styles;
+
diff --git a/src/interface/views/Code.tsx b/src/interface/views/Code.tsx
new file mode 100644
index 00000000..3e101deb
--- /dev/null
+++ b/src/interface/views/Code.tsx
@@ -0,0 +1,29 @@
+import {h, Fragment} from 'preact';
+import Editor from '@monaco-editor/react';
+import {Hint} from 'interface/base/Hint';
+import {Loading} from 'interface/base/Loading';
+
+import type {EditorComponent} from 'types/editor';
+import type {Settings} from 'types/settings';
+
+interface CodeProps {
+ component: EditorComponent;
+ options: Settings['monaco']['general'];
+ monaco: any;
+}
+
+export function Code(props: CodeProps) {
+ return (
+
+ {!props.component?.code && }
+ as JSX.Element}
+ />
+
+ );
+}
diff --git a/src/interface/views/Export.tsx b/src/interface/views/Export.tsx
new file mode 100644
index 00000000..6421fe70
--- /dev/null
+++ b/src/interface/views/Export.tsx
@@ -0,0 +1,33 @@
+import {h} from 'preact';
+import {useExport} from 'interface/hooks/useExport';
+
+export function Export() {
+ useExport();
+ return (
+
+ );
+}
diff --git a/src/interface/views/Preview.tsx b/src/interface/views/Preview.tsx
new file mode 100644
index 00000000..b8ae8087
--- /dev/null
+++ b/src/interface/views/Preview.tsx
@@ -0,0 +1,45 @@
+import {h, Fragment} from 'preact';
+import {useState, useCallback, useEffect, useRef} from 'preact/hooks';
+import {usePreview} from 'interface/hooks/usePreview';
+import {Hint} from 'interface/base/Hint';
+import html from 'templates/previewer';
+
+import type {EditorComponent} from 'types/editor';
+import type {Settings} from 'types/settings';
+
+interface PreviewProps {
+ component: EditorComponent,
+ settings: Settings;
+}
+
+export function Preview(props: PreviewProps) {
+ const [src, setSrc] = useState('');
+ const preview = usePreview(props.component, props.settings);
+ const iframe = useRef(null);
+
+ const update = useCallback(() => {
+ iframe.current?.contentWindow?.postMessage({preview, name: props.component?.name});
+ }, [preview]);
+
+ const load = useCallback(() => {
+ html(props.settings).then(setSrc);
+ }, []);
+
+ useEffect(load, []);
+ useEffect(update, [preview]);
+
+ return (
+
+ {!props.component?.preview && }
+
+
+ );
+}
diff --git a/src/interface/views/Settings.tsx b/src/interface/views/Settings.tsx
new file mode 100644
index 00000000..bc8677d9
--- /dev/null
+++ b/src/interface/views/Settings.tsx
@@ -0,0 +1,40 @@
+import {h} from 'preact';
+import Editor from '@monaco-editor/react';
+import {useMemo} from 'preact/hooks';
+import {debounce} from 'common/delay';
+import {Loading} from 'interface/base/Loading';
+
+import type {Settings} from 'types/settings';
+import type {SettingsData} from 'interface/hooks/useSettings';
+
+interface SettingsProps {
+ settings: SettingsData;
+ options: Settings['monaco']['general'];
+ monaco: any;
+}
+
+export function Settings(props: SettingsProps) {
+ const update = useMemo(() =>
+ debounce(props.settings.update, 750), [props.settings.update]);
+ return (
+ as JSX.Element}
+ onChange={value => update(value)}
+ onValidate={markers => {
+ if (markers.length === 0) {
+ const uri = props.monaco.Uri.parse('Settings.json');
+ const model = props.monaco.editor.getModel(uri);
+ props.settings.update(model.getValue(), true);
+ props.settings.locked.current = false;
+ } else {
+ props.settings.locked.current = true;
+ }
+ }}
+ />
+ );
+}
diff --git a/src/interface/views/Story.tsx b/src/interface/views/Story.tsx
new file mode 100644
index 00000000..591ea45f
--- /dev/null
+++ b/src/interface/views/Story.tsx
@@ -0,0 +1,28 @@
+import {h, Fragment} from 'preact';
+import Editor from '@monaco-editor/react';
+import {Hint} from 'interface/base/Hint';
+import {Loading} from 'interface/base/Loading';
+
+import type {EditorComponent} from 'types/editor';
+import type {Settings} from 'types/settings';
+
+interface StoryProps {
+ component: EditorComponent;
+ options: Settings['monaco']['general'];
+}
+
+export function Story(props: StoryProps) {
+ return (
+
+ {!props.component?.story && }
+ as JSX.Element}
+ />
+
+ );
+}
diff --git a/src/interface/views/Theme.tsx b/src/interface/views/Theme.tsx
new file mode 100644
index 00000000..2ea736c5
--- /dev/null
+++ b/src/interface/views/Theme.tsx
@@ -0,0 +1,24 @@
+import {h} from 'preact';
+import Editor from '@monaco-editor/react';
+import {Loading} from 'interface/base/Loading';
+import {useTheme} from 'interface/hooks/useTheme';
+
+import type {Settings} from 'types/settings';
+
+interface ThemeProps {
+ options: Settings['monaco']['general'];
+}
+
+export function Theme(props: ThemeProps) {
+ const theme = useTheme();
+ return (
+ as JSX.Element}
+ />
+ );
+}
diff --git a/src/main.ts b/src/main.ts
index 5fee1f82..381b9b20 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,33 +1,9 @@
-import * as plugin from 'utils/plugin';
-import defaultConfig from 'config';
+import {showUI, on} from '@create-figma-plugin/utilities';
+import {start} from 'modules/app/start';
-figma.showUI(__html__, defaultConfig.display.plugin);
-
-(async function main() {
- await plugin.loadConfig();
- setInterval(plugin.updateCode, 300);
- setInterval(plugin.updateTheme, 1000);
- figma.on('selectionchange', plugin.updateCode);
- figma.on('run', ({command}: RunEvent) => {
- switch (command) {
- case 'export-doc':
- return plugin.exportDocument('all');
- case 'export-page':
- return plugin.exportDocument('page');
- case 'export-selected':
- return plugin.exportDocument('selected');
- }
- })
- figma.ui.on('message', ({type, payload}) => {
- switch (type) {
- case 'config':
- return plugin.updateConfig(payload);
- case 'export':
- return plugin.exportDocument(payload);
- case 'focus':
- return plugin.focusComponent(payload);
- case 'error':
- return figma.notify(payload, {error: true});
- }
- });
-})();
+export default function() {
+ on('RESIZE_WINDOW', (size: {width: number; height: number}) =>
+ figma.ui.resize(size.width, size.height));
+ showUI({width: 400, height: 600});
+ start();
+}
diff --git a/src/modules/app/start.ts b/src/modules/app/start.ts
new file mode 100644
index 00000000..57d966a4
--- /dev/null
+++ b/src/modules/app/start.ts
@@ -0,0 +1,21 @@
+import * as utils from 'modules/app/utils';
+import {focusComponent} from 'modules/fig/utils';
+
+export async function start() {
+ await utils.loadConfig();
+ setInterval(utils.updateCode, 300);
+ setInterval(utils.updateTheme, 400);
+ figma.on('selectionchange', utils.updateCode);
+ figma.ui.on('message', ({type, payload}) => {
+ switch (type) {
+ case 'config':
+ return utils.updateConfig(payload);
+ case 'export':
+ return utils.exportDocument(payload);
+ case 'focus':
+ return focusComponent(payload);
+ case 'error':
+ return figma.notify(payload, {error: true});
+ }
+ });
+};
diff --git a/src/utils/plugin.ts b/src/modules/app/utils.ts
similarity index 64%
rename from src/utils/plugin.ts
rename to src/modules/app/utils.ts
index a32b51d7..7bf4019d 100644
--- a/src/utils/plugin.ts
+++ b/src/modules/app/utils.ts
@@ -1,16 +1,15 @@
-import {generateBundle, generateTheme} from 'modules/generate';
-import {getSelectedComponent, getComponents, getPage} from 'utils/figma';
-import config from 'config';
-
+import defaultConfig from 'config';
+import {getSelectedComponent, getComponents} from 'modules/fig/utils';
+import {generateBundle, generateTheme} from 'modules/gen';
import type {Settings} from 'types/settings';
+const settingsKey = `settings::v1`;
+let _config = defaultConfig;
+let _props = '';
let _code = '';
-let _config = config;
-let _width = _config.display.plugin.width;
-let _height = _config.display.plugin.height;
export async function loadConfig() {
- const config: Settings = await figma.clientStorage.getAsync('config');
+ const config: Settings = await figma.clientStorage.getAsync(settingsKey);
if (config) {
updateConfig(config, true);
figma.ui.postMessage({type: 'config', payload: config});
@@ -19,16 +18,18 @@ export async function loadConfig() {
export function updateConfig(value: Settings, skipSave?: boolean) {
_config = JSON.parse(value as any);
- if (!skipSave) figma.clientStorage.setAsync('config', value);
- updateDimensions();
updateCode();
+ if (!skipSave) {
+ figma.clientStorage.setAsync(settingsKey, value);
+ }
}
export function updateCode() {
const selected = getSelectedComponent();
const bundle = generateBundle(selected, _config);
- if (bundle.code !== _code) {
+ if (bundle.code !== _code || bundle.props !== _props) {
_code = bundle.code;
+ _props = bundle.props;
figma.ui.postMessage({
type: 'code',
payload: JSON.stringify(bundle),
@@ -44,32 +45,6 @@ export function updateTheme() {
});
}
-export function updateDimensions() {
- const {plugin} = _config.display;
- const width = Math.floor(Math.max(300, plugin.width));
- const height = Math.floor(Math.max(300, plugin.height));
- if (width !== _width || height !== _height) {
- figma.ui.resize(width, height);
- _width = width;
- _height = height;
- }
-}
-
-export function focusComponent(id: string) {
- try {
- const node = figma.getNodeById(id);
-
- if (node) {
- const page = getPage(node);
- if (page && figma.currentPage !== page) {
- figma.currentPage = page;
- }
- figma.currentPage.selection = [node as any];
- figma.viewport.scrollAndZoomIntoView([node]);
- }
- } catch (e) {}
-}
-
export function exportDocument(type: 'all' | 'page' | 'selected') {
const theme = generateTheme(_config);
const document = figma.currentPage.parent;
diff --git a/src/modules/fig/asset.ts b/src/modules/fig/asset.ts
new file mode 100644
index 00000000..f85bbf6b
--- /dev/null
+++ b/src/modules/fig/asset.ts
@@ -0,0 +1,3 @@
+export async function parseAsset(node: SceneNode) {
+ // ...
+}
diff --git a/src/modules/parse/nodes.ts b/src/modules/fig/nodes.ts
similarity index 76%
rename from src/modules/parse/nodes.ts
rename to src/modules/fig/nodes.ts
index 172cd882..a08eb435 100644
--- a/src/modules/parse/nodes.ts
+++ b/src/modules/fig/nodes.ts
@@ -1,10 +1,10 @@
-import {parseStyles} from 'modules/parse/styles';
-import {getTag, getName, getSlug} from 'utils/figma';
+import * as utils from 'modules/fig/utils';
+import {parseStyles} from 'modules/fig/styles';
-import type {ParseData, ParseState, ParsedComponent} from 'types/parse';
+import type * as T from 'types/parse';
import type {TargetNode} from 'types/figma';
-export function parseNodes(nodes: TargetNode[], state?: ParseState): ParseData {
+export function parseNodes(nodes: TargetNode[], state?: T.ParseState): T.ParseData {
// Init state (haven't recursed yet)
if (!state) {
state = {
@@ -17,7 +17,7 @@ export function parseNodes(nodes: TargetNode[], state?: ParseState): ParseData {
}
// Lines of codes will be inserted here
- let code: ParsedComponent[] = [];
+ let code: T.ParsedComponent[] = [];
// Loop through each direct child node
nodes.forEach((node) => {
@@ -35,15 +35,17 @@ export function parseNodes(nodes: TargetNode[], state?: ParseState): ParseData {
const hasStyles = node.type === 'TEXT'
|| node.type === 'GROUP'
|| node.type === 'FRAME'
- || node.type === 'COMPONENT';
+ || node.type === 'COMPONENT'
+ || node.type === 'RECTANGLE'
+ || node.type === 'ELLIPSE';
// Create component
- const component: ParsedComponent = {
+ const component: T.ParsedComponent = {
node,
id: node.id,
- tag: getTag(node.type),
- name: getName(node.name),
- slug: hasStyles && getSlug(node.name),
+ tag: utils.getTag(node.type),
+ name: utils.getName(node.name),
+ slug: hasStyles && utils.getSlug(node.name),
};
// Transform styles for child (if applicable)
@@ -73,13 +75,13 @@ export function parseNodes(nodes: TargetNode[], state?: ParseState): ParseData {
// Instances get inserted w/ props and the master component recorded
case 'INSTANCE': {
- const main = isVariant ? node.masterComponent.parent : node.mainComponent;
+ const main = isVariant ? node.mainComponent.parent : node.mainComponent;
const props = node.componentProperties;
const propId = node.componentPropertyReferences?.mainComponent;
- const propName = propId ? getSlug(propId.split('#').shift()) : null;
+ const propName = propId ? utils.getSlug(propId.split('#').shift()) : null;
// Explicit component (does not change)
if (!propName) {
- code.push({...component, props, tag: getName(node.name)});
+ code.push({...component, props, tag: utils.getName(node.name)});
// Queue this component for import
state.components[main.id] = main;
// Also queue any component used in a prop
@@ -99,11 +101,18 @@ export function parseNodes(nodes: TargetNode[], state?: ParseState): ParseData {
break;
}
+ // Basic shapes get inserted (styles already handled)
+ case 'RECTANGLE':
+ case 'ELLIPSE': {
+ code.push({...component});
+ break;
+ }
+
// Text nodes get inserted and the primitive added
case 'TEXT': {
state.primitives.add('Text');
const propId = propRefs?.characters;
- const propName = propId ? getSlug(propId.split('#').shift()) : null;
+ const propName = propId ? utils.getSlug(propId.split('#').shift()) : null;
code.push({...component, value: propName ? `props.${propName}` : node.characters || ''});
break;
}
@@ -114,18 +123,10 @@ export function parseNodes(nodes: TargetNode[], state?: ParseState): ParseData {
break;
}
- // TODO (rectangles & ellipses are just views, ellipses have 99999 border radius)
- // case 'RECTANGLE':
- // case 'ELLIPSE':
-
// Vectors get inserted w/ paths, fills, dimensions, paths. Add RNSVG library.
- case 'VECTOR':
- case 'LINE':
- case 'STAR':
- case 'ELLIPSE':
- case 'POLYGON':
- case 'BOOLEAN_OPERATION': {
+ case 'VECTOR': {
state.libraries.add('react-native-svg');
+ // node.parent.exportAsync({format: 'SVG_STRING'}).then(console.log);
code.push({...component, paths: node.vectorPaths, fills: node.fills, box: node.absoluteBoundingBox});
break;
}
diff --git a/src/modules/parse/styles.ts b/src/modules/fig/styles.ts
similarity index 73%
rename from src/modules/parse/styles.ts
rename to src/modules/fig/styles.ts
index 84bb8def..dc1b17b5 100644
--- a/src/modules/parse/styles.ts
+++ b/src/modules/fig/styles.ts
@@ -1,29 +1,14 @@
-import {
- getSize,
- getColor,
- getTopFill,
- getFillStyle,
- getFontWeight,
- getLineHeight,
- getLetterSpacing,
-} from 'utils/figma';
+import * as utils from 'modules/fig/utils';
+import type * as T from 'types/styles';
import type {TargetNode} from 'types/figma';
-import type {
- Styles,
- StylesDimension,
- StylesPosition,
- StylesLayout,
- StylesPadding,
- StylesBackground,
- StylesBorder,
- StylesTypography,
-} from 'types/styles';
-
-export function parseStyles(node: TargetNode, isRoot?: boolean): Styles {
+
+export function parseStyles(node: TargetNode, isRoot?: boolean): T.Styles {
switch (node.type) {
case 'GROUP':
case 'FRAME':
+ case 'ELLIPSE':
+ case 'RECTANGLE':
case 'COMPONENT':
case 'COMPONENT_SET': {
return {
@@ -33,18 +18,14 @@ export function parseStyles(node: TargetNode, isRoot?: boolean): Styles {
...padding(node),
...background(node),
...border(node),
- // TODO
//...shadow(node),
//...blends(node),
};
}
- // TODO
- // case 'RECTANGLE':
- // case 'ELLIPSE':
case 'TEXT': {
return {
...position(node),
- ...dimension(node),
+ ...dimension(node, false, true),
...typography(node),
}
}
@@ -55,10 +36,10 @@ export function parseStyles(node: TargetNode, isRoot?: boolean): Styles {
}
}
-function dimension(node: TargetNode, isRoot?: boolean): StylesDimension {
- const style: StylesDimension = {};
- const size = getSize(node, isRoot);
- if (typeof size.width === 'number') {
+function dimension(node: TargetNode, isRoot?: boolean, isText?: boolean): T.StylesDimension {
+ const style: T.StylesDimension = {};
+ const size = utils.getSize(node, isRoot);
+ if (!isText && typeof size.width === 'number') {
style.width = size.width;
} else if (size.width === 'full') {
if (!isRoot
@@ -85,13 +66,13 @@ function dimension(node: TargetNode, isRoot?: boolean): StylesDimension {
return style;
}
-function position(node: TargetNode, isRoot?: boolean): StylesPosition {
+function position(node: TargetNode, isRoot?: boolean): T.StylesPosition {
// TODO: Handle absolute positioning
return {};
}
-function layout(node: TargetNode, isRoot?: boolean): StylesLayout {
- const style: StylesLayout = {};
+function layout(node: TargetNode, isRoot?: boolean): T.StylesLayout {
+ const style: T.StylesLayout = {};
// if AutoLayout not used, return empty layout
if (node.layoutPositioning !== 'AUTO') {
@@ -147,8 +128,8 @@ function layout(node: TargetNode, isRoot?: boolean): StylesLayout {
return style;
}
-function padding(node: TargetNode): StylesPadding {
- const style: StylesPadding = {};
+function padding(node: TargetNode): T.StylesPadding {
+ const style: T.StylesPadding = {};
if (node.paddingLeft > 0
&& node.paddingLeft === node.paddingRight
&& node.paddingLeft === node.paddingBottom
@@ -175,20 +156,20 @@ function padding(node: TargetNode): StylesPadding {
return style;
}
-function background(node: TargetNode): StylesBackground {
- const style: StylesBackground = {};
+function background(node: TargetNode): T.StylesBackground {
+ const style: T.StylesBackground = {};
- if (node.backgrounds.length > 0) {
- const fill = getTopFill(node.backgrounds);
- const fillStyle = getFillStyle(figma.getStyleById(node.fillStyleId));
- style.backgroundColor = fillStyle ?? getColor(fill?.color, fill?.opacity);
+ if (node.backgrounds?.length > 0) {
+ const fill = utils.getTopFill(node.backgrounds);
+ const fillStyle = utils.getFillStyle(figma.getStyleById(node.fillStyleId));
+ style.backgroundColor = fillStyle ?? utils.getColor(fill?.color, fill?.opacity);
}
return style;
}
-function border(node: TargetNode): StylesBorder {
- const style: StylesBorder = {};
+function border(node: TargetNode): T.StylesBorder {
+ const style: T.StylesBorder = {};
// Radius
if (node.type === 'ELLIPSE') {
@@ -206,8 +187,8 @@ function border(node: TargetNode): StylesBorder {
if (node.strokes?.length > 0
// TODO: figure out what to do with "mixed" border strokes (ignore for now)
&& (node.strokeWeight !== figma.mixed && node.strokeWeight > 0)) {
- const fill = getTopFill(node.strokes);
- style.borderColor = getColor(fill?.color, fill?.opacity);
+ const fill = utils.getTopFill(node.strokes);
+ style.borderColor = utils.getColor(fill?.color, fill?.opacity);
style.borderWidth = node.strokeWeight;
style.borderStyle = node.dashPattern.length > 0 ? 'dotted' : 'solid';
}
@@ -215,18 +196,18 @@ function border(node: TargetNode): StylesBorder {
return style;
}
-function typography(node: TargetNode): StylesTypography {
+function typography(node: TargetNode): T.StylesTypography {
let color: string;
if (node.fills.length > 0) {
- const fill = getTopFill(node.fills);
- const fillStyle = getFillStyle(figma.getStyleById(node.fillStyleId));
- color = fillStyle ?? getColor(fill?.color, fill?.opacity);
+ const fill = utils.getTopFill(node.fills);
+ const fillStyle = utils.getFillStyle(figma.getStyleById(node.fillStyleId));
+ color = fillStyle ?? utils.getColor(fill?.color, fill?.opacity);
}
const fontSize = node.fontSize;
const fontFamily = node.fontFamily;
- const fontWeight = getFontWeight(node.fontName.style);
- const lineHeight = getLineHeight(node);
- const letterSpacing = getLetterSpacing(node);
+ const fontWeight = utils.getFontWeight(node.fontName.style);
+ const lineHeight = utils.getLineHeight(node);
+ const letterSpacing = utils.getLetterSpacing(node);
const isItalic = node.fontName.style.match(/italic/i);
const isCrossed = node.textDecoration === 'STRIKETHROUGH';
const isUnderline = node.textDecoration === 'UNDERLINE';
@@ -235,6 +216,8 @@ function typography(node: TargetNode): StylesTypography {
const isAlignLeft = node.textAlignHorizontal === 'LEFT';
const isAlignTop = node.textAlignVertical === 'TOP';
const isAlignBottom = node.textAlignVertical === 'BOTTOM';
+ const isUpperCase = node.textCase === 'UPPER';
+ const isLowerCase = node.textCase === 'LOWER';
return {
lineHeight,
@@ -246,6 +229,7 @@ function typography(node: TargetNode): StylesTypography {
textAlign: isAlignLeft ? 'left' : isAlignRight ? 'right' : isAlignCenter ? 'center' : undefined,
textAlignVertical: isAlignTop ? 'top' : isAlignBottom ? 'bottom' : undefined,
textDecorationLine: isUnderline ? 'underline' : isCrossed ? 'line-through' : undefined,
+ textTransform: isUpperCase ? 'uppercase' : isLowerCase ? 'lowercase' : undefined,
color,
};
}
diff --git a/src/utils/figma.ts b/src/modules/fig/utils.ts
similarity index 93%
rename from src/utils/figma.ts
rename to src/modules/fig/utils.ts
index 390c2fcc..c2cd9381 100644
--- a/src/utils/figma.ts
+++ b/src/modules/fig/utils.ts
@@ -1,7 +1,22 @@
-import {rgbToHex} from 'utils/common';
+import {rgbToHex} from 'common/color';
import type {TargetNode, SizeResult} from 'types/figma';
+// Go to the component's page and focus it
+export function focusComponent(id: string) {
+ try {
+ const node = figma.getNodeById(id);
+ if (node) {
+ const page = getPage(node);
+ if (page && figma.currentPage !== page) {
+ figma.currentPage = page;
+ }
+ figma.currentPage.selection = [node as any];
+ figma.viewport.scrollAndZoomIntoView([node]);
+ }
+ } catch (e) {}
+}
+
// Get the page of a node
export function getPage(node: BaseNode): PageNode {
while (node.type !== 'PAGE') {
@@ -74,7 +89,8 @@ export function getSlug(value: string, skipPrefix?: boolean) {
return value.split(' ').map((word, index) => {
const safe = getName(word, skipPrefix);
if (index == 0) return safe.toLowerCase();
- return safe.charAt(0).toUpperCase() + safe.slice(1).toLowerCase();
+ const camelCase = safe.charAt(0).toUpperCase() + safe.slice(1).toLowerCase();
+ return camelCase;
}).join('');
}
@@ -83,6 +99,8 @@ export function getTag(type: string) {
switch (type) {
case 'COMPONENT':
case 'INSTANCE':
+ case 'RECTANGLE':
+ case 'ELLIPSE':
case 'FRAME':
case 'GROUP':
return 'View';
@@ -93,7 +111,7 @@ export function getTag(type: string) {
case 'VECTOR':
return 'Svg';
default:
- return 'Unknown';
+ return 'View';
}
}
diff --git a/src/modules/fig/variant.ts b/src/modules/fig/variant.ts
new file mode 100644
index 00000000..19cf383f
--- /dev/null
+++ b/src/modules/fig/variant.ts
@@ -0,0 +1,33 @@
+import {diff} from 'deep-object-diff';
+import {parseNodes} from 'modules/fig/nodes';
+import {parseStyles} from 'modules/fig/styles';
+
+export function parseVariantStyles(
+ node: ComponentNode,
+ baseStyles: Record,
+ baseStyleSheet: any,
+) {
+ const styles = {};
+ if (!node.variantProperties) return styles;
+ const componentSet = node.parent as ComponentSetNode;
+ componentSet.children
+ .filter((child: ComponentNode) => child !== componentSet.defaultVariant)
+ .forEach((variant: ComponentNode) => {
+ console.log(variant.name);
+ const name = variant.name.split('=').pop();
+ const nodesData = parseNodes([...variant.children]);
+ const stylesRoot = diff(baseStyles, parseStyles(variant, true));
+ const stylesNodes = diff(baseStyleSheet, nodesData.state.stylesheet);
+ if (Object.keys(stylesRoot).length > 0) {
+ if (!styles['root']) styles['root'] = {};
+ styles['root'][name] = stylesRoot;
+ }
+ Object.keys(stylesNodes).forEach((subKey: string) => {
+ if (stylesNodes[subKey]?.styles) {
+ if (!styles[subKey]) styles[subKey] = {};
+ styles[subKey][name] = stylesNodes[subKey].styles;
+ }
+ });
+ });
+ return styles;
+}
diff --git a/src/modules/generate/index.ts b/src/modules/gen/index.ts
similarity index 55%
rename from src/modules/generate/index.ts
rename to src/modules/gen/index.ts
index d77d7a4b..4abbf743 100644
--- a/src/modules/generate/index.ts
+++ b/src/modules/gen/index.ts
@@ -1,13 +1,10 @@
-import * as reactNative from 'modules/generate/react-native';
-import * as tamagui from 'modules/generate/react-native';
+import * as reactNative from 'modules/gen/react-native';
import type {TargetNode} from 'types/figma';
import type {Settings} from 'types/settings';
export function generateBundle(node: TargetNode, settings: Settings, skipBundle?: boolean) {
- switch (settings.output?.react.flavor) {
- case 'tamagui':
- return tamagui.generateBundle(node, settings, skipBundle);
+ switch (settings?.react.flavor) {
case 'react-native':
default:
return reactNative.generateBundle(node, settings, skipBundle);
@@ -15,9 +12,7 @@ export function generateBundle(node: TargetNode, settings: Settings, skipBundle?
}
export function generateTheme(settings: Settings) {
- switch (settings.output?.react.flavor) {
- case 'tamagui':
- return tamagui.generateTheme(settings);
+ switch (settings?.react.flavor) {
case 'react-native':
default:
return reactNative.generateTheme(settings);
diff --git a/src/modules/generate/react-native/bundle.ts b/src/modules/gen/react-native/bundle.ts
similarity index 60%
rename from src/modules/generate/react-native/bundle.ts
rename to src/modules/gen/react-native/bundle.ts
index b3138d52..1c6c9ab8 100644
--- a/src/modules/generate/react-native/bundle.ts
+++ b/src/modules/gen/react-native/bundle.ts
@@ -1,9 +1,9 @@
-import {generateComponent} from 'modules/generate/react-native/component';
-import {generatePreview} from 'modules/generate/react-native/preview';
-import {generateStory} from 'modules/generate/react-native/story';
-import {parseStyles} from 'modules/parse/styles';
-import {parseNodes} from 'modules/parse/nodes';
-import {getName, propsToString} from 'utils/figma';
+import {generateStory} from 'modules/gen/react-native/story';
+import {generatePreview} from 'modules/gen/react-native/preview';
+import {generateComponent} from 'modules/gen/react-native/component';
+import {getName, propsToString} from 'modules/fig/utils';
+import {parseStyles} from 'modules/fig/styles';
+import {parseNodes} from 'modules/fig/nodes';
import type {EditorComponent, EditorLinks} from 'types/editor';
import type {ParsedComponent} from 'types/parse';
@@ -17,8 +17,19 @@ export function generateBundle(component: TargetNode, settings: Settings, noPrev
const isVariant = !!component.variantProperties;
const masterNode = isVariant ? component?.parent : component;
+ const selectedVariant = isVariant
+ ? masterNode.children.filter((n: any) => figma.currentPage.selection.includes(n)).pop()
+ : undefined;
+
const children = parseNodes([...component.children]);
- const props = propsToString(masterNode?.componentPropertyDefinitions);
+ const propDefs = masterNode?.componentPropertyDefinitions;
+ if (selectedVariant) {
+ Object.entries(selectedVariant?.variantProperties).forEach((v: any) => {
+ propDefs[v[0]].defaultValue = v[1];
+ });
+ }
+
+ const props = propsToString({...propDefs});
const links: EditorLinks = {};
const root: ParsedComponent = {
id: component.id,
diff --git a/src/modules/generate/react-native/component.ts b/src/modules/gen/react-native/component.ts
similarity index 59%
rename from src/modules/generate/react-native/component.ts
rename to src/modules/gen/react-native/component.ts
index fefebbcf..4d76d783 100644
--- a/src/modules/generate/react-native/component.ts
+++ b/src/modules/gen/react-native/component.ts
@@ -1,22 +1,26 @@
import CodeBlockWriter from 'code-block-writer';
-import {writeImports, writeFunction, writeStyleSheet} from 'modules/generate/react-native/utils';
-import {getName} from 'utils/figma';
+import {writeImports, writeFunction, writeStyleSheet} from 'modules/gen/react-native/utils';
+import {parseVariantStyles} from 'modules/fig/variant';
+import {getName} from 'modules/fig/utils';
import type {ParseData, ParsedComponent} from 'types/parse';
import type {Settings} from 'types/settings';
export function generateComponent(root: ParsedComponent, parsed: ParseData, settings: Settings) {
- const writer = new CodeBlockWriter(settings.output?.format);
+ const writer = new CodeBlockWriter(settings?.writer);
const {components, stylesheet, primitives, libraries} = parsed.state;
const imports = Object.entries(components)
.map((c: any) => c ? getName(c[1].name) : '')
.filter(Boolean);
+
+ const stylePrefix = 'styles';
+ const variantStyles = parseVariantStyles(root.node, root.styles, stylesheet);
writeImports(writer, settings, primitives, libraries, imports);
writer.blankLine();
- writeFunction(writer, settings, root, parsed.code);
+ writeFunction(writer, settings, root, parsed.code, stylePrefix, variantStyles);
writer.blankLine();
- writeStyleSheet(writer, root, stylesheet);
+ writeStyleSheet(writer, root, stylesheet, stylePrefix, variantStyles);
writer.newLine();
return writer.toString();
diff --git a/src/modules/gen/react-native/index.ts b/src/modules/gen/react-native/index.ts
new file mode 100644
index 00000000..9579f871
--- /dev/null
+++ b/src/modules/gen/react-native/index.ts
@@ -0,0 +1,2 @@
+export {generateBundle} from 'modules/gen/react-native/bundle';
+export {generateTheme} from 'modules/gen/react-native/theme';
diff --git a/src/modules/generate/react-native/preview.ts b/src/modules/gen/react-native/preview.ts
similarity index 56%
rename from src/modules/generate/react-native/preview.ts
rename to src/modules/gen/react-native/preview.ts
index 7eedffc9..12f28979 100644
--- a/src/modules/generate/react-native/preview.ts
+++ b/src/modules/gen/react-native/preview.ts
@@ -1,26 +1,30 @@
import CodeBlockWriter from 'code-block-writer';
-import {generateTheme} from 'modules/generate/react-native/theme';
-import {writeImports, writeFunction, writeStyleSheet} from 'modules/generate/react-native/utils';
-import {parseStyles} from 'modules/parse/styles';
-import {parseNodes} from 'modules/parse/nodes';
-import {getName} from 'utils/figma';
+import {generateTheme} from 'modules/gen/react-native/theme';
+import {writeImports, writeFunction, writeStyleSheet} from 'modules/gen/react-native/utils';
+import {parseVariantStyles} from 'modules/fig/variant';
+import {parseStyles} from 'modules/fig/styles';
+import {parseNodes} from 'modules/fig/nodes';
+import {getName} from 'modules/fig/utils';
import type {ParsedComponent, ParseData} from 'types/parse';
import type {Settings} from 'types/settings';
export function generatePreview(root: ParsedComponent, children: ParseData, settings: Settings) {
- const writer = new CodeBlockWriter(settings.output?.format);
+ const writer = new CodeBlockWriter(settings?.writer);
const {stylesheet, components, includes} = children.state;
const primitives = new Set(['Text', 'Image']);
const libraries = new Set(['react-native-svg']);
+
+ const stylePrefix = 'styles';
+ const variantStyles = parseVariantStyles(root.node, root.styles, stylesheet);
writeImports(writer, settings, primitives, libraries);
writer.blankLine();
writer.write(generateTheme(settings));
writer.blankLine();
- writeFunction(writer, settings, root, children.code);
+ writeFunction(writer, settings, root, children.code, stylePrefix, variantStyles);
writer.blankLine();
- writeStyleSheet(writer, root, stylesheet);
+ writeStyleSheet(writer, root, stylesheet, stylePrefix, variantStyles);
writer.blankLine();
writeComponents(writer, settings, components);
writer.blankLine();
@@ -32,21 +36,23 @@ export function generatePreview(root: ParsedComponent, children: ParseData, sett
function writeComponents(writer: CodeBlockWriter, settings: Settings, components?: string[]) {
Object.values(components).forEach((sub: any) => {
+ const content = sub.defaultVariant ?? sub;
const root: ParsedComponent = {
id: sub.id,
tag: 'View',
slug: 'root',
- node: sub,
+ node: content,
name: getName(sub.name),
- styles: parseStyles(sub, true),
+ styles: parseStyles(content, true),
};
- const styleid = '_' + sub.id.split(':').join('_');
- const parsed = parseNodes([...sub.children]);
+ const parsed = parseNodes([...content.children]);
+ const stylePrefix = '_' + sub.id.split(':').join('_');
+ const variantStyles = parseVariantStyles(root.node, root.styles, parsed.state.stylesheet);
- writeFunction(writer, settings, root, parsed.code, styleid);
+ writeFunction(writer, settings, root, parsed.code, stylePrefix);
writer.blankLine();
- writeStyleSheet(writer, root, parsed.state.stylesheet, styleid);
+ writeStyleSheet(writer, root, parsed.state.stylesheet, stylePrefix, variantStyles);
writer.blankLine();
writeComponents(writer, settings, parsed.state.components);
});
diff --git a/src/modules/generate/react-native/story.ts b/src/modules/gen/react-native/story.ts
similarity index 97%
rename from src/modules/generate/react-native/story.ts
rename to src/modules/gen/react-native/story.ts
index 448c7b5c..6ccce3d6 100644
--- a/src/modules/generate/react-native/story.ts
+++ b/src/modules/gen/react-native/story.ts
@@ -1,11 +1,11 @@
import CodeBlockWriter from 'code-block-writer';
-import {sortProps, getSlug, getName} from 'utils/figma';
+import {sortProps, getSlug, getName} from 'modules/fig/utils';
import type {ParsedComponent} from 'types/parse';
import type {Settings} from 'types/settings';
export function generateStory(root: ParsedComponent, settings: Settings) {
- const writer = new CodeBlockWriter(settings.output?.format);
+ const writer = new CodeBlockWriter(settings?.writer);
const isVariant = !!root.node?.variantProperties;
const nodeProps = Object.entries(isVariant
? root.node?.parent?.componentPropertyDefinitions
diff --git a/src/modules/generate/react-native/theme.ts b/src/modules/gen/react-native/theme.ts
similarity index 55%
rename from src/modules/generate/react-native/theme.ts
rename to src/modules/gen/react-native/theme.ts
index bdfcee57..7836a129 100644
--- a/src/modules/generate/react-native/theme.ts
+++ b/src/modules/gen/react-native/theme.ts
@@ -1,5 +1,5 @@
import CodeBlockWriter from 'code-block-writer';
-import {getSlug, getColor} from 'utils/figma';
+import {getSlug, getColor} from 'modules/fig/utils';
import type {Settings} from 'types/settings';
@@ -7,14 +7,14 @@ export function generateTheme(settings: Settings) {
type ThemeColors = Record>;
type ThemeColor = {value: string, comment: string};
- const writer = new CodeBlockWriter(settings.output?.format);
+ const writer = new CodeBlockWriter(settings?.writer);
writer.write('export default').space().inlineBlock(() => {
+ let maxLineLength = 0;
// TODO: skip theme if no values at all
// TODO: effects styles: console.log('effects', figma.getLocalEffectStyles());
// Build color map
const colors: ThemeColors = {};
- let maxLineLength = 0;
figma.getLocalPaintStyles().forEach(paint => {
const [group, token] = paint.name.split('/');
const name = getSlug(token, true);
@@ -32,53 +32,60 @@ export function generateTheme(settings: Settings) {
});
// Write theme colors
- writer.write('colors:').space().inlineBlock(() => {
- Object.keys(colors).forEach(group => {
- writer.write(`${getSlug(group)}: `).inlineBlock(() => {
- Object.keys(colors[group]).forEach(name => {
- const color: ThemeColor = colors[group][name];
- writer.write(`$${name}: `);
- writer.quote(color.value);
- writer.write(`,`);
- if (color.comment) {
- const padding = (' ').repeat(maxLineLength - (name.length + color.value.length));
- writer.write(`${padding}// ${color.comment}`);
- }
- writer.newLine();
+ if (maxLineLength > 0) {
+ writer.write('colors:').space().inlineBlock(() => {
+ Object.keys(colors).forEach(group => {
+ writer.write(`${getSlug(group)}: `).inlineBlock(() => {
+ Object.keys(colors[group]).forEach(name => {
+ const color: ThemeColor = colors[group][name];
+ writer.write(`$${name}: `);
+ writer.quote(color.value);
+ writer.write(`,`);
+ if (color.comment) {
+ const padding = (' ').repeat(maxLineLength - (name.length + color.value.length));
+ writer.write(`${padding}// ${color.comment}`);
+ }
+ writer.newLine();
+ });
+ writer.newLineIfLastNot();
});
- writer.newLineIfLastNot();
+ writer.write(',');
+ writer.newLine();
});
- writer.write(',');
- writer.newLine();
});
- });
- writer.write(',');
- writer.newLine();
+ writer.write(',');
+ writer.newLine();
+ }
// TODO build font maps
// console.log('text', figma.getLocalTextStyles());
// Write font names
- writer.write('fonts:').space().inlineBlock(() => {
- // TODO
- });
- writer.write(',');
- writer.newLine();
+ /*
+ writer.write('fonts:').space().inlineBlock(() => {
+ // TODO
+ });
+ writer.write(',');
+ writer.newLine();
- // Write font weights
- writer.write('fontWeights:').space().inlineBlock(() => {
- // TODO
- });
- writer.write(',');
- writer.newLine();
+ // Write font weights
+ writer.write('fontWeights:').space().inlineBlock(() => {
+ // TODO
+ });
+ writer.write(',');
+ writer.newLine();
- // Write line heights
- writer.write('lineHeights:').space().inlineBlock(() => {
- // TODO
- });
- writer.write(',');
- writer.newLine();
+ // Write line heights
+ writer.write('lineHeights:').space().inlineBlock(() => {
+ // TODO
+ });
+ writer.write(',');
+ writer.newLine();
+ */
+ if (maxLineLength === 0) {
+ writer.write('// No figma styles found');
+ }
});
writer.write(';');
writer.newLine();
@@ -86,7 +93,6 @@ export function generateTheme(settings: Settings) {
return writer.toString();
}
-
/*
{
colors: {
diff --git a/src/modules/generate/react-native/utils.ts b/src/modules/gen/react-native/utils.ts
similarity index 71%
rename from src/modules/generate/react-native/utils.ts
rename to src/modules/gen/react-native/utils.ts
index 028c19aa..7d515f9f 100644
--- a/src/modules/generate/react-native/utils.ts
+++ b/src/modules/gen/react-native/utils.ts
@@ -1,5 +1,5 @@
import CodeBlockWriter from 'code-block-writer';
-import {getColor, sortProps, getSlug, propsToString} from 'utils/figma';
+import {getColor, sortProps, getSlug, propsToString} from 'modules/fig/utils';
import type {ParsedComponent, ParseState} from 'types/parse';
import type {Settings} from 'types/settings';
@@ -12,7 +12,7 @@ export function writeImports(
components?: string[],
) {
// Import React explicitly if set
- if (settings.output?.react?.addImport) {
+ if (settings?.react?.addImport) {
writer.write('import React from');
writer.space();
writer.quote('react');
@@ -21,7 +21,7 @@ export function writeImports(
}
// Import LinguiJS if set and Text primitive is used
- if (settings.output?.react?.addTranslate && primitives.has('Text')) {
+ if (settings?.react?.addTranslate && primitives.has('Text')) {
writer.write('import {t} from');
writer.space();
writer.quote('@lingui/macro');
@@ -68,14 +68,16 @@ export function writeFunction(
settings: Settings,
rootView: ParsedComponent,
children: ParsedComponent[],
- styleid: string = 'styles',
+ stylePrefix: string = 'styles',
+ variantStyles: any = {},
) {
const isVariant = !!rootView.node?.variantProperties;
const masterNode = isVariant ? rootView.node?.parent : rootView.node;
+ const getStylePrefix = (key: string) =>
+ Object.keys(variantStyles).includes(key) ? 'classes' : stylePrefix;
// Component props
const propDefs = Object.entries(masterNode?.componentPropertyDefinitions);
- let propVariants: string[] = [];
if (propDefs.length > 0) {
writer.write(`export interface ${rootView.name}Props`).block(() => {
propDefs.sort(sortProps).forEach(([key, prop]) => {
@@ -88,8 +90,6 @@ export function writeFunction(
: type === 'TEXT'
? 'string'
: type.toLowerCase();
- if (type === 'VARIANT')
- propVariants = variantOptions;
writer.writeLine(`${name}: ${typing};`);
});
});
@@ -111,13 +111,11 @@ export function writeFunction(
// Component function body and children
const attrProps = `${propDefs.length > 0 ? `props: ${rootView.name}Props` : ''}`;
writer.write(`export function ${rootView.name}(${attrProps})`).block(() => {
- if (isVariant && propVariants.length > 0) {
- writeClasses(writer, rootView, propVariants);
- }
-
+ if (isVariant && Object.keys(variantStyles).length > 0)
+ writeClasses(writer, variantStyles);
writer.write(`return (`).indent(() => {
- writer.write(`<${rootView.tag} style={${styleid}.${rootView.slug}}>`).indent(() => {
- writeChildren(writer, settings, children, styleid);
+ writer.write(`<${rootView.tag} style={${getStylePrefix(rootView.slug)}.${rootView.slug}}>`).indent(() => {
+ writeChildren(writer, settings, children, getStylePrefix);
});
writer.writeLine(`${rootView.tag}>`);
});
@@ -129,7 +127,7 @@ export function writeChildren(
writer: CodeBlockWriter,
settings: Settings,
children: ParsedComponent[],
- styleid: string = 'styles',
+ getStylePrefix: (key: string) => string,
) {
children.forEach((child) => {
const isVariant = !!child.node.variantProperties;
@@ -139,11 +137,11 @@ export function writeChildren(
if (propRefs?.visible) {
const name = getSlug(propRefs?.visible.split('#').shift());
writer.write(`{props.${name} &&`).space().indent(() => {
- writeChild(writer, settings, child, styleid);
+ writeChild(writer, settings, child, getStylePrefix);
}).write('}').newLine();
// Default rendering
} else {
- writeChild(writer, settings, child, styleid);
+ writeChild(writer, settings, child, getStylePrefix);
}
});
}
@@ -152,7 +150,7 @@ export function writeChild(
writer: CodeBlockWriter,
settings: Settings,
child: ParsedComponent,
- styleid: string = 'styles',
+ getStylePrefix: (key: string) => string,
) {
// Component instance swap
if (child.swap) {
@@ -163,7 +161,7 @@ export function writeChild(
// Create component tag
const attrProps = propsToString(child.props);
const attrRect = child.box ? ` width="${child.box.width}" height="${child.box.height}"` : '';
- const attrStyle = child.slug ? ` style={${styleid}.${child.slug}}` : '';
+ const attrStyle = child.slug ? ` style={${getStylePrefix(child.slug)}.${child.slug}}` : '';
const tagString = child.tag + attrStyle + attrRect + attrProps;
// No children
@@ -179,7 +177,7 @@ export function writeChild(
if (child.value.startsWith('props.')) {
writer.write(`{${child.value}}`);
} else {
- if (settings.output?.react?.addTranslate) {
+ if (settings?.react?.addTranslate) {
writer.write('{t`' + child.value + '`}');
} else {
writer.write('{`' + child.value + '`}');
@@ -193,7 +191,7 @@ export function writeChild(
});
// View children (recurse)
} else if (child.tag === 'View') {
- writeChildren(writer, settings, child.children);
+ writeChildren(writer, settings, child.children, getStylePrefix);
}
});
@@ -205,13 +203,26 @@ export function writeStyleSheet(
writer: CodeBlockWriter,
rootView: ParsedComponent,
stylesheet: ParseState['stylesheet'],
- styleid: string = 'styles',
+ stylePrefix: string = 'styles',
+ variantStyles: any = {},
) {
- writer.write(`const ${styleid} = StyleSheet.create(`).inlineBlock(() => {
- writeStyle(writer, rootView, rootView.styles);
+ writer.write(`const ${stylePrefix} = StyleSheet.create(`).inlineBlock(() => {
+ writeStyle(writer, rootView.slug, rootView.styles);
+ if (variantStyles.root) {
+ Object.keys(variantStyles.root).forEach(key => {
+ writeStyle(writer, `root${key}`, variantStyles.root[key]);
+ });
+ }
Object.keys(stylesheet).forEach(slug => {
const {component, styles} = stylesheet[slug];
- writeStyle(writer, component, styles);
+ writeStyle(writer, component.slug, styles);
+ if (variantStyles[slug]) {
+ Object.keys(variantStyles[slug]).forEach(key => {
+ if (variantStyles[slug][key]) {
+ writeStyle(writer, `${slug}${key}`, variantStyles[slug][key]);
+ }
+ });
+ }
});
});
writer.write(');');
@@ -219,12 +230,12 @@ export function writeStyleSheet(
export function writeStyle(
writer: CodeBlockWriter,
- node: ParsedComponent,
+ slug: string,
styles: any,
) {
const props = Object.keys(styles).filter(c => styles[c] !== undefined);
if (props.length > 0) {
- writer.write(`${node.slug}: {`).indent(() => {
+ writer.write(`${slug}: {`).indent(() => {
props.forEach(prop => {
const value = styles[prop];
writer.write(`${prop}: `);
@@ -245,32 +256,36 @@ export function writeStyle(
export function writeClasses(
writer: CodeBlockWriter,
- rootView: ParsedComponent,
- propVariants: string[],
+ variantStyles: any,
) {
- /*
- getObjectDiff(rootView.styles, propVariants.map(variant => rootView.styles[variant]));
+ /*Object.keys(variantStyles).forEach((k: string) => {
+ const mods = Object.keys(variantStyles[k]).filter(v => !!variantStyles[k][v]);
+ if (mods.length > 0) {
+ mods.forEach(v => writer.writeLine(`const is${v} = props.state === '${v}';`));
+ }
+ });*/
writer.write(`const classes = `).inlineBlock(() => {
- const stylesWithDifferences = ['root', 'test'];
- stylesWithDifferences.forEach(styleName => {
- writer.write(`${styleName}: [`).indent(() => {
- writer.writeLine(`styles.${styleName},`);
- propVariants.forEach((variant, i) => {
- writer.writeLine(`props.state === '${variant}' && styles.${styleName}${variant},`);
+ Object.keys(variantStyles).forEach((k: string) => {
+ const mods = Object.keys(variantStyles[k]).filter(v => !!variantStyles[k][v]);
+ if (mods.length > 0) {
+ writer.write(`${k}: [`).indent(() => {
+ writer.writeLine(`styles.${k},`);
+ mods.forEach(v => {
+ writer.writeLine(`props.state === '${v}' && styles.${k}${v},`);
+ });
});
- });
- writer.writeLine('],');
+ writer.writeLine('],');
+ }
});
});
writer.write(';');
writer.blankLine();
- */
}
export function writeInteractionStyle(
writer: CodeBlockWriter,
rootView: ParsedComponent,
- styleid: string = 'styles',
+ stylePrefix: string = 'styles',
) {
/*
({hovered, pressed, focused}) => [
@@ -295,10 +310,10 @@ export function writeInteractionStyle(
.filter(c => rootView.styles[c] !== undefined);
if (rules.length > 0) {
rules.forEach(rule => {
- writer.writeLine(`${styleid}.${rule},`);
- hasHover && writer.write(`${styleid}.${rule}Hover,`);
- hasPressed && writer.write(`${styleid}.${rule}Pressed,`);
- hasFocused && writer.write(`${styleid}.${rule}Focused,`);
+ writer.writeLine(`${stylePrefix}.${rule},`);
+ hasHover && writer.write(`${stylePrefix}.${rule}Hover,`);
+ hasPressed && writer.write(`${stylePrefix}.${rule}Pressed,`);
+ hasFocused && writer.write(`${stylePrefix}.${rule}Focused,`);
});
}
});
diff --git a/src/modules/generate/react-native/index.ts b/src/modules/generate/react-native/index.ts
deleted file mode 100644
index b06607de..00000000
--- a/src/modules/generate/react-native/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export {generateBundle} from 'modules/generate/react-native/bundle';
-export {generateTheme} from 'modules/generate/react-native/theme';
diff --git a/src/templates/index.ts b/src/templates/index.ts
deleted file mode 100644
index e26f56f9..00000000
--- a/src/templates/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// @ts-ignore
-import preview from './preview.html';
-import imports from './imports.json';
-
-export const html = {
- preview: atob(preview).replace(
- '__IMPORTS__',
- JSON.stringify(imports, undefined, 2),
- ),
-};
diff --git a/src/templates/preview.html b/src/templates/preview.html
deleted file mode 100644
index ba54ff28..00000000
--- a/src/templates/preview.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
- Figaro Component Preview
-
-
-
-
-
-
-
-
-
-
diff --git a/src/templates/previewer/iframe.tpl.html b/src/templates/previewer/iframe.tpl.html
new file mode 100644
index 00000000..96cc1a29
--- /dev/null
+++ b/src/templates/previewer/iframe.tpl.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+ Component Previewer
+
+
+
+
+
+
+
+
+
+
diff --git a/src/templates/imports.json b/src/templates/previewer/importMap.json
similarity index 100%
rename from src/templates/imports.json
rename to src/templates/previewer/importMap.json
diff --git a/src/templates/previewer/index.ts b/src/templates/previewer/index.ts
new file mode 100644
index 00000000..13619733
--- /dev/null
+++ b/src/templates/previewer/index.ts
@@ -0,0 +1,15 @@
+// @ts-ignore
+import iframe from './iframe.tpl.html';
+import imports from './importMap.json';
+import loader from './loader.tpl';
+import {build} from 'common/esbuild';
+
+import type {Settings} from 'types/settings';
+
+export default async (settings: Settings) => {
+ const previewer = atob(loader.toString());
+ const {code} = await build(previewer, settings);
+ return atob(iframe)
+ .replace('__IMPORT_MAP__', JSON.stringify(imports, undefined, 2))
+ .replace('__LOADER__', code.toString());
+};
diff --git a/src/templates/previewer/loader.tpl.tsx b/src/templates/previewer/loader.tpl.tsx
new file mode 100644
index 00000000..f1b92a8f
--- /dev/null
+++ b/src/templates/previewer/loader.tpl.tsx
@@ -0,0 +1,54 @@
+// @ts-nocheck
+
+import React from 'react';
+import {render} from 'react-dom';
+import {useEffect, useState} from 'react';
+import {useControls, TransformWrapper, TransformComponent} from 'react-zoom-pan-pinch';
+
+export function Preview() {
+ const {zoomToElement} = useControls();
+ const [name, setName] = useState();
+
+ useEffect(() => {
+ const load = (e: JSON) => {
+ if (e.data) {
+ const component = document.getElementById('component');
+ const prev = document.getElementById('target');
+ const next = document.createElement('script');
+ next.id = 'target';
+ next.type = 'module';
+ next.innerHTML = e.data.preview;
+ prev && document.body.removeChild(prev);
+ next && document.body.appendChild(next);
+ if (name !== e.data.name) {
+ setName(e.data.name);
+ setTimeout(() =>
+ requestIdleCallback(() =>
+ requestAnimationFrame(() =>
+ zoomToElement(component, 1, 0)
+ )
+ )
+ , 0);
+ }
+ }
+ };
+ addEventListener('message', load);
+ return () => removeEventListener('message', load);
+ }, [name ]);
+
+ return (
+
+
+
+ );
+}
+
+export default function Loader() {
+ return (
+
+
+
+ );
+}
+
+render(, document.getElementById('previewer'));
diff --git a/src/templates/schema.json b/src/templates/settings/schema.json
similarity index 99%
rename from src/templates/schema.json
rename to src/templates/settings/schema.json
index 3a9d7618..1aecb11b 100644
--- a/src/templates/schema.json
+++ b/src/templates/settings/schema.json
@@ -7759,6 +7759,7 @@
"enum": [
"base64",
"binary",
+ "copy",
"css",
"dataurl",
"default",
@@ -8304,6 +8305,14 @@
"Permissions": {
"type": "object"
},
+ "Platform": {
+ "enum": [
+ "browser",
+ "neutral",
+ "node"
+ ],
+ "type": "string"
+ },
"ProcessingInstruction": {
"properties": {
"ATTRIBUTE_NODE": {
@@ -8428,7 +8437,7 @@
},
"Promise": {
"properties": {
- "__@toStringTag@311": {
+ "__@toStringTag@108": {
"type": "string"
}
},
@@ -8436,12 +8445,18 @@
},
"Promise": {
"properties": {
- "__@toStringTag@311": {
+ "__@toStringTag@108": {
"type": "string"
}
},
"type": "object"
},
+ "Record": {
+ "type": "object"
+ },
+ "Record": {
+ "type": "object"
+ },
"Record": {
"type": "object"
},
@@ -10994,37 +11009,6 @@
],
"type": "string"
},
- "ShowUIOptions": {
- "properties": {
- "height": {
- "type": "number"
- },
- "position": {
- "properties": {
- "x": {
- "type": "number"
- },
- "y": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "themeColors": {
- "type": "boolean"
- },
- "title": {
- "type": "string"
- },
- "visible": {
- "type": "boolean"
- },
- "width": {
- "type": "number"
- }
- },
- "type": "object"
- },
"SlotAssignmentMode": {
"enum": [
"manual",
@@ -11102,7 +11086,7 @@
"description": "Documentation: https://esbuild.github.io/api/#format"
},
"globalName": {
- "description": "Documentation: https://esbuild.github.io/api/#globalName",
+ "description": "Documentation: https://esbuild.github.io/api/#global-name",
"type": "string"
},
"ignoreAnnotations": {
@@ -11112,11 +11096,16 @@
"jsx": {
"description": "Documentation: https://esbuild.github.io/api/#jsx",
"enum": [
+ "automatic",
"preserve",
"transform"
],
"type": "string"
},
+ "jsxDev": {
+ "description": "Documentation: https://esbuild.github.io/api/#jsx-development",
+ "type": "boolean"
+ },
"jsxFactory": {
"description": "Documentation: https://esbuild.github.io/api/#jsx-factory",
"type": "string"
@@ -11125,6 +11114,10 @@
"description": "Documentation: https://esbuild.github.io/api/#jsx-fragment",
"type": "string"
},
+ "jsxImportSource": {
+ "description": "Documentation: https://esbuild.github.io/api/#jsx-import-source",
+ "type": "string"
+ },
"keepNames": {
"description": "Documentation: https://esbuild.github.io/api/#keep-names",
"type": "boolean"
@@ -11151,6 +11144,10 @@
"description": "Documentation: https://esbuild.github.io/api/#log-limit",
"type": "number"
},
+ "logOverride": {
+ "$ref": "#/definitions/Record",
+ "description": "Documentation: https://esbuild.github.io/api/#log-override"
+ },
"mangleCache": {
"$ref": "#/definitions/Record",
"description": "Documentation: https://esbuild.github.io/api/#mangle-props"
@@ -11179,6 +11176,10 @@
"description": "Documentation: https://esbuild.github.io/api/#minify",
"type": "boolean"
},
+ "platform": {
+ "$ref": "#/definitions/Platform",
+ "description": "Documentation: https://esbuild.github.io/api/#platform"
+ },
"pure": {
"description": "Documentation: https://esbuild.github.io/api/#pure",
"items": {
@@ -11212,6 +11213,10 @@
"description": "Documentation: https://esbuild.github.io/api/#sources-content",
"type": "boolean"
},
+ "supported": {
+ "$ref": "#/definitions/Record",
+ "description": "Documentation: https://esbuild.github.io/api/#supported"
+ },
"target": {
"anyOf": [
{
@@ -11403,8 +11408,16 @@
"description": "Configuration options for editor drop into behavior",
"properties": {
"enabled": {
- "description": "Enable the dropping into editor.\nDefaults to true.",
+ "description": "Enable dropping into editor.\nDefaults to true.",
"type": "boolean"
+ },
+ "showDropSelector": {
+ "description": "Controls if a widget is shown after a drop.\nDefaults to 'afterDrop'.",
+ "enum": [
+ "afterDrop",
+ "never"
+ ],
+ "type": "string"
}
},
"type": "object"
@@ -11769,6 +11782,10 @@
"description": "Enable or disable the rendering of automatic inline completions.",
"type": "boolean"
},
+ "keepOnBlur": {
+ "description": "Does not clear active inline suggestions when the editor loses focus.",
+ "type": "boolean"
+ },
"mode": {
"description": "Configures the mode.\nUse `prefix` to only show ghost text if the text to replace is a prefix of the suggestion text.\nUse `subword` to only show ghost text if the replace text is a subword of the suggestion text.\nUse `subwordSmart` to only show ghost text if the replace text is a subword of the suggestion text, but the subword must start after the cursor position.\nDefaults to `prefix`.",
"enum": [
@@ -12015,6 +12032,10 @@
"description": "Control the width of the cursor when cursorStyle is set to 'line'",
"type": "number"
},
+ "defaultColorDecorators": {
+ "description": "Controls whether to use default color decorations or not using the default document color provider",
+ "type": "boolean"
+ },
"definitionLinkOpensInPeek": {
"description": "Controls whether the definition link opens element in the peek widget.\nDefaults to false.",
"type": "boolean"
@@ -13339,57 +13360,46 @@
}
},
"properties": {
- "display": {
+ "esbuild": {
+ "$ref": "#/definitions/TransformOptions"
+ },
+ "monaco": {
"properties": {
- "editor": {
- "properties": {
- "compiler": {
- "$ref": "#/definitions/languages.typescript.CompilerOptions"
- },
- "diagnostics": {
- "$ref": "#/definitions/languages.typescript.DiagnosticsOptions"
- },
- "general": {
- "$ref": "#/definitions/editor.IStandaloneEditorConstructionOptions"
- },
- "inlayHints": {
- "$ref": "#/definitions/languages.typescript.InlayHintsOptions"
- }
- },
- "type": "object"
+ "compiler": {
+ "$ref": "#/definitions/languages.typescript.CompilerOptions"
+ },
+ "diagnostics": {
+ "$ref": "#/definitions/languages.typescript.DiagnosticsOptions"
+ },
+ "general": {
+ "$ref": "#/definitions/editor.IStandaloneEditorConstructionOptions"
},
- "plugin": {
- "$ref": "#/definitions/ShowUIOptions"
+ "inlayHints": {
+ "$ref": "#/definitions/languages.typescript.InlayHintsOptions"
}
},
"type": "object"
},
- "output": {
+ "react": {
"properties": {
- "format": {
- "$ref": "#/definitions/Options"
+ "addImport": {
+ "type": "boolean"
},
- "react": {
- "properties": {
- "addImport": {
- "type": "boolean"
- },
- "addTranslate": {
- "type": "boolean"
- }
- },
- "type": "object"
+ "addTranslate": {
+ "type": "boolean"
+ },
+ "flavor": {
+ "enum": [
+ "react-native",
+ "tamagui"
+ ],
+ "type": "string"
}
},
"type": "object"
},
- "preview": {
- "properties": {
- "transform": {
- "$ref": "#/definitions/TransformOptions"
- }
- },
- "type": "object"
+ "writer": {
+ "$ref": "#/definitions/Options"
}
},
"type": "object"
diff --git a/src/types/messages.ts b/src/types/messages.ts
new file mode 100644
index 00000000..cb8962f1
--- /dev/null
+++ b/src/types/messages.ts
@@ -0,0 +1,6 @@
+import {EventHandler} from '@create-figma-plugin/utilities';
+
+export interface InsertCodeHandler extends EventHandler {
+ name: 'INSERT_CODE';
+ handler: (code: string) => void;
+}
diff --git a/src/types/parse.ts b/src/types/parse.ts
index 2fd08788..1dc919f0 100644
--- a/src/types/parse.ts
+++ b/src/types/parse.ts
@@ -26,4 +26,3 @@ export interface ParsedComponent {
fills?: any[],
box?: any,
}
-
diff --git a/src/types/settings.ts b/src/types/settings.ts
index 02e3be29..cc1a65e4 100644
--- a/src/types/settings.ts
+++ b/src/types/settings.ts
@@ -3,24 +3,17 @@ import type {editor, languages} from 'monaco-editor/esm/vs/editor/editor.api';
import type {Options as CodeBlockWriterOptions} from 'code-block-writer';
export interface Settings {
- display: {
- plugin: ShowUIOptions,
- editor: {
- general: editor.IStandaloneEditorConstructionOptions,
- compiler?: languages.typescript.CompilerOptions,
- inlayHints?: languages.typescript.InlayHintsOptions,
- diagnostics?: languages.typescript.DiagnosticsOptions,
- },
- },
- output: {
- react: {
- flavor: 'react-native' | 'tamagui',
- addImport?: boolean,
- addTranslate?: boolean,
- }
- format?: CodeBlockWriterOptions,
- },
- preview: {
- transform: TransformOptions,
+ react: {
+ flavor: 'react-native' | 'tamagui',
+ addImport?: boolean,
+ addTranslate?: boolean,
+ }
+ writer: CodeBlockWriterOptions,
+ monaco: {
+ general: editor.IStandaloneEditorConstructionOptions,
+ compiler?: languages.typescript.CompilerOptions,
+ inlayHints?: languages.typescript.InlayHintsOptions,
+ diagnostics?: languages.typescript.DiagnosticsOptions,
},
+ esbuild: TransformOptions,
}
diff --git a/src/types/styles.ts b/src/types/styles.ts
index 9cd79a1f..f35e38d6 100644
--- a/src/types/styles.ts
+++ b/src/types/styles.ts
@@ -64,4 +64,5 @@ export interface StylesTypography {
textAlign?: string,
textAlignVertical?: string,
textDecorationLine?: string,
+ textTransform?: string,
}
diff --git a/src/ui.tsx b/src/ui.tsx
new file mode 100644
index 00000000..f03aea4b
--- /dev/null
+++ b/src/ui.tsx
@@ -0,0 +1,21 @@
+import {h} from 'preact';
+import {emit} from '@create-figma-plugin/utilities';
+import {render, useWindowResize} from '@create-figma-plugin/ui';
+import {App} from 'interface/App';
+
+import '!./interface/styles/default.css';
+import '!./interface/styles/plugin.css';
+
+function Main() {
+ useWindowResize(e => emit('RESIZE_WINDOW', e), {
+ minWidth: 300,
+ minHeight: 100,
+ });
+ return (
+
+ );
+}
+
+export default render(Main);
diff --git a/src/utils/common.ts b/src/utils/common.ts
deleted file mode 100644
index 38ebc7a3..00000000
--- a/src/utils/common.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-type Func = (...args: any[]) => void;
-
-export function debounce(func: F, delay: number): (...args: Parameters) => void {
- let timeoutId: ReturnType | null;
-
- return function debounced(...args: Parameters) {
- const context = this;
-
- if (timeoutId !== null) {
- clearTimeout(timeoutId);
- }
-
- timeoutId = setTimeout(() => {
- func.apply(context, args);
- timeoutId = null;
- }, delay);
- };
-}
-
-export function rgbToHex(r: number, g: number, b: number, a?: number) {
- // Convert RGB values to hexadecimal
- const hexValue = ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0');
-
- // If an alpha value is provided, add it to the hexadecimal representation
- if (a !== undefined && a !== 1) {
- const alphaValue = Math.round(a * 255).toString(16).padStart(2, '0');
- return `#${hexValue}${alphaValue}`;
- }
-
- return `#${hexValue}`;
-}
diff --git a/tsconfig.json b/tsconfig.json
index 9375f30f..e8a7d3d0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,18 +1,12 @@
{
+ "extends": "@create-figma-plugin/tsconfig",
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
"compilerOptions": {
- "strict": false,
- "jsx": "react",
- "baseUrl": "./src",
- "target": "es2019",
- "module": "es2020",
- "lib": ["es2020", "dom"],
- "moduleResolution": "node",
- "skipLibCheck": true,
+ "typeRoots": ["node_modules/@figma", "node_modules/@types"],
"resolveJsonModule": true,
- "allowSyntheticDefaultImports": true,
- "typeRoots": [
- "./node_modules/@types",
- "./node_modules/@figma"
- ]
+ "skipLibCheck": true,
+ "target": "ES2020",
+ "baseUrl": "./src",
+ "strict": false,
}
}
diff --git a/yarn.lock b/yarn.lock
deleted file mode 100644
index b0f4eb34..00000000
--- a/yarn.lock
+++ /dev/null
@@ -1,723 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@babel/runtime@^7.13.10":
- version "7.16.7"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz"
- integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
- dependencies:
- regenerator-runtime "^0.13.4"
-
-"@cspotcode/source-map-support@^0.8.0":
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
- integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
- dependencies:
- "@jridgewell/trace-mapping" "0.3.9"
-
-"@donedeal0/superdiff@^1.0.9":
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/@donedeal0/superdiff/-/superdiff-1.0.9.tgz#c225b077e46f71c1b6fb335693aab902fc028655"
- integrity sha512-b0j7m3flthG03JEQCt4lFn6RJbRmSRDJISWUF7OlyR82lbEAtuIE8HLMqu3d7PIiL5m2WzhMAMSMaOE/N0dZRA==
-
-"@figma/plugin-typings@^1.62.0":
- version "1.62.0"
- resolved "https://registry.yarnpkg.com/@figma/plugin-typings/-/plugin-typings-1.62.0.tgz#b3d416ce0a8df6c8b611e091b960ab79fbaeaf66"
- integrity sha512-Pv1DZqsuJJbzVsqgCz1fPPxEdQ1o521jbcMw1MDyM9oerw7QltM8TluR5BrGgBi6Zc8zXE6J6ZuUbzz/x7Bh6A==
-
-"@jridgewell/resolve-uri@^3.0.3":
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
- integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
-
-"@jridgewell/sourcemap-codec@^1.4.10":
- version "1.4.14"
- resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
- integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
-
-"@jridgewell/trace-mapping@0.3.9":
- version "0.3.9"
- resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
- integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
- dependencies:
- "@jridgewell/resolve-uri" "^3.0.3"
- "@jridgewell/sourcemap-codec" "^1.4.10"
-
-"@monaco-editor/loader@^1.3.3":
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/@monaco-editor/loader/-/loader-1.3.3.tgz#7f1742bd3cc21c0362a46a4056317f6e5215cfca"
- integrity sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==
- dependencies:
- state-local "^1.0.6"
-
-"@monaco-editor/react@^4.5.0":
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.5.0.tgz#5a581f1ce5af6597dd127ac2c0d22d15ca3f3928"
- integrity sha512-VJMkp5Fe1+w8pLEq8tZPHZKu8zDXQIA1FtiDTSNccg1D3wg1YIZaH2es2Qpvop1k62g3c/YySRb3bnGXu2XwYQ==
- dependencies:
- "@monaco-editor/loader" "^1.3.3"
-
-"@radix-ui/primitive@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253"
- integrity sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==
- dependencies:
- "@babel/runtime" "^7.13.10"
-
-"@radix-ui/react-collection@1.0.2":
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.2.tgz#d50da00bfa2ac14585319efdbbb081d4c5a29a97"
- integrity sha512-s8WdQQ6wNXpaxdZ308KSr8fEWGrg4un8i4r/w7fhiS4ElRNjk5rRcl0/C6TANG2LvLOGIxtzo/jAg6Qf73TEBw==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/react-compose-refs" "1.0.0"
- "@radix-ui/react-context" "1.0.0"
- "@radix-ui/react-primitive" "1.0.2"
- "@radix-ui/react-slot" "1.0.1"
-
-"@radix-ui/react-compose-refs@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz#37595b1f16ec7f228d698590e78eeed18ff218ae"
- integrity sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==
- dependencies:
- "@babel/runtime" "^7.13.10"
-
-"@radix-ui/react-context@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.0.tgz#f38e30c5859a9fb5e9aa9a9da452ee3ed9e0aee0"
- integrity sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==
- dependencies:
- "@babel/runtime" "^7.13.10"
-
-"@radix-ui/react-direction@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.0.tgz#a2e0b552352459ecf96342c79949dd833c1e6e45"
- integrity sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==
- dependencies:
- "@babel/runtime" "^7.13.10"
-
-"@radix-ui/react-id@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.0.tgz#8d43224910741870a45a8c9d092f25887bb6d11e"
- integrity sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/react-use-layout-effect" "1.0.0"
-
-"@radix-ui/react-presence@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.0.tgz#814fe46df11f9a468808a6010e3f3ca7e0b2e84a"
- integrity sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/react-compose-refs" "1.0.0"
- "@radix-ui/react-use-layout-effect" "1.0.0"
-
-"@radix-ui/react-primitive@1.0.2":
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz#54e22f49ca59ba88d8143090276d50b93f8a7053"
- integrity sha512-zY6G5Qq4R8diFPNwtyoLRZBxzu1Z+SXMlfYpChN7Dv8gvmx9X3qhDqiLWvKseKVJMuedFeU/Sa0Sy/Ia+t06Dw==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/react-slot" "1.0.1"
-
-"@radix-ui/react-roving-focus@1.0.3":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.3.tgz#0b4f4f9bd509f4510079e9e0734a734fd17cdce3"
- integrity sha512-stjCkIoMe6h+1fWtXlA6cRfikdBzCLp3SnVk7c48cv/uy3DTGoXhN76YaOYUJuy3aEDvDIKwKR5KSmvrtPvQPQ==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/primitive" "1.0.0"
- "@radix-ui/react-collection" "1.0.2"
- "@radix-ui/react-compose-refs" "1.0.0"
- "@radix-ui/react-context" "1.0.0"
- "@radix-ui/react-direction" "1.0.0"
- "@radix-ui/react-id" "1.0.0"
- "@radix-ui/react-primitive" "1.0.2"
- "@radix-ui/react-use-callback-ref" "1.0.0"
- "@radix-ui/react-use-controllable-state" "1.0.0"
-
-"@radix-ui/react-slot@1.0.1":
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.1.tgz#e7868c669c974d649070e9ecbec0b367ee0b4d81"
- integrity sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/react-compose-refs" "1.0.0"
-
-"@radix-ui/react-tabs@^1.0.3":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.3.tgz#8b4158160a7c6633c893c74641e929d2708e709a"
- integrity sha512-4CkF/Rx1GcrusI/JZ1Rvyx4okGUs6wEenWA0RG/N+CwkRhTy7t54y7BLsWUXrAz/GRbBfHQg/Odfs/RoW0CiRA==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/primitive" "1.0.0"
- "@radix-ui/react-context" "1.0.0"
- "@radix-ui/react-direction" "1.0.0"
- "@radix-ui/react-id" "1.0.0"
- "@radix-ui/react-presence" "1.0.0"
- "@radix-ui/react-primitive" "1.0.2"
- "@radix-ui/react-roving-focus" "1.0.3"
- "@radix-ui/react-use-controllable-state" "1.0.0"
-
-"@radix-ui/react-use-callback-ref@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90"
- integrity sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==
- dependencies:
- "@babel/runtime" "^7.13.10"
-
-"@radix-ui/react-use-controllable-state@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz#a64deaafbbc52d5d407afaa22d493d687c538b7f"
- integrity sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@radix-ui/react-use-callback-ref" "1.0.0"
-
-"@radix-ui/react-use-layout-effect@1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz#2fc19e97223a81de64cd3ba1dc42ceffd82374dc"
- integrity sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==
- dependencies:
- "@babel/runtime" "^7.13.10"
-
-"@tsconfig/node10@^1.0.7":
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
- integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
-
-"@tsconfig/node12@^1.0.7":
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
- integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
-
-"@tsconfig/node14@^1.0.0":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
- integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
-
-"@tsconfig/node16@^1.0.2":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
- integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
-
-"@types/json-schema@^7.0.9":
- version "7.0.11"
- resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
- integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
-
-"@types/node@^16.9.2":
- version "16.18.16"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.16.tgz#09ff98b144abae2d7cce3e9fe9040ab2bf73222c"
- integrity sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA==
-
-"@types/prop-types@*":
- version "15.7.4"
- resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz"
- integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
-
-"@types/react-dom@^17.0.19":
- version "17.0.19"
- resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.19.tgz#36feef3aa35d045cacd5ed60fe0eef5272f19492"
- integrity sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==
- dependencies:
- "@types/react" "^17"
-
-"@types/react@^17":
- version "17.0.45"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.45.tgz#9b3d5b661fd26365fefef0e766a1c6c30ccf7b3f"
- integrity sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
-"@types/react@^17.0.57":
- version "17.0.57"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.57.tgz#341152f222222075caf020ae6e0e68b9b835404c"
- integrity sha512-e4msYpu5QDxzNrXDHunU/VPyv2M1XemGG/p7kfCjUiPtlLDCWLGQfgAMng6YyisWYxZ09mYdQlmMnyS0NfZdEg==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
-"@types/scheduler@*":
- version "0.16.2"
- resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
- integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
-
-acorn-walk@^8.1.1:
- version "8.2.0"
- resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
- integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
-
-acorn@^8.4.1:
- version "8.8.2"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
- integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
-
-ansi-regex@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
- integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
-
-ansi-styles@^4.0.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
- integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
- dependencies:
- color-convert "^2.0.1"
-
-arg@^4.1.0:
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
- integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
-
-balanced-match@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
- integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
-
-brace-expansion@^1.1.7:
- version "1.1.11"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
- integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
- dependencies:
- balanced-match "^1.0.0"
- concat-map "0.0.1"
-
-client-zip@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/client-zip/-/client-zip-2.3.1.tgz#65289e9c0d8bd6a08f4f770bd5eb650deb98cf8c"
- integrity sha512-iRSvLjnKWXln/Q3m4thNe7IQWHBZg1fYjnuFXjLOgXg7GQYTFdVfHJ3n1J7qpgFpGbfXYt8pfngfIl/FVDYPqg==
-
-cliui@^8.0.1:
- version "8.0.1"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
- integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
- dependencies:
- string-width "^4.2.0"
- strip-ansi "^6.0.1"
- wrap-ansi "^7.0.0"
-
-code-block-writer@^12.0.0:
- version "12.0.0"
- resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770"
- integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==
-
-color-convert@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
- integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
- dependencies:
- color-name "~1.1.4"
-
-color-name@~1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
- integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-
-concat-map@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
- integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
-
-create-require@^1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
- integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
-
-csstype@^3.0.2:
- version "3.0.10"
- resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz"
- integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==
-
-diff@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
- integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
-
-emoji-regex@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
- integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-
-esbuild-android-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.39.tgz#09f12a372eed9743fd77ff6d889ac14f7b340c21"
- integrity sha512-EJOu04p9WgZk0UoKTqLId9VnIsotmI/Z98EXrKURGb3LPNunkeffqQIkjS2cAvidh+OK5uVrXaIP229zK6GvhQ==
-
-esbuild-android-arm64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.39.tgz#f608d00ea03fe26f3b1ab92a30f99220390f3071"
- integrity sha512-+twajJqO7n3MrCz9e+2lVOnFplRsaGRwsq1KL/uOy7xK7QdRSprRQcObGDeDZUZsacD5gUkk6OiHiYp6RzU3CA==
-
-esbuild-darwin-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.39.tgz#31528daa75b4c9317721ede344195163fae3e041"
- integrity sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==
-
-esbuild-darwin-arm64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.39.tgz#247f770d86d90a215fa194f24f90e30a0bd97245"
- integrity sha512-/fcQ5UhE05OiT+bW5v7/up1bDsnvaRZPJxXwzXsMRrr7rZqPa85vayrD723oWMT64dhrgWeA3FIneF8yER0XTw==
-
-esbuild-freebsd-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.39.tgz#479414d294905055eb396ebe455ed42213284ee0"
- integrity sha512-oMNH8lJI4wtgN5oxuFP7BQ22vgB/e3Tl5Woehcd6i2r6F3TszpCnNl8wo2d/KvyQ4zvLvCWAlRciumhQg88+kQ==
-
-esbuild-freebsd-arm64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.39.tgz#cedeb10357c88533615921ae767a67dc870a474c"
- integrity sha512-1GHK7kwk57ukY2yI4ILWKJXaxfr+8HcM/r/JKCGCPziIVlL+Wi7RbJ2OzMcTKZ1HpvEqCTBT/J6cO4ZEwW4Ypg==
-
-esbuild-linux-32@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.39.tgz#d9f008c4322d771f3958f59c1eee5a05cdf92485"
- integrity sha512-g97Sbb6g4zfRLIxHgW2pc393DjnkTRMeq3N1rmjDUABxpx8SjocK4jLen+/mq55G46eE2TA0MkJ4R3SpKMu7dg==
-
-esbuild-linux-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.39.tgz#ba58d7f66858913aeb1ab5c6bde1bbd824731795"
- integrity sha512-4tcgFDYWdI+UbNMGlua9u1Zhu0N5R6u9tl5WOM8aVnNX143JZoBZLpCuUr5lCKhnD0SCO+5gUyMfupGrHtfggQ==
-
-esbuild-linux-arm64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.39.tgz#708785a30072702b5b1c16b65cf9c25c51202529"
- integrity sha512-23pc8MlD2D6Px1mV8GMglZlKgwgNKAO8gsgsLLcXWSs9lQsCYkIlMo/2Ycfo5JrDIbLdwgP8D2vpfH2KcBqrDQ==
-
-esbuild-linux-arm@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.39.tgz#4e8b5deaa7ab60d0d28fab131244ef82b40684f4"
- integrity sha512-t0Hn1kWVx5UpCzAJkKRfHeYOLyFnXwYynIkK54/h3tbMweGI7dj400D1k0Vvtj2u1P+JTRT9tx3AjtLEMmfVBQ==
-
-esbuild-linux-mips64le@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.39.tgz#6f3bf3023f711084e5a1e8190487d2020f39f0f7"
- integrity sha512-epwlYgVdbmkuRr5n4es3B+yDI0I2e/nxhKejT9H0OLxFAlMkeQZxSpxATpDc9m8NqRci6Kwyb/SfmD1koG2Zuw==
-
-esbuild-linux-ppc64le@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.39.tgz#900e718a4ea3f6aedde8424828eeefdd4b48d4b9"
- integrity sha512-W/5ezaq+rQiQBThIjLMNjsuhPHg+ApVAdTz2LvcuesZFMsJoQAW2hutoyg47XxpWi7aEjJGrkS26qCJKhRn3QQ==
-
-esbuild-linux-riscv64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.39.tgz#dcbff622fa37047a75d2ff7a1d8d2949d80277e4"
- integrity sha512-IS48xeokcCTKeQIOke2O0t9t14HPvwnZcy+5baG13Z1wxs9ZrC5ig5ypEQQh4QMKxURD5TpCLHw2W42CLuVZaA==
-
-esbuild-linux-s390x@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.39.tgz#3f725a7945b419406c99d93744b28552561dcdfd"
- integrity sha512-zEfunpqR8sMomqXhNTFEKDs+ik7HC01m3M60MsEjZOqaywHu5e5682fMsqOlZbesEAAaO9aAtRBsU7CHnSZWyA==
-
-esbuild-netbsd-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.39.tgz#e10e40b6a765798b90d4eb85901cc85c8b7ff85e"
- integrity sha512-Uo2suJBSIlrZCe4E0k75VDIFJWfZy+bOV6ih3T4MVMRJh1lHJ2UyGoaX4bOxomYN3t+IakHPyEoln1+qJ1qYaA==
-
-esbuild-openbsd-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.39.tgz#935ec143f75ce10bd9cdb1c87fee00287eb0edbc"
- integrity sha512-secQU+EpgUPpYjJe3OecoeGKVvRMLeKUxSMGHnK+aK5uQM3n1FPXNJzyz1LHFOo0WOyw+uoCxBYdM4O10oaCAA==
-
-esbuild-sunos-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.39.tgz#0e7aa82b022a2e6d55b0646738b2582c2d72c3c0"
- integrity sha512-qHq0t5gePEDm2nqZLb+35p/qkaXVS7oIe32R0ECh2HOdiXXkj/1uQI9IRogGqKkK+QjDG+DhwiUw7QoHur/Rwg==
-
-esbuild-wasm@^0.14.54:
- version "0.14.54"
- resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.14.54.tgz#6e31c86700850664ed9781876cb907c13d230d69"
- integrity sha512-Lk1Rq6mnHCIgYpUGQGsJn1dgW26w5uV0KYTl6CdoixSF4hD4v8Nyyxmhrqo4lUkV8AQoWLVfIBWYo7l+JTPl9g==
-
-esbuild-windows-32@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.39.tgz#3f1538241f31b538545f4b5841b248cac260fa35"
- integrity sha512-XPjwp2OgtEX0JnOlTgT6E5txbRp6Uw54Isorm3CwOtloJazeIWXuiwK0ONJBVb/CGbiCpS7iP2UahGgd2p1x+Q==
-
-esbuild-windows-64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.39.tgz#b100c59f96d3c2da2e796e42fee4900d755d3e03"
- integrity sha512-E2wm+5FwCcLpKsBHRw28bSYQw0Ikxb7zIMxw3OPAkiaQhLVr3dnVO8DofmbWhhf6b97bWzg37iSZ45ZDpLw7Ow==
-
-esbuild-windows-arm64@0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.39.tgz#00268517e665b33c89778d61f144e4256b39f631"
- integrity sha512-sBZQz5D+Gd0EQ09tZRnz/PpVdLwvp/ufMtJ1iDFYddDaPpZXKqPyaxfYBLs3ueiaksQ26GGa7sci0OqFzNs7KA==
-
-esbuild@^0.14.39:
- version "0.14.39"
- resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.39.tgz#c926b2259fe6f6d3a94f528fb42e103c5a6d909a"
- integrity sha512-2kKujuzvRWYtwvNjYDY444LQIA3TyJhJIX3Yo4+qkFlDDtGlSicWgeHVJqMUP/2sSfH10PGwfsj+O2ro1m10xQ==
- optionalDependencies:
- esbuild-android-64 "0.14.39"
- esbuild-android-arm64 "0.14.39"
- esbuild-darwin-64 "0.14.39"
- esbuild-darwin-arm64 "0.14.39"
- esbuild-freebsd-64 "0.14.39"
- esbuild-freebsd-arm64 "0.14.39"
- esbuild-linux-32 "0.14.39"
- esbuild-linux-64 "0.14.39"
- esbuild-linux-arm "0.14.39"
- esbuild-linux-arm64 "0.14.39"
- esbuild-linux-mips64le "0.14.39"
- esbuild-linux-ppc64le "0.14.39"
- esbuild-linux-riscv64 "0.14.39"
- esbuild-linux-s390x "0.14.39"
- esbuild-netbsd-64 "0.14.39"
- esbuild-openbsd-64 "0.14.39"
- esbuild-sunos-64 "0.14.39"
- esbuild-windows-32 "0.14.39"
- esbuild-windows-64 "0.14.39"
- esbuild-windows-arm64 "0.14.39"
-
-escalade@^3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
- integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
-
-fs.realpath@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
- integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
-
-get-caller-file@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
- integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
-
-glob@^7.1.7:
- version "7.2.3"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
- integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.1.1"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-inflight@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
- integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
- dependencies:
- once "^1.3.0"
- wrappy "1"
-
-inherits@2:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-is-fullwidth-code-point@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
- integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
-
-"js-tokens@^3.0.0 || ^4.0.0":
- version "4.0.0"
- resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
- integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-loose-envify@^1.1.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
- integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
- dependencies:
- js-tokens "^3.0.0 || ^4.0.0"
-
-make-error@^1.1.1:
- version "1.3.6"
- resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
- integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
-
-minimatch@^3.1.1:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
- integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
- dependencies:
- brace-expansion "^1.1.7"
-
-monaco-editor@^0.37.1:
- version "0.37.1"
- resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.37.1.tgz#d6f5ffb593e019e74e19bf8a2bdef5a691876f4e"
- integrity sha512-jLXEEYSbqMkT/FuJLBZAVWGuhIb4JNwHE9kPTorAVmsdZ4UzHAfgWxLsVtD7pLRFaOwYPhNG9nUCpmFL1t/dIg==
-
-object-assign@^4.1.1:
- version "4.1.1"
- resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-once@^1.3.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
- dependencies:
- wrappy "1"
-
-path-equal@^1.1.2:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/path-equal/-/path-equal-1.2.5.tgz#9fcbdd5e5daee448e96f43f3bac06c666b5e982a"
- integrity sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g==
-
-path-is-absolute@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
- integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
-
-react-dom@^17.0.2:
- version "17.0.2"
- resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
- integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
- scheduler "^0.20.2"
-
-react@^17.0.2:
- version "17.0.2"
- resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
- integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
-
-regenerator-runtime@^0.13.4:
- version "0.13.9"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
- integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
-
-require-directory@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
- integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
-
-safe-stable-stringify@^2.2.0:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz#ec7b037768098bf65310d1d64370de0dc02353aa"
- integrity sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==
-
-scheduler@^0.20.2:
- version "0.20.2"
- resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz"
- integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
-
-state-local@^1.0.6:
- version "1.0.7"
- resolved "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz"
- integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==
-
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
-ts-node@^10.9.1:
- version "10.9.1"
- resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
- integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
- dependencies:
- "@cspotcode/source-map-support" "^0.8.0"
- "@tsconfig/node10" "^1.0.7"
- "@tsconfig/node12" "^1.0.7"
- "@tsconfig/node14" "^1.0.0"
- "@tsconfig/node16" "^1.0.2"
- acorn "^8.4.1"
- acorn-walk "^8.1.1"
- arg "^4.1.0"
- create-require "^1.1.0"
- diff "^4.0.1"
- make-error "^1.1.1"
- v8-compile-cache-lib "^3.0.1"
- yn "3.1.1"
-
-typescript-json-schema@^0.56.0:
- version "0.56.0"
- resolved "https://registry.yarnpkg.com/typescript-json-schema/-/typescript-json-schema-0.56.0.tgz#de3fe196633197aa66b10191e78f51d5f6b45847"
- integrity sha512-k/aSEqx89YR2z/f2y3VwoOGzlKTWern0EIey2qqEpMRP7HL4CI8udPElzJs4eFVkPowCLJ1yVBSzuIWIUF+mMA==
- dependencies:
- "@types/json-schema" "^7.0.9"
- "@types/node" "^16.9.2"
- glob "^7.1.7"
- path-equal "^1.1.2"
- safe-stable-stringify "^2.2.0"
- ts-node "^10.9.1"
- typescript "~4.9.5"
- yargs "^17.1.1"
-
-typescript@^5.0.4:
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
- integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
-
-typescript@~4.9.5:
- version "4.9.5"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
- integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
-
-v8-compile-cache-lib@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
- integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
-
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
-
-y18n@^5.0.5:
- version "5.0.8"
- resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
- integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
-
-yargs-parser@^21.1.1:
- version "21.1.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
- integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
-
-yargs@^17.1.1:
- version "17.7.1"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967"
- integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==
- dependencies:
- cliui "^8.0.1"
- escalade "^3.1.1"
- get-caller-file "^2.0.5"
- require-directory "^2.1.1"
- string-width "^4.2.3"
- y18n "^5.0.5"
- yargs-parser "^21.1.1"
-
-yn@3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
- integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==