From ee6adf4af14c1b8a2096d0762dc719398cf08673 Mon Sep 17 00:00:00 2001 From: Syntax <2079305+TheUltDev@users.noreply.github.com> Date: Fri, 15 Dec 2023 23:22:11 -0600 Subject: [PATCH] v45 (#20) --- .gitignore | 7 +- .vscode/settings.json | 2 +- README.md | 113 +- ROADMAP.md | 47 - art/banner.png | Bin 407878 -> 0 bytes {art => artwork}/logo.png | Bin build-figma-plugin.ui.js | 18 - package.json | 69 +- packages/css-to-rn/README.md | 7 + packages/css-to-rn/declaration.ts | 571 +++ packages/css-to-rn/declarations/_index.ts | 31 + .../css-to-rn/declarations/align-content.ts | 36 + .../css-to-rn/declarations/align-items.ts | 40 + packages/css-to-rn/declarations/align-self.ts | 40 + packages/css-to-rn/declarations/angle.ts | 13 + .../css-to-rn/declarations/aspect-ratio.ts | 11 + .../declarations/border-side-width.ts | 13 + .../css-to-rn/declarations/border-style.ts | 26 + packages/css-to-rn/declarations/box-shadow.ts | 21 + packages/css-to-rn/declarations/color.ts | 29 + packages/css-to-rn/declarations/dimension.ts | 21 + packages/css-to-rn/declarations/display.ts | 49 + .../css-to-rn/declarations/font-family.ts | 6 + packages/css-to-rn/declarations/font-size.ts | 15 + packages/css-to-rn/declarations/font-style.ts | 13 + .../declarations/font-variant-caps.ts | 19 + .../css-to-rn/declarations/font-weight.ts | 17 + packages/css-to-rn/declarations/gap.ts | 12 + .../css-to-rn/declarations/justify-content.ts | 37 + .../length-or-coerce-percentage-to-runtime.ts | 21 + .../declarations/length-percentage-or-auto.ts | 14 + packages/css-to-rn/declarations/length.ts | 112 + .../css-to-rn/declarations/line-height.ts | 29 + packages/css-to-rn/declarations/overflow.ts | 13 + .../runtime-specifics-function.ts | 83 + packages/css-to-rn/declarations/size.ts | 32 + packages/css-to-rn/declarations/text-align.ts | 13 + .../declarations/text-decoration-line.ts | 27 + .../declarations/text-decoration-style.ts | 13 + .../css-to-rn/declarations/text-shadow.ts | 18 + packages/css-to-rn/declarations/transform.ts | 84 + packages/css-to-rn/declarations/unparsed.ts | 236 ++ .../css-to-rn/declarations/vertical-align.ts | 17 + packages/css-to-rn/index.ts | 507 +++ packages/css-to-rn/package.json | 11 + packages/css-to-rn/properties.ts | 162 + packages/css-to-rn/types/index.ts | 232 ++ packages/css-to-rn/types/parse.ts | 43 + packages/css-to-rn/utils.ts | 44 + packages/exo-primitives/README.md | 1 + .../build-figma-plugin.main.js | 0 .../build-figma-plugin.manifest.js | 0 .../build-figma-plugin.ui.js | 42 + packages/figma-to-react-native/package.json | 81 + .../src/common/assert.ts | 40 + .../src}/common/delay.ts | 0 .../src}/common/string.ts | 0 .../figma-to-react-native/src}/config/env.ts | 20 +- .../src}/config/project.ts | 2 +- .../figma-to-react-native/src}/config/user.ts | 3 - packages/figma-to-react-native/src/env.d.ts | 4 + .../src/interface/App.tsx | 131 + .../src/interface/base/NavBar.tsx | 166 + .../src/interface/base/ProgressBar.tsx | 29 + .../src/interface/base/ScreenInfo.tsx | 22 + .../src/interface/base/ScreenWarning.tsx | 15 + .../src/interface/base/SearchBar.tsx | 34 + .../src/interface/base/StatusBar.tsx | 31 + .../src/interface/base/Tabs.tsx | 46 + .../src}/interface/css/default.css | 161 +- .../src/interface/css/default.css.d.ts | 22 + .../src}/interface/css/editor.css | 0 .../src}/interface/css/editor.css.d.ts | 0 .../src}/interface/css/plugin.css | 0 .../src}/interface/css/plugin.css.d.ts | 0 .../src/interface/hooks/useBuild.ts | 40 + .../src}/interface/hooks/useDarkMode.ts | 2 + .../src/interface/hooks/useEditor.ts | 27 + .../src/interface/hooks/useNavigation.ts | 54 + .../src/interface/hooks/useProjectBuild.ts | 38 + .../src}/interface/hooks/useProjectConfig.ts | 0 .../src/interface/hooks/useProjectIcons.ts | 19 + .../src/interface/hooks/useProjectTheme.ts | 18 + .../src/interface/hooks/useSelectedVariant.ts | 16 + .../src/interface/hooks/useStyleGenServer.ts | 14 + .../src/interface/hooks/useUserSettings.ts | 20 +- .../src/interface/store.ts | 92 + .../src}/interface/telemetry.tsx | 0 .../src/interface/utils/bundler/index.ts | 34 + .../interface/utils/bundler/lib/barrier.ts | 33 + .../interface/utils/bundler/lib/compiler.ts | 64 + .../src/interface/utils/bundler/lib/path.ts | 215 + .../interface/utils/bundler/lib/resolver.ts | 8 + .../interface/utils/bundler/plugins/css.ts | 34 + .../interface/utils/bundler/plugins/png.ts | 47 + .../interface/utils/bundler/plugins/react.ts | 64 + .../interface/utils/bundler/plugins/svg.ts | 37 + .../src/interface/utils/editor/index.ts | 135 + .../src/interface/utils/editor/lib/patch.ts | 19 + .../src/interface/utils/editor/lib/yjs.ts | 252 ++ .../utils/editor/schemas/settings.json | 2814 +++++++++++++ .../utils/editor/templates/env.ts.tpl | 10 + .../interface/utils/editor/templates/index.ts | 13 + .../editor/templates/react-native-exo.ts.tpl | 3 + .../editor/templates/react-native.ts.tpl | 179 + .../utils/editor/templates/styles.ts.tpl | 4 + .../src/interface/utils/exporter}/download.ts | 6 +- .../src/interface/utils/exporter}/upload.ts | 2 +- .../src/interface/utils/exporter/zip.ts | 33 + .../src/interface/utils/importer/icons.ts | 42 + .../interface/utils/previewer}/importMap.json | 7 +- .../src/interface/utils/previewer/index.ts | 102 + .../utils/previewer/templates/app.tsx.tpl | 70 + .../utils/previewer/templates/iframe.html.tpl | 89 +- .../utils/previewer/templates/loader.tsx.tpl | 84 +- .../src/interface/views/ComponentCode.tsx | 116 + .../src/interface/views/ComponentPreview.tsx | 136 + .../src/interface/views/ComponentStory.tsx | 35 + .../src/interface/views/ProjectAssets.tsx | 45 + .../src/interface/views/ProjectComponents.tsx | 238 ++ .../src/interface/views/ProjectExport.tsx | 73 +- .../src/interface/views/ProjectIcons.tsx | 192 + .../src/interface/views/ProjectSettings.tsx | 46 + .../src/interface/views/ProjectTheme.tsx | 35 + packages/figma-to-react-native/src/main.ts | 129 + .../src/plugin/fig/index.ts | 108 +- .../src/plugin/fig/lib/assets.ts | 72 + .../src/plugin/fig/lib/colors.ts | 81 + .../src/plugin/fig/lib/index.ts | 36 + .../src/plugin/fig/lib/node.ts | 47 + .../src/plugin/fig/lib/props.ts | 132 + .../src/plugin/fig/lib/styles.ts | 62 +- .../src/plugin/fig/lib}/traverse.ts | 22 +- .../src/plugin/fig/lib}/validate.ts | 0 .../src}/plugin/gen/common/generateIndex.ts | 0 .../src/plugin/gen/index.ts | 272 ++ .../src}/plugin/gen/primitives/exo/Slider.ts | 13 +- .../src}/plugin/gen/primitives/index.ts | 14 +- .../plugin/gen/react-native/generateBundle.ts | 114 + .../plugin/gen/react-native/generateCode.ts | 28 + .../plugin/gen/react-native/generateStory.ts | 0 .../plugin/gen/react-native/generateTheme.ts | 87 +- .../src}/plugin/gen/react-native/index.ts | 0 .../gen/react-native/lib/writeChildren.ts | 148 +- .../gen/react-native/lib/writeClasses.ts | 17 +- .../gen/react-native/lib/writeColors.ts | 83 + .../gen/react-native/lib/writeFunction.ts | 79 +- .../gen/react-native/lib/writeImports.ts | 100 + .../plugin/gen/react-native/lib/writeProps.ts | 14 +- .../plugin/gen/react-native/lib/writeState.ts | 7 +- .../gen/react-native/lib/writeStyleSheet.ts | 120 + .../figma-to-react-native/src/plugin/index.ts | 8 + .../src/plugin/lib/app.ts | 31 + .../src/plugin/lib}/codegen.ts | 8 +- .../src/plugin/lib}/config.ts | 2 +- .../src/plugin/lib/drop.ts | 19 + .../src/plugin/lib/icons.ts | 231 ++ .../src/plugin/lib}/project.ts | 29 +- .../src/plugin/lib/vscode.ts | 1 + .../figma-to-react-native/src/types/app.ts | 30 + .../src/types/component.ts | 50 + .../figma-to-react-native/src/types/events.ts | 121 + .../figma-to-react-native/src}/types/parse.ts | 40 +- .../src}/types/project.ts | 10 +- .../src/types/settings.ts | 33 + .../figma-to-react-native/src}/ui.tsx | 32 +- .../figma-to-react-native/tsconfig.json | 2 +- packages/ui-kit-figma/README.md | 1 + pnpm-lock.yaml | 3612 +++++++++-------- pnpm-workspace.yaml | 3 + src/common/color.ts | 8 - src/common/random.ts | 17 - src/interface/App.tsx | 92 - src/interface/base/Tabs.tsx | 57 - src/interface/base/Watermark.tsx | 11 - src/interface/css/default.css.d.ts | 10 - src/interface/hooks/useEditor.ts | 55 - src/interface/hooks/usePreviewComponent.ts | 13 - src/interface/hooks/usePreviewTheme.ts | 12 - src/interface/hooks/useProjectBuild.ts | 42 - src/interface/pages/Code.tsx | 107 - src/interface/pages/Preview.tsx | 97 - src/interface/pages/Settings.tsx | 41 - src/interface/pages/Story.tsx | 31 - src/interface/pages/Theme.tsx | 25 - src/interface/utils/build.ts | 28 - src/interface/utils/editor.ts | 13 - src/interface/utils/preview/index.ts | 49 - .../utils/preview/template/_entry.tpl.tsx | 52 - src/interface/utils/sync.ts | 58 - src/interface/utils/zip.ts | 19 - src/main.ts | 104 - src/plugin/app.ts | 18 - src/plugin/fig/lib/convertAssets.ts | 57 - src/plugin/fig/lib/getColor.ts | 14 - src/plugin/fig/lib/getInstanceInfo.ts | 10 - src/plugin/fig/lib/getPropName.ts | 6 - src/plugin/fig/lib/getTopFill.ts | 6 - src/plugin/fig/lib/index.ts | 10 - src/plugin/fig/lib/isNodeVisible.ts | 6 - src/plugin/fig/lib/propsToString.ts | 78 - src/plugin/fig/lib/reactions.ts | 8 - src/plugin/fig/lib/sortProps.ts | 22 - src/plugin/gen/index.ts | 30 - .../gen/primitives/utils/getFillToken.ts | 13 - src/plugin/gen/react-native/generateBundle.ts | 127 - src/plugin/gen/react-native/generateCode.ts | 22 - .../gen/react-native/generatePreview.ts | 60 - .../gen/react-native/lib/writeImports.ts | 86 - .../gen/react-native/lib/writeStyleSheet.ts | 123 - src/plugin/preview.ts | 40 - src/plugin/styles/css-to-rn/generateStyles.ts | 10 - .../css-to-rn/utils/convertToReactNative.ts | 15 - .../styles/css-to-rn/utils/processStyles.ts | 42 - .../styles/css-to-rn/utils/shorthandStyles.ts | 64 - src/plugin/styles/css-to-rn/vendor/index.d.ts | 10 - src/plugin/styles/css-to-rn/vendor/index.js | 43 - .../css-to-rn/vendor/lib/TokenStream.js | 76 - .../css-to-rn/vendor/lib/parse/index.d.ts | 177 - .../css-to-rn/vendor/lib/parse/index.js | 28 - .../css-to-rn/vendor/lib/parse/parse.js | 321 -- .../css-to-rn/vendor/lib/parse/stringify.js | 48 - .../styles/css-to-rn/vendor/lib/parse/unit.js | 120 - .../styles/css-to-rn/vendor/lib/parse/walk.js | 22 - .../styles/css-to-rn/vendor/lib/tokenTypes.js | 61 - .../vendor/transforms/aspectRatio.js | 12 - .../css-to-rn/vendor/transforms/border.js | 67 - .../css-to-rn/vendor/transforms/boxShadow.js | 11 - .../css-to-rn/vendor/transforms/flex.js | 67 - .../css-to-rn/vendor/transforms/flexFlow.js | 40 - .../css-to-rn/vendor/transforms/font.js | 59 - .../css-to-rn/vendor/transforms/fontFamily.js | 20 - .../vendor/transforms/fontVariant.js | 14 - .../css-to-rn/vendor/transforms/index.js | 84 - .../vendor/transforms/placeContent.js | 25 - .../vendor/transforms/textDecoration.js | 52 - .../vendor/transforms/textDecorationLine.js | 20 - .../css-to-rn/vendor/transforms/textShadow.js | 10 - .../css-to-rn/vendor/transforms/transform.js | 79 - .../css-to-rn/vendor/transforms/util.js | 92 - .../styles/experimental/generateStyles.ts | 35 - .../styles/experimental/lib/background.ts | 16 - src/plugin/styles/experimental/lib/border.ts | 31 - .../styles/experimental/lib/dimension.ts | 29 - src/plugin/styles/experimental/lib/index.ts | 7 - src/plugin/styles/experimental/lib/layout.ts | 58 - src/plugin/styles/experimental/lib/padding.ts | 29 - .../styles/experimental/lib/position.ts | 6 - .../styles/experimental/lib/typography.ts | 45 - .../experimental/lib/utils/getFillStyle.ts | 10 - .../experimental/lib/utils/getFontWeight.ts | 27 - .../lib/utils/getLetterSpacing.ts | 12 - .../experimental/lib/utils/getLineHeight.ts | 12 - .../styles/experimental/lib/utils/getSize.ts | 65 - .../styles/experimental/types/styles.ts | 73 - src/plugin/styles/index.ts | 18 - src/plugin/styles/service/generateStyles.ts | 19 - src/types/app.ts | 7 - src/types/events.ts | 65 - src/types/preview.ts | 17 - src/types/settings.ts | 19 - 261 files changed, 13311 insertions(+), 6203 deletions(-) delete mode 100644 ROADMAP.md delete mode 100644 art/banner.png rename {art => artwork}/logo.png (100%) delete mode 100644 build-figma-plugin.ui.js create mode 100644 packages/css-to-rn/README.md create mode 100644 packages/css-to-rn/declaration.ts create mode 100644 packages/css-to-rn/declarations/_index.ts create mode 100644 packages/css-to-rn/declarations/align-content.ts create mode 100644 packages/css-to-rn/declarations/align-items.ts create mode 100644 packages/css-to-rn/declarations/align-self.ts create mode 100644 packages/css-to-rn/declarations/angle.ts create mode 100644 packages/css-to-rn/declarations/aspect-ratio.ts create mode 100644 packages/css-to-rn/declarations/border-side-width.ts create mode 100644 packages/css-to-rn/declarations/border-style.ts create mode 100644 packages/css-to-rn/declarations/box-shadow.ts create mode 100644 packages/css-to-rn/declarations/color.ts create mode 100644 packages/css-to-rn/declarations/dimension.ts create mode 100644 packages/css-to-rn/declarations/display.ts create mode 100644 packages/css-to-rn/declarations/font-family.ts create mode 100644 packages/css-to-rn/declarations/font-size.ts create mode 100644 packages/css-to-rn/declarations/font-style.ts create mode 100644 packages/css-to-rn/declarations/font-variant-caps.ts create mode 100644 packages/css-to-rn/declarations/font-weight.ts create mode 100644 packages/css-to-rn/declarations/gap.ts create mode 100644 packages/css-to-rn/declarations/justify-content.ts create mode 100644 packages/css-to-rn/declarations/length-or-coerce-percentage-to-runtime.ts create mode 100644 packages/css-to-rn/declarations/length-percentage-or-auto.ts create mode 100644 packages/css-to-rn/declarations/length.ts create mode 100644 packages/css-to-rn/declarations/line-height.ts create mode 100644 packages/css-to-rn/declarations/overflow.ts create mode 100644 packages/css-to-rn/declarations/runtime-specifics-function.ts create mode 100644 packages/css-to-rn/declarations/size.ts create mode 100644 packages/css-to-rn/declarations/text-align.ts create mode 100644 packages/css-to-rn/declarations/text-decoration-line.ts create mode 100644 packages/css-to-rn/declarations/text-decoration-style.ts create mode 100644 packages/css-to-rn/declarations/text-shadow.ts create mode 100644 packages/css-to-rn/declarations/transform.ts create mode 100644 packages/css-to-rn/declarations/unparsed.ts create mode 100644 packages/css-to-rn/declarations/vertical-align.ts create mode 100644 packages/css-to-rn/index.ts create mode 100644 packages/css-to-rn/package.json create mode 100644 packages/css-to-rn/properties.ts create mode 100644 packages/css-to-rn/types/index.ts create mode 100644 packages/css-to-rn/types/parse.ts create mode 100644 packages/css-to-rn/utils.ts create mode 100644 packages/exo-primitives/README.md rename build-figma-plugin.main.js => packages/figma-to-react-native/build-figma-plugin.main.js (100%) rename build-figma-plugin.manifest.js => packages/figma-to-react-native/build-figma-plugin.manifest.js (100%) create mode 100644 packages/figma-to-react-native/build-figma-plugin.ui.js create mode 100644 packages/figma-to-react-native/package.json create mode 100644 packages/figma-to-react-native/src/common/assert.ts rename {src => packages/figma-to-react-native/src}/common/delay.ts (100%) rename {src => packages/figma-to-react-native/src}/common/string.ts (100%) rename {src => packages/figma-to-react-native/src}/config/env.ts (56%) rename {src => packages/figma-to-react-native/src}/config/project.ts (92%) rename {src => packages/figma-to-react-native/src}/config/user.ts (81%) create mode 100644 packages/figma-to-react-native/src/env.d.ts create mode 100644 packages/figma-to-react-native/src/interface/App.tsx create mode 100644 packages/figma-to-react-native/src/interface/base/NavBar.tsx create mode 100644 packages/figma-to-react-native/src/interface/base/ProgressBar.tsx create mode 100644 packages/figma-to-react-native/src/interface/base/ScreenInfo.tsx create mode 100644 packages/figma-to-react-native/src/interface/base/ScreenWarning.tsx create mode 100644 packages/figma-to-react-native/src/interface/base/SearchBar.tsx create mode 100644 packages/figma-to-react-native/src/interface/base/StatusBar.tsx create mode 100644 packages/figma-to-react-native/src/interface/base/Tabs.tsx rename {src => packages/figma-to-react-native/src}/interface/css/default.css (57%) create mode 100644 packages/figma-to-react-native/src/interface/css/default.css.d.ts rename {src => packages/figma-to-react-native/src}/interface/css/editor.css (100%) rename {src => packages/figma-to-react-native/src}/interface/css/editor.css.d.ts (100%) rename {src => packages/figma-to-react-native/src}/interface/css/plugin.css (100%) rename {src => packages/figma-to-react-native/src}/interface/css/plugin.css.d.ts (100%) create mode 100644 packages/figma-to-react-native/src/interface/hooks/useBuild.ts rename {src => packages/figma-to-react-native/src}/interface/hooks/useDarkMode.ts (99%) create mode 100644 packages/figma-to-react-native/src/interface/hooks/useEditor.ts create mode 100644 packages/figma-to-react-native/src/interface/hooks/useNavigation.ts create mode 100644 packages/figma-to-react-native/src/interface/hooks/useProjectBuild.ts rename {src => packages/figma-to-react-native/src}/interface/hooks/useProjectConfig.ts (100%) create mode 100644 packages/figma-to-react-native/src/interface/hooks/useProjectIcons.ts create mode 100644 packages/figma-to-react-native/src/interface/hooks/useProjectTheme.ts create mode 100644 packages/figma-to-react-native/src/interface/hooks/useSelectedVariant.ts create mode 100644 packages/figma-to-react-native/src/interface/hooks/useStyleGenServer.ts rename src/interface/hooks/useConfig.ts => packages/figma-to-react-native/src/interface/hooks/useUserSettings.ts (80%) create mode 100644 packages/figma-to-react-native/src/interface/store.ts rename {src => packages/figma-to-react-native/src}/interface/telemetry.tsx (100%) create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/index.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/lib/barrier.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/lib/compiler.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/lib/path.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/lib/resolver.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/plugins/css.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/plugins/png.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/plugins/react.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/bundler/plugins/svg.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/index.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/lib/patch.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/lib/yjs.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/schemas/settings.json create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/templates/env.ts.tpl create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/templates/index.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/templates/react-native-exo.ts.tpl create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/templates/react-native.ts.tpl create mode 100644 packages/figma-to-react-native/src/interface/utils/editor/templates/styles.ts.tpl rename {src/interface/utils => packages/figma-to-react-native/src/interface/utils/exporter}/download.ts (58%) rename {src/interface/utils => packages/figma-to-react-native/src/interface/utils/exporter}/upload.ts (97%) create mode 100644 packages/figma-to-react-native/src/interface/utils/exporter/zip.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/importer/icons.ts rename {src/interface/utils/preview/template => packages/figma-to-react-native/src/interface/utils/previewer}/importMap.json (96%) create mode 100644 packages/figma-to-react-native/src/interface/utils/previewer/index.ts create mode 100644 packages/figma-to-react-native/src/interface/utils/previewer/templates/app.tsx.tpl rename src/interface/utils/preview/template/iframe.tpl.html => packages/figma-to-react-native/src/interface/utils/previewer/templates/iframe.html.tpl (52%) rename src/interface/utils/preview/template/_loader.tpl.tsx => packages/figma-to-react-native/src/interface/utils/previewer/templates/loader.tsx.tpl (53%) create mode 100644 packages/figma-to-react-native/src/interface/views/ComponentCode.tsx create mode 100644 packages/figma-to-react-native/src/interface/views/ComponentPreview.tsx create mode 100644 packages/figma-to-react-native/src/interface/views/ComponentStory.tsx create mode 100644 packages/figma-to-react-native/src/interface/views/ProjectAssets.tsx create mode 100644 packages/figma-to-react-native/src/interface/views/ProjectComponents.tsx rename src/interface/pages/Export.tsx => packages/figma-to-react-native/src/interface/views/ProjectExport.tsx (80%) create mode 100644 packages/figma-to-react-native/src/interface/views/ProjectIcons.tsx create mode 100644 packages/figma-to-react-native/src/interface/views/ProjectSettings.tsx create mode 100644 packages/figma-to-react-native/src/interface/views/ProjectTheme.tsx create mode 100644 packages/figma-to-react-native/src/main.ts rename src/plugin/fig/parse.ts => packages/figma-to-react-native/src/plugin/fig/index.ts (66%) create mode 100644 packages/figma-to-react-native/src/plugin/fig/lib/assets.ts create mode 100644 packages/figma-to-react-native/src/plugin/fig/lib/colors.ts create mode 100644 packages/figma-to-react-native/src/plugin/fig/lib/index.ts create mode 100644 packages/figma-to-react-native/src/plugin/fig/lib/node.ts create mode 100644 packages/figma-to-react-native/src/plugin/fig/lib/props.ts rename src/plugin/fig/lib/convertStyles.ts => packages/figma-to-react-native/src/plugin/fig/lib/styles.ts (52%) rename {src/plugin/fig => packages/figma-to-react-native/src/plugin/fig/lib}/traverse.ts (84%) rename {src/plugin/fig => packages/figma-to-react-native/src/plugin/fig/lib}/validate.ts (100%) rename {src => packages/figma-to-react-native/src}/plugin/gen/common/generateIndex.ts (100%) create mode 100644 packages/figma-to-react-native/src/plugin/gen/index.ts rename {src => packages/figma-to-react-native/src}/plugin/gen/primitives/exo/Slider.ts (76%) rename {src => packages/figma-to-react-native/src}/plugin/gen/primitives/index.ts (58%) create mode 100644 packages/figma-to-react-native/src/plugin/gen/react-native/generateBundle.ts create mode 100644 packages/figma-to-react-native/src/plugin/gen/react-native/generateCode.ts rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/generateStory.ts (100%) rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/generateTheme.ts (52%) rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/index.ts (100%) rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/lib/writeChildren.ts (58%) rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/lib/writeClasses.ts (87%) create mode 100644 packages/figma-to-react-native/src/plugin/gen/react-native/lib/writeColors.ts rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/lib/writeFunction.ts (67%) create mode 100644 packages/figma-to-react-native/src/plugin/gen/react-native/lib/writeImports.ts rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/lib/writeProps.ts (85%) rename {src => packages/figma-to-react-native/src}/plugin/gen/react-native/lib/writeState.ts (79%) create mode 100644 packages/figma-to-react-native/src/plugin/gen/react-native/lib/writeStyleSheet.ts create mode 100644 packages/figma-to-react-native/src/plugin/index.ts create mode 100644 packages/figma-to-react-native/src/plugin/lib/app.ts rename {src/plugin => packages/figma-to-react-native/src/plugin/lib}/codegen.ts (91%) rename {src/plugin => packages/figma-to-react-native/src/plugin/lib}/config.ts (92%) create mode 100644 packages/figma-to-react-native/src/plugin/lib/drop.ts create mode 100644 packages/figma-to-react-native/src/plugin/lib/icons.ts rename {src/plugin => packages/figma-to-react-native/src/plugin/lib}/project.ts (77%) create mode 100644 packages/figma-to-react-native/src/plugin/lib/vscode.ts create mode 100644 packages/figma-to-react-native/src/types/app.ts create mode 100644 packages/figma-to-react-native/src/types/component.ts create mode 100644 packages/figma-to-react-native/src/types/events.ts rename {src => packages/figma-to-react-native/src}/types/parse.ts (61%) rename {src => packages/figma-to-react-native/src}/types/project.ts (79%) create mode 100644 packages/figma-to-react-native/src/types/settings.ts rename {src => packages/figma-to-react-native/src}/ui.tsx (53%) rename tsconfig.json => packages/figma-to-react-native/tsconfig.json (66%) create mode 100644 packages/ui-kit-figma/README.md create mode 100644 pnpm-workspace.yaml delete mode 100644 src/common/color.ts delete mode 100644 src/common/random.ts delete mode 100644 src/interface/App.tsx delete mode 100644 src/interface/base/Tabs.tsx delete mode 100644 src/interface/base/Watermark.tsx delete mode 100644 src/interface/css/default.css.d.ts delete mode 100644 src/interface/hooks/useEditor.ts delete mode 100644 src/interface/hooks/usePreviewComponent.ts delete mode 100644 src/interface/hooks/usePreviewTheme.ts delete mode 100644 src/interface/hooks/useProjectBuild.ts delete mode 100644 src/interface/pages/Code.tsx delete mode 100644 src/interface/pages/Preview.tsx delete mode 100644 src/interface/pages/Settings.tsx delete mode 100644 src/interface/pages/Story.tsx delete mode 100644 src/interface/pages/Theme.tsx delete mode 100644 src/interface/utils/build.ts delete mode 100644 src/interface/utils/editor.ts delete mode 100644 src/interface/utils/preview/index.ts delete mode 100644 src/interface/utils/preview/template/_entry.tpl.tsx delete mode 100644 src/interface/utils/sync.ts delete mode 100644 src/interface/utils/zip.ts delete mode 100644 src/main.ts delete mode 100644 src/plugin/app.ts delete mode 100644 src/plugin/fig/lib/convertAssets.ts delete mode 100644 src/plugin/fig/lib/getColor.ts delete mode 100644 src/plugin/fig/lib/getInstanceInfo.ts delete mode 100644 src/plugin/fig/lib/getPropName.ts delete mode 100644 src/plugin/fig/lib/getTopFill.ts delete mode 100644 src/plugin/fig/lib/index.ts delete mode 100644 src/plugin/fig/lib/isNodeVisible.ts delete mode 100644 src/plugin/fig/lib/propsToString.ts delete mode 100644 src/plugin/fig/lib/reactions.ts delete mode 100644 src/plugin/fig/lib/sortProps.ts delete mode 100644 src/plugin/gen/index.ts delete mode 100644 src/plugin/gen/primitives/utils/getFillToken.ts delete mode 100644 src/plugin/gen/react-native/generateBundle.ts delete mode 100644 src/plugin/gen/react-native/generateCode.ts delete mode 100644 src/plugin/gen/react-native/generatePreview.ts delete mode 100644 src/plugin/gen/react-native/lib/writeImports.ts delete mode 100644 src/plugin/gen/react-native/lib/writeStyleSheet.ts delete mode 100644 src/plugin/preview.ts delete mode 100644 src/plugin/styles/css-to-rn/generateStyles.ts delete mode 100644 src/plugin/styles/css-to-rn/utils/convertToReactNative.ts delete mode 100644 src/plugin/styles/css-to-rn/utils/processStyles.ts delete mode 100644 src/plugin/styles/css-to-rn/utils/shorthandStyles.ts delete mode 100644 src/plugin/styles/css-to-rn/vendor/index.d.ts delete mode 100644 src/plugin/styles/css-to-rn/vendor/index.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/TokenStream.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/parse/index.d.ts delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/parse/index.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/parse/parse.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/parse/stringify.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/parse/unit.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/parse/walk.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/lib/tokenTypes.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/aspectRatio.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/border.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/boxShadow.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/flex.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/flexFlow.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/font.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/fontFamily.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/fontVariant.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/index.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/placeContent.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/textDecoration.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/textDecorationLine.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/textShadow.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/transform.js delete mode 100644 src/plugin/styles/css-to-rn/vendor/transforms/util.js delete mode 100644 src/plugin/styles/experimental/generateStyles.ts delete mode 100644 src/plugin/styles/experimental/lib/background.ts delete mode 100644 src/plugin/styles/experimental/lib/border.ts delete mode 100644 src/plugin/styles/experimental/lib/dimension.ts delete mode 100644 src/plugin/styles/experimental/lib/index.ts delete mode 100644 src/plugin/styles/experimental/lib/layout.ts delete mode 100644 src/plugin/styles/experimental/lib/padding.ts delete mode 100644 src/plugin/styles/experimental/lib/position.ts delete mode 100644 src/plugin/styles/experimental/lib/typography.ts delete mode 100644 src/plugin/styles/experimental/lib/utils/getFillStyle.ts delete mode 100644 src/plugin/styles/experimental/lib/utils/getFontWeight.ts delete mode 100644 src/plugin/styles/experimental/lib/utils/getLetterSpacing.ts delete mode 100644 src/plugin/styles/experimental/lib/utils/getLineHeight.ts delete mode 100644 src/plugin/styles/experimental/lib/utils/getSize.ts delete mode 100644 src/plugin/styles/experimental/types/styles.ts delete mode 100644 src/plugin/styles/index.ts delete mode 100644 src/plugin/styles/service/generateStyles.ts delete mode 100644 src/types/app.ts delete mode 100644 src/types/events.ts delete mode 100644 src/types/preview.ts delete mode 100644 src/types/settings.ts diff --git a/.gitignore b/.gitignore index 04134197..85a33290 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,10 @@ # Project manifest.json -build/ -.ref/ -.old/ -settings-schema.json TODO.md +build/ # OSX .DS_Store # Node node_modules/ -npm-debug.log -yarn-error.log diff --git a/.vscode/settings.json b/.vscode/settings.json index 3301228e..1a46f111 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "json.schemas": [ { "fileMatch": [ - "package.json" + "packages/figma-to-react-native/package.json" ], "url": "https://yuanqing.github.io/create-figma-plugin/figma-plugin.json" } diff --git a/README.md b/README.md index 65a38404..0cf71905 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,92 @@

- +

-

- Figma โ†’ React Native -

+ Figma โ†’ React Native +

+

Install Plugin -

+ +
+ +> Transforms Figma components to React Native components in real time. It also exports themes, icons, assets, and much more. The mission goal is to eliminate the designer to developer handoff while embracing existing workflows and tooling. Join the [Discord Channel](https://discord.com/invite/TzhDRyj) or follow [@TheUltDev](https://x.com/theultdev) to track project development. + +## Features -> This plugin transforms Figma components to React Native components in real time. The goal is to reduce the handoff time between design and development. Design your UI components in Figma and export them for use in your React Native app. +| | | +| - | - | +| โœจ | Realtime code and preview rendering +| ๐Ÿ“ฆ | Batch exporting of components and assets +| ๐ŸŽจ | Theme generation from local styles and variables +| ๐Ÿž | Images, vectors, and icons support +| ๐ŸŽฒ | Variants and properties support +| ๐Ÿงฑ | Nested components support +| ๐Ÿงฉ | Figma variables support +| ๐ŸŽฎ | Pressables generation +| ๐ŸŽญ | Conditional rendering +| ๐Ÿ“š | Storybook syncing +| ๐Ÿ“– | JSDoc generation +| ๐Ÿ’ก | Dark/light mode -[![Preview of plugin](./art/banner.png)](https://www.figma.com/community/plugin/821138713091291738) +### Roadmap +#### V46 - Polishing & Bug Fixes +- `Interface` Keep Figma component order in list +- `Compiler` Add remaining EXO primitives + Iconify +- `Compiler` Fix default color missing for dynamic colors (variants) +- `Compiler` On component/icon/asset delete keep record +- `Compiler` MVP app ui package (runnable w/ storybook) +- `Previewer` Profile extraneous builds +- `Previewer` Goto code and highlight JSX tag when inspect clicked +- `Previewer` Pass bundler error text to interface +- `Editor` Improve intellisense startup time +- `Editor` Type unistyles file (update on theme update) +- `Editor` Highlight JSX tag when node focused +- `Editor` Auto-collapse classes, colors, and stylesheet +- `Editor` Add color provider for theme tokens +- `Editor` Hover over icon name for preview +- `Icons` When importing, add browsing icon sets and prefixes +- `Theme` If no colors found, offer shadcn themes + - Try to generate dark/light if variables available + - Fallback to local styles with just light theme -### Getting started +#### V47 โ€” Asset Gallery +- `Assets` Enable new assets page +- `Assets` Add bounding box + title + hover +- `Assets` Add lightbox (yet-another-react-lightbox) +- `Assets` Add drag and drop to figma / others -1. [Install the plugin](https://www.figma.com/community/plugin/821138713091291738) in Figma and run it. -2. Select any [Figma component](https://help.figma.com/hc/en-us/articles/360038662654-Guide-to-Components-in-Figma) on the screen. -3. View the component code, render, storybook file, or theme file in real time. -4. Go to the "Export" tab and choose which components to bulk export. -5. To change the settings, click the cog icon and edit the JSON. Settings will save and update in real time. +#### V48 โ€” Saved User Edits +- `Compiler` Compare user changes to last build +- `Interface` Show modified state in list + component views +- `Editor` Show modified lines in gutter (like git) +- `Editor` Show selected node in gutter +#### V49 โ€” Collaboration +- `YJS` Setup websocket provider (y-sweet) +- `Editor` Awareness cursors selections +- `Preview` Show cursors and inspects +- `Interface` Show color dots in component list +- `Storybook` Update syncing api to match plugin -### Plugin Features +#### V50 โ€” Services -| | Feature | | -| - | ------- | - | -| โœจ | Realtime code and preview rendering | โœ… | -| ๐ŸŽจ | Theme generation from variable modes | โœ… | -| ๐Ÿ“ฆ | Batch exporting of components and assets | โœ… | -| ๐Ÿž | Asset exporting of rasters and vectors | โœ… | -| โญ๏ธ | AutoLayout to Flexbox translation | โœ… | -| ๐ŸŽฒ | Variants and properties support | โœ… | -| ๐Ÿงฑ | Nested components support | โœ… | -| ๐Ÿงฉ | Figma variables support | โœ… | -| ๐ŸŽฎ | Pressables generation | โœ… | -| ๐ŸŽญ | Conditional rendering | โœ… | -| ๐ŸชŸ | Borders and rounding | โœ… | -| ๐Ÿ”„ | Rotations and effects | โฑ | -| ๐Ÿ” | Background gradients | โฑ | -| ๐Ÿ“š | Storybook syncing | โœ… | -| ๐Ÿ“– | JSDoc generation | โœ… | -| ๐Ÿ’ก | Dark/light mode | โœ… | -| ๐Ÿ’Ž | Tamagui output | โฑ | +##### GPT-4 Vision +- `Service` Verify output and fine-tune prompt +- `Interface` Send component code + preview image to api +- `Interface` Update component code Y.JS value if accepted +##### GitHub Release +- `Service` Process files and create pull request -### Community +##### Redux Sync +- `Service` Sync Redux store -> Figma Variables via Figma REST API +- `Compiler` Generate usage similar to useState implementation +- `Compiler` Use saved variables plugin data to get redux store code for previews + builds -- [Discord Channel](https://discord.com/invite/TzhDRyj) -- [Figma Forums](https://forum.figma.com/t/react-component-generator/14236) -- [Discussions](https://github.com/kat-tax/figma/discussions) -- [Issues](https://github.com/kat-tax/figma/issues) +##### Icon Service +- `Service` Provide hosted Iconify source +- `Service` Import SVGs from Figma to Iconify set via Figma REST API -> _Disclaimer: This plugin __does not require__ an account, remote service, or any other bullsh*t. There will be an optional paid service for syncing and collaboration features to support development. Donations are also welcome._ diff --git a/ROADMAP.md b/ROADMAP.md deleted file mode 100644 index d3012b83..00000000 --- a/ROADMAP.md +++ /dev/null @@ -1,47 +0,0 @@ -# ROADMAP - -# v44 -- Compile components in background: - - [ ] use browser bundler, conform preview and code output - - [ ] precompile components, cache code to component node storage - - [ ] batch compilation, put selected components at top of queue - - [ ] recompile component when update triggered for it - - [ ] combine constrained user edits with compiled code - -## Style Libraries -- [x] Unistyles (default) -- [ ] Tamagui (planned...) -- [ ] GlueStack (planned...) -- [ ] NativeWind (maybe...) - -## Planned Features -- [ ] Interactions: (accessibility, pressablility, etc.) -- [ ] Screens: (navigation based on prototype settings) -- [ ] Improved Devtools: - - diff text instead of fully replacing (highlight changes?) - - show console log in preview: - - https://github.com/storybookjs/react-inspector - -## Planned Tools -- [ ] Doctor (fix structure, autolayout, etc.) -- [ ] Auto Shimmer (auto create shimmer variant) -- [ ] Import Redux Store -- [ ] Import Primitives -- [ ] Import Icons -- [ ] Import Theme - -## Optimization Goals -- Replace ESBuild with SWC? (https://swc.rs/docs/usage/wasm) - -## Known Issues -- Missing type imports -- Extraneous Pressable import -- SVGs don't adapt correct colors -- Storybook variant import name wrong -- Border colors (without variables) not converting -- Error "failed to export" caused by hidden assets -- Refactor primitive generation code (template string -> codewriter) -- Triage preview using wrong default value for Child in Frame example -- Code tab is cleared when going to Theme tab -- Monaco sometimes appears in light mode -- Address or document TODOs throughout the app... diff --git a/art/banner.png b/art/banner.png deleted file mode 100644 index 9940e631ba4e5bb83ddf00b36c76c9bbba6e5604..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 407878 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

VrngghA|ce@V%ZToxdSz2o6>`Bp#WwbDUr-e4TL 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 G^M3%$L0Uxs diff --git a/art/logo.png b/artwork/logo.png similarity index 100% rename from art/logo.png rename to artwork/logo.png diff --git a/build-figma-plugin.ui.js b/build-figma-plugin.ui.js deleted file mode 100644 index 7e5e9268..00000000 --- a/build-figma-plugin.ui.js +++ /dev/null @@ -1,18 +0,0 @@ -// @ts-check -/** - * @param buildOptions {Partial} - * @returns {Partial} - */ -module.exports = (buildOptions) => { - return { - ...buildOptions, - target: 'es2020', - loader: { - '.tpl.tsx': 'base64', - '.tpl.html': 'base64', - }, - define: { - global: 'window', - }, - }; -} diff --git a/package.json b/package.json index 92a6b610..971fcd37 100644 --- a/package.json +++ b/package.json @@ -1,68 +1,5 @@ { - "private": true, - "license": "GPL-3.0", - "scripts": { - "dev": "build-figma-plugin --typecheck --watch", - "build": "build-figma-plugin --typecheck --minify", - "schema": "typescript-json-schema tsconfig.json Settings --out ./src/settings-schema.json" - }, - "figma-plugin": { - "id": "821138713091291738", - "name": "Figma -> React Native", - "networkAccess": { - "allowedDomains": [ - "*" - ], - "reasoning": "Needed for Monaco Editor blob workers to load" - }, - "permissions": [ - "currentuser" - ], - "editorType": [ - "figma", - "dev" - ], - "capabilities": [ - "codegen", - "inspect", - "panel" - ], - "main": "src/main.ts", - "ui": "src/ui.tsx" - }, - "dependencies": { - "@create-figma-plugin/ui": "^2.6.1", - "@create-figma-plugin/utilities": "^2.6.1", - "@hocuspocus/provider": "^2.6.1", - "@logtail/browser": "^0.4.12", - "@monaco-editor/react": "^4.6.0", - "@radix-ui/react-tabs": "^1.0.4", - "@uppy/core": "^3.5.1", - "@uppy/tus": "^3.3.1", - "client-zip": "^2.4.4", - "code-block-writer": "^12.0.0", - "constrained-editor-plugin": "^1.3.0", - "deep-object-diff": "^1.1.9", - "esbuild-wasm": "^0.17.19", - "lodash.camelcase": "^4.3.0", - "monaco-editor": "^0.44.0", - "preact": "^10.18.1", - "reserved": "^0.1.2", - "yjs": "^13.6.8" - }, - "devDependencies": { - "@create-figma-plugin/build": "^2.6.1", - "@create-figma-plugin/tsconfig": "^2.6.1", - "@figma/plugin-typings": "1.79.0", - "@types/lodash.camelcase": "^4.3.7", - "@types/react": "^18.2.27", - "esbuild": "^0.17.19", - "react-native-unistyles": "^1.0.0-beta.6", - "react-zoom-pan-pinch": "^3.1.0", - "typescript": "^4.9.5", - "typescript-json-schema": "^0.61.0" - }, - "browser": { - "crypto": false - } + "name": "exo", + "version": "0.45.0", + "license": "GPL-3.0" } diff --git a/packages/css-to-rn/README.md b/packages/css-to-rn/README.md new file mode 100644 index 00000000..ecef3b4a --- /dev/null +++ b/packages/css-to-rn/README.md @@ -0,0 +1,7 @@ +> Forked from NativeWind's css-to-rn interop: + +https://github.com/marklawlor/nativewind/tree/main/packages/react-native-css-interop + +Copyright (c) 2023 Mark Lawlor + +MIT License \ No newline at end of file diff --git a/packages/css-to-rn/declaration.ts b/packages/css-to-rn/declaration.ts new file mode 100644 index 00000000..811dbd10 --- /dev/null +++ b/packages/css-to-rn/declaration.ts @@ -0,0 +1,571 @@ +import * as _ from './declarations/_index'; +import {isValid, validPropertiesLoose} from './properties'; + +import type {Declaration} from 'lightningcss-wasm'; +import type {ParseDeclarationOptions} from './types/parse'; + +export function parseDeclaration(d: Declaration, opts: ParseDeclarationOptions) { + const { + addWarning, + addStyleProp, + addAnimationProp, + addTransitionProp, + handleStyleShorthand, + } = opts; + + if (d.property === 'unparsed') { + if (!isValid(d.value.propertyId)) { + return addWarning({type: 'IncompatibleNativeProperty', property: d.value.propertyId.property}); + } + return addStyleProp( + d.value.propertyId.property, + _.unparsed(d.value.value, { + ...opts, + addFunctionValueWarning(value: any) { + return addWarning({type: 'IncompatibleNativeFunctionValue', property: d.value.propertyId.property, value}); + }, + addValueWarning(value: any) { + return addWarning({type: 'IncompatibleNativeValue', property: d.value.propertyId.property, value}); + }, + }), + ); + } else if (d.property === 'custom') { + const property = d.value.name; + if ( + validPropertiesLoose.has(property) || + property.startsWith('--') || + property.startsWith('-rn-') + ) { + return addStyleProp( + property, + _.unparsed(d.value.value, { + ...opts, + addValueWarning(value: any) { + return addWarning({type: 'IncompatibleNativeValue', property, value}); + }, + addFunctionValueWarning(value: any) { + return addWarning({type: 'IncompatibleNativeFunctionValue', property, value}); + }, + }), + ); + } else { + return addWarning({type: 'IncompatibleNativeProperty', property: d.value.name}); + } + } + + const options = { + ...opts, + addValueWarning(value: any) { + return addWarning({type: 'IncompatibleNativeValue', property: d.property, value}); + }, + addFunctionValueWarning(value: any) { + return addWarning({type: 'IncompatibleNativeFunctionValue', property: d.property, value}); + }, + }; + + const addInvalidProperty = () => { + return addWarning({type: 'IncompatibleNativeProperty', property: d.property}); + }; + + if (!isValid(d)) { + return addInvalidProperty(); + } + + switch (d.property) { + case 'background-color': + return addStyleProp(d.property, _.color(d.value, options)); + case 'opacity': + return addStyleProp(d.property, d.value); + case 'color': + return addStyleProp(d.property, _.color(d.value, options)); + case 'display': + return addStyleProp(d.property, _.display(d.value, options)); + case 'width': + return addStyleProp(d.property, _.size(d.value, options)); + case 'height': + return addStyleProp(d.property, _.size(d.value, options)); + case 'min-width': + return addStyleProp(d.property, _.size(d.value, options)); + case 'min-height': + return addStyleProp(d.property, _.size(d.value, options)); + case 'max-width': + return addStyleProp(d.property, _.size(d.value, options)); + case 'max-height': + return addStyleProp(d.property, _.size(d.value, options)); + case 'block-size': + return addStyleProp('width', _.size(d.value, options)); + case 'inline-size': + return addStyleProp('height', _.size(d.value, options)); + case 'min-block-size': + return addStyleProp('min-width', _.size(d.value, options)); + case 'min-inline-size': + return addStyleProp('min-height', _.size(d.value, options)); + case 'max-block-size': + return addStyleProp('max-width', _.size(d.value, options)); + case 'max-inline-size': + return addStyleProp('max-height', _.size(d.value, options)); + case 'overflow': + return addStyleProp(d.property, _.overflow(d.value.x, options)); + case 'position': + return; // Note: position works differently on web and native + case 'top': + return addStyleProp(d.property, _.size(d.value, options)); + case 'bottom': + return addStyleProp(d.property, _.size(d.value, options)); + case 'left': + return addStyleProp(d.property, _.size(d.value, options)); + case 'right': + return addStyleProp(d.property, _.size(d.value, options)); + case 'inset-block-start': + return addStyleProp(d.property, _.lengthPercentageOrAuto(d.value, options)); + case 'inset-block-end': + return addStyleProp(d.property, _.lengthPercentageOrAuto(d.value, options)); + case 'inset-inline-start': + return addStyleProp( d.property, _.lengthPercentageOrAuto(d.value, options)); + case 'inset-inline-end': + return addStyleProp(d.property, _.lengthPercentageOrAuto(d.value, options)); + case 'inset-block': + return handleStyleShorthand('inset-block', { + 'inset-block-start': _.lengthPercentageOrAuto(d.value.blockStart, options), + 'inset-block-end': _.lengthPercentageOrAuto(d.value.blockEnd, options), + }); + case 'inset-inline': + return handleStyleShorthand('inset-inline', { + 'inset-block-start': _.lengthPercentageOrAuto(d.value.inlineStart, options), + 'inset-block-end': _.lengthPercentageOrAuto(d.value.inlineEnd, options), + }); + case 'inset': + handleStyleShorthand('inset', { + top: _.lengthPercentageOrAuto(d.value.top, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'top', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'top', value}); + }, + }), + bottom: _.lengthPercentageOrAuto(d.value.bottom, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'bottom', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'bottom', value}); + }, + }), + left: _.lengthPercentageOrAuto(d.value.left, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'left', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'left', value}); + }, + }), + right: _.lengthPercentageOrAuto(d.value.right, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'right', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'right', value}); + }, + }), + }); + return; + case 'border-top-color': + return addStyleProp(d.property, _.color(d.value, options)); + case 'border-bottom-color': + return addStyleProp(d.property, _.color(d.value, options)); + case 'border-left-color': + return addStyleProp(d.property, _.color(d.value, options)); + case 'border-right-color': + return addStyleProp(d.property, _.color(d.value, options)); + case 'border-block-start-color': + return addStyleProp('border-top-color', _.color(d.value, options)); + case 'border-block-end-color': + return addStyleProp('border-bottom-color', _.color(d.value, options)); + case 'border-inline-start-color': + return addStyleProp('border-left-color', _.color(d.value, options)); + case 'border-inline-end-color': + return addStyleProp('border-right-color', _.color(d.value, options)); + case 'border-top-width': + return addStyleProp(d.property, _.borderSideWidth(d.value, options)); + case 'border-bottom-width': + return addStyleProp(d.property, _.borderSideWidth(d.value, options)); + case 'border-left-width': + return addStyleProp(d.property, _.borderSideWidth(d.value, options)); + case 'border-right-width': + return addStyleProp(d.property, _.borderSideWidth(d.value, options)); + case 'border-block-start-width': + return addStyleProp('border-top-width', _.borderSideWidth(d.value, options)); + case 'border-block-end-width': + return addStyleProp('border-bottom-width', _.borderSideWidth(d.value, options)); + case 'border-inline-start-width': + return addStyleProp('border-left-width', _.borderSideWidth(d.value, options)); + case 'border-inline-end-width': + return addStyleProp('border-right-width', _.borderSideWidth(d.value, options)); + case 'border-top-left-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-top-right-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-bottom-left-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-bottom-right-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-start-start-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-start-end-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-end-start-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-end-end-radius': + return addStyleProp(d.property, _.length(d.value[0], options)); + case 'border-radius': + handleStyleShorthand('border-radius', { + 'border-bottom-left-radius': _.length(d.value.bottomLeft[0], options), + 'border-bottom-right-radius': _.length(d.value.bottomRight[0], options), + 'border-top-left-radius': _.length(d.value.topLeft[0], options), + 'border-top-right-radius': _.length(d.value.topRight[0], options), + }); + return; + case 'border-color': + handleStyleShorthand('border-color', { + 'border-top-color': _.color(d.value.top, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'border-top-color', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'border-top-color', value}); + }, + }), + 'border-bottom-color': _.color(d.value.bottom, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'border-bottom-color', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'border-bottom-color', value}); + }, + }), + 'border-left-color': _.color(d.value.left, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'border-left-color', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'border-left-color', value}); + }, + }), + 'border-right-color': _.color(d.value.right, { + ...options, + addValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeValue', property: 'border-right-color', value}); + }, + addFunctionValueWarning(value: any) { + addWarning({type: 'IncompatibleNativeFunctionValue', property: 'border-right-color', value}); + }, + }), + }); + return; + case 'border-style': + return addStyleProp(d.property, _.borderStyle(d.value, options)); + case 'border-width': + handleStyleShorthand('border-width', { + 'border-top-width': _.borderSideWidth(d.value.top, options), + 'border-bottom-width': _.borderSideWidth(d.value.bottom, options), + 'border-left-width': _.borderSideWidth(d.value.left, options), + 'border-right-width': _.borderSideWidth(d.value.right, options), + }); + return; + case 'border-block-color': + addStyleProp('border-top-color', _.color(d.value.start, options)); + addStyleProp('border-bottom-color', _.color(d.value.end, options)); + return; + case 'border-block-width': + addStyleProp('border-top-width', _.borderSideWidth(d.value.start, options)); + addStyleProp('border-bottom-width', _.borderSideWidth(d.value.end, options)); + return; + case 'border-inline-color': + addStyleProp('border-left-color', _.color(d.value.start, options)); + addStyleProp('border-right-color', _.color(d.value.end, options)); + return; + case 'border-inline-width': + addStyleProp('border-left-width', _.borderSideWidth(d.value.start, options)); + addStyleProp('border-right-width', _.borderSideWidth(d.value.end, options)); + return; + case 'border': + handleStyleShorthand('border', { + 'border-width': _.borderSideWidth(d.value.width, options), + 'border-style': _.borderStyle(d.value.style, options,), + }); + return; + case 'border-top': + addStyleProp(d.property + '-color', _.color(d.value.color, options)); + addStyleProp(d.property + '-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-bottom': + addStyleProp(d.property + '-color', _.color(d.value.color, options)); + addStyleProp(d.property + '-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-left': + addStyleProp(d.property + '-color', _.color(d.value.color, options)); + addStyleProp(d.property + '-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-right': + addStyleProp(d.property + '-color', _.color(d.value.color, options)); + addStyleProp(d.property + '-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-block': + addStyleProp('border-top-color', _.color(d.value.color, options)); + addStyleProp('border-bottom-color', _.color(d.value.color, options)); + addStyleProp('border-top-width', _.borderSideWidth(d.value.width, options)); + addStyleProp('border-bottom-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-block-start': + addStyleProp('border-top-color', _.color(d.value.color, options)); + addStyleProp('border-top-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-block-end': + addStyleProp('border-bottom-color', _.color(d.value.color, options)); + addStyleProp('border-bottom-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-inline': + addStyleProp('border-left-color', _.color(d.value.color, options)); + addStyleProp('border-right-color', _.color(d.value.color, options)); + addStyleProp('border-left-width', _.borderSideWidth(d.value.width, options)); + addStyleProp('border-right-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-inline-start': + addStyleProp('border-left-color', _.color(d.value.color, options)); + addStyleProp('border-left-width', _.borderSideWidth(d.value.width, options)); + return; + case 'border-inline-end': + addStyleProp('border-right-color', _.color(d.value.color, options)); + addStyleProp('border-right-width', _.borderSideWidth(d.value.width, options)); + return; + case 'flex-direction': + return addStyleProp(d.property, d.value); + case 'flex-wrap': + return addStyleProp(d.property, d.value); + case 'flex-flow': + addStyleProp('flexWrap', d.value.wrap); + addStyleProp('flexDirection', d.value.direction); + break; + case 'flex-grow': + return addStyleProp(d.property, d.value); + case 'flex-shrink': + return addStyleProp(d.property, d.value); + case 'flex-basis': + return addStyleProp(d.property, _.lengthPercentageOrAuto(d.value, options)); + case 'flex': + addStyleProp('flex-grow', d.value.grow); + addStyleProp('flex-shrink', d.value.shrink); + addStyleProp('flex-basis', _.lengthPercentageOrAuto(d.value.basis, options)); + break; + case 'align-content': + return addStyleProp(d.property, _.alignContent(d.value, options)); + case 'justify-content': + return addStyleProp( d.property, _.justifyContent(d.value, options)); + case 'align-self': + return addStyleProp(d.property, _.alignSelf(d.value, options)); + case 'align-items': + return addStyleProp(d.property, _.alignItems(d.value, options)); + case 'row-gap': + return addStyleProp('row-gap', _.gap(d.value, options)); + case 'column-gap': + return addStyleProp('row-gap', _.gap(d.value, options)); + case 'gap': + addStyleProp('row-gap', _.gap(d.value.row, options)); + addStyleProp('column-gap', _.gap(d.value.column, options)); + return; + case 'margin-top': + return addStyleProp(d.property, _.size(d.value, options)); + case 'margin-bottom': + return addStyleProp(d.property, _.size(d.value, options)); + case 'margin-left': + return addStyleProp(d.property, _.size(d.value, options)); + case 'margin-right': + return addStyleProp(d.property, _.size(d.value, options)); + case 'margin-block-start': + return addStyleProp('margin-start', _.lengthPercentageOrAuto(d.value, options)); + case 'margin-block-end': + return addStyleProp('margin-end', _.lengthPercentageOrAuto(d.value, options)); + case 'margin-inline-start': + return addStyleProp('margin-start', _.lengthPercentageOrAuto(d.value, options)); + case 'margin-inline-end': + return addStyleProp('margin-end', _.lengthPercentageOrAuto(d.value, options)); + case 'margin': + handleStyleShorthand('margin', { + 'margin-top': _.size(d.value.top, options), + 'margin-bottom': _.size(d.value.bottom, options), + 'margin-left': _.size(d.value.left, options), + 'margin-right': _.size(d.value.right, options), + }); + return; + case 'margin-block': + handleStyleShorthand('margin-block', { + 'margin-start': _.lengthPercentageOrAuto(d.value.blockStart, options), + 'margin-end': _.lengthPercentageOrAuto(d.value.blockEnd, options), + }); + return; + case 'margin-inline': + handleStyleShorthand('margin-inline', { + 'margin-start': _.lengthPercentageOrAuto(d.value.inlineStart, options), + 'margin-end': _.lengthPercentageOrAuto(d.value.inlineEnd, options), + }); + return; + case 'padding': + handleStyleShorthand('padding', { + 'padding-top': _.size(d.value.top, options), + 'padding-left': _.size(d.value.left, options), + 'padding-right': _.size(d.value.right, options), + 'padding-bottom': _.size(d.value.bottom, options), + }); + break; + case 'padding-top': + return addStyleProp(d.property, _.size(d.value, options)); + case 'padding-bottom': + return addStyleProp(d.property, _.size(d.value, options)); + case 'padding-left': + return addStyleProp(d.property, _.size(d.value, options)); + case 'padding-right': + return addStyleProp(d.property, _.size(d.value, options)); + case 'padding-block-start': + return addStyleProp('padding-start', _.lengthPercentageOrAuto(d.value, options)); + case 'padding-block-end': + return addStyleProp('padding-end', _.lengthPercentageOrAuto(d.value, options)); + case 'padding-inline-start': + return addStyleProp('padding-start', _.lengthPercentageOrAuto(d.value, options)); + case 'padding-inline-end': + return addStyleProp('padding-end', _.lengthPercentageOrAuto(d.value, options)); + case 'padding-block': + handleStyleShorthand('padding-block', { + 'padding-start': _.lengthPercentageOrAuto(d.value.blockStart, options), + 'padding-end': _.lengthPercentageOrAuto(d.value.blockEnd, options), + }); + return; + case 'padding-inline': + handleStyleShorthand('padding-inline', { + 'padding-start': _.lengthPercentageOrAuto(d.value.inlineStart, options), + 'padding-end': _.lengthPercentageOrAuto(d.value.inlineEnd, options), + }); + return; + case 'font-weight': + return addStyleProp(d.property, _.fontWeight(d.value, options)); + case 'font-size': + return addStyleProp(d.property, _.fontSize(d.value, options)); + case 'font-family': + return addStyleProp(d.property, _.fontFamily(d.value)); + case 'font-style': + return addStyleProp(d.property, _.fontStyle(d.value, options)); + case 'font-variant-caps': + return addStyleProp(d.property, _.fontVariantCaps(d.value, options)); + case 'line-height': + return addStyleProp(d.property, _.lineHeight(d.value, options)); + case 'font': + addStyleProp(d.property + '-family', _.fontFamily(d.value.family)); + addStyleProp('line-height', _.lineHeight(d.value.lineHeight, options)); + addStyleProp(d.property + '-size', _.fontSize(d.value.size, options)); + addStyleProp(d.property + '-style', _.fontStyle(d.value.style, options)); + addStyleProp(d.property + '-variant', _.fontVariantCaps(d.value.variantCaps, options)); + addStyleProp(d.property + '-weight', _.fontWeight(d.value.weight, options)); + return; + case 'vertical-align': + return addStyleProp(d.property, _.verticalAlign(d.value, options)); + case 'transition-property': + case 'transition-duration': + case 'transition-delay': + case 'transition-timing-function': + case 'transition': + return addTransitionProp(d); + case 'animation-duration': + case 'animation-timing-function': + case 'animation-iteration-count': + case 'animation-direction': + case 'animation-play-state': + case 'animation-delay': + case 'animation-fill-mode': + case 'animation-name': + case 'animation': + return addAnimationProp(d.property, d.value); + case 'transform': { + return addStyleProp(d.property, _.transform(d.value, options)); + } + case 'translate': + return addStyleProp( + 'transform', + [ + {translateX: d.value.x}, + {translateY: d.value.y}, + ], + {append: true}, + ); + case 'rotate': + return addStyleProp( + 'transform', + [ + {rotateX: d.value.x}, + {rotateY: d.value.y}, + {rotateY: d.value.z}, + ], + {append: true}, + ); + case 'scale': + return addStyleProp( + 'transform', + [ + {scaleX: _.length(d.value.x, options)}, + {scaleY: _.length(d.value.y, options)}, + ], + {append: true}, + ); + case 'text-transform': + return addStyleProp(d.property, d.value.case); + case 'letter-spacing': + if (d.value.type !== 'normal') { + return addStyleProp(d.property, _.length(d.value.value, options)); + } + return; + case 'text-decoration-line': + return addStyleProp(d.property, _.textDecorationLine(d.value, options)); + case 'text-decoration-color': + return addStyleProp(d.property, _.color(d.value, options)); + case 'text-decoration': + addStyleProp('text-decoration-color', _.color(d.value.color, options)); + addStyleProp('text-decoration-line', _.textDecorationLine(d.value.line, options)); + return; + case 'text-shadow': + return _.textShadow(d.value, addStyleProp, options); + case 'z-index': + if (d.value.type === 'integer') { + addStyleProp(d.property, _.length(d.value.value, options)); + } else { + addWarning({type: 'IncompatibleNativeValue', property: d.property, value: d.value}); + } + return; + case 'text-decoration-style': + return addStyleProp(d.property, _.textDecorationStyle(d.value, options)); + case 'text-align': + return addStyleProp(d.property, _.textAlign(d.value, options)); + case 'box-shadow': + return addStyleProp(d.property, _.boxShadow(d.value, options)); + case 'aspect-ratio': + return addStyleProp(d.property, _.aspectRatio(d.value)); + case 'container-type': + case 'container-name': + case 'container': + return addWarning({type: 'IncompatibleNativeValue', property: d.property, value: d.value}); + default: { + /** + * This is used to know when lightningcss has added a new property and we need to add it to the + * switch. + * + * If your build fails here, its because you have a newer version of lightningcss installed. + */ + d satisfies never; + } + } +} diff --git a/packages/css-to-rn/declarations/_index.ts b/packages/css-to-rn/declarations/_index.ts new file mode 100644 index 00000000..9f0b104e --- /dev/null +++ b/packages/css-to-rn/declarations/_index.ts @@ -0,0 +1,31 @@ +export {default as alignContent} from './align-content'; +export {default as alignItems} from './align-items'; +export {default as alignSelf} from './align-self'; +export {default as angle} from './angle'; +export {default as aspectRatio} from './aspect-ratio'; +export {default as borderSideWidth} from './border-side-width'; +export {default as borderStyle} from './border-style'; +export {default as boxShadow} from './box-shadow'; +export {default as color} from './color'; +export {default as dimension} from './dimension'; +export {default as display} from './display'; +export {default as fontFamily} from './font-family'; +export {default as fontSize} from './font-size'; +export {default as fontStyle} from './font-style'; +export {default as fontVariantCaps} from './font-variant-caps'; +export {default as fontWeight} from './font-weight'; +export {default as gap} from './gap'; +export {default as justifyContent} from './justify-content'; +export {default as length} from './length'; +export {default as lengthOrCoercePercentageToRuntime} from './length-or-coerce-percentage-to-runtime'; +export {default as lengthPercentageOrAuto} from './length-percentage-or-auto'; +export {default as lineHeight} from './line-height'; +export {default as overflow} from './overflow'; +export {default as size} from './size'; +export {default as textAlign} from './text-align'; +export {default as textDecorationLine} from './text-decoration-line'; +export {default as textDecorationStyle} from './text-decoration-style'; +export {default as textShadow} from './text-shadow'; +export {default as transform} from './transform'; +export {default as unparsed} from './unparsed'; +export {default as verticalAlign} from './vertical-align'; diff --git a/packages/css-to-rn/declarations/align-content.ts b/packages/css-to-rn/declarations/align-content.ts new file mode 100644 index 00000000..3d57c4c5 --- /dev/null +++ b/packages/css-to-rn/declarations/align-content.ts @@ -0,0 +1,36 @@ +import type {AlignContent} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (alignContent: AlignContent, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set([ + 'flex-start', + 'flex-end', + 'center', + 'stretch', + 'space-between', + 'space-around', + ]); + + let value: string | undefined; + + switch (alignContent.type) { + case 'normal': + case 'baseline-position': + value = alignContent.type; + break; + case 'content-distribution': + case 'content-position': + value = alignContent.value; + break; + default: { + alignContent satisfies never; + } + } + + if (value && !allowed.has(value)) { + options.addValueWarning(value); + return; + } + + return value; +} diff --git a/packages/css-to-rn/declarations/align-items.ts b/packages/css-to-rn/declarations/align-items.ts new file mode 100644 index 00000000..338c4b7e --- /dev/null +++ b/packages/css-to-rn/declarations/align-items.ts @@ -0,0 +1,40 @@ +import type {AlignItems} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (alignItems: AlignItems, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set([ + 'auto', + 'flex-start', + 'flex-end', + 'center', + 'stretch', + 'baseline', + ]); + + let value: string | undefined; + + switch (alignItems.type) { + case 'normal': + value = 'auto'; + break; + case 'stretch': + value = alignItems.type; + break; + case 'baseline-position': + value = 'baseline'; + break; + case 'self-position': + value = alignItems.value; + break; + default: { + alignItems satisfies never; + } + } + + if (value && !allowed.has(value)) { + options.addValueWarning(value); + return; + } + + return value; +} diff --git a/packages/css-to-rn/declarations/align-self.ts b/packages/css-to-rn/declarations/align-self.ts new file mode 100644 index 00000000..46e027e7 --- /dev/null +++ b/packages/css-to-rn/declarations/align-self.ts @@ -0,0 +1,40 @@ +import type {AlignSelf} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (alignSelf: AlignSelf, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set([ + 'auto', + 'flex-start', + 'flex-end', + 'center', + 'stretch', + 'baseline', + ]); + + let value: string | undefined; + + switch (alignSelf.type) { + case 'normal': + case 'auto': + value = 'auto'; + case 'stretch': + value = alignSelf.type; + break; + case 'baseline-position': + value = 'baseline'; + break; + case 'self-position': + value = alignSelf.value; + break; + default: { + alignSelf satisfies never; + } + } + + if (value && !allowed.has(value)) { + options.addValueWarning(value); + return; + } + + return value; +} diff --git a/packages/css-to-rn/declarations/angle.ts b/packages/css-to-rn/declarations/angle.ts new file mode 100644 index 00000000..fe1cfc79 --- /dev/null +++ b/packages/css-to-rn/declarations/angle.ts @@ -0,0 +1,13 @@ +import type {Angle} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (angle: Angle, options: ParseDeclarationOptionsWithValueWarning) => { + switch (angle.type) { + case 'deg': + case 'rad': + return `${angle.value}${angle.type}`; + default: + options.addValueWarning(angle.value); + return undefined; + } +} diff --git a/packages/css-to-rn/declarations/aspect-ratio.ts b/packages/css-to-rn/declarations/aspect-ratio.ts new file mode 100644 index 00000000..9952074e --- /dev/null +++ b/packages/css-to-rn/declarations/aspect-ratio.ts @@ -0,0 +1,11 @@ +export default (aspectRatio: any) => { + if (aspectRatio.auto) { + return 'auto'; + } else { + if (aspectRatio.ratio[0] === aspectRatio.ratio[1]) { + return 1; + } else { + return aspectRatio.ratio.join(' / '); + } + } +} diff --git a/packages/css-to-rn/declarations/border-side-width.ts b/packages/css-to-rn/declarations/border-side-width.ts new file mode 100644 index 00000000..77f1204c --- /dev/null +++ b/packages/css-to-rn/declarations/border-side-width.ts @@ -0,0 +1,13 @@ +import parseLength from './length'; + +import type {BorderSideWidth} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (borderSideWidth: BorderSideWidth, options: ParseDeclarationOptionsWithValueWarning) => { + if (borderSideWidth.type === 'length') { + return parseLength(borderSideWidth.value, options); + } + + options.addValueWarning(borderSideWidth.type); + return undefined; +} diff --git a/packages/css-to-rn/declarations/border-style.ts b/packages/css-to-rn/declarations/border-style.ts new file mode 100644 index 00000000..3731f453 --- /dev/null +++ b/packages/css-to-rn/declarations/border-style.ts @@ -0,0 +1,26 @@ +import type {BorderStyle, LineStyle} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (borderStyle: BorderStyle | LineStyle, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set(['solid', 'dotted', 'dashed']); + + if (typeof borderStyle === 'string') { + if (allowed.has(borderStyle)) { + return borderStyle; + } else { + options.addValueWarning(borderStyle); + return undefined; + } + } else if ( + borderStyle.top === borderStyle.bottom && + borderStyle.top === borderStyle.left && + borderStyle.top === borderStyle.right && + allowed.has(borderStyle.top) + ) { + return borderStyle.top; + } + + options.addValueWarning(JSON.stringify(borderStyle.top)); + + return undefined; +} diff --git a/packages/css-to-rn/declarations/box-shadow.ts b/packages/css-to-rn/declarations/box-shadow.ts new file mode 100644 index 00000000..efca2c22 --- /dev/null +++ b/packages/css-to-rn/declarations/box-shadow.ts @@ -0,0 +1,21 @@ +import parseColor from './color'; +import parseLength from './length'; + +import type {BoxShadow} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (boxShadows: BoxShadow[], options: ParseDeclarationOptionsWithValueWarning) => { + if (boxShadows.length > 1) { + options.addValueWarning('multiple box shadows'); + return; + } + + const boxShadow = boxShadows[0]; + + options.addStyleProp('shadowColor', parseColor(boxShadow.color, options)); + options.addStyleProp('shadowRadius', parseLength(boxShadow.blur, options)); + options.addStyleProp('shadowOffset', { + width: parseLength(boxShadow.xOffset, options), + height: parseLength(boxShadow.yOffset, options), + }); +} diff --git a/packages/css-to-rn/declarations/color.ts b/packages/css-to-rn/declarations/color.ts new file mode 100644 index 00000000..a9ca5d97 --- /dev/null +++ b/packages/css-to-rn/declarations/color.ts @@ -0,0 +1,29 @@ +import type {CssColor} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (color: CssColor, options: ParseDeclarationOptionsWithValueWarning) => { + switch (color.type) { + case 'rgb': + return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.alpha})`; + case 'hsl': + return `hsla(${color.h}, ${color.s}, ${color.l}, ${color.alpha})`; + case 'currentcolor': + options.addValueWarning(color.type); + return; + case 'lab': + case 'lch': + case 'oklab': + case 'oklch': + case 'srgb': + case 'srgb-linear': + case 'display-p3': + case 'a98-rgb': + case 'prophoto-rgb': + case 'rec2020': + case 'xyz-d50': + case 'xyz-d65': + case 'hwb': + options.addValueWarning(`Invalid color unit ${color.type}`); + return undefined; + } +} diff --git a/packages/css-to-rn/declarations/dimension.ts b/packages/css-to-rn/declarations/dimension.ts new file mode 100644 index 00000000..d1e257ea --- /dev/null +++ b/packages/css-to-rn/declarations/dimension.ts @@ -0,0 +1,21 @@ +import type {Token} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default ({unit, value}: Extract, options: ParseDeclarationOptionsWithValueWarning) => { + switch (unit) { + case 'px': + return value; + case '%': + return `${value}%`; + case 'ch': + case 'cw': + return { + type: 'runtime', + name: unit, + arguments: [value / 100], + }; + default: { + return options.addValueWarning(`${value}${unit}`); + } + } +} diff --git a/packages/css-to-rn/declarations/display.ts b/packages/css-to-rn/declarations/display.ts new file mode 100644 index 00000000..3d5e1d40 --- /dev/null +++ b/packages/css-to-rn/declarations/display.ts @@ -0,0 +1,49 @@ +import type {Display} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (display: Display, options: ParseDeclarationOptionsWithValueWarning) => { + if (display.type === 'keyword') { + if (display.value === 'none') { + return display.value; + } else { + return options.addValueWarning(display.value); + } + } else if (display.type === 'pair') { + if (display.outside === 'block') { + switch (display.inside.type) { + case 'flow': + if (display.isListItem) { + return options.addValueWarning('list-item'); + } else { + return options.addValueWarning('block'); + } + case 'flow-root': + return options.addValueWarning('flow-root'); + case 'table': + return options.addValueWarning(display.inside.type); + case 'flex': + return display.inside.type; + case 'box': + case 'grid': + case 'ruby': + return options.addValueWarning(display.inside.type); + } + } else { + switch (display.inside.type) { + case 'flow': + return options.addValueWarning('inline'); + case 'flow-root': + return options.addValueWarning('inline-block'); + case 'table': + return options.addValueWarning('inline-table'); + case 'flex': + return options.addValueWarning('inline-flex'); + case 'box': + case 'grid': + return options.addValueWarning('inline-grid'); + case 'ruby': + return options.addValueWarning(display.inside.type); + } + } + } +} diff --git a/packages/css-to-rn/declarations/font-family.ts b/packages/css-to-rn/declarations/font-family.ts new file mode 100644 index 00000000..f6aff4f0 --- /dev/null +++ b/packages/css-to-rn/declarations/font-family.ts @@ -0,0 +1,6 @@ +import type {FontFamily} from 'lightningcss-wasm'; + +export default (fontFamily: FontFamily[]) => { + // React Native only allows one font family - better hope this is the right one :) + return fontFamily[0]; +} diff --git a/packages/css-to-rn/declarations/font-size.ts b/packages/css-to-rn/declarations/font-size.ts new file mode 100644 index 00000000..6c733b55 --- /dev/null +++ b/packages/css-to-rn/declarations/font-size.ts @@ -0,0 +1,15 @@ +import parseLength from './length'; + +import type {FontSize} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (fontSize: FontSize, options: ParseDeclarationOptionsWithValueWarning) => { + switch (fontSize.type) { + case 'length': + return parseLength(fontSize.value, options); + case 'absolute': + case 'relative': + options.addValueWarning(fontSize.value); + return undefined; + } +} diff --git a/packages/css-to-rn/declarations/font-style.ts b/packages/css-to-rn/declarations/font-style.ts new file mode 100644 index 00000000..c2b6317f --- /dev/null +++ b/packages/css-to-rn/declarations/font-style.ts @@ -0,0 +1,13 @@ +import type {FontStyle} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (fontStyle: FontStyle, options: ParseDeclarationOptionsWithValueWarning) => { + switch (fontStyle.type) { + case 'normal': + case 'italic': + return fontStyle.type; + case 'oblique': + options.addValueWarning(fontStyle.type); + return undefined; + } +} diff --git a/packages/css-to-rn/declarations/font-variant-caps.ts b/packages/css-to-rn/declarations/font-variant-caps.ts new file mode 100644 index 00000000..0c76b1aa --- /dev/null +++ b/packages/css-to-rn/declarations/font-variant-caps.ts @@ -0,0 +1,19 @@ +import type {FontVariantCaps} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (fontVariantCaps: FontVariantCaps, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set([ + 'small-caps', + 'oldstyle-nums', + 'lining-nums', + 'tabular-nums', + 'proportional-nums', + ]); + + if (allowed.has(fontVariantCaps)) { + return fontVariantCaps; + } + + options.addValueWarning(fontVariantCaps); + return undefined; +} diff --git a/packages/css-to-rn/declarations/font-weight.ts b/packages/css-to-rn/declarations/font-weight.ts new file mode 100644 index 00000000..acf3d410 --- /dev/null +++ b/packages/css-to-rn/declarations/font-weight.ts @@ -0,0 +1,17 @@ +import type {FontWeight} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (fontWeight: FontWeight, options: ParseDeclarationOptionsWithValueWarning) => { + switch (fontWeight.type) { + case 'absolute': + if (fontWeight.value.type === 'weight') { + return fontWeight.value.value.toString(); + } else { + return fontWeight.value.type; + } + case 'bolder': + case 'lighter': + options.addValueWarning(fontWeight.type); + return; + } +} diff --git a/packages/css-to-rn/declarations/gap.ts b/packages/css-to-rn/declarations/gap.ts new file mode 100644 index 00000000..f8d18542 --- /dev/null +++ b/packages/css-to-rn/declarations/gap.ts @@ -0,0 +1,12 @@ +import parseLength from './length'; + +import type {GapValue} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (value: GapValue, options: ParseDeclarationOptionsWithValueWarning) => { + if (value.type === 'normal') { + options.addValueWarning(value.type); + return; + } + return parseLength(value.value, options); +} diff --git a/packages/css-to-rn/declarations/justify-content.ts b/packages/css-to-rn/declarations/justify-content.ts new file mode 100644 index 00000000..6d1a98c0 --- /dev/null +++ b/packages/css-to-rn/declarations/justify-content.ts @@ -0,0 +1,37 @@ +import type {JustifyContent} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (justifyContent: JustifyContent, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set([ + 'flex-start', + 'flex-end', + 'center', + 'space-between', + 'space-around', + 'space-evenly', + ]); + + let value: string | undefined; + + switch (justifyContent.type) { + case 'normal': + case 'left': + case 'right': + value = justifyContent.type; + break; + case 'content-distribution': + case 'content-position': + value = justifyContent.value; + break; + default: { + justifyContent satisfies never; + } + } + + if (value && !allowed.has(value)) { + options.addValueWarning(value); + return; + } + + return value; +} diff --git a/packages/css-to-rn/declarations/length-or-coerce-percentage-to-runtime.ts b/packages/css-to-rn/declarations/length-or-coerce-percentage-to-runtime.ts new file mode 100644 index 00000000..92c0c876 --- /dev/null +++ b/packages/css-to-rn/declarations/length-or-coerce-percentage-to-runtime.ts @@ -0,0 +1,21 @@ +import parseLength from './length'; + +import type {Length, DimensionPercentageFor_LengthValue, NumberOrPercentage} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse' + +export default ( + value: Length | DimensionPercentageFor_LengthValue | NumberOrPercentage, + runtimeName: string, + options: ParseDeclarationOptionsWithValueWarning, +) => { + if (value.type === 'percentage') { + options.requiresLayout(); + return { + type: 'runtime', + name: runtimeName, + arguments: [value.value], + }; + } else { + return parseLength(value, options); + } +} diff --git a/packages/css-to-rn/declarations/length-percentage-or-auto.ts b/packages/css-to-rn/declarations/length-percentage-or-auto.ts new file mode 100644 index 00000000..7466bb9b --- /dev/null +++ b/packages/css-to-rn/declarations/length-percentage-or-auto.ts @@ -0,0 +1,14 @@ +import parseLength from './length'; + +import type {LengthPercentageOrAuto} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (lengthPercentageOrAuto: LengthPercentageOrAuto, options: ParseDeclarationOptionsWithValueWarning) => { + switch (lengthPercentageOrAuto.type) { + case 'auto': + options.addValueWarning(lengthPercentageOrAuto.type); + return; + case 'length-percentage': + return parseLength(lengthPercentageOrAuto.value, options); + } +} diff --git a/packages/css-to-rn/declarations/length.ts b/packages/css-to-rn/declarations/length.ts new file mode 100644 index 00000000..ab8bfb5b --- /dev/null +++ b/packages/css-to-rn/declarations/length.ts @@ -0,0 +1,112 @@ +import parseLength from './length'; +import {round} from '../utils'; + +import type {Length, LengthValue, DimensionPercentageFor_LengthValue, NumberOrPercentage} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; +import type {RuntimeValue} from '../types/index'; + +export default ( + length: + | number + | Length + | DimensionPercentageFor_LengthValue + | NumberOrPercentage + | LengthValue, + options: ParseDeclarationOptionsWithValueWarning, +): number | string | RuntimeValue | undefined => { + const { inlineRem = 14 } = options; + + if (typeof length === 'number') { + return length; + } + + if ('unit' in length) { + switch (length.unit) { + case 'px': + return length.value; + case 'rem': + if (typeof inlineRem === 'number') { + return length.value * inlineRem; + } else { + return { + type: 'runtime', + name: 'rem', + arguments: [length.value], + }; + } + case 'vw': + case 'vh': + return { + type: 'runtime', + name: length.unit, + arguments: [length.value], + }; + case 'in': + case 'cm': + case 'mm': + case 'q': + case 'pt': + case 'pc': + case 'em': + case 'ex': + case 'rex': + case 'ch': + case 'rch': + case 'cap': + case 'rcap': + case 'ic': + case 'ric': + case 'lh': + case 'rlh': + case 'lvw': + case 'svw': + case 'dvw': + case 'cqw': + case 'lvh': + case 'svh': + case 'dvh': + case 'cqh': + case 'vi': + case 'svi': + case 'lvi': + case 'dvi': + case 'cqi': + case 'vb': + case 'svb': + case 'lvb': + case 'dvb': + case 'cqb': + case 'vmin': + case 'svmin': + case 'lvmin': + case 'dvmin': + case 'cqmin': + case 'vmax': + case 'svmax': + case 'lvmax': + case 'dvmax': + case 'cqmax': + options.addValueWarning(`${length.value}${length.unit}`); + return undefined; + } + + length.unit satisfies never; + } else { + switch (length.type) { + case 'calc': { + return undefined; + } + case 'number': { + return round(length.value); + } + case 'percentage': { + return `${round(length.value * 100)}%`; + } + case 'dimension': + case 'value': { + return parseLength(length.value, options); + } + } + } + return undefined; +} diff --git a/packages/css-to-rn/declarations/line-height.ts b/packages/css-to-rn/declarations/line-height.ts new file mode 100644 index 00000000..eb99dd34 --- /dev/null +++ b/packages/css-to-rn/declarations/line-height.ts @@ -0,0 +1,29 @@ +import parseLength from './length'; + +import type {LineHeight} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (lineHeight: LineHeight, options: ParseDeclarationOptionsWithValueWarning) => { + switch (lineHeight.type) { + case 'normal': + return undefined; + case 'number': + return { + type: 'runtime', + name: 'em', + arguments: [lineHeight.value], + }; + case 'length': { + const length = lineHeight.value; + + switch (length.type) { + case 'dimension': + return parseLength(length, options); + case 'percentage': + case 'calc': + options.addValueWarning(length.value); + return undefined; + } + } + } +} diff --git a/packages/css-to-rn/declarations/overflow.ts b/packages/css-to-rn/declarations/overflow.ts new file mode 100644 index 00000000..e56db542 --- /dev/null +++ b/packages/css-to-rn/declarations/overflow.ts @@ -0,0 +1,13 @@ +import type {OverflowKeyword} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (overflow: OverflowKeyword, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set(['visible', 'hidden']); + + if (allowed.has(overflow)) { + return overflow; + } + + options.addValueWarning(overflow); + return undefined; +} diff --git a/packages/css-to-rn/declarations/runtime-specifics-function.ts b/packages/css-to-rn/declarations/runtime-specifics-function.ts new file mode 100644 index 00000000..9653d267 --- /dev/null +++ b/packages/css-to-rn/declarations/runtime-specifics-function.ts @@ -0,0 +1,83 @@ +import parseUnparsed from './unparsed'; + +import type {TokenOrValue} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default ( + name: string, + args: TokenOrValue[], + options: ParseDeclarationOptionsWithValueWarning, +) => { + let key: string | undefined; + const runtimeArgs: Record = {}; + + for (const token of args) { + if (!key) { + if ( + token.type === 'token' && + (token.value.type === 'ident' || token.value.type === 'number') + ) { + key = token.value.value.toString(); + continue; + } + } else { + if (token.type !== 'token') { + const value = parseUnparsed(token, options); + if (value === undefined) { + return; + } + runtimeArgs[key] = value; + key = undefined; + } else { + switch (token.value.type) { + case 'string': + case 'number': + case 'ident': { + if (key) { + runtimeArgs[key] = parseUnparsed(token, options); + key = undefined; + } else { + return; + } + } + case 'delim': + case 'comma': + continue; + case 'function': + case 'at-keyword': + case 'hash': + case 'id-hash': + case 'unquoted-url': + case 'percentage': + case 'dimension': + case 'white-space': + case 'comment': + case 'colon': + case 'semicolon': + case 'include-match': + case 'dash-match': + case 'prefix-match': + case 'suffix-match': + case 'substring-match': + case 'cdo': + case 'cdc': + case 'parenthesis-block': + case 'square-bracket-block': + case 'curly-bracket-block': + case 'bad-url': + case 'bad-string': + case 'close-parenthesis': + case 'close-square-bracket': + case 'close-curly-bracket': + return undefined; + } + } + } + } + + return { + type: 'runtime', + name, + arguments: [runtimeArgs], + }; +} diff --git a/packages/css-to-rn/declarations/size.ts b/packages/css-to-rn/declarations/size.ts new file mode 100644 index 00000000..8509bb81 --- /dev/null +++ b/packages/css-to-rn/declarations/size.ts @@ -0,0 +1,32 @@ +import parseLength from './length'; + +import type {Size, MaxSize} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +type ParseSizeOptions = ParseDeclarationOptionsWithValueWarning & { + allowAuto?: boolean; +}; + +export default (size: Size | MaxSize, {allowAuto = false, ...options}: ParseSizeOptions) => { + switch (size.type) { + case 'length-percentage': + return parseLength(size.value, options); + case 'none': + return size.type; + case 'auto': + if (allowAuto) { + return size.type; + } else { + options.addValueWarning(size.type); + return undefined; + } + case 'min-content': + case 'max-content': + case 'fit-content': + case 'fit-content-function': + case 'stretch': + case 'contain': + options.addValueWarning(size.type); + return undefined; + } +} diff --git a/packages/css-to-rn/declarations/text-align.ts b/packages/css-to-rn/declarations/text-align.ts new file mode 100644 index 00000000..c49c100f --- /dev/null +++ b/packages/css-to-rn/declarations/text-align.ts @@ -0,0 +1,13 @@ +import type {TextAlign} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (textAlign: TextAlign, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set(['auto', 'left', 'right', 'center', 'justify']); + + if (allowed.has(textAlign)) { + return textAlign; + } + + options.addValueWarning(textAlign); + return undefined; +} diff --git a/packages/css-to-rn/declarations/text-decoration-line.ts b/packages/css-to-rn/declarations/text-decoration-line.ts new file mode 100644 index 00000000..05afcb25 --- /dev/null +++ b/packages/css-to-rn/declarations/text-decoration-line.ts @@ -0,0 +1,27 @@ +import type {TextDecorationLine} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (textDecorationLine: TextDecorationLine, options: ParseDeclarationOptionsWithValueWarning) => { + if (!Array.isArray(textDecorationLine)) { + if (textDecorationLine === 'none') { + return textDecorationLine; + } + options.addValueWarning(textDecorationLine); + return; + } + + const set = new Set(textDecorationLine); + + if (set.has('underline')) { + if (set.has('line-through')) { + return 'underline line-through'; + } else { + return 'underline'; + } + } else if (set.has('line-through')) { + return 'line-through'; + } + + options.addValueWarning(textDecorationLine.join(' ')); + return undefined; +} diff --git a/packages/css-to-rn/declarations/text-decoration-style.ts b/packages/css-to-rn/declarations/text-decoration-style.ts new file mode 100644 index 00000000..f3e5d334 --- /dev/null +++ b/packages/css-to-rn/declarations/text-decoration-style.ts @@ -0,0 +1,13 @@ +import type {TextDecorationStyle} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (textDecorationStyle: TextDecorationStyle, options: ParseDeclarationOptionsWithValueWarning) => { + const allowed = new Set(['solid', 'double', 'dotted', 'dashed']); + + if (allowed.has(textDecorationStyle)) { + return textDecorationStyle; + } + + options.addValueWarning(textDecorationStyle); + return undefined; +} diff --git a/packages/css-to-rn/declarations/text-shadow.ts b/packages/css-to-rn/declarations/text-shadow.ts new file mode 100644 index 00000000..306724d8 --- /dev/null +++ b/packages/css-to-rn/declarations/text-shadow.ts @@ -0,0 +1,18 @@ +import parseColor from './color'; +import parseLength from './length'; + +import type {TextShadow} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning, AddStyleProp} from '../types/parse'; + +export default ( + [textShadow]: TextShadow[], + addStyleProp: AddStyleProp, + options: ParseDeclarationOptionsWithValueWarning, +) => { + addStyleProp('textShadowColor', parseColor(textShadow.color, options)); + addStyleProp('textShadowRadius', parseLength(textShadow.blur, options)); + addStyleProp('textShadowOffset', { + width: parseLength(textShadow.xOffset, options), + height: parseLength(textShadow.yOffset, options), + }); +} diff --git a/packages/css-to-rn/declarations/transform.ts b/packages/css-to-rn/declarations/transform.ts new file mode 100644 index 00000000..932c317e --- /dev/null +++ b/packages/css-to-rn/declarations/transform.ts @@ -0,0 +1,84 @@ +import parseAngle from './angle'; +import parseLength from './length'; +import parseLengthOrCoercePercentageToRuntime from './length-or-coerce-percentage-to-runtime'; + +import type {Transform} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; +import type {TransformRecord} from '../types/index'; + +export default (transforms: Transform[], options: ParseDeclarationOptionsWithValueWarning) => { + const records: TransformRecord[] = []; + for (const transform of transforms) { + switch (transform.type) { + case 'perspective': + records.push({ + [transform.type]: parseLength(transform.value, options) as number, + }); + break; + case 'translateX': + case 'scaleX': + records.push({ + [transform.type]: parseLengthOrCoercePercentageToRuntime( + transform.value, + 'cw', + options, + ) as number, + }); + break; + case 'translateY': + case 'scaleY': + records.push({ + [transform.type]: parseLengthOrCoercePercentageToRuntime( + transform.value, + 'ch', + options, + ) as number, + }); + break; + case 'translate': + records.push({ + translateX: parseLength(transform.value[0], options) as number, + }); + records.push({ + translateY: parseLength(transform.value[1], options) as number, + }); + break; + case 'scale': + records.push({ + scaleX: parseLength(transform.value[0], options) as number, + }); + records.push({ + scaleY: parseLength(transform.value[1], options) as number, + }); + break; + case 'skew': + records.push({ + skewX: parseAngle(transform.value[0], options), + }); + records.push({ + skewY: parseAngle(transform.value[1], options), + }); + break; + case 'rotate': + case 'rotateX': + case 'rotateY': + case 'rotateZ': + case 'skewX': + case 'skewY': + records.push({ + [transform.type]: parseAngle(transform.value, options), + }); + break; + case 'translateZ': + case 'translate3d': + case 'scaleZ': + case 'scale3d': + case 'rotate3d': + case 'matrix': + case 'matrix3d': + break; + } + } + + return records; +} diff --git a/packages/css-to-rn/declarations/unparsed.ts b/packages/css-to-rn/declarations/unparsed.ts new file mode 100644 index 00000000..65b8672e --- /dev/null +++ b/packages/css-to-rn/declarations/unparsed.ts @@ -0,0 +1,236 @@ +import parseAngle from './angle'; +import parseColor from './color'; +import parseLength from './length'; +import parseDimension from './dimension'; +import parseRNRuntimeSpecificsFunction from './runtime-specifics-function'; + +import {invalidIdent} from '../properties'; +import {round} from '../utils'; + +import type {TokenOrValue} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +type UnparsedInput = TokenOrValue | TokenOrValue[] | string | number | undefined; +type UnparsedOutput = string | number | object | undefined; + +/** + * When the CSS cannot be parsed (often due to a runtime condition like a CSS variable) + * This function best efforts parsing it into a function that we can evaluate at runtime + */ +export default (tokenOrValue: UnparsedInput, options: ParseDeclarationOptionsWithValueWarning): UnparsedOutput => { + return parseUnparsed(tokenOrValue, options); +} + +function parseUnparsed(tokenOrValue: UnparsedInput, options: ParseDeclarationOptionsWithValueWarning): UnparsedOutput { + if (tokenOrValue === undefined) { + return; + } + + if (typeof tokenOrValue === 'string') { + return tokenOrValue; + } + + if (typeof tokenOrValue === 'number') { + return round(tokenOrValue); + } + + if (Array.isArray(tokenOrValue)) { + return reduceParseUnparsed(tokenOrValue, options, true); + } + + switch (tokenOrValue.type) { + case 'unresolved-color': { + const value = tokenOrValue.value; + if (value.type === 'rgb') { + return { + type: 'runtime', + name: 'rgba', + arguments: [ + round(value.r * 255), + round(value.g * 255), + round(value.b * 255), + parseUnparsed(tokenOrValue.value.alpha, options), + ], + }; + } else { + return { + type: 'runtime', + name: tokenOrValue.value.type, + arguments: [ + value.h, + value.s, + value.l, + parseUnparsed(tokenOrValue.value.alpha, options), + ], + }; + } + } + case 'var': { + return { + type: 'runtime', + name: 'var', + arguments: [tokenOrValue.value.name.ident, tokenOrValue.value.fallback], + }; + } + case 'function': { + switch (tokenOrValue.value.name) { + case 'rgb': + tokenOrValue.value.name = 'rgb'; + return unparsedFunction(tokenOrValue, options); + case 'hsl': + tokenOrValue.value.name = 'hsla'; + return unparsedFunction(tokenOrValue, options); + case 'translate': + return unparsedKnownShorthand( + { + translateX: tokenOrValue.value.arguments[0], + translateY: tokenOrValue.value.arguments[2], + }, + options, + ); + case 'scale': + return unparsedKnownShorthand( + { + scaleX: tokenOrValue.value.arguments[0], + scaleY: tokenOrValue.value.arguments[2], + }, + options, + ); + case 'rotate': + case 'skewX': + case 'skewY': + case 'scaleX': + case 'scaleY': + return unparsedFunction(tokenOrValue, options); + case 'platformColor': + case 'getPixelSizeForLayoutSize': + case 'roundToNearestPixel': + case 'pixelScale': + case 'fontScale': + case 'shadow': + return unparsedFunction(tokenOrValue, options); + case 'hairlineWidth': + return { + type: 'runtime', + name: tokenOrValue.value.name, + arguments: [], + }; + case 'platformSelect': + case 'fontScaleSelect': + case 'pixelScaleSelect': + return parseRNRuntimeSpecificsFunction( + tokenOrValue.value.name, + tokenOrValue.value.arguments, + options, + ); + default: { + options.addFunctionValueWarning(tokenOrValue.value.name); + return; + } + } + } + case 'length': + return parseLength(tokenOrValue.value, options); + case 'angle': + return parseAngle(tokenOrValue.value, options); + case 'token': + switch (tokenOrValue.value.type) { + case 'string': + case 'number': + case 'ident': + if (invalidIdent.has(tokenOrValue.value.value.toString())) { + return options.addValueWarning(tokenOrValue.value.value); + } else { + return tokenOrValue.value.value; + } + case 'function': + options.addValueWarning(tokenOrValue.value.value); + return; + case 'percentage': + options.addValueWarning(`${tokenOrValue.value.value}%`); + return; + case 'dimension': + return parseDimension(tokenOrValue.value, options); + case 'at-keyword': + case 'hash': + case 'id-hash': + case 'unquoted-url': + case 'delim': + case 'white-space': + case 'comment': + case 'colon': + case 'semicolon': + case 'comma': + case 'include-match': + case 'dash-match': + case 'prefix-match': + case 'suffix-match': + case 'substring-match': + case 'cdo': + case 'cdc': + case 'parenthesis-block': + case 'square-bracket-block': + case 'curly-bracket-block': + case 'bad-url': + case 'bad-string': + case 'close-parenthesis': + case 'close-square-bracket': + case 'close-curly-bracket': + return; + default: { + tokenOrValue.value satisfies never; + return; + } + } + case 'color': + return parseColor(tokenOrValue.value, options); + case 'url': + case 'env': + case 'time': + case 'resolution': + case 'dashed-ident': + return; + } +} + +function reduceParseUnparsed( + tokenOrValues: TokenOrValue[], + options: ParseDeclarationOptionsWithValueWarning, + allowUnwrap = false, +) { + const result = tokenOrValues + .flatMap((tokenOrValue) => parseUnparsed(tokenOrValue, options)) + .filter((v) => v !== undefined); + + if (result.length === 0) { + return undefined; + } else if (result.length === 1 && allowUnwrap) { + return result[0]; + } else { + return result; + } +} + +function unparsedFunction( + token: Extract, + options: ParseDeclarationOptionsWithValueWarning, +) { + return { + type: 'runtime', + name: token.value.name, + arguments: reduceParseUnparsed(token.value.arguments, options), + }; +} + +function unparsedKnownShorthand( + mapping: Record, + options: ParseDeclarationOptionsWithValueWarning, +) { + return Object.entries(mapping).map(([name, tokenOrValue]) => { + return { + type: 'runtime', + name, + arguments: [parseUnparsed(tokenOrValue, options)], + }; + }); +} diff --git a/packages/css-to-rn/declarations/vertical-align.ts b/packages/css-to-rn/declarations/vertical-align.ts new file mode 100644 index 00000000..04c0e4bf --- /dev/null +++ b/packages/css-to-rn/declarations/vertical-align.ts @@ -0,0 +1,17 @@ +import type {VerticalAlign} from 'lightningcss-wasm'; +import type {ParseDeclarationOptionsWithValueWarning} from '../types/parse'; + +export default (verticalAlign: VerticalAlign, options: ParseDeclarationOptionsWithValueWarning) => { + if (verticalAlign.type === 'length') { + return undefined; + } + + const allowed = new Set(['auto', 'top', 'bottom', 'middle']); + + if (allowed.has(verticalAlign.value)) { + return verticalAlign.value; + } + + options.addValueWarning(verticalAlign.value); + return undefined; +} diff --git a/packages/css-to-rn/index.ts b/packages/css-to-rn/index.ts new file mode 100644 index 00000000..f8fe5901 --- /dev/null +++ b/packages/css-to-rn/index.ts @@ -0,0 +1,507 @@ +import {transform} from 'lightningcss-wasm'; +import {parseDeclaration} from './declaration'; +import {kebabToCamelCase, allEqual} from './utils'; + +import type * as LightningCSS from 'lightningcss-wasm'; +import type {ParseDeclarationOptions} from './types/parse'; +import type { + RuntimeValue, + ExtractedStyle, + StyleSheetRegisterOptions, + AnimatableCSSProperty, + ExtractedAnimation, + ExtractionWarning, + ExtractRuleOptions, + CssToReactNativeOptions, +} from './types/index'; + +export type {CssToReactNativeOptions}; + +export {default as init} from 'lightningcss-wasm'; + +/** + * Converts a CSS file to a collection of style declarations that can be used with the StyleSheet API + * + * @param code - The CSS file contents + * @param options - (Optional) Options for the conversion process + * @returns An object containing the extracted style declarations and animations + */ +export function cssToRN( + code: string, + options: CssToReactNativeOptions = {}, +): StyleSheetRegisterOptions { + // These will by mutated by `extractRule` + const extractOptions: ExtractRuleOptions = { + ...options, + declarations: new Map(), + keyframes: new Map(), + }; + + // Use LightningCSS to traverse the CSS AST + // and extract style declarations and animations + transform({ + // This is ignored, but required + filename: 'style.css', + code: new TextEncoder().encode(code), + visitor: { + Rule(rule: LightningCSS.Rule) { + // Extract the style declarations and animations from the current rule + extractRule(rule, extractOptions); + // We have processed this rule, so now delete it from the AST + return []; + }, + }, + }); + + // Convert the extracted style declarations and animations from maps to objects and return them + return { + declarations: Object.fromEntries(extractOptions.declarations), + keyframes: Object.fromEntries(extractOptions.keyframes), + }; +} + +/** + * Converts a CSS file to a collection of style declarations that can be used with the StyleSheet API + * + * @param data - The object to transform to CSS + */ +export function buildCSS(data: {[s: string]: {[s: string]: unknown}}) { + let css = ''; + for (const [id, styles] of Object.entries(data)) { + css += `._${id.replace(/\:/g, '-')} { `; + for (const [prop, value] of Object.entries(styles)) { + // TODO: break this normalization out + const _prop = prop === 'background' ? 'background-color' : prop; + const _value = value === 'inline-flex' ? 'flex' : value; + css += `${_prop}: ${_value}; `; + } + css += ' }\n'; + } + return css; +} + +/** + * Extracts style declarations and animations from a given CSS rule, based on its type. + * + * @param rule - The CSS rule to extract style declarations and animations from. + * @param extractOptions - Options for the extraction process, including maps for storing extracted data. + * @param parseOptions - Options for parsing the CSS code + */ +function extractRule( + rule: LightningCSS.Rule, + extractOptions: ExtractRuleOptions, + partialStyle: Partial = {}, +) { + // Check the rule's type to determine which extraction function to call + switch (rule.type) { + // If the rule is a keyframe animation, extract it with the `extractKeyFrames` function + case 'keyframes': { + extractKeyFrames(rule.value, extractOptions); + break; + } + // If the rule is a style declaration, extract it with the `getExtractedStyle` function + // and store it in the `declarations` map + case 'style': { + if (rule.value.declarations) { + for (const style of getExtractedStyles( + rule.value.declarations, + extractOptions, + )) { + setStyleForSelectorList( + { ...partialStyle, ...style }, + rule.value.selectors, + extractOptions, + ); + } + } + break; + } + } +} + +/** + * @param style - The ExtractedStyle object to use when setting styles. + * @param selectorList - The SelectorList object containing the selectors to use when setting styles. + * @param declarations - The declarations object to use when adding declarations. + */ +function setStyleForSelectorList( + extractedStyle: ExtractedStyle, + selectorList: LightningCSS.SelectorList, + options: ExtractRuleOptions, +) { + const {declarations} = options; + + for (const selector of normalizeSelectors(selectorList)) { + const style = {...extractedStyle}; + const {className} = selector; + addDeclaration(className, {...style}, declarations); + } +} + +function addDeclaration( + className: string, + style: ExtractedStyle, + declarations: ExtractRuleOptions['declarations'], +) { + const existing = declarations.get(className); + + if (Array.isArray(existing)) { + existing.push(style); + } else if (existing) { + declarations.set(className, [existing, style]); + } else { + declarations.set(className, style); + } +} + +function extractKeyFrames( + keyframes: LightningCSS.KeyframesRule, + extractOptions: ExtractRuleOptions, +) { + const extractedAnimation: ExtractedAnimation = { frames: [] }; + const frames = extractedAnimation.frames; + + for (const frame of keyframes.keyframes) { + if (!frame.declarations.declarations) continue; + + /** + * Animations ignore !important declarations + */ + const { style } = declarationsToStyle( + frame.declarations.declarations, + { + ...extractOptions, + requiresLayout() { + extractedAnimation.requiresLayout = true; + }, + }, + ); + + for (const selector of frame.selectors) { + const keyframe = + selector.type === 'percentage' + ? selector.value * 100 + : selector.type === 'from' + ? 0 + : selector.type === 'to' + ? 100 + : undefined; + + if (keyframe === undefined) continue; + + switch (selector.type) { + case 'percentage': + frames.push({ selector: selector.value, style }); + break; + case 'from': + frames.push({ selector: 0, style }); + break; + case 'to': + frames.push({ selector: 1, style }); + break; + default: + selector satisfies never; + } + } + } + + // Ensure there are always two frames, a start and end + if (frames.length === 1) { + frames.push({ selector: 0, style: {} }); + } + + extractedAnimation.frames = frames.sort((a, b) => a.selector - b.selector); + + extractOptions.keyframes.set(keyframes.name.value, extractedAnimation); +} + +interface GetExtractedStyleOptions extends ExtractRuleOptions { + requiresLayout?: () => void; +} + +function getExtractedStyles( + declarationBlock: LightningCSS.DeclarationBlock, + options: GetExtractedStyleOptions, +): ExtractedStyle[] { + const extractedStyles: ExtractedStyle[] = []; + + if (declarationBlock.declarations && declarationBlock.declarations.length) { + extractedStyles.push( + declarationsToStyle(declarationBlock.declarations, options), + ); + } + + if ( + declarationBlock.importantDeclarations && + declarationBlock.importantDeclarations.length + ) { + extractedStyles.push( + declarationsToStyle(declarationBlock.importantDeclarations, options), + ); + } + + return extractedStyles; +} + +function declarationsToStyle( + declarations: LightningCSS.Declaration[], + options: GetExtractedStyleOptions, +): ExtractedStyle { + const extractedStyle: ExtractedStyle = { + style: {}, + }; + + /* + * Adds a style property to the rule record. + * + * The shorthand option handles if the style came from a long or short hand property + * E.g. `margin` is a shorthand property for `margin-top`, `margin-bottom`, `margin-left` and `margin-right` + * + * The `append` option allows the same property to be added multiple times + * E.g. `transform` accepts an array of transforms + */ + function addStyleProp(property: string, value: any, {append = false} = {}) { + if (value === undefined) { + return; + } + + if (property.startsWith('--')) { + return addVariable(property, value); + } + + property = kebabToCamelCase(property); + + const style = extractedStyle.style; + + if (append) { + const styleValue = style[property]; + if (Array.isArray(styleValue)) { + styleValue.push(...value); + } else { + style[property] = [value]; + } + } else { + style[property] = value; + } + + if (isRuntimeValue(value)) { + extractedStyle.isDynamic = true; + } + } + + function handleStyleShorthand( + name: string, + options: Record, + ) { + if (allEqual(...Object.values(options))) { + return addStyleProp(name, Object.values(options)[0]); + } else { + for (const [name, value] of Object.entries(options)) { + addStyleProp(name, value); + } + } + } + + function addVariable(property: string, value: any) { + extractedStyle.variables ??= {}; + extractedStyle.variables[property] = value; + } + + function addTransitionProp( + declaration: Extract< + LightningCSS.Declaration, + { + property: + | 'transition-property' + | 'transition-duration' + | 'transition-delay' + | 'transition-timing-function' + | 'transition'; + } + >, + ) { + extractedStyle.transition ??= {}; + + switch (declaration.property) { + case 'transition-property': + extractedStyle.transition.property = declaration.value.map((v: any) => { + return kebabToCamelCase(v.property) as AnimatableCSSProperty; + }); + break; + case 'transition-duration': + extractedStyle.transition.duration = declaration.value; + break; + case 'transition-delay': + extractedStyle.transition.delay = declaration.value; + break; + case 'transition-timing-function': + extractedStyle.transition.timingFunction = declaration.value; + break; + case 'transition': { + let setProperty = true; + let setDuration = true; + let setDelay = true; + let setTiming = true; + + // Shorthand properties cannot override the longhand property + // So we skip setting the property if it already exists + // Otherwise, we need to set the property to an empty array + if (extractedStyle.transition.property) { + setProperty = false; + } else { + extractedStyle.transition.property = []; + } + if (extractedStyle.transition.duration) { + setDuration = false; + } else { + extractedStyle.transition.duration = []; + } + if (extractedStyle.transition.delay) { + setDelay = false; + } else { + extractedStyle.transition.delay = []; + } + if (extractedStyle.transition.timingFunction) { + setTiming = false; + } else { + extractedStyle.transition.timingFunction = []; + } + + // Loop through each transition value and only set the properties that + // were not already set by the longhand property + for (const value of declaration.value) { + if (setProperty) { + extractedStyle.transition.property?.push( + kebabToCamelCase( + value.property.property, + ) as AnimatableCSSProperty, + ); + } + if (setDuration) { + extractedStyle.transition.duration?.push(value.duration); + } + if (setDelay) { + extractedStyle.transition.delay?.push(value.delay); + } + if (setTiming) { + extractedStyle.transition.timingFunction?.push( + value.timingFunction, + ); + } + } + break; + } + } + } + + function addAnimationProp(property: string, value: any) { + if (property === 'animation') { + const groupedProperties: Record = {}; + + for (const animation of value as LightningCSS.Animation[]) { + for (const [key, value] of Object.entries(animation)) { + groupedProperties[key] ??= []; + groupedProperties[key].push(value); + } + } + + extractedStyle.animations ??= {}; + for (const [property, value] of Object.entries(groupedProperties)) { + const key = property + .replace('animation-', '') + .replace(/-./g, (x) => x[1].toUpperCase()) as keyof LightningCSS.Animation; + + extractedStyle.animations[key] ??= value; + } + } else { + const key = property + .replace('animation-', '') + .replace(/-./g, (x) => x[1].toUpperCase()) as keyof LightningCSS.Animation; + + extractedStyle.animations ??= {}; + extractedStyle.animations[key] = value; + } + } + + function addWarning(warning: ExtractionWarning): undefined { + const warningRegexArray = options.ignorePropertyWarningRegex; + + if (warningRegexArray) { + const match = warningRegexArray.some((regex) => + new RegExp(regex).test(warning.property), + ); + + if (match) return; + } + + extractedStyle.warnings ??= []; + extractedStyle.warnings.push(warning); + + console.warn(warning); + } + + function requiresLayout() { + extractedStyle.requiresLayout = true; + } + + const parseDeclarationOptions: ParseDeclarationOptions = { + addStyleProp, + handleStyleShorthand, + addAnimationProp, + addTransitionProp, + requiresLayout, + addWarning, + ...options, + }; + + for (const declaration of declarations) { + parseDeclaration(declaration, parseDeclarationOptions); + } + + return extractedStyle; +} + +function isRuntimeValue(value: unknown): value is RuntimeValue { + if (!value) { + return false; + } else if (Array.isArray(value)) { + return value.some((v) => isRuntimeValue(v)); + } else if (typeof value === "object") { + if ((value as Record).type === "runtime") { + return true; + } else { + return Object.values(value).some((v) => isRuntimeValue(v)); + } + } else { + return false; + } +} + +type NormalizeSelector = { + type: 'className', + className: string, +}; + +function normalizeSelectors( + selectorList: LightningCSS.SelectorList, + selectors: NormalizeSelector[] = [], + defaults: Partial = {}, +) { + for (const lightningSelector of selectorList) { + const selector: NormalizeSelector = { + ...defaults, + className: '', + type: 'className', + }; + for (const component of lightningSelector) { + switch (component.type) { + case 'class': { + selector.className = component.name; + break; + } + } + } + selectors.push(selector); + } + return selectors; +} diff --git a/packages/css-to-rn/package.json b/packages/css-to-rn/package.json new file mode 100644 index 00000000..d8bb1140 --- /dev/null +++ b/packages/css-to-rn/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "name": "css-to-rn", + "main": "index.ts", + "dependencies": { + "lightningcss-wasm": "^1.22.1" + }, + "devDependencies": { + "@types/react-native": "^0.72.8" + } +} diff --git a/packages/css-to-rn/properties.ts b/packages/css-to-rn/properties.ts new file mode 100644 index 00000000..8562b35b --- /dev/null +++ b/packages/css-to-rn/properties.ts @@ -0,0 +1,162 @@ +import type {Declaration, PropertyId} from 'lightningcss-wasm'; + +export const invalidIdent = new Set(['auto', 'inherit']); + +export const validProperties = [ + 'background-color', + 'opacity', + 'color', + 'display', + 'width', + 'height', + 'min-width', + 'min-height', + 'max-width', + 'max-height', + 'block-size', + 'inline-size', + 'min-block-size', + 'min-inline-size', + 'max-block-size', + 'max-inline-size', + 'overflow', + 'position', + 'top', + 'bottom', + 'left', + 'right', + 'box-shadow', + 'inset-block-start', + 'inset-block-end', + 'inset-inline-start', + 'inset-inline-end', + 'inset-block', + 'inset-inline', + 'inset', + 'border-top-color', + 'border-bottom-color', + 'border-left-color', + 'border-right-color', + 'border-block-start-color', + 'border-block-end-color', + 'border-inline-start-color', + 'border-inline-end-color', + 'border-top-width', + 'border-bottom-width', + 'border-left-width', + 'border-right-width', + 'border-block-start-width', + 'border-block-end-width', + 'border-inline-start-width', + 'border-inline-end-width', + 'border-top-left-radius', + 'border-top-right-radius', + 'border-bottom-left-radius', + 'border-bottom-right-radius', + 'border-start-start-radius', + 'border-start-end-radius', + 'border-end-start-radius', + 'border-end-end-radius', + 'border-radius', + 'border-color', + 'border-style', + 'border-width', + 'border-block-color', + 'border-block-width', + 'border-inline-color', + 'border-inline-width', + 'border', + 'border-top', + 'border-bottom', + 'border-left', + 'border-right', + 'border-block', + 'border-block-start', + 'border-block-end', + 'border-inline', + 'border-inline-start', + 'border-inline-end', + 'flex-direction', + 'flex-wrap', + 'flex-flow', + 'flex-grow', + 'flex-shrink', + 'flex-basis', + 'flex', + 'align-content', + 'justify-content', + 'align-self', + 'align-items', + 'row-gap', + 'column-gap', + 'gap', + 'margin-top', + 'margin-bottom', + 'margin-left', + 'margin-right', + 'margin-block-start', + 'margin-block-end', + 'margin-inline-start', + 'margin-inline-end', + 'margin-block', + 'margin-inline', + 'margin', + 'padding-top', + 'padding-bottom', + 'padding-left', + 'padding-right', + 'padding-block-start', + 'padding-block-end', + 'padding-inline-start', + 'padding-inline-end', + 'padding-block', + 'padding-inline', + 'padding', + 'font-weight', + 'font-size', + 'font-family', + 'font-style', + 'font-variant-caps', + 'line-height', + 'font', + 'vertical-align', + 'transition-property', + 'transition-duration', + 'transition-delay', + 'transition-timing-function', + 'transition', + 'aspect-ratio', + 'animation-duration', + 'animation-timing-function', + 'animation-iteration-count', + 'animation-direction', + 'animation-play-state', + 'animation-delay', + 'animation-fill-mode', + 'animation-name', + 'animation', + 'transform', + 'translate', + 'rotate', + 'scale', + 'text-transform', + 'letter-spacing', + 'text-decoration-line', + 'text-decoration-color', + 'text-decoration', + 'text-shadow', + 'z-index', + 'container-type', + 'text-decoration-style', + 'container-name', + 'container', + 'text-align', +] as const; + +export const validPropertiesLoose = new Set(validProperties); + +export function isValid( + declaration: T, +): declaration is Extract { + return validPropertiesLoose.has(declaration.property); +} diff --git a/packages/css-to-rn/types/index.ts b/packages/css-to-rn/types/index.ts new file mode 100644 index 00000000..973171a9 --- /dev/null +++ b/packages/css-to-rn/types/index.ts @@ -0,0 +1,232 @@ +import type { + Time, + Animation, + EasingFunction, +} from 'lightningcss-wasm'; + +import type { + ViewStyle, + TextStyle, + ImageStyle, + Dimensions, + Appearance, + PerpectiveTransform, + RotateTransform, + RotateXTransform, + RotateYTransform, + RotateZTransform, + ScaleTransform, + ScaleXTransform, + ScaleYTransform, + TranslateXTransform, + TranslateYTransform, + SkewXTransform, + SkewYTransform, + MatrixTransform, +} from 'react-native'; + +export type CssToReactNativeOptions = { + inlineRem?: number | false; + ignorePropertyWarningRegex?: (string | RegExp)[]; +}; + +export interface ExtractRuleOptions extends CssToReactNativeOptions { + declarations: Map; + keyframes: Map; +} + +export type RuntimeValue = { + type: 'runtime'; + name: string; + arguments: any[]; +}; + +export type ExtractedStyleValue = + | string + | number + | RuntimeValue + | ExtractedStyleValue[] + | (() => ExtractedStyleValue); + +export type ExtractedStyle = { + isDynamic?: boolean; + variables?: Record; + prop?: [string, string | true]; + style: Record; + animations?: ExtractedAnimations; + transition?: ExtractedTransition; + requiresLayout?: boolean; + warnings?: ExtractionWarning[]; +}; + +export type StyleMeta = { + alreadyProcessed?: true; + variableProps?: Set; + variables?: Record; + animations?: ExtractedAnimations; + transition?: ExtractedTransition; + requiresLayout?: boolean; +}; + +export type ExtractedAnimations = { + [K in keyof Animation]?: Animation[K][]; +}; + +export type ExtractedTransition = { + /** + * The delay before the transition starts. + */ + delay?: Time[]; + /** + * The duration of the transition. + */ + duration?: Time[]; + /** + * The property to transition. + */ + property?: AnimatableCSSProperty[]; + /** + * The easing function for the transition. + */ + timingFunction?: EasingFunction[]; +}; + +export type ExtractedAnimation = { + frames: ExtractedKeyframe[]; + requiresLayout?: boolean; +}; + +export type ExtractedKeyframe = { + selector: number; + style: Record; +}; + +export type StyleSheetRegisterOptions = { + declarations?: Record; + keyframes?: Record; +}; + +export type Style = ViewStyle & TextStyle & ImageStyle; + +export type TransformRecord = Partial< + PerpectiveTransform & + RotateTransform & + RotateXTransform & + RotateYTransform & + RotateZTransform & + ScaleTransform & + ScaleXTransform & + ScaleYTransform & + TranslateXTransform & + TranslateYTransform & + SkewXTransform & + SkewYTransform & + MatrixTransform +>; + +export type CamelToKebabCase< + T extends string, + A extends string = '', +> = T extends `${infer F}${infer R}` + ? CamelToKebabCase ? '' : '-'}${Lowercase}`> + : A; + +export type KebabToCamelCase = + S extends `${infer P1}-${infer P2}${infer P3}` + ? `${Lowercase}${Uppercase}${KebabToCamelCase}` + : Lowercase; + +export interface ResetOptions { + dimensions?: Dimensions; + appearance?: typeof Appearance; +} + +export type ExtractionWarning = + | ExtractionWarningProperty + | ExtractionWarningValue + | ExtractionWarningFunctionValue; + +export type ExtractionWarningProperty = { + type: 'IncompatibleNativeProperty'; + property: string; +}; + +export type ExtractionWarningValue = { + type: 'IncompatibleNativeValue'; + property: string; + value: any; +}; + +export type ExtractionWarningFunctionValue = { + type: 'IncompatibleNativeFunctionValue'; + property: string; + value: any; +}; + +/* + * This is a list of all the CSS properties that can be animated + * Source: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties + */ +export type AnimatableCSSProperty = (keyof Style | 'fill' | 'stroke') & + KebabToCamelCase< + | 'background-color' + | 'border-bottom-color' + | 'border-bottom-left-radius' + | 'border-bottom-right-radius' + | 'border-bottom-width' + | 'border-color' + | 'border-left-color' + | 'border-left-width' + | 'border-radius' + | 'border-right-color' + | 'border-right-width' + | 'border-top-color' + | 'border-top-width' + | 'border-width' + | 'bottom' + | 'color' + | 'fill' + | 'flex' + | 'flex-basis' + | 'flex-grow' + | 'flex-shrink' + | 'font-size' + | 'font-weight' + | 'gap' + | 'height' + | 'left' + | 'letter-spacing' + | 'line-height' + | 'margin' + | 'margin-bottom' + | 'margin-left' + | 'margin-right' + | 'margin-top' + | 'max-height' + | 'max-width' + | 'min-height' + | 'min-width' + | 'object-position' + | 'opacity' + | 'order' + | 'padding' + | 'padding-bottom' + | 'padding-left' + | 'padding-right' + | 'padding-top' + | 'right' + | 'rotate' + | 'scale' + | 'stroke' + | 'text-decoration' + | 'text-decoration-color' + | 'top' + | 'transform' + | 'transform-origin' + | 'translate' + | 'vertical-align' + | 'visibility' + | 'width' + | 'word-spacing' + | 'z-index' + >; diff --git a/packages/css-to-rn/types/parse.ts b/packages/css-to-rn/types/parse.ts new file mode 100644 index 00000000..367408f7 --- /dev/null +++ b/packages/css-to-rn/types/parse.ts @@ -0,0 +1,43 @@ +import type {Declaration} from 'lightningcss-wasm'; +import type {ExtractionWarning} from './index'; + +export interface ParseDeclarationOptions { + inlineRem?: number | false; + addStyleProp: AddStyleProp; + handleStyleShorthand: HandleStyleShorthand; + addAnimationProp: AddAnimationDefaultProp; + addTransitionProp: AddTransitionProp; + addWarning: AddWarning; + requiresLayout: () => void; +} + +export interface ParseDeclarationOptionsWithValueWarning extends ParseDeclarationOptions { + addValueWarning: (value: any) => undefined; + addFunctionValueWarning: (value: any) => undefined; +} + +export type AddWarning = (warning: ExtractionWarning) => undefined; +export type AddAnimationDefaultProp = (property: string, value: unknown[]) => void; + +export type AddStyleProp = ( + property: string, + value: unknown, + options?: { + shortHand?: boolean; + append?: boolean; + }, +) => void; + +export type HandleStyleShorthand = ( + property: string, + options: Record, +) => void; + +export type AddTransitionProp = (declaration: Extract) => void; diff --git a/packages/css-to-rn/utils.ts b/packages/css-to-rn/utils.ts new file mode 100644 index 00000000..454e6774 --- /dev/null +++ b/packages/css-to-rn/utils.ts @@ -0,0 +1,44 @@ +export function round(number: number) { + return Math.round((number + Number.EPSILON) * 100) / 100; +} + +export function kebabToCamelCase(str: string) { + if (str.startsWith('-rn-')) { + str = str.slice('-rn-'.length); + } + return str.replace(/-./g, (x) => x[1].toUpperCase()); +} + +export function allEqual(...params: unknown[]) { + return params.every((param, index, array) => { + return index === 0 ? true : equal(array[0], param); + }); +} + +export function equal(a: unknown, b: unknown) { + if (a === b) return true; + if (typeof a !== typeof b) return false; + if (a === null || b === null) return false; + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; i++) { + if (!equal(a[i], b[i])) return false; + } + return true; + } + if (typeof a === "object" && typeof b === "object") { + if (Object.keys(a).length !== Object.keys(b).length) return false; + for (const key in a) { + if ( + !equal( + (a as Record)[key], + (b as Record)[key], + ) + ) + return false; + } + return true; + } + + return false; +} diff --git a/packages/exo-primitives/README.md b/packages/exo-primitives/README.md new file mode 100644 index 00000000..3ec5501e --- /dev/null +++ b/packages/exo-primitives/README.md @@ -0,0 +1 @@ +TODO: move to monorepo \ No newline at end of file diff --git a/build-figma-plugin.main.js b/packages/figma-to-react-native/build-figma-plugin.main.js similarity index 100% rename from build-figma-plugin.main.js rename to packages/figma-to-react-native/build-figma-plugin.main.js diff --git a/build-figma-plugin.manifest.js b/packages/figma-to-react-native/build-figma-plugin.manifest.js similarity index 100% rename from build-figma-plugin.manifest.js rename to packages/figma-to-react-native/build-figma-plugin.manifest.js diff --git a/packages/figma-to-react-native/build-figma-plugin.ui.js b/packages/figma-to-react-native/build-figma-plugin.ui.js new file mode 100644 index 00000000..c152c9cf --- /dev/null +++ b/packages/figma-to-react-native/build-figma-plugin.ui.js @@ -0,0 +1,42 @@ +const fs = require('fs').promises; +const {NodeModulesPolyfillPlugin} = require('@esbuild-plugins/node-modules-polyfill'); + +// @ts-check +/** + * @param buildOptions {Partial} + * @returns {Partial} + */ +module.exports = (buildOptions) => { + return { + ...buildOptions, + target: 'es2020', + plugins: [ + ...buildOptions.plugins, + NodeModulesPolyfillPlugin({ + path: true, + }), + // Hack: replace \22EF with \x12 + // Legacy octal escape sequences cannot be used in template literals + // Caused by y-monaco loading folding.js + { + name: 'fix-y-monaco', + setup(ctx) { + ctx.onLoad({filter: /folding\.js$/}, async (args) => { + const contents = await fs.readFile(args.path, 'utf8'); + const sanitized = contents.replace(/\\22EF/g, '\\x12'); + return { + contents: sanitized, + loader: 'js', + }; + }); + }, + }, + ], + loader: { + '.tpl': 'base64', + }, + define: { + global: 'window', + }, + }; +} diff --git a/packages/figma-to-react-native/package.json b/packages/figma-to-react-native/package.json new file mode 100644 index 00000000..2c14720b --- /dev/null +++ b/packages/figma-to-react-native/package.json @@ -0,0 +1,81 @@ +{ + "private": true, + "name": "figma-plugin", + "license": "GPL-3.0", + "scripts": { + "dev": "build-figma-plugin --watch", + "build": "build-figma-plugin --typecheck --minify", + "schema": "typescript-json-schema tsconfig.json Settings --out ./src/interface/utils/editor/schemas/settings.json" + }, + "figma-plugin": { + "id": "821138713091291738", + "name": "Figma -> React Native", + "networkAccess": { + "allowedDomains": [ + "*" + ], + "reasoning": "Needed for Monaco Editor blob workers to load" + }, + "permissions": [ + "currentuser" + ], + "editorType": [ + "figma", + "dev" + ], + "capabilities": [ + "codegen", + "inspect", + "vscode" + ], + "main": "src/main.ts", + "ui": "src/ui.tsx" + }, + "dependencies": { + "css-to-rn": "workspace:*", + "@create-figma-plugin/ui": "^2.6.1", + "@create-figma-plugin/utilities": "^2.6.1", + "@iconify/react": "^4.1.1", + "@logtail/browser": "^0.4.18", + "@monaco-editor/react": "^4.6.0", + "@radix-ui/react-tabs": "^1.0.4", + "@uidotdev/usehooks": "^2.4.1", + "@uppy/core": "^3.7.1", + "@uppy/tus": "^3.4.0", + "@y-sweet/client": "^0.1.0", + "@y-sweet/react": "^0.1.0", + "blakejs": "^1.2.1", + "client-zip": "^2.4.4", + "code-block-writer": "^12.0.0", + "constrained-editor-plugin": "^1.3.0", + "deep-object-diff": "^1.1.9", + "esbuild-wasm": "^0.17.19", + "fzf": "^0.5.2", + "lib0": "^0.2.88", + "lodash.camelcase": "^4.3.0", + "monaco-editor": "^0.44.0", + "monaco-editor-auto-typings": "^0.4.5", + "preact": "^10.18.1", + "react-photo-album": "^2.3.0", + "react-virtuoso": "^4.6.2", + "reserved": "^0.1.2", + "y-protocols": "^1.0.6", + "y-webrtc": "^10.2.6", + "yjs": "^13.6.10" + }, + "devDependencies": { + "@create-figma-plugin/build": "^2.6.1", + "@create-figma-plugin/tsconfig": "^2.6.1", + "@esbuild-plugins/node-modules-polyfill": "^0.2.2", + "@figma/plugin-typings": "1.82.0", + "@types/lodash.camelcase": "^4.3.9", + "@types/react": "^18.2.41", + "esbuild": "^0.17.19", + "react-zoom-pan-pinch": "^3.3.0", + "typescript": "^4.9.5", + "typescript-json-schema": "^0.62.0" + }, + "browser": { + "crypto": false + } +} diff --git a/packages/figma-to-react-native/src/common/assert.ts b/packages/figma-to-react-native/src/common/assert.ts new file mode 100644 index 00000000..243eec92 --- /dev/null +++ b/packages/figma-to-react-native/src/common/assert.ts @@ -0,0 +1,40 @@ +export function areMapsEqual(map1: Map, map2: Map): boolean { + // Check if the maps have the same size + if (map1.size !== map2.size) { + return false; + } + + // Iterate over each key-value pair in the first map + for (const [key, value] of map1) { + // Check if the second map has the same key + if (!map2.has(key)) { + return false; + } + + // Check if the values associated with the key are equal + if (map2.get(key) !== value) { + return false; + } + } + + // If all checks passed, the maps are equal + return true; +} + +export function areSetsEqual(set1: Set, set2: Set): boolean { + // Check if the sets have the same size + if (set1.size !== set2.size) { + return false; + } + + // Iterate over each element in the first set + for (const element of set1) { + // Check if the second set contains the same element + if (!set2.has(element)) { + return false; + } + } + + // If all checks passed, the sets are equal + return true; +} diff --git a/src/common/delay.ts b/packages/figma-to-react-native/src/common/delay.ts similarity index 100% rename from src/common/delay.ts rename to packages/figma-to-react-native/src/common/delay.ts diff --git a/src/common/string.ts b/packages/figma-to-react-native/src/common/string.ts similarity index 100% rename from src/common/string.ts rename to packages/figma-to-react-native/src/common/string.ts diff --git a/src/config/env.ts b/packages/figma-to-react-native/src/config/env.ts similarity index 56% rename from src/config/env.ts rename to packages/figma-to-react-native/src/config/env.ts index e78aa46b..ee23e347 100644 --- a/src/config/env.ts +++ b/packages/figma-to-react-native/src/config/env.ts @@ -1,11 +1,21 @@ -export const F2RN_CONFIG_NS = 'f2rn:config:v1'; -export const F2RN_PROJECT_NS = 'f2rn:project:v1'; -export const F2RN_NAVIGATE_NS = 'f2rn:navigate:v1'; +export const F2RN_UI_WIDTH_MIN = 249; + +export const F2RN_EDITOR_NS = 'figma://preview/'; +export const F2RN_CONFIG_NS = 'f2rn:config:v3'; +export const F2RN_PROJECT_NS = 'f2rn:project:v3'; +export const F2RN_NAVIGATE_NS = 'f2rn:navigate:v3'; export const F2RN_STYLEGEN_API = 'https://f2rn.deno.dev'; export const SUPABASE_PROJECT_URL = 'http://localhost:54321'; // 'https://ndfwacmspvrwdiqqeecz.supabase.co'; export const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0'; // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im5kZndhY21zcHZyd2RpcXFlZWN6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTUyODA0MDYsImV4cCI6MjAxMDg1NjQwNn0.1ZfkWFCp20pYVU0d9ggmaIe36lFbZFYmOP_bXgtrHxI'; -export const TIPTAP_APP_ID = 'l89jn3k7'; - export const LOGTAIL_TOKEN = '3hRzjtVJTBk6BDFt3pSjjKam'; + +export const UNISTYLES_LIB = `import {createUnistyles} from 'react-native-unistyles'; +import theme, {breakpoints} from 'theme'; + +export const {createStyleSheet, useStyles} = createUnistyles< + typeof breakpoints, + typeof theme +>(breakpoints); +`; diff --git a/src/config/project.ts b/packages/figma-to-react-native/src/config/project.ts similarity index 92% rename from src/config/project.ts rename to packages/figma-to-react-native/src/config/project.ts index df7fd3a5..49c0c671 100644 --- a/src/config/project.ts +++ b/packages/figma-to-react-native/src/config/project.ts @@ -8,7 +8,7 @@ const config: ProjectConfig = { isPackage: false, packageName: '', packageVersion: '', - includeFrames: false, + includeAssets: true, enableAssetOptimizations: false, enableAutoTranslations: false, }; diff --git a/src/config/user.ts b/packages/figma-to-react-native/src/config/user.ts similarity index 81% rename from src/config/user.ts rename to packages/figma-to-react-native/src/config/user.ts index 020f73b6..64834a3d 100644 --- a/src/config/user.ts +++ b/packages/figma-to-react-native/src/config/user.ts @@ -3,7 +3,6 @@ import type {Settings} from 'types/settings'; const user: Settings = { react: { flavor: 'react-native', - styleGen: 'default', addTranslate: false, }, writer: { @@ -20,9 +19,7 @@ const user: Settings = { } }, esbuild: { - loader: 'tsx', format: 'esm', - define: {'process.env.NODE_ENV': 'development'}, }, }; diff --git a/packages/figma-to-react-native/src/env.d.ts b/packages/figma-to-react-native/src/env.d.ts new file mode 100644 index 00000000..f1de2313 --- /dev/null +++ b/packages/figma-to-react-native/src/env.d.ts @@ -0,0 +1,4 @@ +declare module '*.tpl' { + const content: string; + export default content; +} diff --git a/packages/figma-to-react-native/src/interface/App.tsx b/packages/figma-to-react-native/src/interface/App.tsx new file mode 100644 index 00000000..b80178df --- /dev/null +++ b/packages/figma-to-react-native/src/interface/App.tsx @@ -0,0 +1,131 @@ +import {h} from 'preact'; +import {useState, useEffect} from 'preact/hooks'; +import {Tabs, Tab} from 'interface/base/Tabs'; +import {NavBar} from 'interface/base/NavBar'; + +import {ComponentCode} from 'interface/views/ComponentCode'; +import {ComponentStory} from 'interface/views/ComponentStory'; +import {ComponentPreview} from 'interface/views/ComponentPreview'; + +import {ProjectTheme} from 'interface/views/ProjectTheme'; +import {ProjectIcons} from 'interface/views/ProjectIcons'; +import {ProjectAssets} from 'interface/views/ProjectAssets'; +import {ProjectExport} from 'interface/views/ProjectExport'; +import {ProjectSettings} from 'interface/views/ProjectSettings'; +import {ProjectComponents} from 'interface/views/ProjectComponents'; + +import {useBuild} from 'interface/hooks/useBuild'; +import {useEditor} from 'interface/hooks/useEditor'; +import {useDarkMode} from 'interface/hooks/useDarkMode'; +import {useNavigation} from 'interface/hooks/useNavigation'; +import {useUserSettings} from 'interface/hooks/useUserSettings'; +import {useProjectTheme} from 'interface/hooks/useProjectTheme'; +import {useProjectIcons} from 'interface/hooks/useProjectIcons'; +import {useProjectConfig} from 'interface/hooks/useProjectConfig'; +import {useStyleGenServer} from 'interface/hooks/useStyleGenServer'; + +import * as F from '@create-figma-plugin/ui'; + +import type {AppPages, AppTabs} from 'types/app'; + +interface AppProps { + startPage: AppPages | null, + isDevMode: boolean, + isVSCode: boolean, +} + +const tabs: AppTabs = { + main: [ + 'components', + 'icons', + // 'assets', + 'theme', + 'settings', + 'export', + ], + component: [ + 'code', + 'preview', + 'story', + ], +}; + +export function App(props: AppProps) { + const {isDevMode, isVSCode} = props; + const [searchMode, setSearchMode] = useState(false); + const [searchQuery, setSearchQuery] = useState(''); + + const build = useBuild(); + const theme = useProjectTheme(); + const icons = useProjectIcons(); + const project = useProjectConfig(); + const settings = useUserSettings(); + const monaco = useEditor(settings.config, build.links); + const nav = useNavigation(build); + const isDark = useDarkMode(); + + const isReady = Boolean(props.startPage && project && monaco); + const isReadOnly = isDevMode || isVSCode; + const componentKey = build.roster[nav.component] ? nav.component: null; + const options = { + ...settings.config.monaco.general, + tabSize: settings.config.writer.indentNumberOfSpaces, + theme: isDark ? 'vs-dark' : 'vs', + }; + + // Start style gen server + useStyleGenServer(); + + // Go to overview when viewing a component that doesn't exist + useEffect(() => { + if (!componentKey && nav.component) { + nav.gotoOverview(); + } + }, [componentKey, nav]); + + return isReady ? ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) : ( +
+ +
+ ); +} diff --git a/packages/figma-to-react-native/src/interface/base/NavBar.tsx b/packages/figma-to-react-native/src/interface/base/NavBar.tsx new file mode 100644 index 00000000..eb25d97c --- /dev/null +++ b/packages/figma-to-react-native/src/interface/base/NavBar.tsx @@ -0,0 +1,166 @@ +import {h, Fragment} from 'preact'; +import {useEffect, useState} from 'preact/hooks'; +import {useWindowSize} from "@uidotdev/usehooks"; +import {Bar, Link} from 'interface/base/Tabs'; +import {SearchBar} from 'interface/base/SearchBar'; +import {patch, actions} from 'interface/utils/editor/lib/patch'; +import {titleCase} from 'common/string'; + +import * as F from '@create-figma-plugin/ui'; + +import type {StateUpdater} from 'preact/hooks'; +import type {ComponentBuild} from 'types/component'; +import type {AppTabs, AppPages, AppPagesMain} from 'types/app'; +import type {Navigation} from 'interface/hooks/useNavigation'; + +interface NavBarProps { + nav: Navigation, + tabs: AppTabs, + build: ComponentBuild, + isVSCode: boolean, + setSearchQuery: StateUpdater, + setSearchMode: StateUpdater, + searchQuery: string, + searchMode: boolean, +} + +export function NavBar(props: NavBarProps) { + const {width} = useWindowSize(); + const [mainTabs, setMainTabs] = useState>([]); + + const hasTarget = Boolean(props.nav.component); + const hasChanges = false; + const hasDropModMenu = !hasTarget; + const isTargetInRoster = hasTarget && props.build.roster[props.nav.component]; + const hasDropModTargetUnsaved = hasTarget && hasChanges; + const classMenu = hasDropModMenu + ? 'drop-mod-menu' + : hasDropModTargetUnsaved + ? 'drop-mod-target-unsaved' + : hasTarget + ? 'drop-mod-target' + : ''; + + const menuMainExt: Array = props.tabs.main + .filter(page => !mainTabs.includes(page)) + .map(value => ({ + value, + text: titleCase(value.toString(), + )}) as F.DropdownOption); + + const menuComponent: Array = Object + .entries(props.build.roster) + .sort(([,a], [,b]) => a.name.localeCompare(b.name)) + .map(([name, component]) => ({ + value: name, + text: component.name, + disabled: component.loading, + })); + + const menuComponentUnsaved: Array = actions.map(action => ({ + value: action, + text: titleCase(action), + })); + + useEffect(() => { + const tabs: Array = []; + let spaceLeft = width - 100; + let i = 0; + for (const name of props.tabs.main) { + const tab = (16.5 + name.length * 5.5); + const mod = i === props.tabs.main.length - 1 + ? tab - 40 + : i === 2 + ? tab - 17 + : tab; + if (mod < spaceLeft) { + tabs.push(name); + spaceLeft -= tab; + i++; + } else { + break; + } + } + setMainTabs(tabs); + }, [props.tabs, width]); + + return ( +
+ + {hasTarget + ?
+
+ +
+ {props.tabs.component + .map(page => ( + + + {titleCase(page.toString())} + + + ))} +
+ : + {props.searchMode + ? + :
+
props.setSearchMode(true)}> + +
+ {mainTabs.map(page => ( + + + {titleCase(page.toString())} + + + ))} +
+ } +
+ } +
+ {!hasTarget && !props.searchMode && menuMainExt.length > 0 && + } + onChange={(e) => props.nav.gotoTab(e.currentTarget.value as AppPages)} + /> + } + {hasTarget && !hasChanges && + } + onChange={(e) => props.nav.setComponent(e.currentTarget.value)} + /> + } + {hasTarget && hasChanges && + } + onChange={(e) => patch(e.currentTarget.value)} + /> + } +
+ ); +} diff --git a/packages/figma-to-react-native/src/interface/base/ProgressBar.tsx b/packages/figma-to-react-native/src/interface/base/ProgressBar.tsx new file mode 100644 index 00000000..ad281cb4 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/base/ProgressBar.tsx @@ -0,0 +1,29 @@ +import {h} from 'preact'; +import {Container} from '@create-figma-plugin/ui'; + +interface ProgressBarProps { + percent: string, +} + +export function ProgressBar(props: ProgressBarProps) { + return ( + +
+
+
+ + ); +} diff --git a/packages/figma-to-react-native/src/interface/base/ScreenInfo.tsx b/packages/figma-to-react-native/src/interface/base/ScreenInfo.tsx new file mode 100644 index 00000000..613129c9 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/base/ScreenInfo.tsx @@ -0,0 +1,22 @@ +import {h} from 'preact'; +import {Container, Muted, IconNotice32} from '@create-figma-plugin/ui'; + +interface ScreenInfoProps { + message: string, + action?: JSX.Element, +} + +export function ScreenInfo(props: ScreenInfoProps) { + return ( + +
+ + {props.message} +
+ {props.action} +
+ ); +} diff --git a/packages/figma-to-react-native/src/interface/base/ScreenWarning.tsx b/packages/figma-to-react-native/src/interface/base/ScreenWarning.tsx new file mode 100644 index 00000000..35866206 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/base/ScreenWarning.tsx @@ -0,0 +1,15 @@ +import {h} from 'preact'; +import {Container, Muted, IconWarning32} from '@create-figma-plugin/ui'; + +interface ScreenWarningProps { + message: string, +} + +export function ScreenWarning(props: ScreenWarningProps) { + return ( + + + {props.message} + + ); +} diff --git a/packages/figma-to-react-native/src/interface/base/SearchBar.tsx b/packages/figma-to-react-native/src/interface/base/SearchBar.tsx new file mode 100644 index 00000000..19c8b50f --- /dev/null +++ b/packages/figma-to-react-native/src/interface/base/SearchBar.tsx @@ -0,0 +1,34 @@ +import {h, Fragment} from 'preact'; +import {SearchTextbox, IconButton, IconCross32} from '@create-figma-plugin/ui'; + +interface SearchBarProps { + searchQuery: string, + setSearchQuery: (value: string) => void, + setSearchMode: (value: boolean) => void, +} + +export function SearchBar(props: SearchBarProps) { + return ( + + { + const {value} = e.currentTarget; + props.setSearchQuery(value); + if (!value) { + props.setSearchMode(false); + } + }} + /> + {!Boolean(props.searchQuery) && + props.setSearchMode(false)}> + + + } + + ); +} diff --git a/packages/figma-to-react-native/src/interface/base/StatusBar.tsx b/packages/figma-to-react-native/src/interface/base/StatusBar.tsx new file mode 100644 index 00000000..bee2a936 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/base/StatusBar.tsx @@ -0,0 +1,31 @@ +import {h} from 'preact'; +import * as F from '@create-figma-plugin/ui'; + +import type {ProjectConfig} from 'types/project'; +import type {ComponentBuild} from 'types/component'; + +interface StatusBarProps { + build: ComponentBuild, + project: ProjectConfig, + setTarget: (value: string) => void, +} + +export function StatusBar(props: StatusBarProps) { + const assetCount = props.build.assets ? Object.keys(props.build.assets).length : 0; + const isFullyLoaded = true; // props.build.loaded === props.build.total; + const textComponents = `${props.build.total} component${props.build.total === 1 ? '' : 's'}`; + const textAssets = `${assetCount} asset${assetCount === 1 ? '' : 's'}`; + return ( +
+ {isFullyLoaded + ?
+ {textComponents} + {textAssets} +
+ :
+ {`Loading components... [${props.build.loaded}/${props.build.total}]`} +
+ } +
+ ); +} diff --git a/packages/figma-to-react-native/src/interface/base/Tabs.tsx b/packages/figma-to-react-native/src/interface/base/Tabs.tsx new file mode 100644 index 00000000..201da33a --- /dev/null +++ b/packages/figma-to-react-native/src/interface/base/Tabs.tsx @@ -0,0 +1,46 @@ +import {h} from 'preact'; +import {Root, List, Trigger, Content} from '@radix-ui/react-tabs'; + +import type { + TabsProps as TabsBaseProps, + TabsListProps, + TabsTriggerProps, + TabsContentProps, +} from '@radix-ui/react-tabs'; + +interface TabsProps extends TabsBaseProps { + children: JSX.Element[], +} + +export function Tabs(props: TabsProps) { + // @ts-ignore Preact issue + return ; +} + +interface BarProps extends TabsListProps { + children: any, +} + +export function Bar(props: BarProps) { + // @ts-ignore Preact issue + return ; +} + +interface LinkProps extends TabsTriggerProps { + children: JSX.Element | string; + hasIcon?: boolean; +} + +export function Link(props: LinkProps) { + // @ts-ignore Preact issue + return ; +} + +interface TabProps extends TabsContentProps { + children: JSX.Element, +} + +export function Tab(props: TabProps) { + // @ts-ignore Preact issue + return ; +} diff --git a/src/interface/css/default.css b/packages/figma-to-react-native/src/interface/css/default.css similarity index 57% rename from src/interface/css/default.css rename to packages/figma-to-react-native/src/interface/css/default.css index 62f16889..02ea6ac9 100644 --- a/src/interface/css/default.css +++ b/packages/figma-to-react-native/src/interface/css/default.css @@ -112,13 +112,47 @@ iframe { flex: 1; } -.tab-bar { - padding: 4px 5px; +.tab-menu { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + background-color: var(--figma-color-bg); border-bottom: 1px solid var(--figma-color-border); - z-index: 5; +} + +.tab-bar { + display: flex; + overflow-x: auto; + overflow-y: hidden; + flex-direction: row; + flex-shrink: 0; + flex-grow: 1; +} + +.tab-bar > div { + width: 100%; +} + +.tab-bar-nav { display: flex; + align-items: center; flex-direction: row; overflow: auto; + padding: 4px; + padding-right: 0; +} + +.tab-bar-nav .tab[title="Project Components"] { + padding-left: 2px; +} + +.tab-bar-nav .tab[title="Component Code"] { + padding-left: 6px; +} + +.tab-bar-nav .tab[title="Component Story"] { + margin-right: 6px; } .tab { @@ -154,7 +188,128 @@ iframe { opacity: 1; } +.tab-btn { + width: 32; + height: 32; + padding: 0; + border: 0; + opacity: 0.6; + border-radius: 2px; + display: flex; + background: none; + justify-content: center; + align-items: center; +} + +.tab-btn:hover { + background-color: var(--figma-color-bg-pressed); + opacity: 1; +} + .tab-view { flex: 1; overflow: auto; } + +/* Status Bar */ + +.status-bar { + width: 100%; + height: 27px; + padding-right: 10px; + z-index: 99999; + gap: 8px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + border-top: 1px solid var(--figma-color-border); + background-color: var(--figma-color-bg); +} + +.status-actions { + display: flex; + padding-left: 10px; + flex-direction: row; + align-items: center; + gap: 10px; +} + +/* Component */ + +.components { + display: flex; + flex-direction: row; + align-items: center; + margin: 0px; +} + +/* Disclosure override */ +.components > div { + padding: 0; + width: 100%; +} + +.component { + background-color: #000000; + border-radius: 4px; + height: 120px; + width: 200px; +} + +.components label { + width: 100%; +} + +.components .highlight { + text-decoration: underline; + font-weight: 600; +} + +/* Dropdowns */ + +/* Positioning menu dropdown */ +.drop-mod-menu [class*="_dropdown_"] { + width: 32px; + margin-right: 5px; + align-self: center; +} + +/* Positioning target dropdown */ +.drop-mod-target [class*="_dropdown_"], +.drop-mod-target-unsaved [class*="_dropdown_"] { + width: auto; + margin-right: 8px; + align-self: center; +} + +/* Status icon padding removed for unsaved target */ +.drop-mod-target-unsaved [class*="_optionValue_"] { + padding: 4px var(--space-medium); +} + +/* Text changed for target */ +.drop-mod-target [class*="_dropdown_"] { + color: var(--figma-color-text-component); +} + +/* Text changed for unsaved target */ +.drop-mod-target-unsaved [class*="_dropdown_"] { + color: var(--figma-color-icon-warning); +} + +/* Placeholder text changed for unsaved target */ +.drop-mod-target-unsaved [class*="_placeholder_"] { + color: var(--figma-color-icon-warning); +} + +/* Status chevron icon removed for menu */ +.drop-mod-menu [class*="_chevronIcon_"] { + display: none; +} + +/* Virtual List */ +.virtuoso-grid-list { + display: flex; + flex-flow: wrap; +} diff --git a/packages/figma-to-react-native/src/interface/css/default.css.d.ts b/packages/figma-to-react-native/src/interface/css/default.css.d.ts new file mode 100644 index 00000000..f0b40d32 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/css/default.css.d.ts @@ -0,0 +1,22 @@ +declare const styles: { + readonly "create-figma-plugin": string; + readonly "tabs": string; + readonly "tab-menu": string; + readonly "tab-bar": string; + readonly "tab-bar-nav": string; + readonly "tab": string; + readonly "icon": string; + readonly "tab-btn": string; + readonly "tab-view": string; + readonly "status-bar": string; + readonly "status-actions": string; + readonly "components": string; + readonly "component": string; + readonly "highlight": string; + readonly "drop-mod-menu": string; + readonly "drop-mod-target": string; + readonly "drop-mod-target-unsaved": string; + readonly "virtuoso-grid-list": string; +}; +export = styles; + diff --git a/src/interface/css/editor.css b/packages/figma-to-react-native/src/interface/css/editor.css similarity index 100% rename from src/interface/css/editor.css rename to packages/figma-to-react-native/src/interface/css/editor.css diff --git a/src/interface/css/editor.css.d.ts b/packages/figma-to-react-native/src/interface/css/editor.css.d.ts similarity index 100% rename from src/interface/css/editor.css.d.ts rename to packages/figma-to-react-native/src/interface/css/editor.css.d.ts diff --git a/src/interface/css/plugin.css b/packages/figma-to-react-native/src/interface/css/plugin.css similarity index 100% rename from src/interface/css/plugin.css rename to packages/figma-to-react-native/src/interface/css/plugin.css diff --git a/src/interface/css/plugin.css.d.ts b/packages/figma-to-react-native/src/interface/css/plugin.css.d.ts similarity index 100% rename from src/interface/css/plugin.css.d.ts rename to packages/figma-to-react-native/src/interface/css/plugin.css.d.ts diff --git a/packages/figma-to-react-native/src/interface/hooks/useBuild.ts b/packages/figma-to-react-native/src/interface/hooks/useBuild.ts new file mode 100644 index 00000000..5610fa7f --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useBuild.ts @@ -0,0 +1,40 @@ +import {useState, useEffect} from 'preact/hooks'; +import {on} from '@create-figma-plugin/utilities'; +import * as $ from 'interface/store'; + +import type {EventComponentBuild} from 'types/events'; +import type {ComponentBuild} from 'types/component'; + +const initial: ComponentBuild = { + loaded: 0, + total: 0, + index: '', + pages: [], + links: {}, + roster: {}, + assets: {}, + assetMap: {}, + icons: [], +}; + +export function useBuild(): ComponentBuild { + const [build, setBuild] = useState(initial); + + useEffect(() => on('COMPONENT_BUILD', (newBuild, component) => { + setBuild(newBuild); + $.doc.transact(() => { + $.setProjectIndex(newBuild.index); + $.setProjectFiles(Object.keys(newBuild.roster)); + $.setComponentCode(component.key, component.code); + $.setComponentIndex(component.key, component.index); + $.setComponentStory(component.key, component.story); + Object.values(build.assets).forEach(asset => + $.assets.set(`${asset.name}.${asset.isVector ? 'svg' : 'png'}`, asset.bytes)); + const {id, key, name, page, props, width, height} = component; + $.components.set(component.key, {id, key, name, page, props, width, height}); + }); + // console.log('[build]', component.name, newBuild); + }), []); + + return build; +} diff --git a/src/interface/hooks/useDarkMode.ts b/packages/figma-to-react-native/src/interface/hooks/useDarkMode.ts similarity index 99% rename from src/interface/hooks/useDarkMode.ts rename to packages/figma-to-react-native/src/interface/hooks/useDarkMode.ts index b63de9d6..0f59b074 100644 --- a/src/interface/hooks/useDarkMode.ts +++ b/packages/figma-to-react-native/src/interface/hooks/useDarkMode.ts @@ -3,11 +3,13 @@ import {useRef, useState, useEffect} from 'preact/hooks'; 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/packages/figma-to-react-native/src/interface/hooks/useEditor.ts b/packages/figma-to-react-native/src/interface/hooks/useEditor.ts new file mode 100644 index 00000000..64b63504 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useEditor.ts @@ -0,0 +1,27 @@ +import {useMonaco} from '@monaco-editor/react'; +import {useEffect} from 'preact/hooks'; +import * as lib from 'interface/utils/editor'; + +import type {Settings} from 'types/settings'; +import type {ComponentLinks} from 'types/component'; + +export function useEditor(settings: Settings, links?: ComponentLinks) { + const monaco = useMonaco(); + + useEffect(() => { + if (!monaco) return; + return lib.initFileOpener(monaco, links); + }, [monaco, links]); + + useEffect(() => { + if (!monaco) return; + lib.initSettingsSchema(monaco); + }, [monaco]); + + useEffect(() => { + if (!monaco) return; + lib.initTypescript(monaco, settings); + }, [monaco, settings]); + + return monaco; +} diff --git a/packages/figma-to-react-native/src/interface/hooks/useNavigation.ts b/packages/figma-to-react-native/src/interface/hooks/useNavigation.ts new file mode 100644 index 00000000..95a67006 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useNavigation.ts @@ -0,0 +1,54 @@ +import {emit, on} from '@create-figma-plugin/utilities'; +import {useState, useEffect} from 'preact/hooks'; + +import type {StateUpdater} from 'preact/hooks'; +import type {ComponentBuild} from 'types/component'; +import type {EventAppNavigate, EventFocusNode, EventSelectComponent} from 'types/events'; +import type {AppPages} from 'types/app'; + +export interface Navigation { + tab: AppPages, + component: string, + setComponent: StateUpdater, + gotoOverview: () => void, + gotoTab: (value: AppPages) => void, +} + +export function useNavigation(build: ComponentBuild) { + const [tab, setTab] = useState('components'); + const [component, setComponent] = useState(null); + + const isComponentTab = (tab: AppPages) => + tab === 'code' + || tab === 'preview' + || tab === 'story'; + + const gotoOverview = () => { + setTab('components'); + setComponent(null); + emit('FOCUS', null); + }; + + const gotoTab = (value: AppPages) => { + setTab(value); + if (!isComponentTab(value)) + setComponent(null); + emit('APP_NAVIGATE', value); + }; + + useEffect(() => on('SELECT_COMPONENT', (key) => { + if (build?.roster?.[key] !== undefined) { + setComponent(key); + if (!isComponentTab(tab)) + setTab('code'); + } + }), [build, tab]); + + return { + tab, + component, + setComponent, + gotoOverview, + gotoTab, + }; +} diff --git a/packages/figma-to-react-native/src/interface/hooks/useProjectBuild.ts b/packages/figma-to-react-native/src/interface/hooks/useProjectBuild.ts new file mode 100644 index 00000000..01585ba9 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useProjectBuild.ts @@ -0,0 +1,38 @@ +import {useEffect} from 'preact/hooks'; +import {on} from '@create-figma-plugin/utilities'; +import {log} from 'interface/telemetry'; +import {upload} from 'interface/utils/exporter/upload'; +import {download} from 'interface/utils/exporter/download'; + +import type {StateUpdater} from 'preact/hooks'; +import type {EventProjectBuild} from 'types/events'; + +export function useProjectBuild( + onSuccess: () => void, + onError: () => void, + setExportCount: StateUpdater, +): void { + useEffect(() => on('PROJECT_BUILD', async (project, config, user) => { + if (project === null) { + onError(); + return; + } + const assets = project.assets.length; + const components = project.components.length; + switch (config.method) { + case 'download': + download(project, config); + break; + case 'release': + upload(project, config); + break; + case 'preview': + const url = 'http://127.0.0.1:5102'; // 'https://fig.run'; + open(`${url}/#/${project.id}`); + break; + } + onSuccess(); + setExportCount(components); + log(`export_${config.method}_complete`, {components, assets}); + }), []); +} diff --git a/src/interface/hooks/useProjectConfig.ts b/packages/figma-to-react-native/src/interface/hooks/useProjectConfig.ts similarity index 100% rename from src/interface/hooks/useProjectConfig.ts rename to packages/figma-to-react-native/src/interface/hooks/useProjectConfig.ts diff --git a/packages/figma-to-react-native/src/interface/hooks/useProjectIcons.ts b/packages/figma-to-react-native/src/interface/hooks/useProjectIcons.ts new file mode 100644 index 00000000..36122cb0 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useProjectIcons.ts @@ -0,0 +1,19 @@ +import {useState, useEffect} from 'preact/hooks'; +import {on} from '@create-figma-plugin/utilities'; + +import type {EventProjectIcons} from 'types/events'; +import type {ProjectIcons} from 'types/project'; + +export function useProjectIcons(): ProjectIcons { + const [sets, setSets] = useState([]); + const [list, setList] = useState([]); + const [map, setMap] = useState>({}); + + useEffect(() => on('PROJECT_ICONS', (sets, list, map) => { + setSets(sets); + setList(list); + setMap(map); + }), []); + + return {sets, list, map}; +} diff --git a/packages/figma-to-react-native/src/interface/hooks/useProjectTheme.ts b/packages/figma-to-react-native/src/interface/hooks/useProjectTheme.ts new file mode 100644 index 00000000..d719df80 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useProjectTheme.ts @@ -0,0 +1,18 @@ +import {useState, useEffect} from 'preact/hooks'; +import {on} from '@create-figma-plugin/utilities'; +import * as $ from 'interface/store'; + +import type {EventProjectTheme} from 'types/events'; + +export function useProjectTheme(): string { + const [theme, setTheme] = useState('default'); + + useEffect(() => on('PROJECT_THEME', (code, current) => { + setTheme(current); + if (code !== $.getProjectTheme().toString()) { + $.setProjectTheme(code); + } + }), []); + + return theme; +} diff --git a/packages/figma-to-react-native/src/interface/hooks/useSelectedVariant.ts b/packages/figma-to-react-native/src/interface/hooks/useSelectedVariant.ts new file mode 100644 index 00000000..7c38dc0e --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useSelectedVariant.ts @@ -0,0 +1,16 @@ +import {useState, useEffect} from 'preact/hooks'; +import {on} from '@create-figma-plugin/utilities'; + +import type {EventSelectVariant} from 'types/events'; + +export function useSelectedVariant() { + const [name, setName] = useState(''); + const [props, setProps] = useState<{[property: string]: string}>({}); + + useEffect(() => on('SELECT_VARIANT', (name, props) => { + setName(name); + setProps(props); + }), []); + + return {props, name}; +} diff --git a/packages/figma-to-react-native/src/interface/hooks/useStyleGenServer.ts b/packages/figma-to-react-native/src/interface/hooks/useStyleGenServer.ts new file mode 100644 index 00000000..87405a7b --- /dev/null +++ b/packages/figma-to-react-native/src/interface/hooks/useStyleGenServer.ts @@ -0,0 +1,14 @@ +import {on, emit} from '@create-figma-plugin/utilities'; +import {useEffect} from 'preact/hooks'; +import {cssToRN, buildCSS, init} from 'css-to-rn'; + +init('https://esm.sh/lightningcss-wasm@1.22.0/lightningcss_node.wasm'); + +import type {EventStyleGenReq, EventStyleGenRes} from 'types/events'; + +export function useStyleGenServer() { + useEffect(() => on('STYLE_GEN_REQ', async (css) => { + const stylesheet = cssToRN(buildCSS(css)); + emit('STYLE_GEN_RES', stylesheet); + }), []); +} diff --git a/src/interface/hooks/useConfig.ts b/packages/figma-to-react-native/src/interface/hooks/useUserSettings.ts similarity index 80% rename from src/interface/hooks/useConfig.ts rename to packages/figma-to-react-native/src/interface/hooks/useUserSettings.ts index 7cc9fc4f..54d33b7f 100644 --- a/src/interface/hooks/useConfig.ts +++ b/packages/figma-to-react-native/src/interface/hooks/useUserSettings.ts @@ -9,20 +9,21 @@ const indent = defaultConfig?.writer?.indentNumberOfSpaces || 2; const configRaw = JSON.stringify(defaultConfig, undefined, indent); export type ConfigData = { - config: Settings; - raw: string; - locked: MutableRef; - update: (payload: string, force?: boolean) => void; + config: Settings, + raw: string, + locked: MutableRef, + update: (payload: string, force?: boolean) => void, } -export function useConfig(): ConfigData { - const locked = useRef(false); - const [raw, setRaw] = useState(configRaw); +export function useUserSettings(): ConfigData { const [config, setConfig] = useState(defaultConfig); + const [raw, setRaw] = useState(configRaw); + const locked = useRef(false); + const update = useCallback((payload: string, force?: boolean) => { if (!force && locked.current) return; let decoded: Settings; - try { decoded = JSON.parse(payload)} catch (e) {} + try {decoded = JSON.parse(payload)} catch (e) {} if (decoded) { emit('CONFIG_UPDATE', decoded); setConfig(decoded); @@ -30,11 +31,10 @@ export function useConfig(): ConfigData { } }, [locked]); - useEffect(() => on('CONFIG_LOAD', (config) => { const indent = config?.writer?.indentNumberOfSpaces || 2; update(JSON.stringify(config, undefined, indent)); }), []); - return {config, raw, update, locked}; + return {config, raw, locked, update}; } diff --git a/packages/figma-to-react-native/src/interface/store.ts b/packages/figma-to-react-native/src/interface/store.ts new file mode 100644 index 00000000..70f0484f --- /dev/null +++ b/packages/figma-to-react-native/src/interface/store.ts @@ -0,0 +1,92 @@ +import * as Y from 'yjs'; +import {WebrtcProvider} from 'y-webrtc'; +// import {createYjsProvider} from '@y-sweet/client'; + +export const doc = new Y.Doc(); + +export const provider = new WebrtcProvider('xxx', doc); + +provider.connect(); + +export const assets = doc.getMap('assets'); + +export const components = doc.getMap<{ + id: string, + key: string, + name: string, + page: string, + props: string, + width: number, + height: number, +}>('components'); + +export const project = doc.getMap<{ + index: Y.Text, + theme: Y.Text, +}>('project'); + +export function sync(key: string) { + const connect = () => provider.connect(); + const disconnect = () => provider.disconnect(); + return {connect, disconnect}; +} + +// Setters and getters + +export function setProjectFiles(files: string[]) { + const $files = doc.getArray('files'); + $files.delete(0, $files.length); + files.forEach(file => $files.push([file])); +} + +export function getProjectTheme() { + return doc.getText('theme'); +} + +export function setProjectTheme(theme: string) { + const text = doc.getText('theme'); + text.delete(0, text.length); + text.insert(0, theme); +} + +export function getProjectIndex() { + return doc.getText('index'); +} + +export function setProjectIndex(index: string) { + const text = doc.getText('index'); + text.delete(0, text.length); + text.insert(0, index); +} + +export function getComponentCode(key: string) { + return doc.getText(`code::${key}`); +} + +export function setComponentCode(key: string, code: string) { + const text = doc.getText(`code::${key}`); + text.delete(0, text.length); + text.insert(0, code); +} + +export function getComponentIndex(key: string) { + const text = doc.getText(`index::${key}`); + return text.toString(); +} + +export function setComponentIndex(key: string, code: string) { + const text = doc.getText(`index::${key}`); + text.delete(0, text.length) + text.insert(0, code); +} + +export function setComponentStory(key: string, code: string) { + const text = doc.getText(`story::${key}`); + text.delete(0, text.length) + text.insert(0, code); +} + +export function getComponentStory(key: string) { + const text = doc.getText(`story::${key}`); + return text.toString(); +} diff --git a/src/interface/telemetry.tsx b/packages/figma-to-react-native/src/interface/telemetry.tsx similarity index 100% rename from src/interface/telemetry.tsx rename to packages/figma-to-react-native/src/interface/telemetry.tsx diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/index.ts b/packages/figma-to-react-native/src/interface/utils/bundler/index.ts new file mode 100644 index 00000000..1956e841 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/index.ts @@ -0,0 +1,34 @@ +import {Compiler} from './lib/compiler'; +import {Resolver} from './lib/resolver'; + +import react from './plugins/react'; +import css from './plugins/css'; +import png from './plugins/png'; +import svg from './plugins/svg'; + +import type {BuildOptions} from 'esbuild-wasm'; + +export async function bundle( + entry: string, + files: Map, + config: BuildOptions, + importMap?: Record, +): Promise { + const resolver = new Resolver(files); + const compiler = new Compiler(); + + return await compiler.compile(entry, { + ...config, + define: {'process.env.NODE_ENV': '"development"'}, + inject: ['import-react'], + target: 'esnext', + format: 'esm', + jsx: 'automatic', + jsxDev: true, + }, [ + png({resolver}), + svg({resolver}), + css({resolver}), + react({resolver, importMap}), + ]); +} diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/lib/barrier.ts b/packages/figma-to-react-native/src/interface/utils/bundler/lib/barrier.ts new file mode 100644 index 00000000..cd931b74 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/lib/barrier.ts @@ -0,0 +1,33 @@ +export class Barrier { + private readonly resolvers: Array<() => void> = []; + private paused: boolean = true; + + constructor(paused: boolean = true) { + this.paused = paused; + } + + /** Pauses this barrier causing operations to wait. */ + public pause(): void { + this.paused = true; + } + + /** Resumes this barrier causing all operations to run. */ + public resume(): void { + this.paused = false; + this.dispatch(); + } + + /** Waits until this barrier enters a resumed state. */ + public wait(): Promise { + return this.paused + ? new Promise((resolve) => this.resolvers.push(resolve)) + : Promise.resolve(void 0); + } + + private async dispatch(): Promise { + while (!this.paused && this.resolvers.length > 0) { + const resolve = this.resolvers.shift()!; + resolve(); + } + } +} diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/lib/compiler.ts b/packages/figma-to-react-native/src/interface/utils/bundler/lib/compiler.ts new file mode 100644 index 00000000..90192de7 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/lib/compiler.ts @@ -0,0 +1,64 @@ +import {initialize, build} from 'esbuild-wasm'; +import {Barrier} from './barrier'; + +import type {InitializeOptions, BuildOptions, Plugin} from 'esbuild-wasm'; + +const wasmURL = 'https://unpkg.com/esbuild-wasm@0.17.19/esbuild.wasm'; + +let _initialized = false; +let _initializing = false; + +export interface CompilerOptions extends InitializeOptions {} + +export class Compiler { + private readonly decoder: TextDecoder; + private readonly barrier: Barrier; + + constructor( + private readonly options: CompilerOptions = { + wasmURL, + worker: true, + } + ) { + this.decoder = new TextDecoder(); + this.barrier = new Barrier(true); + if (!_initialized && !_initializing) { + this.initialize(); + } else if(_initialized) { + this.barrier.resume(); + } + } + + private async initialize() { + _initializing = true; + await initialize({...this.options}); + _initialized = true; + _initializing = false; + this.barrier.resume(); + } + + public async compile( + entryPoint: string, + options: BuildOptions = {}, + plugins: Plugin[] = [], + ) { + await this.barrier.wait(); + const result = await build({ + plugins, + entryPoints: [ + entryPoint.charAt(0) === '/' + ? entryPoint.slice(1) + : entryPoint, + ], + // User options + ...options, + // Required options + bundle: true, + write: false, + }); + + // Return the first output file + const contents = result.outputFiles![0].contents; + return this.decoder.decode(contents); + } +} diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/lib/path.ts b/packages/figma-to-react-native/src/interface/utils/bundler/lib/path.ts new file mode 100644 index 00000000..3eab4d37 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/lib/path.ts @@ -0,0 +1,215 @@ +export interface PathObject { + root: string, + dir: string, + base: string, + ext: string, + name: string, +} + +export namespace Path { + const splitPathPattern = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + + /** file path seperator. */ + export const sep: string = '/'; + + /** file path delimitor. */ + export const delimiter: string = ':'; + + /** The current working directory. */ + export const cwd: string = '/'; + + /** Gets the basename of the given path. */ + export function basename(path: string, ext?: string): string { + let f = posixSplitPath(path)[2]; + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; + } + + /** Gets the directory path of the given path. */ + export function dirname(path: string): string { + const result = posixSplitPath(path); + const root = result[0]; + let dir = result[1]; + if (!root && !dir) { + return '.'; + } + if (dir) { + dir = dir.substr(0, dir.length - 1); + } + return root + dir; + } + + /** Gets the file extension of the the given path. */ + export function extname(path: string): string { + return posixSplitPath(path)[3]; + } + + /** Formats the given PathObject into a path string. */ + export function format(pathObject: Partial): string { + if (typeof pathObject !== 'object') { + throw new TypeError(`Parameter 'pathObject' must be an object, not ${typeof pathObject}`); + } + const root = pathObject.root || ''; + if (typeof root !== 'string') { + throw new TypeError(`'pathObject.root' must be a string or undefined, not ${typeof pathObject.root}`); + } + const dir = pathObject.dir ? pathObject.dir + sep : ''; + const base = pathObject.base || ''; + return dir + base; + } + + /** Returns true if the given path is absolute. */ + export function isAbsolute(path: string): boolean { + return path.charAt(0) === '/'; + } + + /** Joins the given path parameters. */ + export function join(...paths: string[]): string { + let path = ''; + for (let i = 0; i < paths.length; i++) { + const segment = paths[i]; + if (typeof segment !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + if (segment) { + if (!path) { + path += segment; + } else { + path += '/' + segment; + } + } + } + return normalize(path); + } + + /** Normalizes the a path. */ + export function normalize(path: string): string { + const absolute = isAbsolute(path); + const trailingSlash = path && path[path.length - 1] === '/'; + path = normalizeArray(path.split('/'), !absolute).join('/'); + if (!path && !absolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + return (absolute ? '/' : '') + path; + } + + /** Parses the given path into a PathObject. */ + export function parse(path: string): PathObject { + if (typeof path !== 'string') { + throw new TypeError(`Parameter 'pathString' must be a string, not ${typeof path}`); + } + let parts = posixSplitPath(path); + if (!parts || parts.length !== 4) { + throw new TypeError(`Invalid path '${path}'`); + } + parts[1] = parts[1] || ''; + parts[2] = parts[2] || ''; + parts[3] = parts[3] || ''; + return { + root: parts[0], + dir: parts[0] + parts[1].slice(0, -1), + base: parts[2], + ext: parts[3], + name: parts[2].slice(0, parts[2].length - parts[3].length), + }; + } + + /** Solves the relative path for the given 'from' and 'to' paths. */ + export function relative(from: string, to: string): string { + from = resolve(from).substr(1); + to = resolve(to).substr(1); + const fromParts = trimArray(from.split('/')); + const toParts = trimArray(to.split('/')); + const length = Math.min(fromParts.length, toParts.length); + let samePartsLength = length; + for (let i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + let outputParts = []; + for (let i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + return outputParts.join('/'); + } + + /** Resolves the given paths. */ + export function resolve(...paths: string[]): string { + let resolvedPath = ''; + let resolvedAbsolute = false; + for (let i = paths.length - 1; i >= -1 && !resolvedAbsolute; i--) { + let path = i >= 0 ? paths[i] : cwd; + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path[0] === '/'; + } + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + // Normalize the path + resolvedPath = normalizeArray(resolvedPath.split('/'), !resolvedAbsolute).join('/'); + return (resolvedAbsolute ? '/' : '') + resolvedPath || '.'; + } + + // #region utility + + /** Splits the given path. */ + function posixSplitPath(path: string) { + return splitPathPattern.exec(path)!.slice(1); + } + + // Resolves '.' and '..' elements in a path array with directory names there must be no slashes or device names + // (c:\) in the array (so also no leading and trailing slashes - it does not distinguish relative and absolute paths) + function normalizeArray(parts: string[], allowAboveRoot: boolean): string[] { + const res = []; + for (let i = 0; i < parts.length; i++) { + const p = parts[i]; + if (!p || p === '.') { + continue; + } + if (p === '..') { + if (res.length && res[res.length - 1] !== '..') { + res.pop(); + } else if (allowAboveRoot) { + res.push('..'); + } + } else { + res.push(p); + } + } + return res; + } + + // returns an array with empty elements removed from either end of the input + // array or the original array if no elements need to be removed + function trimArray(array: string[]): string[] { + const lastIndex = array.length - 1; + let start = 0; + for (; start <= lastIndex; start++) { + if (array[start]) break; + } + let end = lastIndex; + for (; end >= 0; end--) { + if (array[end]) break; + } + if (start === 0 && end === lastIndex) { + return array; + } + if (start > end) { + return []; + } + return array.slice(start, end + 1); + } +} diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/lib/resolver.ts b/packages/figma-to-react-native/src/interface/utils/bundler/lib/resolver.ts new file mode 100644 index 00000000..7b20bf3c --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/lib/resolver.ts @@ -0,0 +1,8 @@ +export class Resolver { + constructor(private readonly files: Map) {} + public resolve(path: string) { + if (!this.files.has(path)) + throw Error(`[bundler] ${path} not found`); + return this.files.get(path)!; + } +} diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/plugins/css.ts b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/css.ts new file mode 100644 index 00000000..f873506b --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/css.ts @@ -0,0 +1,34 @@ +import type {Plugin} from 'esbuild'; +import type {Resolver} from '../lib/resolver'; + +interface PluginOptions { + resolver: Resolver, + importMap?: Record, +} + +export default (opts: PluginOptions): Plugin => ({ + name: 'css', + setup: (build) => { + const filter = /\.css$/; + + build.onResolve({filter}, (args) => { + switch (args.kind) { + case 'import-statement': + case 'require-call': + case 'dynamic-import': + case 'require-resolve': + return; + default: + return {external: true}; + } + }); + + build.onLoad({filter}, async (args) => { + const contents = await Promise.resolve(opts.resolver.resolve(args.path)); + return { + contents, + loader: 'css', + }; + }); + }, +}); diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/plugins/png.ts b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/png.ts new file mode 100644 index 00000000..49340d19 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/png.ts @@ -0,0 +1,47 @@ +import type {Plugin} from 'esbuild'; +import type {Resolver} from '../lib/resolver'; + +interface PluginOptions { + resolver: Resolver, + importMap?: Record, +} + +export default (opts: PluginOptions): Plugin => ({ + name: 'png', + setup: (build) => { + const filter = /\.png$/; + + build.onResolve({filter}, (args) => { + switch (args.kind) { + case 'import-statement': + case 'require-call': + case 'dynamic-import': + case 'require-resolve': + return; + default: + return {external: true}; + } + }); + + build.onLoad({filter}, async (args) => { + const data = await Promise.resolve(opts.resolver.resolve(args.path)); + const image = (data instanceof Uint8Array) + ? await bytesToDataURL(data, 'image/png') + : `data:image/png;base64,${data}`; + return { + contents: image, + loader: 'text', + }; + }); + }, +}); + +async function bytesToDataURL(bytes: Uint8Array, type?: string): Promise { + const blob = new Blob([bytes], {type}); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onerror = reject; + reader.onloadend = () => resolve(reader.result as string); + reader.readAsDataURL(blob); + }); +} diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/plugins/react.ts b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/react.ts new file mode 100644 index 00000000..8ecdaa4e --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/react.ts @@ -0,0 +1,64 @@ +import type {Plugin} from 'esbuild'; +import type {Resolver} from '../lib/resolver'; + +interface PluginOptions { + resolver: Resolver, + importMap?: Record, +} + +export default (opts: PluginOptions): Plugin => ({ + name: 'react', + setup: (build) => { + const filter = /.*/; + + build.onResolve({filter}, (args) => { + switch (args.kind) { + case 'entry-point': + return { + path: '/' + args.path, + }; + case 'import-statement': + if (args.path === '@lingui/macro') { + return { + path: '/lingui-macro', + } + // Package import + } else if (opts.importMap && opts.importMap[args.path]) { + return { + path: args.path, + external: true, + }; + // Local import + } else { + return { + path: '/' + args.path, + }; + } + default: + throw Error('not resolvable'); + } + }); + + build.onLoad({filter}, async (args) => { + const isReactInject = args.path === '/import-react'; + const isLinguiMacro = args.path === '/lingui-macro'; + const isComponent = args.path.startsWith('/components/'); + const isStyles = args.path.startsWith('/styles'); + const isTheme = args.path.startsWith('/theme'); + return { + contents: isReactInject + ? `export * as React from 'react'` + : isLinguiMacro + ? `export const Trans = ({children}) => ({children})` + : await Promise.resolve(opts.resolver.resolve(args.path)), + loader: isReactInject + ? 'js' + : isComponent || isLinguiMacro + ? 'tsx' + : isStyles || isTheme + ? 'ts' + : 'default', + }; + }); + }, +}); diff --git a/packages/figma-to-react-native/src/interface/utils/bundler/plugins/svg.ts b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/svg.ts new file mode 100644 index 00000000..b63f17c4 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/bundler/plugins/svg.ts @@ -0,0 +1,37 @@ +import type {Plugin} from 'esbuild'; +import type {Resolver} from '../lib/resolver'; + +interface PluginOptions { + resolver: Resolver, + importMap?: Record, +} + +export default (opts: PluginOptions): Plugin => ({ + name: 'svg', + setup: (build) => { + const filter = /\.svg$/; + + build.onResolve({filter}, (args) => { + switch (args.kind) { + case 'import-statement': + case 'require-call': + case 'dynamic-import': + case 'require-resolve': + return; + default: + return {external: true}; + } + }); + + build.onLoad({filter}, async (args) => { + const data = await Promise.resolve(opts.resolver.resolve(args.path)); + const svg = (data instanceof Uint8Array) + ? new TextDecoder('utf-8').decode(data) + : data; + return { + contents: `export default () => ${svg}`, + loader: 'tsx', + }; + }); + }, +}); diff --git a/packages/figma-to-react-native/src/interface/utils/editor/index.ts b/packages/figma-to-react-native/src/interface/utils/editor/index.ts new file mode 100644 index 00000000..c6153152 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/index.ts @@ -0,0 +1,135 @@ +// @ts-ignore No types +import {constrainedEditor} from 'constrained-editor-plugin'; +import {AutoTypings, LocalStorageCache} from 'monaco-editor-auto-typings/custom-editor'; +import {emit} from '@create-figma-plugin/utilities'; +import {F2RN_EDITOR_NS} from 'config/env'; + +import schema from './schemas/settings.json'; +import templates from './templates'; + +import type * as monaco from 'monaco-editor'; +import type {Settings} from 'types/settings'; +import type {EventFocusNode} from 'types/events'; +import type {ComponentLinks} from 'types/component'; + +const sourceCache = new LocalStorageCache(); + +export type Editor = monaco.editor.IStandaloneCodeEditor; +export type Monaco = typeof monaco; + +export function initTypescript(monaco: Monaco, settings: Settings) { + const ts = monaco.languages.typescript.typescriptDefaults; + ts?.setInlayHintsOptions(settings.monaco.inlayHints); + ts?.setDiagnosticsOptions(settings.monaco.diagnostics); + ts?.setCompilerOptions({ + ...settings.monaco.compiler, + jsx: monaco.languages.typescript.JsxEmit.ReactNative, + moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs, + target: monaco.languages.typescript.ScriptTarget.ESNext, + module: monaco.languages.typescript.ModuleKind.CommonJS, + noEmit: true, + paths: { + ['components/*']: [`${F2RN_EDITOR_NS}*`], + } + }); + + try { + const libs = Object.keys(templates); + libs.forEach(key => { + monaco.editor.createModel(templates[key], 'typescript', monaco.Uri.parse(key)); + }); + } catch (e) { + console.error(e); + } +} + +export function initFileOpener(monaco: Monaco, links?: ComponentLinks) { + const regexTestId = /testID=(?:"(\d+:\d+)"|{(props\.testID)})/; + const regexComponentName = /\/([^\/]+)\.[^.]+$/; + return monaco.editor.registerEditorOpener({ + openCodeEditor(source, resource) { + let nodeId: string | undefined; + const base = `${resource.scheme}://${resource.authority}/`; + if (base === F2RN_EDITOR_NS) { + // Search for component name in links + nodeId = links?.[resource.path?.match(regexComponentName)?.[1]]; + // Search for test ids if no component name found + if (!nodeId) { + const sel = source.getSelection(); + const model = source.getModel(); + for (let i = sel.startLineNumber; i <= sel.endLineNumber; i++) { + const line = model?.getLineContent(i); + const match = line?.match(regexTestId); + const [_, literal, prop] = match; + nodeId = prop + ? links?.[model.uri.path?.match(regexComponentName)?.[1]] + : literal; + } + } + } + // Focus node in editor + // TODO: support multiple nodes + if (nodeId) { + emit('FOCUS', nodeId); + } + console.debug('[open file]', {resource, base, nodeId, links, source}); + return false; + } + }).dispose; +} + +export function initSettingsSchema(monaco: Monaco) { + const json = monaco.languages.json.jsonDefaults; + json?.setDiagnosticsOptions({ + validate: true, + schemas: [{ + schema, + uri: 'http://fig.run/schema-settings.json', + fileMatch: [ + monaco?.Uri.parse(`${F2RN_EDITOR_NS}settings.json`).toString(), + ], + }], + }); +} + +export function initComponentEditor( + editor: Editor, + monaco: Monaco, + onTriggerGPT: () => void, +) { + // Automatically import package types + AutoTypings.create(editor, { + monaco, + sourceCache, + shareCache: true, + preloadPackages: true, + fileRootPath: F2RN_EDITOR_NS, + versions: { + '@types/react': '17.0.2', + '@types/react-native': '0.72.6', + 'react-native-svg': '13.14.0', + }, + }); + + // Setup constrained editor to limit user input + const constraint = constrainedEditor(monaco); + constraint.initializeIn(editor); + + // Setup custom commands + editor.addAction({ + id: 'f2rn-gpt', + label: 'Patch with GPT-4', + contextMenuGroupId: '1_modification', + contextMenuOrder: 99, + precondition: null, + keybindingContext: null, + keybindings: [ + monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyG, + ], + run: () => { + onTriggerGPT(); + }, + }); + + return constraint; +} diff --git a/packages/figma-to-react-native/src/interface/utils/editor/lib/patch.ts b/packages/figma-to-react-native/src/interface/utils/editor/lib/patch.ts new file mode 100644 index 00000000..a1dcca56 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/lib/patch.ts @@ -0,0 +1,19 @@ +export const actions = [ + 'apply', + 'view diff', + 'reset', +]; + +export async function patch(action: string) { + switch (action) { + case 'View Diff': + console.log('[diff]', action); + break; + case 'Apply': + confirm(`Are you sure you want to apply the component code changes?`); + break; + case 'reset': + confirm(`Are you sure you want to clear the code changes?`); + break; + } +} diff --git a/packages/figma-to-react-native/src/interface/utils/editor/lib/yjs.ts b/packages/figma-to-react-native/src/interface/utils/editor/lib/yjs.ts new file mode 100644 index 00000000..b1d6a5a3 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/lib/yjs.ts @@ -0,0 +1,252 @@ +import * as Y from 'yjs'; +import * as monaco from 'monaco-editor'; +import * as error from 'lib0/error'; +import {createMutex} from 'lib0/mutex'; + +import type {Awareness} from 'y-protocols/awareness'; +import type {mutex} from 'lib0/mutex'; + +class RelativeSelection { + start: Y.RelativePosition; + end: Y.RelativePosition; + direction: monaco.SelectionDirection; + constructor ( + start: Y.RelativePosition, + end: Y.RelativePosition, + direction: monaco.SelectionDirection, + ) { + this.start = start; + this.end = end; + this.direction = direction; + } +} + +const createRelativeSelection = ( + editor: monaco.editor.IStandaloneCodeEditor, + monacoModel: monaco.editor.ITextModel, + type: Y.Text, +) => { + const sel = editor.getSelection(); + if (sel !== null) { + const startPos = sel.getStartPosition(); + const endPos = sel.getEndPosition(); + const start = Y.createRelativePositionFromTypeIndex(type, monacoModel.getOffsetAt(startPos)); + const end = Y.createRelativePositionFromTypeIndex(type, monacoModel.getOffsetAt(endPos)); + return new RelativeSelection(start, end, sel.getDirection()); + } + return null +} + +const createMonacoSelectionFromRelativeSelection = ( + editor: monaco.editor.IStandaloneCodeEditor, + type: Y.Text, + relSel: RelativeSelection, + doc: Y.Doc, +): null | monaco.Selection => { + const start = Y.createAbsolutePositionFromRelativePosition(relSel.start, doc); + const end = Y.createAbsolutePositionFromRelativePosition(relSel.end, doc); + if (start !== null && end !== null && start.type === type && end.type === type) { + const model = editor.getModel(); + const startPos = model.getPositionAt(start.index); + const endPos = model.getPositionAt(end.index); + return monaco.Selection.createWithDirection( + startPos.lineNumber, + startPos.column, + endPos.lineNumber, + endPos.column, + relSel.direction, + ); + } + return null; +} + +export class MonacoBinding { + mux: mutex; + doc: Y.Doc; + ytext: Y.Text; + monacoModel: monaco.editor.ITextModel; + editors: Set; + awareness: Awareness; + + _savedSelections: Map; + _decorations: Map; + _monacoChangeHandler: any; + _monacoDisposeHandler: any; + _beforeTransaction: () => void; + _rerenderDecorations: () => void; + _ytextObserver: (event: any) => void; + + constructor ( + ytext: Y.Text, + monacoModel: monaco.editor.ITextModel, + editors = new Set(), + awareness: Awareness = null, + ) { + // Setup + this.mux = createMutex(); + this.doc = ytext.doc; + this.ytext = ytext; + this.editors = editors; + this.monacoModel = monacoModel; + this._savedSelections = new Map(); + + // Transactions + this._beforeTransaction = () => { + this.mux(() => { + this._savedSelections = new Map(); + editors.forEach(editor => { + if (editor.getModel() === monacoModel) { + const rel = createRelativeSelection(editor, monacoModel, ytext); + if (rel !== null) { + this._savedSelections.set(editor, rel); + } + } + }) + }) + } + this.doc.on('beforeAllTransactions', this._beforeTransaction); + + // Decorations + this._decorations = new Map(); + this._rerenderDecorations = () => { + editors.forEach(editor => { + if (awareness && editor.getModel() === monacoModel) { + const currentDecorations = this._decorations.get(editor) || []; + const newDecorations: Array = []; + awareness.getStates().forEach((state, clientID) => { + if (clientID !== this.doc.clientID + && state.selection != null + && state.selection.anchor != null + && state.selection.head != null) { + const anchorAbs = Y.createAbsolutePositionFromRelativePosition(state.selection.anchor, this.doc); + const headAbs = Y.createAbsolutePositionFromRelativePosition(state.selection.head, this.doc); + if (anchorAbs !== null + && headAbs !== null + && anchorAbs.type === ytext + && headAbs.type === ytext) { + let start, end, afterContentClassName, beforeContentClassName; + if (anchorAbs.index < headAbs.index) { + start = monacoModel.getPositionAt(anchorAbs.index); + end = monacoModel.getPositionAt(headAbs.index); + afterContentClassName = 'yRemoteSelectionHead yRemoteSelectionHead-' + clientID; + beforeContentClassName = null; + } else { + start = monacoModel.getPositionAt(headAbs.index); + end = monacoModel.getPositionAt(anchorAbs.index); + afterContentClassName = null; + beforeContentClassName = 'yRemoteSelectionHead yRemoteSelectionHead-' + clientID; + } + newDecorations.push({ + range: new monaco.Range(start.lineNumber, start.column, end.lineNumber, end.column), + options: { + className: 'yRemoteSelection yRemoteSelection-' + clientID, + afterContentClassName, + beforeContentClassName, + }, + }); + } + } + }); + this._decorations.set(editor, editor.deltaDecorations(currentDecorations, newDecorations)); + } else { + this._decorations.delete(editor); + } + }) + } + + // YText Observer + this._ytextObserver = (event: Y.YTextEvent) => { + this.mux(() => { + let index = 0 + event.delta.forEach(op => { + if (op.retain !== undefined) { + index += op.retain + } else if (op.insert !== undefined) { + const pos = monacoModel.getPositionAt(index); + const range = new monaco.Selection(pos.lineNumber, pos.column, pos.lineNumber, pos.column); + const insert = (op.insert) as string; + monacoModel.applyEdits([{range, text: insert}]); + index += insert.length; + } else if (op.delete !== undefined) { + const pos = monacoModel.getPositionAt(index); + const endPos = monacoModel.getPositionAt(index + op.delete); + const range = new monaco.Selection(pos.lineNumber, pos.column, endPos.lineNumber, endPos.column); + monacoModel.applyEdits([{range, text: ''}]); + } else { + throw error.unexpectedCase(); + } + }) + this._savedSelections.forEach((rsel, editor) => { + const sel = createMonacoSelectionFromRelativeSelection(editor, ytext, rsel, this.doc); + if (sel !== null) { + editor.setSelection(sel); + } + }); + }); + this._rerenderDecorations(); + } + ytext.observe(this._ytextObserver); + { + const ytextValue = ytext.toString(); + if (monacoModel.getValue() !== ytextValue) { + monacoModel.setValue(ytextValue); + } + } + + // Editor Change Handler + // (apply changes from right to left) + this._monacoChangeHandler = monacoModel.onDidChangeContent(event => { + this.mux(() => { + this.doc.transact(() => { + event.changes.sort((change1, change2) => + change2.rangeOffset - change1.rangeOffset).forEach(change => { + ytext.delete(change.rangeOffset, change.rangeLength); + ytext.insert(change.rangeOffset, change.text); + }); + }, this); + }); + }); + + // Editor Dispose Handler + this._monacoDisposeHandler = monacoModel.onWillDispose(() => { + this.destroy(); + }) + + // Selection Awareness + if (awareness) { + editors.forEach(editor => { + editor.onDidChangeCursorSelection(() => { + if (editor.getModel() === monacoModel) { + const sel = editor.getSelection(); + if (sel === null) { + return; + } + let anchor = monacoModel.getOffsetAt(sel.getStartPosition()); + let head = monacoModel.getOffsetAt(sel.getEndPosition()); + if (sel.getDirection() === monaco.SelectionDirection.RTL) { + const tmp = anchor; + anchor = head; + head = tmp; + } + awareness.setLocalStateField('selection', { + anchor: Y.createRelativePositionFromTypeIndex(ytext, anchor), + head: Y.createRelativePositionFromTypeIndex(ytext, head), + }); + } + }) + awareness.on('change', this._rerenderDecorations); + }) + this.awareness = awareness; + } + } + + destroy () { + this._monacoChangeHandler.dispose(); + this._monacoDisposeHandler.dispose(); + this.ytext.unobserve(this._ytextObserver); + this.doc.off('beforeAllTransactions', this._beforeTransaction); + if (this.awareness) { + this.awareness.off('change', this._rerenderDecorations); + } + } +} diff --git a/packages/figma-to-react-native/src/interface/utils/editor/schemas/settings.json b/packages/figma-to-react-native/src/interface/utils/editor/schemas/settings.json new file mode 100644 index 00000000..15f4c66f --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/schemas/settings.json @@ -0,0 +1,2814 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "ArrayBuffer": { + "properties": { + "__@toStringTag@283": { + "type": "string" + }, + "byteLength": { + "type": "number" + } + }, + "type": "object" + }, + "ArrayBufferLike": { + "anyOf": [ + { + "$ref": "#/definitions/ArrayBuffer" + }, + { + "$ref": "#/definitions/SharedArrayBuffer" + } + ] + }, + "BuildOptions": { + "properties": { + "absWorkingDir": { + "description": "Documentation: https://esbuild.github.io/api/#working-directory", + "type": "string" + }, + "alias": { + "$ref": "#/definitions/Record", + "description": "Documentation: https://esbuild.github.io/api/#alias" + }, + "allowOverwrite": { + "description": "Documentation: https://esbuild.github.io/api/#allow-overwrite", + "type": "boolean" + }, + "assetNames": { + "description": "Documentation: https://esbuild.github.io/api/#asset-names", + "type": "string" + }, + "banner": { + "additionalProperties": { + "type": "string" + }, + "description": "Documentation: https://esbuild.github.io/api/#banner", + "type": "object" + }, + "bundle": { + "description": "Documentation: https://esbuild.github.io/api/#bundle", + "type": "boolean" + }, + "charset": { + "$ref": "#/definitions/Charset", + "description": "Documentation: https://esbuild.github.io/api/#charset" + }, + "chunkNames": { + "description": "Documentation: https://esbuild.github.io/api/#chunk-names", + "type": "string" + }, + "color": { + "description": "Documentation: https://esbuild.github.io/api/#color", + "type": "boolean" + }, + "conditions": { + "description": "Documentation: https://esbuild.github.io/api/#conditions", + "items": { + "type": "string" + }, + "type": "array" + }, + "define": { + "additionalProperties": { + "type": "string" + }, + "description": "Documentation: https://esbuild.github.io/api/#define", + "type": "object" + }, + "drop": { + "description": "Documentation: https://esbuild.github.io/api/#drop", + "items": { + "$ref": "#/definitions/Drop" + }, + "type": "array" + }, + "entryNames": { + "description": "Documentation: https://esbuild.github.io/api/#entry-names", + "type": "string" + }, + "entryPoints": { + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "items": { + "properties": { + "in": { + "type": "string" + }, + "out": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "description": "Documentation: https://esbuild.github.io/api/#entry-points" + }, + "external": { + "description": "Documentation: https://esbuild.github.io/api/#external", + "items": { + "type": "string" + }, + "type": "array" + }, + "footer": { + "additionalProperties": { + "type": "string" + }, + "description": "Documentation: https://esbuild.github.io/api/#footer", + "type": "object" + }, + "format": { + "$ref": "#/definitions/Format", + "description": "Documentation: https://esbuild.github.io/api/#format" + }, + "globalName": { + "description": "Documentation: https://esbuild.github.io/api/#global-name", + "type": "string" + }, + "ignoreAnnotations": { + "description": "Documentation: https://esbuild.github.io/api/#ignore-annotations", + "type": "boolean" + }, + "inject": { + "description": "Documentation: https://esbuild.github.io/api/#inject", + "items": { + "type": "string" + }, + "type": "array" + }, + "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" + }, + "jsxFragment": { + "description": "Documentation: https://esbuild.github.io/api/#jsx-fragment", + "type": "string" + }, + "jsxImportSource": { + "description": "Documentation: https://esbuild.github.io/api/#jsx-import-source", + "type": "string" + }, + "jsxSideEffects": { + "description": "Documentation: https://esbuild.github.io/api/#jsx-side-effects", + "type": "boolean" + }, + "keepNames": { + "description": "Documentation: https://esbuild.github.io/api/#keep-names", + "type": "boolean" + }, + "legalComments": { + "description": "Documentation: https://esbuild.github.io/api/#legal-comments", + "enum": [ + "eof", + "external", + "inline", + "linked", + "none" + ], + "type": "string" + }, + "loader": { + "additionalProperties": { + "$ref": "#/definitions/Loader" + }, + "description": "Documentation: https://esbuild.github.io/api/#loader", + "type": "object" + }, + "logLevel": { + "$ref": "#/definitions/LogLevel", + "description": "Documentation: https://esbuild.github.io/api/#log-level" + }, + "logLimit": { + "description": "Documentation: https://esbuild.github.io/api/#log-limit", + "type": "number" + }, + "logOverride": { + "$ref": "#/definitions/Record", + "description": "Documentation: https://esbuild.github.io/api/#log-override" + }, + "mainFields": { + "description": "Documentation: https://esbuild.github.io/api/#main-fields", + "items": { + "type": "string" + }, + "type": "array" + }, + "mangleCache": { + "$ref": "#/definitions/Record", + "description": "Documentation: https://esbuild.github.io/api/#mangle-props" + }, + "mangleProps": { + "$ref": "#/definitions/RegExp", + "description": "Documentation: https://esbuild.github.io/api/#mangle-props" + }, + "mangleQuoted": { + "description": "Documentation: https://esbuild.github.io/api/#mangle-props", + "type": "boolean" + }, + "metafile": { + "description": "Documentation: https://esbuild.github.io/api/#metafile", + "type": "boolean" + }, + "minify": { + "description": "Documentation: https://esbuild.github.io/api/#minify", + "type": "boolean" + }, + "minifyIdentifiers": { + "description": "Documentation: https://esbuild.github.io/api/#minify", + "type": "boolean" + }, + "minifySyntax": { + "description": "Documentation: https://esbuild.github.io/api/#minify", + "type": "boolean" + }, + "minifyWhitespace": { + "description": "Documentation: https://esbuild.github.io/api/#minify", + "type": "boolean" + }, + "nodePaths": { + "description": "Documentation: https://esbuild.github.io/api/#node-paths", + "items": { + "type": "string" + }, + "type": "array" + }, + "outExtension": { + "additionalProperties": { + "type": "string" + }, + "description": "Documentation: https://esbuild.github.io/api/#out-extension", + "type": "object" + }, + "outbase": { + "description": "Documentation: https://esbuild.github.io/api/#outbase", + "type": "string" + }, + "outdir": { + "description": "Documentation: https://esbuild.github.io/api/#outdir", + "type": "string" + }, + "outfile": { + "description": "Documentation: https://esbuild.github.io/api/#outfile", + "type": "string" + }, + "packages": { + "const": "external", + "description": "Documentation: https://esbuild.github.io/api/#packages", + "type": "string" + }, + "platform": { + "$ref": "#/definitions/Platform", + "description": "Documentation: https://esbuild.github.io/api/#platform" + }, + "plugins": { + "description": "Documentation: https://esbuild.github.io/plugins/", + "items": { + "$ref": "#/definitions/Plugin" + }, + "type": "array" + }, + "preserveSymlinks": { + "description": "Documentation: https://esbuild.github.io/api/#preserve-symlinks", + "type": "boolean" + }, + "publicPath": { + "description": "Documentation: https://esbuild.github.io/api/#public-path", + "type": "string" + }, + "pure": { + "description": "Documentation: https://esbuild.github.io/api/#pure", + "items": { + "type": "string" + }, + "type": "array" + }, + "reserveProps": { + "$ref": "#/definitions/RegExp", + "description": "Documentation: https://esbuild.github.io/api/#mangle-props" + }, + "resolveExtensions": { + "description": "Documentation: https://esbuild.github.io/api/#resolve-extensions", + "items": { + "type": "string" + }, + "type": "array" + }, + "sourceRoot": { + "description": "Documentation: https://esbuild.github.io/api/#source-root", + "type": "string" + }, + "sourcemap": { + "description": "Documentation: https://esbuild.github.io/api/#sourcemap", + "enum": [ + "both", + "external", + false, + "inline", + "linked", + true + ] + }, + "sourcesContent": { + "description": "Documentation: https://esbuild.github.io/api/#sources-content", + "type": "boolean" + }, + "splitting": { + "description": "Documentation: https://esbuild.github.io/api/#splitting", + "type": "boolean" + }, + "stdin": { + "$ref": "#/definitions/StdinOptions", + "description": "Documentation: https://esbuild.github.io/api/#stdin" + }, + "supported": { + "$ref": "#/definitions/Record", + "description": "Documentation: https://esbuild.github.io/api/#supported" + }, + "target": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ], + "description": "Documentation: https://esbuild.github.io/api/#target" + }, + "treeShaking": { + "description": "Documentation: https://esbuild.github.io/api/#tree-shaking", + "type": "boolean" + }, + "tsconfig": { + "description": "Documentation: https://esbuild.github.io/api/#tsconfig", + "type": "string" + }, + "write": { + "description": "Documentation: https://esbuild.github.io/api/#write", + "type": "boolean" + } + }, + "type": "object" + }, + "Charset": { + "enum": [ + "ascii", + "utf8" + ], + "type": "string" + }, + "Drop": { + "enum": [ + "console", + "debugger" + ], + "type": "string" + }, + "Format": { + "enum": [ + "cjs", + "esm", + "iife" + ], + "type": "string" + }, + "IEvent": { + "type": "object" + }, + "IEvent": { + "type": "object" + }, + "IEvent": { + "type": "object" + }, + "IEvent": { + "type": "object" + }, + "IEvent": { + "type": "object" + }, + "IMarkdownString": { + "properties": { + "baseUri": { + "$ref": "#/definitions/UriComponents" + }, + "isTrusted": { + "anyOf": [ + { + "$ref": "#/definitions/MarkdownStringTrustedOptions" + }, + { + "type": "boolean" + } + ] + }, + "supportHtml": { + "type": "boolean" + }, + "supportThemeIcons": { + "type": "boolean" + }, + "uris": { + "additionalProperties": { + "$ref": "#/definitions/UriComponents" + }, + "type": "object" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "Loader": { + "enum": [ + "base64", + "binary", + "copy", + "css", + "dataurl", + "default", + "empty", + "file", + "js", + "json", + "jsx", + "text", + "ts", + "tsx" + ], + "type": "string" + }, + "LogLevel": { + "enum": [ + "debug", + "error", + "info", + "silent", + "verbose", + "warning" + ], + "type": "string" + }, + "MarkdownStringTrustedOptions": { + "properties": { + "enabledCommands": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "Omit": { + "properties": { + "acceptSuggestionOnCommitCharacter": { + "description": "Accept suggestions on provider defined characters.\nDefaults to true.", + "type": "boolean" + }, + "acceptSuggestionOnEnter": { + "description": "Accept suggestions on ENTER.\nDefaults to 'on'.", + "enum": [ + "off", + "on", + "smart" + ], + "type": "string" + }, + "accessibilityHelpUrl": { + "description": "An URL to open when Ctrl+H (Windows and Linux) or Cmd+H (OSX) is pressed in\nthe accessibility help dialog in the editor.\n\nDefaults to \"https://go.microsoft.com/fwlink/?linkid=852450\"", + "type": "string" + }, + "accessibilityPageSize": { + "description": "Controls the number of lines in the editor that can be read out by a screen reader", + "type": "number" + }, + "accessibilitySupport": { + "description": "Configure the editor's accessibility support.\nDefaults to 'auto'. It is best to leave this to 'auto'.", + "enum": [ + "auto", + "off", + "on" + ], + "type": "string" + }, + "ariaLabel": { + "description": "The aria label for the editor's textarea (when it is focused).", + "type": "string" + }, + "ariaRequired": { + "description": "Whether the aria-required attribute should be set on the editors textarea.", + "type": "boolean" + }, + "autoClosingBrackets": { + "$ref": "#/definitions/editor.EditorAutoClosingStrategy", + "description": "Options for auto closing brackets.\nDefaults to language defined behavior." + }, + "autoClosingComments": { + "$ref": "#/definitions/editor.EditorAutoClosingStrategy", + "description": "Options for auto closing comments.\nDefaults to language defined behavior." + }, + "autoClosingDelete": { + "$ref": "#/definitions/editor.EditorAutoClosingEditStrategy", + "description": "Options for pressing backspace near quotes or bracket pairs." + }, + "autoClosingOvertype": { + "$ref": "#/definitions/editor.EditorAutoClosingEditStrategy", + "description": "Options for typing over closing quotes or brackets." + }, + "autoClosingQuotes": { + "$ref": "#/definitions/editor.EditorAutoClosingStrategy", + "description": "Options for auto closing quotes.\nDefaults to language defined behavior." + }, + "autoDetectHighContrast": { + "description": "If enabled, will automatically change to high contrast theme if the OS is using a high contrast theme.\nDefaults to true.", + "type": "boolean" + }, + "autoIndent": { + "description": "Controls whether the editor should automatically adjust the indentation when users type, paste, move or indent lines.\nDefaults to advanced.", + "enum": [ + "advanced", + "brackets", + "full", + "keep", + "none" + ], + "type": "string" + }, + "autoSurround": { + "$ref": "#/definitions/editor.EditorAutoSurroundStrategy", + "description": "Options for auto surrounding.\nDefaults to always allowing auto surrounding." + }, + "automaticLayout": { + "description": "Enable that the editor will install a ResizeObserver to check if its container dom node size has changed.\nDefaults to false.", + "type": "boolean" + }, + "bracketPairColorization": { + "$ref": "#/definitions/editor.IBracketPairColorizationOptions", + "description": "Configures bracket pair colorization (disabled by default)." + }, + "codeActionsOnSaveTimeout": { + "description": "Timeout for running code actions on save.", + "type": "number" + }, + "codeLens": { + "description": "Show code lens\nDefaults to true.", + "type": "boolean" + }, + "codeLensFontFamily": { + "description": "Code lens font family. Defaults to editor font family.", + "type": "string" + }, + "codeLensFontSize": { + "description": "Code lens font size. Default to 90% of the editor font size", + "type": "number" + }, + "colorDecorators": { + "description": "Enable inline color decorators and color picker rendering.", + "type": "boolean" + }, + "colorDecoratorsActivatedOn": { + "description": "Controls what is the condition to spawn a color picker from a color dectorator", + "enum": [ + "click", + "clickAndHover", + "hover" + ], + "type": "string" + }, + "colorDecoratorsLimit": { + "description": "Controls the max number of color decorators that can be rendered in an editor at once.", + "type": "number" + }, + "columnSelection": { + "description": "Enable that the selection with the mouse and keys is doing column selection.\nDefaults to false.", + "type": "boolean" + }, + "comments": { + "$ref": "#/definitions/editor.IEditorCommentsOptions", + "description": "Control the behaviour of comments in the editor." + }, + "contextmenu": { + "description": "Enable custom contextmenu.\nDefaults to true.", + "type": "boolean" + }, + "copyWithSyntaxHighlighting": { + "description": "Syntax highlighting is copied.", + "type": "boolean" + }, + "cursorBlinking": { + "description": "Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'.\nDefaults to 'blink'.", + "enum": [ + "blink", + "expand", + "phase", + "smooth", + "solid" + ], + "type": "string" + }, + "cursorSmoothCaretAnimation": { + "description": "Enable smooth caret animation.\nDefaults to 'off'.", + "enum": [ + "explicit", + "off", + "on" + ], + "type": "string" + }, + "cursorStyle": { + "description": "Control the cursor style, either 'block' or 'line'.\nDefaults to 'line'.", + "enum": [ + "block", + "block-outline", + "line", + "line-thin", + "underline", + "underline-thin" + ], + "type": "string" + }, + "cursorSurroundingLines": { + "description": "Controls the minimal number of visible leading and trailing lines surrounding the cursor.\nDefaults to 0.", + "type": "number" + }, + "cursorSurroundingLinesStyle": { + "description": "Controls when `cursorSurroundingLines` should be enforced\nDefaults to `default`, `cursorSurroundingLines` is not enforced when cursor position is changed\nby mouse.", + "enum": [ + "all", + "default" + ], + "type": "string" + }, + "cursorWidth": { + "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" + }, + "detectIndentation": { + "description": "Controls whether `tabSize` and `insertSpaces` will be automatically detected when a file is opened based on the file contents.\nDefaults to true.", + "type": "boolean" + }, + "dimension": { + "$ref": "#/definitions/editor.IDimension", + "description": "The initial editor dimension (to avoid measuring the container)." + }, + "disableLayerHinting": { + "description": "Disable the use of `transform: translate3d(0px, 0px, 0px)` for the editor margin and lines layers.\nThe usage of `transform: translate3d(0px, 0px, 0px)` acts as a hint for browsers to create an extra layer.\nDefaults to false.", + "type": "boolean" + }, + "disableMonospaceOptimizations": { + "description": "Disable the optimizations for monospace fonts.\nDefaults to false.", + "type": "boolean" + }, + "domReadOnly": { + "description": "Should the textarea used for input use the DOM `readonly` attribute.\nDefaults to false.", + "type": "boolean" + }, + "dragAndDrop": { + "description": "Controls if the editor should allow to move selections via drag and drop.\nDefaults to false.", + "type": "boolean" + }, + "dropIntoEditor": { + "$ref": "#/definitions/editor.IDropIntoEditorOptions", + "description": "Controls dropping into the editor from an external source.\n\nWhen enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event." + }, + "emptySelectionClipboard": { + "description": "Copying without a selection copies the current line.", + "type": "boolean" + }, + "experimentalWhitespaceRendering": { + "description": "Enable experimental whitespace rendering.\nDefaults to 'svg'.", + "enum": [ + "font", + "off", + "svg" + ], + "type": "string" + }, + "extraEditorClassName": { + "description": "Class name to be added to the editor.", + "type": "string" + }, + "fastScrollSensitivity": { + "description": "FastScrolling mulitplier speed when pressing `Alt`\nDefaults to 5.", + "type": "number" + }, + "find": { + "$ref": "#/definitions/editor.IEditorFindOptions", + "description": "Control the behavior of the find widget." + }, + "fixedOverflowWidgets": { + "description": "Display overflow widgets as `fixed`.\nDefaults to `false`.", + "type": "boolean" + }, + "folding": { + "description": "Enable code folding.\nDefaults to true.", + "type": "boolean" + }, + "foldingHighlight": { + "description": "Enable highlight for folded regions.\nDefaults to true.", + "type": "boolean" + }, + "foldingImportsByDefault": { + "description": "Auto fold imports folding regions.\nDefaults to true.", + "type": "boolean" + }, + "foldingMaximumRegions": { + "description": "Maximum number of foldable regions.\nDefaults to 5000.", + "type": "number" + }, + "foldingStrategy": { + "description": "Selects the folding strategy. 'auto' uses the strategies contributed for the current document, 'indentation' uses the indentation based folding strategy.\nDefaults to 'auto'.", + "enum": [ + "auto", + "indentation" + ], + "type": "string" + }, + "fontFamily": { + "description": "The font family", + "type": "string" + }, + "fontLigatures": { + "description": "Enable font ligatures.\nDefaults to false.", + "type": [ + "string", + "boolean" + ] + }, + "fontSize": { + "description": "The font size", + "type": "number" + }, + "fontVariations": { + "description": "Enable font variations.\nDefaults to false.", + "type": [ + "string", + "boolean" + ] + }, + "fontWeight": { + "description": "The font weight", + "type": "string" + }, + "formatOnPaste": { + "description": "Enable format on paste.\nDefaults to false.", + "type": "boolean" + }, + "formatOnType": { + "description": "Enable format on type.\nDefaults to false.", + "type": "boolean" + }, + "glyphMargin": { + "description": "Enable the rendering of the glyph margin.\nDefaults to true in vscode and to false in monaco-editor.", + "type": "boolean" + }, + "gotoLocation": { + "$ref": "#/definitions/editor.IGotoLocationOptions" + }, + "guides": { + "$ref": "#/definitions/editor.IGuidesOptions", + "description": "Controls the behavior of editor guides." + }, + "hideCursorInOverviewRuler": { + "description": "Should the cursor be hidden in the overview ruler.\nDefaults to false.", + "type": "boolean" + }, + "hover": { + "$ref": "#/definitions/editor.IEditorHoverOptions", + "description": "Configure the editor's hover." + }, + "inDiffEditor": { + "description": "This editor is used inside a diff editor.", + "type": "boolean" + }, + "inlayHints": { + "$ref": "#/definitions/editor.IEditorInlayHintsOptions", + "description": "Control the behavior and rendering of the inline hints." + }, + "inlineCompletionsAccessibilityVerbose": { + "description": "Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown.", + "type": "boolean" + }, + "inlineSuggest": { + "$ref": "#/definitions/editor.IInlineSuggestOptions" + }, + "insertSpaces": { + "description": "Insert spaces when pressing `Tab`.\nThis setting is overridden based on the file contents when `detectIndentation` is on.\nDefaults to true.", + "type": "boolean" + }, + "language": { + "description": "The initial language of the auto created model in the editor.\nTo not automatically create a model, use `model: null`.", + "type": "string" + }, + "largeFileOptimizations": { + "description": "Special handling for large files to disable certain memory intensive features.\nDefaults to true.", + "type": "boolean" + }, + "letterSpacing": { + "description": "The letter spacing", + "type": "number" + }, + "lightbulb": { + "$ref": "#/definitions/editor.IEditorLightbulbOptions", + "description": "Control the behavior and rendering of the code action lightbulb." + }, + "lineDecorationsWidth": { + "description": "The width reserved for line decorations (in px).\nLine decorations are placed between line numbers and the editor content.\nYou can pass in a string in the format floating point followed by \"ch\". e.g. 1.3ch.\nDefaults to 10.", + "type": [ + "string", + "number" + ] + }, + "lineHeight": { + "description": "The line height", + "type": "number" + }, + "lineNumbers": { + "$ref": "#/definitions/editor.LineNumbersType", + "description": "Control the rendering of line numbers.\nIf it is a function, it will be invoked when rendering a line number and the return value will be rendered.\nOtherwise, if it is a truthy, line numbers will be rendered normally (equivalent of using an identity function).\nOtherwise, line numbers will not be rendered.\nDefaults to `on`." + }, + "lineNumbersMinChars": { + "description": "Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits.\nDefaults to 5.", + "type": "number" + }, + "linkedEditing": { + "description": "Enable linked editing.\nDefaults to false.", + "type": "boolean" + }, + "links": { + "description": "Enable detecting links and making them clickable.\nDefaults to true.", + "type": "boolean" + }, + "matchBrackets": { + "description": "Enable highlighting of matching brackets.\nDefaults to 'always'.", + "enum": [ + "always", + "near", + "never" + ], + "type": "string" + }, + "matchOnWordStartOnly": { + "description": "Controls whether suggestions allow matches in the middle of the word instead of only at the beginning", + "type": "boolean" + }, + "maxTokenizationLineLength": { + "description": "Lines above this length will not be tokenized for performance reasons.\nDefaults to 20000.", + "type": "number" + }, + "minimap": { + "$ref": "#/definitions/editor.IEditorMinimapOptions", + "description": "Control the behavior and rendering of the minimap." + }, + "model": { + "$ref": "#/definitions/editor.ITextModel", + "description": "The initial model associated with this code editor." + }, + "mouseStyle": { + "description": "Control the mouse pointer style, either 'text' or 'default' or 'copy'\nDefaults to 'text'", + "enum": [ + "copy", + "default", + "text" + ], + "type": "string" + }, + "mouseWheelScrollSensitivity": { + "description": "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.\nDefaults to 1.", + "type": "number" + }, + "mouseWheelZoom": { + "description": "Zoom the font in the editor when using the mouse wheel in combination with holding Ctrl.\nDefaults to false.", + "type": "boolean" + }, + "multiCursorLimit": { + "description": "Controls the max number of text cursors that can be in an active editor at once.", + "type": "number" + }, + "multiCursorMergeOverlapping": { + "description": "Merge overlapping selections.\nDefaults to true", + "type": "boolean" + }, + "multiCursorModifier": { + "description": "The modifier to be used to add multiple cursors with the mouse.\nDefaults to 'alt'", + "enum": [ + "alt", + "ctrlCmd" + ], + "type": "string" + }, + "multiCursorPaste": { + "description": "Configure the behaviour when pasting a text with the line count equal to the cursor count.\nDefaults to 'spread'.", + "enum": [ + "full", + "spread" + ], + "type": "string" + }, + "occurrencesHighlight": { + "description": "Enable semantic occurrences highlight.\nDefaults to true.", + "type": "boolean" + }, + "overviewRulerBorder": { + "description": "Controls if a border should be drawn around the overview ruler.\nDefaults to `true`.", + "type": "boolean" + }, + "overviewRulerLanes": { + "description": "The number of vertical lanes the overview ruler should render.\nDefaults to 3.", + "type": "number" + }, + "padding": { + "$ref": "#/definitions/editor.IEditorPaddingOptions", + "description": "Controls the spacing around the editor." + }, + "parameterHints": { + "$ref": "#/definitions/editor.IEditorParameterHintOptions", + "description": "Parameter hint options." + }, + "pasteAs": { + "$ref": "#/definitions/editor.IPasteAsOptions", + "description": "Controls support for changing how content is pasted into the editor." + }, + "peekWidgetDefaultFocus": { + "description": "Controls whether to focus the inline editor in the peek widget by default.\nDefaults to false.", + "enum": [ + "editor", + "tree" + ], + "type": "string" + }, + "quickSuggestions": { + "anyOf": [ + { + "$ref": "#/definitions/editor.IQuickSuggestionsOptions" + }, + { + "type": "boolean" + } + ], + "description": "Enable quick suggestions (shadow suggestions)\nDefaults to true." + }, + "quickSuggestionsDelay": { + "description": "Quick suggestions show delay (in ms)\nDefaults to 10 (ms)", + "type": "number" + }, + "readOnly": { + "description": "Should the editor be read only. See also `domReadOnly`.\nDefaults to false.", + "type": "boolean" + }, + "readOnlyMessage": { + "$ref": "#/definitions/IMarkdownString", + "description": "The message to display when the editor is readonly." + }, + "renameOnType": { + "description": "deprecated, use linkedEditing instead", + "type": "boolean" + }, + "renderControlCharacters": { + "description": "Enable rendering of control characters.\nDefaults to true.", + "type": "boolean" + }, + "renderFinalNewline": { + "description": "Render last line number when the file ends with a newline.\nDefaults to 'on' for Windows and macOS and 'dimmed' for Linux.", + "enum": [ + "dimmed", + "off", + "on" + ], + "type": "string" + }, + "renderLineHighlight": { + "description": "Enable rendering of current line highlight.\nDefaults to all.", + "enum": [ + "all", + "gutter", + "line", + "none" + ], + "type": "string" + }, + "renderLineHighlightOnlyWhenFocus": { + "description": "Control if the current line highlight should be rendered only the editor is focused.\nDefaults to false.", + "type": "boolean" + }, + "renderValidationDecorations": { + "description": "Should the editor render validation decorations.\nDefaults to editable.", + "enum": [ + "editable", + "off", + "on" + ], + "type": "string" + }, + "renderWhitespace": { + "description": "Enable rendering of whitespace.\nDefaults to 'selection'.", + "enum": [ + "all", + "boundary", + "none", + "selection", + "trailing" + ], + "type": "string" + }, + "revealHorizontalRightPadding": { + "description": "When revealing the cursor, a virtual padding (px) is added to the cursor, turning it into a rectangle.\nThis virtual padding ensures that the cursor gets revealed before hitting the edge of the viewport.\nDefaults to 30 (px).", + "type": "number" + }, + "roundedSelection": { + "description": "Render the editor selection with rounded borders.\nDefaults to true.", + "type": "boolean" + }, + "rulers": { + "description": "Render vertical lines at the specified columns.\nDefaults to empty array.", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/editor.IRulerOption" + }, + { + "type": "number" + } + ] + }, + "type": "array" + }, + "screenReaderAnnounceInlineSuggestion": { + "description": "Control whether a screen reader announces inline suggestion content immediately.", + "type": "boolean" + }, + "scrollBeyondLastColumn": { + "description": "Enable that scrolling can go beyond the last column by a number of columns.\nDefaults to 5.", + "type": "number" + }, + "scrollBeyondLastLine": { + "description": "Enable that scrolling can go one screen size after the last line.\nDefaults to true.", + "type": "boolean" + }, + "scrollPredominantAxis": { + "description": "Enable that the editor scrolls only the predominant axis. Prevents horizontal drift when scrolling vertically on a trackpad.\nDefaults to true.", + "type": "boolean" + }, + "scrollbar": { + "$ref": "#/definitions/editor.IEditorScrollbarOptions", + "description": "Control the behavior and rendering of the scrollbars." + }, + "selectOnLineNumbers": { + "description": "Should the corresponding line be selected when clicking on the line number?\nDefaults to true.", + "type": "boolean" + }, + "selectionClipboard": { + "description": "Enable Linux primary clipboard.\nDefaults to true.", + "type": "boolean" + }, + "selectionHighlight": { + "description": "Enable selection highlight.\nDefaults to true.", + "type": "boolean" + }, + "semanticHighlighting.enabled": { + "description": "Controls whether the semanticHighlighting is shown for the languages that support it.\ntrue: semanticHighlighting is enabled for all themes\nfalse: semanticHighlighting is disabled for all themes\n'configuredByTheme': semanticHighlighting is controlled by the current color theme's semanticHighlighting setting.\nDefaults to 'byTheme'.", + "enum": [ + "configuredByTheme", + false, + true + ] + }, + "showDeprecated": { + "description": "Controls strikethrough deprecated variables.", + "type": "boolean" + }, + "showFoldingControls": { + "description": "Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.\nDefaults to 'mouseover'.", + "enum": [ + "always", + "mouseover", + "never" + ], + "type": "string" + }, + "showUnused": { + "description": "Controls fading out of unused variables.", + "type": "boolean" + }, + "smartSelect": { + "$ref": "#/definitions/editor.ISmartSelectOptions", + "description": "Smart select options." + }, + "smoothScrolling": { + "description": "Enable that the editor animates scrolling to a position.\nDefaults to false.", + "type": "boolean" + }, + "snippetSuggestions": { + "description": "Enable snippet suggestions. Default to 'true'.", + "enum": [ + "bottom", + "inline", + "none", + "top" + ], + "type": "string" + }, + "stablePeek": { + "description": "Keep peek editors open even when double-clicking their content or when hitting `Escape`.\nDefaults to false.", + "type": "boolean" + }, + "stickyScroll": { + "$ref": "#/definitions/editor.IEditorStickyScrollOptions", + "description": "Control the behavior of sticky scroll options" + }, + "stickyTabStops": { + "description": "Emulate selection behaviour of tab characters when using spaces for indentation.\nThis means selection will stick to tab stops.", + "type": "boolean" + }, + "stopRenderingLineAfter": { + "description": "Performance guard: Stop rendering a line after x characters.\nDefaults to 10000.\nUse -1 to never stop rendering", + "type": "number" + }, + "suggest": { + "$ref": "#/definitions/editor.ISuggestOptions", + "description": "Suggest options." + }, + "suggestFontSize": { + "description": "The font size for the suggest widget.\nDefaults to the editor font size.", + "type": "number" + }, + "suggestLineHeight": { + "description": "The line height for the suggest widget.\nDefaults to the editor line height.", + "type": "number" + }, + "suggestOnTriggerCharacters": { + "description": "Enable the suggestion box to pop-up on trigger characters.\nDefaults to true.", + "type": "boolean" + }, + "suggestSelection": { + "description": "The history mode for suggestions.", + "enum": [ + "first", + "recentlyUsed", + "recentlyUsedByPrefix" + ], + "type": "string" + }, + "tabCompletion": { + "description": "Enable tab completion.", + "enum": [ + "off", + "on", + "onlySnippets" + ], + "type": "string" + }, + "tabFocusMode": { + "description": "Controls whether the editor / terminal receives tabs or defers them to the workbench for navigation.", + "type": "boolean" + }, + "tabIndex": { + "description": "The `tabindex` property of the editor's textarea", + "type": "number" + }, + "tabSize": { + "description": "The number of spaces a tab is equal to.\nThis setting is overridden based on the file contents when `detectIndentation` is on.\nDefaults to 4.", + "type": "number" + }, + "theme": { + "description": "Initial theme to be used for rendering.\nThe current out-of-the-box available themes are: 'vs' (default), 'vs-dark', 'hc-black', 'hc-light.\nYou can create custom themes via `monaco.editor.defineTheme`.\nTo switch a theme, use `monaco.editor.setTheme`.\n**NOTE**: The theme might be overwritten if the OS is in high contrast mode, unless `autoDetectHighContrast` is set to false.", + "type": "string" + }, + "trimAutoWhitespace": { + "description": "Remove trailing auto inserted whitespace.\nDefaults to true.", + "type": "boolean" + }, + "unfoldOnClickAfterEndOfLine": { + "description": "Controls whether clicking on the empty content after a folded line will unfold the line.\nDefaults to false.", + "type": "boolean" + }, + "unicodeHighlight": { + "$ref": "#/definitions/editor.IUnicodeHighlightOptions", + "description": "Controls the behavior of the unicode highlight feature\n(by default, ambiguous and invisible characters are highlighted)." + }, + "unusualLineTerminators": { + "description": "Remove unusual line terminators like LINE SEPARATOR (LS), PARAGRAPH SEPARATOR (PS).\nDefaults to 'prompt'.", + "enum": [ + "auto", + "off", + "prompt" + ], + "type": "string" + }, + "useShadowDOM": { + "description": "Control if the editor should use shadow DOM.", + "type": "boolean" + }, + "useTabStops": { + "description": "Inserting and deleting whitespace follows tab stops.", + "type": "boolean" + }, + "value": { + "description": "The initial value of the auto created model in the editor.\nTo not automatically create a model, use `model: null`.", + "type": "string" + }, + "wordBasedSuggestions": { + "description": "Controls whether completions should be computed based on words in the document.\nDefaults to true.", + "type": "boolean" + }, + "wordBasedSuggestionsOnlySameLanguage": { + "description": "Controls whether word based completions should be included from opened documents of the same language or any language.", + "type": "boolean" + }, + "wordBreak": { + "description": "Sets whether line breaks appear wherever the text would otherwise overflow its content box.\nWhen wordBreak = 'normal', Use the default line break rule.\nWhen wordBreak = 'keepAll', Word breaks should not be used for Chinese/Japanese/Korean (CJK) text. Non-CJK text behavior is the same as for normal.", + "enum": [ + "keepAll", + "normal" + ], + "type": "string" + }, + "wordSeparators": { + "description": "A string containing the word separators used when doing word navigation.\nDefaults to `~!@#$%^&*()-=+[{]}\\\\|;:\\'\",.<>/?", + "type": "string" + }, + "wordWrap": { + "description": "Control the wrapping of the editor.\nWhen `wordWrap` = \"off\", the lines will never wrap.\nWhen `wordWrap` = \"on\", the lines will wrap at the viewport width.\nWhen `wordWrap` = \"wordWrapColumn\", the lines will wrap at `wordWrapColumn`.\nWhen `wordWrap` = \"bounded\", the lines will wrap at min(viewport width, wordWrapColumn).\nDefaults to \"off\".", + "enum": [ + "bounded", + "off", + "on", + "wordWrapColumn" + ], + "type": "string" + }, + "wordWrapBreakAfterCharacters": { + "description": "Configure word wrapping characters. A break will be introduced after these characters.", + "type": "string" + }, + "wordWrapBreakBeforeCharacters": { + "description": "Configure word wrapping characters. A break will be introduced before these characters.", + "type": "string" + }, + "wordWrapColumn": { + "description": "Control the wrapping of the editor.\nWhen `wordWrap` = \"off\", the lines will never wrap.\nWhen `wordWrap` = \"on\", the lines will wrap at the viewport width.\nWhen `wordWrap` = \"wordWrapColumn\", the lines will wrap at `wordWrapColumn`.\nWhen `wordWrap` = \"bounded\", the lines will wrap at min(viewport width, wordWrapColumn).\nDefaults to 80.", + "type": "number" + }, + "wordWrapOverride1": { + "description": "Override the `wordWrap` setting.", + "enum": [ + "inherit", + "off", + "on" + ], + "type": "string" + }, + "wordWrapOverride2": { + "description": "Override the `wordWrapOverride1` setting.", + "enum": [ + "inherit", + "off", + "on" + ], + "type": "string" + }, + "wrappingIndent": { + "description": "Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'.\nDefaults to 'same' in vscode and to 'none' in monaco-editor.", + "enum": [ + "deepIndent", + "indent", + "none", + "same" + ], + "type": "string" + }, + "wrappingStrategy": { + "description": "Controls the wrapping strategy to use.\nDefaults to 'simple'.", + "enum": [ + "advanced", + "simple" + ], + "type": "string" + } + }, + "type": "object" + }, + "Options": { + "description": "Options for the writer.", + "properties": { + "indentNumberOfSpaces": { + "description": "Number of spaces to indent when `useTabs` is false.", + "type": "number" + }, + "newLine": { + "description": "Newline character.", + "enum": [ + "\n", + "\r\n" + ], + "type": "string" + }, + "useSingleQuote": { + "description": "Whether to use a single quote (true) or double quote (false).", + "type": "boolean" + }, + "useTabs": { + "description": "Whether to use tabs (true) or spaces (false).", + "type": "boolean" + } + }, + "type": "object" + }, + "Platform": { + "enum": [ + "browser", + "neutral", + "node" + ], + "type": "string" + }, + "Plugin": { + "properties": { + "name": { + "type": "string" + }, + "setup": { + "type": "object" + } + }, + "type": "object" + }, + "Record": { + "type": "object" + }, + "Record": { + "type": "object" + }, + "Record": { + "type": "object" + }, + "Record": { + "type": "object" + }, + "Record": { + "type": "object" + }, + "RegExp": { + "properties": { + "dotAll": { + "type": "boolean" + }, + "flags": { + "type": "string" + }, + "global": { + "type": "boolean" + }, + "ignoreCase": { + "type": "boolean" + }, + "lastIndex": { + "type": "number" + }, + "multiline": { + "type": "boolean" + }, + "source": { + "type": "string" + }, + "sticky": { + "type": "boolean" + }, + "unicode": { + "type": "boolean" + } + }, + "type": "object" + }, + "SharedArrayBuffer": { + "properties": { + "__@species@263": { + "$ref": "#/definitions/SharedArrayBuffer" + }, + "__@toStringTag@283": { + "const": "SharedArrayBuffer", + "type": "string" + }, + "byteLength": { + "type": "number" + } + }, + "type": "object" + }, + "StdinOptions": { + "properties": { + "contents": { + "anyOf": [ + { + "additionalProperties": false, + "patternProperties": { + "^[0-9]+$": { + "type": "number" + } + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "__@toStringTag@283": { + "const": "Uint8Array", + "type": "string" + }, + "buffer": { + "$ref": "#/definitions/ArrayBufferLike" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "type": "object" + }, + { + "type": "string" + } + ] + }, + "loader": { + "$ref": "#/definitions/Loader" + }, + "resolveDir": { + "type": "string" + }, + "sourcefile": { + "type": "string" + } + }, + "type": "object" + }, + "T": { + "type": "object" + }, + "Uri": { + "description": "Uniform Resource Identifier (Uri) http://tools.ietf.org/html/rfc3986.\nThis class is a simple parser which creates the basic component parts\n(http://tools.ietf.org/html/rfc3986#section-3) with minimal validation\nand encoding.\n\n```txt\n foo://example.com:8042/over/there?name=ferret#nose\n \\_/ \\______________/\\_________/ \\_________/ \\__/\n | | | | |\n scheme authority path query fragment\n | _____________________|__\n / \\ / \\\n urn:example:animal:ferret:nose\n```", + "properties": { + "authority": { + "description": "authority is the 'www.example.com' part of 'http://www.example.com/some/path?query#fragment'.\nThe part between the first double slashes and the next slash.", + "type": "string" + }, + "fragment": { + "description": "fragment is the 'fragment' part of 'http://www.example.com/some/path?query#fragment'.", + "type": "string" + }, + "fsPath": { + "description": "Returns a string representing the corresponding file system path of this Uri.\nWill handle UNC paths, normalizes windows drive letters to lower-case, and uses the\nplatform specific path separator.\n\n* Will *not* validate the path for invalid characters and semantics.\n* Will *not* look at the scheme of this Uri.\n* The result shall *not* be used for display purposes but for accessing a file on disk.\n\n\nThe *difference* to `Uri#path` is the use of the platform specific separator and the handling\nof UNC paths. See the below sample of a file-uri with an authority (UNC path).\n\n```ts\n const u = Uri.parse('file://server/c$/folder/file.txt')\n u.authority === 'server'\n u.path === '/shares/c$/file.txt'\n u.fsPath === '\\\\server\\c$\\folder\\file.txt'\n```\n\nUsing `Uri#path` to read a file (using fs-apis) would not be enough because parts of the path,\nnamely the server name, would be missing. Therefore `Uri#fsPath` exists - it's sugar to ease working\nwith URIs that represent files on disk (`file` scheme).", + "type": "string" + }, + "path": { + "description": "path is the '/some/path' part of 'http://www.example.com/some/path?query#fragment'.", + "type": "string" + }, + "query": { + "description": "query is the 'query' part of 'http://www.example.com/some/path?query#fragment'.", + "type": "string" + }, + "scheme": { + "description": "scheme is the 'http' part of 'http://www.example.com/some/path?query#fragment'.\nThe part before the first colon.", + "type": "string" + } + }, + "type": "object" + }, + "UriComponents": { + "properties": { + "authority": { + "type": "string" + }, + "fragment": { + "type": "string" + }, + "path": { + "type": "string" + }, + "query": { + "type": "string" + }, + "scheme": { + "type": "string" + } + }, + "type": "object" + }, + "editor.EditorAutoClosingEditStrategy": { + "description": "Configuration options for typing over closing quotes or brackets", + "enum": [ + "always", + "auto", + "never" + ], + "type": "string" + }, + "editor.EditorAutoClosingStrategy": { + "description": "Configuration options for auto closing quotes and brackets", + "enum": [ + "always", + "beforeWhitespace", + "languageDefined", + "never" + ], + "type": "string" + }, + "editor.EditorAutoSurroundStrategy": { + "description": "Configuration options for auto wrapping quotes and brackets", + "enum": [ + "brackets", + "languageDefined", + "never", + "quotes" + ], + "type": "string" + }, + "editor.GoToLocationValues": { + "enum": [ + "goto", + "gotoAndPeek", + "peek" + ], + "type": "string" + }, + "editor.IBracketPairColorizationOptions": { + "properties": { + "enabled": { + "description": "Enable or disable bracket pair colorization.", + "type": "boolean" + }, + "independentColorPoolPerBracketType": { + "description": "Use independent color pool per bracket type.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IDimension": { + "properties": { + "height": { + "type": "number" + }, + "width": { + "type": "number" + } + }, + "type": "object" + }, + "editor.IDropIntoEditorOptions": { + "description": "Configuration options for editor drop into behavior", + "properties": { + "enabled": { + "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" + }, + "editor.IEditorCommentsOptions": { + "description": "Configuration options for editor comments", + "properties": { + "ignoreEmptyLines": { + "description": "Ignore empty lines when inserting line comments.\nDefaults to true.", + "type": "boolean" + }, + "insertSpace": { + "description": "Insert a space after the line comment token and inside the block comments tokens.\nDefaults to true.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IEditorFindOptions": { + "description": "Configuration options for editor find widget", + "properties": { + "addExtraSpaceOnTop": { + "type": "boolean" + }, + "autoFindInSelection": { + "description": "Controls if Find in Selection flag is turned on in the editor.", + "enum": [ + "always", + "multiline", + "never" + ], + "type": "string" + }, + "cursorMoveOnType": { + "description": "Controls whether the cursor should move to find matches while typing.", + "type": "boolean" + }, + "loop": { + "description": "Controls whether the search result and diff result automatically restarts from the beginning (or the end) when no further matches can be found", + "type": "boolean" + }, + "seedSearchStringFromSelection": { + "description": "Controls if we seed search string in the Find Widget with editor selection.", + "enum": [ + "always", + "never", + "selection" + ], + "type": "string" + } + }, + "type": "object" + }, + "editor.IEditorHoverOptions": { + "description": "Configuration options for editor hover", + "properties": { + "above": { + "description": "Should the hover be shown above the line if possible?\nDefaults to false.", + "type": "boolean" + }, + "delay": { + "description": "Delay for showing the hover.\nDefaults to 300.", + "type": "number" + }, + "enabled": { + "description": "Enable the hover.\nDefaults to true.", + "type": "boolean" + }, + "hidingDelay": { + "description": "Controls how long the hover is visible after you hovered out of it.\nRequire sticky setting to be true.", + "type": "number" + }, + "sticky": { + "description": "Is the hover sticky such that it can be clicked and its contents selected?\nDefaults to true.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IEditorInlayHintsOptions": { + "description": "Configuration options for editor inlayHints", + "properties": { + "enabled": { + "description": "Enable the inline hints.\nDefaults to true.", + "enum": [ + "off", + "offUnlessPressed", + "on", + "onUnlessPressed" + ], + "type": "string" + }, + "fontFamily": { + "description": "Font family of inline hints.\nDefaults to editor font family.", + "type": "string" + }, + "fontSize": { + "description": "Font size of inline hints.\nDefault to 90% of the editor font size.", + "type": "number" + }, + "padding": { + "description": "Enables the padding around the inlay hint.\nDefaults to false.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IEditorLightbulbOptions": { + "description": "Configuration options for editor lightbulb", + "properties": { + "enabled": { + "description": "Enable the lightbulb code action.\nDefaults to true.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IEditorMinimapOptions": { + "description": "Configuration options for editor minimap", + "properties": { + "autohide": { + "description": "Control the rendering of minimap.", + "type": "boolean" + }, + "enabled": { + "description": "Enable the rendering of the minimap.\nDefaults to true.", + "type": "boolean" + }, + "maxColumn": { + "description": "Limit the width of the minimap to render at most a certain number of columns.\nDefaults to 120.", + "type": "number" + }, + "renderCharacters": { + "description": "Render the actual text on a line (as opposed to color blocks).\nDefaults to true.", + "type": "boolean" + }, + "scale": { + "description": "Relative size of the font in the minimap. Defaults to 1.", + "type": "number" + }, + "showSlider": { + "description": "Control the rendering of the minimap slider.\nDefaults to 'mouseover'.", + "enum": [ + "always", + "mouseover" + ], + "type": "string" + }, + "side": { + "description": "Control the side of the minimap in editor.\nDefaults to 'right'.", + "enum": [ + "left", + "right" + ], + "type": "string" + }, + "size": { + "description": "Control the minimap rendering mode.\nDefaults to 'actual'.", + "enum": [ + "fill", + "fit", + "proportional" + ], + "type": "string" + } + }, + "type": "object" + }, + "editor.IEditorPaddingOptions": { + "description": "Configuration options for editor padding", + "properties": { + "bottom": { + "description": "Spacing between bottom edge of editor and last line.", + "type": "number" + }, + "top": { + "description": "Spacing between top edge of editor and first line.", + "type": "number" + } + }, + "type": "object" + }, + "editor.IEditorParameterHintOptions": { + "description": "Configuration options for parameter hints", + "properties": { + "cycle": { + "description": "Enable cycling of parameter hints.\nDefaults to false.", + "type": "boolean" + }, + "enabled": { + "description": "Enable parameter hints.\nDefaults to true.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IEditorScrollbarOptions": { + "description": "Configuration options for editor scrollbars", + "properties": { + "alwaysConsumeMouseWheel": { + "description": "Always consume mouse wheel events (always call preventDefault() and stopPropagation() on the browser events).\nDefaults to true.\n**NOTE**: This option cannot be updated using `updateOptions()`", + "type": "boolean" + }, + "arrowSize": { + "description": "The size of arrows (if displayed).\nDefaults to 11.\n**NOTE**: This option cannot be updated using `updateOptions()`", + "type": "number" + }, + "handleMouseWheel": { + "description": "Listen to mouse wheel events and react to them by scrolling.\nDefaults to true.", + "type": "boolean" + }, + "horizontal": { + "description": "Render horizontal scrollbar.\nDefaults to 'auto'.", + "enum": [ + "auto", + "hidden", + "visible" + ], + "type": "string" + }, + "horizontalHasArrows": { + "description": "Render arrows at the left and right of the horizontal scrollbar.\nDefaults to false.\n**NOTE**: This option cannot be updated using `updateOptions()`", + "type": "boolean" + }, + "horizontalScrollbarSize": { + "description": "Height in pixels for the horizontal scrollbar.\nDefaults to 10 (px).", + "type": "number" + }, + "horizontalSliderSize": { + "description": "Height in pixels for the horizontal slider.\nDefaults to `horizontalScrollbarSize`.\n**NOTE**: This option cannot be updated using `updateOptions()`", + "type": "number" + }, + "scrollByPage": { + "description": "Scroll gutter clicks move by page vs jump to position.\nDefaults to false.", + "type": "boolean" + }, + "useShadows": { + "description": "Cast horizontal and vertical shadows when the content is scrolled.\nDefaults to true.\n**NOTE**: This option cannot be updated using `updateOptions()`", + "type": "boolean" + }, + "vertical": { + "description": "Render vertical scrollbar.\nDefaults to 'auto'.", + "enum": [ + "auto", + "hidden", + "visible" + ], + "type": "string" + }, + "verticalHasArrows": { + "description": "Render arrows at the top and bottom of the vertical scrollbar.\nDefaults to false.\n**NOTE**: This option cannot be updated using `updateOptions()`", + "type": "boolean" + }, + "verticalScrollbarSize": { + "description": "Width in pixels for the vertical scrollbar.\nDefaults to 10 (px).", + "type": "number" + }, + "verticalSliderSize": { + "description": "Width in pixels for the vertical slider.\nDefaults to `verticalScrollbarSize`.\n**NOTE**: This option cannot be updated using `updateOptions()`", + "type": "number" + } + }, + "type": "object" + }, + "editor.IEditorStickyScrollOptions": { + "properties": { + "defaultModel": { + "description": "Model to choose for sticky scroll by default", + "enum": [ + "foldingProviderModel", + "indentationModel", + "outlineModel" + ], + "type": "string" + }, + "enabled": { + "description": "Enable the sticky scroll", + "type": "boolean" + }, + "maxLineCount": { + "description": "Maximum number of sticky lines to show", + "type": "number" + }, + "scrollWithEditor": { + "description": "Define whether to scroll sticky scroll with editor horizontal scrollbae", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IGotoLocationOptions": { + "description": "Configuration options for go to location", + "properties": { + "alternativeDeclarationCommand": { + "type": "string" + }, + "alternativeDefinitionCommand": { + "type": "string" + }, + "alternativeImplementationCommand": { + "type": "string" + }, + "alternativeReferenceCommand": { + "type": "string" + }, + "alternativeTypeDefinitionCommand": { + "type": "string" + }, + "multiple": { + "$ref": "#/definitions/editor.GoToLocationValues" + }, + "multipleDeclarations": { + "$ref": "#/definitions/editor.GoToLocationValues" + }, + "multipleDefinitions": { + "$ref": "#/definitions/editor.GoToLocationValues" + }, + "multipleImplementations": { + "$ref": "#/definitions/editor.GoToLocationValues" + }, + "multipleReferences": { + "$ref": "#/definitions/editor.GoToLocationValues" + }, + "multipleTypeDefinitions": { + "$ref": "#/definitions/editor.GoToLocationValues" + } + }, + "type": "object" + }, + "editor.IGuidesOptions": { + "properties": { + "bracketPairs": { + "description": "Enable rendering of bracket pair guides.\nDefaults to false.", + "enum": [ + "active", + false, + true + ] + }, + "bracketPairsHorizontal": { + "description": "Enable rendering of vertical bracket pair guides.\nDefaults to 'active'.", + "enum": [ + "active", + false, + true + ] + }, + "highlightActiveBracketPair": { + "description": "Enable highlighting of the active bracket pair.\nDefaults to true.", + "type": "boolean" + }, + "highlightActiveIndentation": { + "description": "Enable highlighting of the active indent guide.\nDefaults to true.", + "enum": [ + "always", + false, + true + ] + }, + "indentation": { + "description": "Enable rendering of indent guides.\nDefaults to true.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IInlineSuggestOptions": { + "properties": { + "enabled": { + "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": [ + "prefix", + "subword", + "subwordSmart" + ], + "type": "string" + }, + "showToolbar": { + "enum": [ + "always", + "onHover" + ], + "type": "string" + }, + "suppressSuggestions": { + "type": "boolean" + } + }, + "type": "object" + }, + "editor.IPasteAsOptions": { + "description": "Configuration options for editor pasting as into behavior", + "properties": { + "enabled": { + "description": "Enable paste as functionality in editors.\nDefaults to true.", + "type": "boolean" + }, + "showPasteSelector": { + "description": "Controls if a widget is shown after a drop.\nDefaults to 'afterPaste'.", + "enum": [ + "afterPaste", + "never" + ], + "type": "string" + } + }, + "type": "object" + }, + "editor.IQuickSuggestionsOptions": { + "description": "Configuration options for quick suggestions", + "properties": { + "comments": { + "enum": [ + false, + "inline", + "off", + "on", + true + ] + }, + "other": { + "enum": [ + false, + "inline", + "off", + "on", + true + ] + }, + "strings": { + "enum": [ + false, + "inline", + "off", + "on", + true + ] + } + }, + "type": "object" + }, + "editor.IRulerOption": { + "properties": { + "color": { + "type": "string" + }, + "column": { + "type": "number" + } + }, + "type": "object" + }, + "editor.ISmartSelectOptions": { + "properties": { + "selectLeadingAndTrailingWhitespace": { + "type": "boolean" + }, + "selectSubwords": { + "type": "boolean" + } + }, + "type": "object" + }, + "editor.ISuggestOptions": { + "description": "Configuration options for editor suggest widget", + "properties": { + "filterGraceful": { + "description": "Enable graceful matching. Defaults to true.", + "type": "boolean" + }, + "insertMode": { + "description": "Overwrite word ends on accept. Default to false.", + "enum": [ + "insert", + "replace" + ], + "type": "string" + }, + "localityBonus": { + "description": "Favors words that appear close to the cursor.", + "type": "boolean" + }, + "matchOnWordStartOnly": { + "description": "Controls whether suggestions allow matches in the middle of the word instead of only at the beginning", + "type": "boolean" + }, + "preview": { + "description": "Enable or disable the rendering of the suggestion preview.", + "type": "boolean" + }, + "previewMode": { + "description": "Configures the mode of the preview.", + "enum": [ + "prefix", + "subword", + "subwordSmart" + ], + "type": "string" + }, + "selectionMode": { + "description": "Select suggestions when triggered via quick suggest or trigger characters", + "enum": [ + "always", + "never", + "whenQuickSuggestion", + "whenTriggerCharacter" + ], + "type": "string" + }, + "shareSuggestSelections": { + "description": "Enable using global storage for remembering suggestions.", + "type": "boolean" + }, + "showClasses": { + "description": "Show class-suggestions.", + "type": "boolean" + }, + "showColors": { + "description": "Show color-suggestions.", + "type": "boolean" + }, + "showConstants": { + "description": "Show constant-suggestions.", + "type": "boolean" + }, + "showConstructors": { + "description": "Show constructor-suggestions.", + "type": "boolean" + }, + "showDeprecated": { + "description": "Show deprecated-suggestions.", + "type": "boolean" + }, + "showEnumMembers": { + "description": "Show enumMember-suggestions.", + "type": "boolean" + }, + "showEnums": { + "description": "Show enum-suggestions.", + "type": "boolean" + }, + "showEvents": { + "description": "Show event-suggestions.", + "type": "boolean" + }, + "showFields": { + "description": "Show field-suggestions.", + "type": "boolean" + }, + "showFiles": { + "description": "Show file-suggestions.", + "type": "boolean" + }, + "showFolders": { + "description": "Show folder-suggestions.", + "type": "boolean" + }, + "showFunctions": { + "description": "Show function-suggestions.", + "type": "boolean" + }, + "showIcons": { + "description": "Enable or disable icons in suggestions. Defaults to true.", + "type": "boolean" + }, + "showInlineDetails": { + "description": "Show details inline with the label. Defaults to true.", + "type": "boolean" + }, + "showInterfaces": { + "description": "Show interface-suggestions.", + "type": "boolean" + }, + "showIssues": { + "description": "Show issue-suggestions.", + "type": "boolean" + }, + "showKeywords": { + "description": "Show keyword-suggestions.", + "type": "boolean" + }, + "showMethods": { + "description": "Show method-suggestions.", + "type": "boolean" + }, + "showModules": { + "description": "Show module-suggestions.", + "type": "boolean" + }, + "showOperators": { + "description": "Show operator-suggestions.", + "type": "boolean" + }, + "showProperties": { + "description": "Show property-suggestions.", + "type": "boolean" + }, + "showReferences": { + "description": "Show reference-suggestions.", + "type": "boolean" + }, + "showSnippets": { + "description": "Show snippet-suggestions.", + "type": "boolean" + }, + "showStatusBar": { + "description": "Enable or disable the suggest status bar.", + "type": "boolean" + }, + "showStructs": { + "description": "Show struct-suggestions.", + "type": "boolean" + }, + "showTypeParameters": { + "description": "Show typeParameter-suggestions.", + "type": "boolean" + }, + "showUnits": { + "description": "Show unit-suggestions.", + "type": "boolean" + }, + "showUsers": { + "description": "Show user-suggestions.", + "type": "boolean" + }, + "showValues": { + "description": "Show value-suggestions.", + "type": "boolean" + }, + "showVariables": { + "description": "Show variable-suggestions.", + "type": "boolean" + }, + "showWords": { + "description": "Show text-suggestions.", + "type": "boolean" + }, + "snippetsPreventQuickSuggestions": { + "description": "Prevent quick suggestions when a snippet is active. Defaults to true.", + "type": "boolean" + } + }, + "type": "object" + }, + "editor.ITextModel": { + "description": "A model.", + "properties": { + "id": { + "description": "A unique identifier associated with this model.", + "type": "string" + }, + "onDidChangeAttached": { + "$ref": "#/definitions/IEvent", + "description": "An event emitted when the model has been attached to the first editor or detached from the last editor." + }, + "onDidChangeDecorations": { + "$ref": "#/definitions/IEvent", + "description": "An event emitted when decorations of the model have changed." + }, + "onDidChangeLanguage": { + "$ref": "#/definitions/IEvent", + "description": "An event emitted when the language associated with the model has changed." + }, + "onDidChangeLanguageConfiguration": { + "$ref": "#/definitions/IEvent", + "description": "An event emitted when the language configuration associated with the model has changed." + }, + "onDidChangeOptions": { + "$ref": "#/definitions/IEvent", + "description": "An event emitted when the model options have changed." + }, + "onWillDispose": { + "$ref": "#/definitions/IEvent", + "description": "An event emitted right before disposing the model." + }, + "uri": { + "$ref": "#/definitions/Uri", + "description": "Gets the resource associated with this editor model." + } + }, + "type": "object" + }, + "editor.IUnicodeHighlightOptions": { + "description": "Configuration options for unicode highlighting.", + "properties": { + "allowedCharacters": { + "$ref": "#/definitions/Record", + "description": "Defines allowed characters that are not being highlighted." + }, + "allowedLocales": { + "$ref": "#/definitions/Record", + "description": "Unicode characters that are common in allowed locales are not being highlighted." + }, + "ambiguousCharacters": { + "description": "Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale.", + "type": "boolean" + }, + "includeComments": { + "description": "Controls whether characters in comments should also be subject to unicode highlighting.", + "enum": [ + false, + "inUntrustedWorkspace", + true + ] + }, + "includeStrings": { + "description": "Controls whether characters in strings should also be subject to unicode highlighting.", + "enum": [ + false, + "inUntrustedWorkspace", + true + ] + }, + "invisibleCharacters": { + "description": "Controls whether characters that just reserve space or have no width at all are highlighted.", + "type": "boolean" + }, + "nonBasicASCII": { + "description": "Controls whether all non-basic ASCII characters are highlighted. Only characters between U+0020 and U+007E, tab, line-feed and carriage-return are considered basic ASCII.", + "enum": [ + false, + "inUntrustedWorkspace", + true + ] + } + }, + "type": "object" + }, + "editor.LineNumbersType": { + "anyOf": [ + { + "enum": [ + "interval", + "off", + "on", + "relative" + ], + "type": "string" + }, + { + "type": "object" + } + ] + }, + "languages.typescript.CompilerOptions": { + "additionalProperties": { + "$ref": "#/definitions/languages.typescript.CompilerOptionsValue" + }, + "properties": { + "allowJs": { + "type": "boolean" + }, + "allowSyntheticDefaultImports": { + "type": "boolean" + }, + "allowUmdGlobalAccess": { + "type": "boolean" + }, + "allowUnreachableCode": { + "type": "boolean" + }, + "allowUnusedLabels": { + "type": "boolean" + }, + "alwaysStrict": { + "type": "boolean" + }, + "baseUrl": { + "type": "string" + }, + "charset": { + "type": "string" + }, + "checkJs": { + "type": "boolean" + }, + "composite": { + "type": "boolean" + }, + "declaration": { + "type": "boolean" + }, + "declarationDir": { + "type": "string" + }, + "declarationMap": { + "type": "boolean" + }, + "disableSizeLimit": { + "type": "boolean" + }, + "disableSourceOfProjectReferenceRedirect": { + "type": "boolean" + }, + "downlevelIteration": { + "type": "boolean" + }, + "emitBOM": { + "type": "boolean" + }, + "emitDeclarationOnly": { + "type": "boolean" + }, + "emitDecoratorMetadata": { + "type": "boolean" + }, + "esModuleInterop": { + "type": "boolean" + }, + "experimentalDecorators": { + "type": "boolean" + }, + "forceConsistentCasingInFileNames": { + "type": "boolean" + }, + "importHelpers": { + "type": "boolean" + }, + "inlineSourceMap": { + "type": "boolean" + }, + "inlineSources": { + "type": "boolean" + }, + "isolatedModules": { + "type": "boolean" + }, + "jsx": { + "$ref": "#/definitions/languages.typescript.JsxEmit" + }, + "jsxFactory": { + "type": "string" + }, + "keyofStringsOnly": { + "type": "boolean" + }, + "lib": { + "items": { + "type": "string" + }, + "type": "array" + }, + "locale": { + "type": "string" + }, + "mapRoot": { + "type": "string" + }, + "maxNodeModuleJsDepth": { + "type": "number" + }, + "module": { + "$ref": "#/definitions/languages.typescript.ModuleKind" + }, + "moduleResolution": { + "$ref": "#/definitions/languages.typescript.ModuleResolutionKind" + }, + "newLine": { + "$ref": "#/definitions/languages.typescript.NewLineKind" + }, + "noEmit": { + "type": "boolean" + }, + "noEmitHelpers": { + "type": "boolean" + }, + "noEmitOnError": { + "type": "boolean" + }, + "noErrorTruncation": { + "type": "boolean" + }, + "noFallthroughCasesInSwitch": { + "type": "boolean" + }, + "noImplicitAny": { + "type": "boolean" + }, + "noImplicitReturns": { + "type": "boolean" + }, + "noImplicitThis": { + "type": "boolean" + }, + "noImplicitUseStrict": { + "type": "boolean" + }, + "noLib": { + "type": "boolean" + }, + "noResolve": { + "type": "boolean" + }, + "noStrictGenericChecks": { + "type": "boolean" + }, + "noUnusedLocals": { + "type": "boolean" + }, + "noUnusedParameters": { + "type": "boolean" + }, + "out": { + "type": "string" + }, + "outDir": { + "type": "string" + }, + "outFile": { + "type": "string" + }, + "paths": { + "$ref": "#/definitions/languages.typescript.MapLike" + }, + "preserveConstEnums": { + "type": "boolean" + }, + "preserveSymlinks": { + "type": "boolean" + }, + "project": { + "type": "string" + }, + "reactNamespace": { + "type": "string" + }, + "removeComments": { + "type": "boolean" + }, + "resolveJsonModule": { + "type": "boolean" + }, + "rootDir": { + "type": "string" + }, + "rootDirs": { + "items": { + "type": "string" + }, + "type": "array" + }, + "skipDefaultLibCheck": { + "type": "boolean" + }, + "skipLibCheck": { + "type": "boolean" + }, + "sourceMap": { + "type": "boolean" + }, + "sourceRoot": { + "type": "string" + }, + "strict": { + "type": "boolean" + }, + "strictBindCallApply": { + "type": "boolean" + }, + "strictFunctionTypes": { + "type": "boolean" + }, + "strictNullChecks": { + "type": "boolean" + }, + "strictPropertyInitialization": { + "type": "boolean" + }, + "stripInternal": { + "type": "boolean" + }, + "suppressExcessPropertyErrors": { + "type": "boolean" + }, + "suppressImplicitAnyIndexErrors": { + "type": "boolean" + }, + "target": { + "$ref": "#/definitions/languages.typescript.ScriptTarget" + }, + "traceResolution": { + "type": "boolean" + }, + "typeRoots": { + "description": "Paths used to compute primary types search locations", + "items": { + "type": "string" + }, + "type": "array" + }, + "types": { + "items": { + "type": "string" + }, + "type": "array" + }, + "useDefineForClassFields": { + "type": "boolean" + } + }, + "type": "object" + }, + "languages.typescript.CompilerOptionsValue": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "items": { + "type": [ + "string", + "number" + ] + }, + "type": "array" + }, + { + "$ref": "#/definitions/languages.typescript.MapLike" + }, + { + "type": [ + "string", + "number", + "boolean" + ] + } + ] + }, + "languages.typescript.DiagnosticsOptions": { + "properties": { + "diagnosticCodesToIgnore": { + "items": { + "type": "number" + }, + "type": "array" + }, + "noSemanticValidation": { + "type": "boolean" + }, + "noSuggestionDiagnostics": { + "type": "boolean" + }, + "noSyntaxValidation": { + "type": "boolean" + }, + "onlyVisible": { + "description": "Limit diagnostic computation to only visible files.\nDefaults to false.", + "type": "boolean" + } + }, + "type": "object" + }, + "languages.typescript.InlayHintsOptions": { + "properties": { + "includeInlayEnumMemberValueHints": { + "type": "boolean" + }, + "includeInlayFunctionLikeReturnTypeHints": { + "type": "boolean" + }, + "includeInlayFunctionParameterTypeHints": { + "type": "boolean" + }, + "includeInlayParameterNameHints": { + "enum": [ + "all", + "literals", + "none" + ], + "type": "string" + }, + "includeInlayParameterNameHintsWhenArgumentMatchesName": { + "type": "boolean" + }, + "includeInlayPropertyDeclarationTypeHints": { + "type": "boolean" + }, + "includeInlayVariableTypeHints": { + "type": "boolean" + } + }, + "type": "object" + }, + "languages.typescript.JsxEmit": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" + }, + "languages.typescript.MapLike": { + "additionalProperties": { + "$ref": "#/definitions/T" + }, + "type": "object" + }, + "languages.typescript.ModuleKind": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 99 + ], + "type": "number" + }, + "languages.typescript.ModuleResolutionKind": { + "enum": [ + 1, + 2 + ], + "type": "number" + }, + "languages.typescript.NewLineKind": { + "enum": [ + 0, + 1 + ], + "type": "number" + }, + "languages.typescript.ScriptTarget": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 99, + 100, + 99 + ], + "type": "number" + } + }, + "properties": { + "esbuild": { + "$ref": "#/definitions/BuildOptions", + "description": "Options for the preview compiler." + }, + "monaco": { + "description": "Options for the code editor.", + "properties": { + "compiler": { + "$ref": "#/definitions/languages.typescript.CompilerOptions" + }, + "diagnostics": { + "$ref": "#/definitions/languages.typescript.DiagnosticsOptions" + }, + "general": { + "$ref": "#/definitions/Omit" + }, + "inlayHints": { + "$ref": "#/definitions/languages.typescript.InlayHintsOptions" + } + }, + "type": "object" + }, + "react": { + "description": "Options for code generation.", + "properties": { + "addTranslate": { + "description": "Enable to add translations tags to strings", + "type": "boolean" + }, + "flavor": { + "const": "react-native", + "description": "The flavor of React Native to generate", + "type": "string" + } + }, + "type": "object" + }, + "writer": { + "$ref": "#/definitions/Options" + } + }, + "type": "object" +} + diff --git a/packages/figma-to-react-native/src/interface/utils/editor/templates/env.ts.tpl b/packages/figma-to-react-native/src/interface/utils/editor/templates/env.ts.tpl new file mode 100644 index 00000000..c3eeeb2f --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/templates/env.ts.tpl @@ -0,0 +1,10 @@ +declare module "*.svg" { + import { SvgProps } from 'react-native-svg'; + const content: React.FC; + export default content; +} + +declare module "*.png" { + const content: string; + export default content; +} diff --git a/packages/figma-to-react-native/src/interface/utils/editor/templates/index.ts b/packages/figma-to-react-native/src/interface/utils/editor/templates/index.ts new file mode 100644 index 00000000..f783cfc7 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/templates/index.ts @@ -0,0 +1,13 @@ +import {F2RN_EDITOR_NS} from 'config/env'; + +import env from './env.ts.tpl'; +import styles from './styles.ts.tpl'; +import reactNative from './react-native.ts.tpl'; +import reactNativeExo from './react-native-exo.ts.tpl'; + +export default { + [`${F2RN_EDITOR_NS}env.d.ts`]: atob(env.toString()), + [`${F2RN_EDITOR_NS}styles.d.ts`]: atob(styles.toString()), + [`${F2RN_EDITOR_NS}react-native.d.ts`]: atob(reactNative.toString()), + [`${F2RN_EDITOR_NS}react-native-exo.d.ts`]: atob(reactNativeExo.toString()), +} diff --git a/packages/figma-to-react-native/src/interface/utils/editor/templates/react-native-exo.ts.tpl b/packages/figma-to-react-native/src/interface/utils/editor/templates/react-native-exo.ts.tpl new file mode 100644 index 00000000..3fc9c12d --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/templates/react-native-exo.ts.tpl @@ -0,0 +1,3 @@ +declare module 'react-native-exo' { + export const Icon: React.FC; +} diff --git a/packages/figma-to-react-native/src/interface/utils/editor/templates/react-native.ts.tpl b/packages/figma-to-react-native/src/interface/utils/editor/templates/react-native.ts.tpl new file mode 100644 index 00000000..891ea53c --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/templates/react-native.ts.tpl @@ -0,0 +1,179 @@ +declare module 'react-native' { + // The following list is sourced from: + // - https://github.com/necolas/react-native-web/blob/0.17.5/packages/react-native-web/src/types/styles.js#L76 + type CursorValue = + | 'alias' + | 'all-scroll' + | 'auto' + | 'cell' + | 'context-menu' + | 'copy' + | 'crosshair' + | 'default' + | 'grab' + | 'grabbing' + | 'help' + | 'pointer' + | 'progress' + | 'wait' + | 'text' + | 'vertical-text' + | 'move' + | 'none' + | 'no-drop' + | 'not-allowed' + | 'zoom-in' + | 'zoom-out' + | 'col-resize' + | 'e-resize' + | 'ew-resize' + | 'n-resize' + | 'ne-resize' + | 'ns-resize' + | 'nw-resize' + | 'row-resize' + | 's-resize' + | 'se-resize' + | 'sw-resize' + | 'w-resize' + | 'nesw-resize' + | 'nwse-resize'; + // This list is the combination of the following two lists: + // - https://github.com/necolas/react-native-web/blob/0.17.5/packages/react-native-web/src/modules/AccessibilityUtil/propsToAriaRole.js#L10 + // - https://github.com/necolas/react-native-web/blob/0.17.5/packages/react-native-web/src/modules/AccessibilityUtil/propsToAccessibilityComponent.js#L12 + // Plus the single hard-coded value "label" from here: + // - https://github.com/necolas/react-native-web/blob/0.17.5/packages/react-native-web/src/modules/AccessibilityUtil/propsToAccessibilityComponent.js#L36 + type WebAccessibilityRole = + | 'adjustable' + | 'article' + | 'banner' + | 'blockquote' + | 'button' + | 'code' + | 'complementary' + | 'contentinfo' + | 'deletion' + | 'emphasis' + | 'figure' + | 'form' + | 'header' + | 'image' + | 'imagebutton' + | 'insertion' + | 'keyboardkey' + | 'label' + | 'link' + | 'list' + | 'listitem' + | 'main' + | 'navigation' + | 'none' + | 'region' + | 'search' + | 'strong' + | 'summary' + | 'text'; + interface PressableStateCallbackType { + hovered?: boolean; + focused?: boolean; + } + + interface ViewProps { + accessibilityRole?: WebAccessibilityRole; + href?: string; + hrefAttrs?: { + target?: '_blank' | '_self' | '_top' | 'blank' | 'self' | 'top'; + rel?: string; + download?: boolean; + }; + onMouseDown?: (event: React.MouseEvent) => void; + onMouseUp?: (event: React.MouseEvent) => void; + onMouseEnter?: (event: React.MouseEvent) => void; + onMouseLeave?: (event: React.MouseEvent) => void; + onClick?: (event: React.MouseEvent) => void; + onFocus?: (event: React.FocusEvent) => void; + onScroll?: (event: React.UIEvent) => void; + // For compatibility with RNW internals + onScrollShouldSetResponder?: unknown; + onScrollShouldSetResponderCapture?: unknown; + onSelectionChangeShouldSetResponder?: unknown; + onSelectionChangeShouldSetResponderCapture?: unknown; + } + + interface TextProps { + dir?: 'ltr' | 'rtl' | 'auto'; + focusable?: boolean; + accessibilityRole?: WebAccessibilityRole; + accessibilityState?: { + busy?: boolean; + checked?: boolean | 'mixed'; + disabled?: boolean; + expanded?: boolean; + grabbed?: boolean; + hidden?: boolean; + invalid?: boolean; + pressed?: boolean; + readonly?: boolean; + required?: boolean; + selected?: boolean; + }; + href?: string; + hrefAttrs?: { + target?: '_blank' | '_self' | '_top' | 'blank' | 'self' | 'top'; + rel?: string; + download?: boolean; + }; + onMouseEnter?: (event: React.MouseEvent) => void; + onMouseLeave?: (event: React.MouseEvent) => void; + onClick?: (event: React.MouseEvent) => void; + onFocus?: (event: React.FocusEvent) => void; + // For compatibility with RNW internals + onMoveShouldSetResponder?: unknown; + onMoveShouldSetResponderCapture?: unknown; + onResponderEnd?: unknown; + onResponderGrant?: unknown; + onResponderMove?: unknown; + onResponderReject?: unknown; + onResponderRelease?: unknown; + onResponderStart?: unknown; + onResponderTerminate?: unknown; + onResponderTerminationRequest?: unknown; + onScrollShouldSetResponder?: unknown; + onScrollShouldSetResponderCapture?: unknown; + onSelectionChangeShouldSetResponder?: unknown; + onSelectionChangeShouldSetResponderCapture?: unknown; + onStartShouldSetResponder?: unknown; + onStartShouldSetResponderCapture?: unknown; + } + + interface TouchableOpacityProps { + accessibilityRole?: WebAccessibilityRole; + href?: string; + hrefAttrs?: { + target?: '_blank' | '_self' | '_top' | 'blank' | 'self' | 'top'; + rel?: string; + download?: boolean; + }; + nativeID?: string; + onMouseEnter?: (event: React.MouseEvent) => void; + onMouseLeave?: (event: React.MouseEvent) => void; + } + + interface CheckBoxProps { + color?: string | null; + } + + interface ViewStyle { + cursor?: CursorValue; + transitionProperty?: string; + display?: 'flex' | 'inline-flex' | 'none'; + } + + interface TextStyle { + // The following list is sourced from: + // - https://github.com/necolas/react-native-web/blob/0.17.5/packages/react-native-web/src/types/styles.js#L128 + userSelect?: 'all' | 'auto' | 'contain' | 'none' | 'text'; + } +} + +export {}; diff --git a/packages/figma-to-react-native/src/interface/utils/editor/templates/styles.ts.tpl b/packages/figma-to-react-native/src/interface/utils/editor/templates/styles.ts.tpl new file mode 100644 index 00000000..281a3bd2 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/editor/templates/styles.ts.tpl @@ -0,0 +1,4 @@ +declare module 'styles' { + export function useStyles(stylesheet?: any): any; + export function createStyleSheet(theme: any): any; +} diff --git a/src/interface/utils/download.ts b/packages/figma-to-react-native/src/interface/utils/exporter/download.ts similarity index 58% rename from src/interface/utils/download.ts rename to packages/figma-to-react-native/src/interface/utils/exporter/download.ts index ef05b811..389bdeac 100644 --- a/src/interface/utils/download.ts +++ b/packages/figma-to-react-native/src/interface/utils/exporter/download.ts @@ -1,9 +1,9 @@ import {zip} from './zip'; -import type {ProjectBuild} from 'types/project'; +import type {ProjectBuild, ProjectConfig} from 'types/project'; -export async function download(project: ProjectBuild) { - const blob = await zip(project); +export async function download(project: ProjectBuild, config: ProjectConfig) { + const blob = await zip(project, config); const link = document.createElement('a'); const src = URL.createObjectURL(blob); link.href = src; diff --git a/src/interface/utils/upload.ts b/packages/figma-to-react-native/src/interface/utils/exporter/upload.ts similarity index 97% rename from src/interface/utils/upload.ts rename to packages/figma-to-react-native/src/interface/utils/exporter/upload.ts index 19d18a6b..c8c2fa98 100644 --- a/src/interface/utils/upload.ts +++ b/packages/figma-to-react-native/src/interface/utils/exporter/upload.ts @@ -33,7 +33,7 @@ export async function upload( uploader.addFile({ name: path, type: 'application/zip', - data: await zip(project), + data: await zip(project, config), }); }); } diff --git a/packages/figma-to-react-native/src/interface/utils/exporter/zip.ts b/packages/figma-to-react-native/src/interface/utils/exporter/zip.ts new file mode 100644 index 00000000..9fc99dda --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/exporter/zip.ts @@ -0,0 +1,33 @@ +import {downloadZip} from 'client-zip'; +import {UNISTYLES_LIB} from 'config/env'; + +import type {ProjectBuild, ProjectConfig} from 'types/project'; + +export async function zip(project: ProjectBuild, config: ProjectConfig) { + const lastModified = new Date(); + const payload: Array<{ + name: string, + lastModified: Date, + input: string | Uint8Array, + }> = []; + payload.push({name: 'index.ts', lastModified, input: project.index}); + payload.push({name: 'theme.ts', lastModified, input: project.theme}); + payload.push({name: 'styles.ts', lastModified, input: UNISTYLES_LIB}); + project.components.forEach(([name, index, code, story]) => { + payload.push({name: `components/${name}/index.ts`, lastModified, input: index}); + payload.push({name: `components/${name}/${name}.tsx`, lastModified, input: code}); + payload.push({name: `components/${name}/${name}.stories.tsx`, lastModified, input: story}); + }); + if (config.includeAssets) { + project.assets.forEach(([name, isVector, bytes]) => { + const folder = isVector ? 'vectors' : 'images'; + const extension = isVector ? 'svg' : 'png'; + payload.push({ + name: `assets/${folder}/${name}.${extension}`, + input: bytes, + lastModified, + }); + }); + } + return await downloadZip(payload).blob(); +} diff --git a/packages/figma-to-react-native/src/interface/utils/importer/icons.ts b/packages/figma-to-react-native/src/interface/utils/importer/icons.ts new file mode 100644 index 00000000..1de37109 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/importer/icons.ts @@ -0,0 +1,42 @@ +import {loadIcons} from '@iconify/react'; + +export async function loadIconSet( + iconSet: string, + onProgress: (value: number) => void, +): Promise { + if (!iconSet) return; + const host = 'https://api.iconify.design'; + const res = await fetch(`${host}/collection?prefix=${iconSet}`); + const val = await res.json(); + const set = filterIconsBySuffix( + '', + val.suffixes, + val.uncategorized, + ); + + const list = set.map((icon: string) => `${iconSet}:${icon}`); + return new Promise((resolve, _reject) => { + loadIcons(list, (_loaded, _missing, pending, _unsubscribe) => { + onProgress(Math.round((_loaded.length / list.length) * 100)); + if (pending.length) return; + resolve(list); + }); + }); +}; + +function filterIconsBySuffix( + suffix: string, + suffixes: Record, + items: string[], +): string[] { + // Suffix is an empty string, filter out all suffixes + if (suffix === '') { + return items.filter(i => !Object.keys(suffixes).filter(Boolean).some(s => i.endsWith(s))); + // Suffix matches in the suffixes object, use specified suffix + } else if (suffixes.hasOwnProperty(suffix)) { + return items.filter(i => i.endsWith(suffix)); + // If the suffix is not in the suffixes object, return the original array + } else { + return items; + } +} \ No newline at end of file diff --git a/src/interface/utils/preview/template/importMap.json b/packages/figma-to-react-native/src/interface/utils/previewer/importMap.json similarity index 96% rename from src/interface/utils/preview/template/importMap.json rename to packages/figma-to-react-native/src/interface/utils/previewer/importMap.json index ba31917c..56f6c3db 100644 --- a/src/interface/utils/preview/template/importMap.json +++ b/packages/figma-to-react-native/src/interface/utils/previewer/importMap.json @@ -32,10 +32,12 @@ "@radix-ui/react-use-size": "https://ga.jspm.io/npm:@radix-ui/react-use-size@1.0.1/dist/index.mjs", "@react-aria/ssr": "https://ga.jspm.io/npm:@react-aria/ssr@3.8.0/dist/import.mjs", "@react-aria/utils": "https://ga.jspm.io/npm:@react-aria/utils@3.20.0/dist/import.mjs", + "@react-native/normalize-colors": "https://ga.jspm.io/npm:@react-native/normalize-colors@0.74.1/index.js", "@react-native-aria/button": "https://unpkg.com/@react-native-aria/button@0.2.4/lib/module", "@react-native-aria/focus": "https://unpkg.com/@react-native-aria/focus@0.2.8/lib/module", "@react-native-aria/interactions": "https://unpkg.com/@react-native-aria/interactions@0.2.10/lib/module", "@react-stately/utils": "https://ga.jspm.io/npm:@react-stately/utils@3.7.0/dist/import.mjs", + "iconify-icon": "https://ga.jspm.io/npm:iconify-icon@1.0.8/dist/iconify-icon.mjs", "aria-hidden": "https://ga.jspm.io/npm:aria-hidden@1.2.3/dist/es2015/index.js", "clsx": "https://ga.jspm.io/npm:clsx@1.2.1/dist/clsx.m.js", "cross-fetch": "https://ga.jspm.io/npm:cross-fetch@3.1.8/dist/browser-ponyfill.js", @@ -68,11 +70,12 @@ "react-dev-utils/launchEditorEndpoint": "https://ga.jspm.io/npm:react-dev-utils@12.0.1/launchEditorEndpoint.js", "react-dom": "https://ga.jspm.io/npm:react-dom@18.2.0/dev.index.js", "react-dom/client": "https://ga.jspm.io/npm:react-dom@18.2.0/client.js", - "react-exo": "https://unpkg.com/react-exo@0.2.2/lib/module/index.web.js", "react-inspector": "https://ga.jspm.io/npm:react-inspector@6.0.2/dist/index.mjs", "react-is": "https://ga.jspm.io/npm:react-is@16.13.1/index.js", + "react-exo": "https://unpkg.com/react-exo@0.2.2/lib/module/index.web.js", + "react-native-exo": "https://ga.jspm.io/npm:@iconify-icon/react@1.0.8/dist/iconify.mjs", "react-native-svg": "https://ga.jspm.io/npm:react-native-svg-web@1.0.9/index.js", - "react-native-unistyles": "https://unpkg.com/react-native-unistyles@1.0.0-beta.1/lib/module/index.js", + "react-native-unistyles": "https://unpkg.com/react-native-unistyles@1.2.0/lib/module/index.js", "react-native": "https://ga.jspm.io/npm:react-native-web@0.19.5/dist/index.js", "react-remove-scroll-bar": "https://ga.jspm.io/npm:react-remove-scroll-bar@2.3.4/dist/es2015/index.js", "react-remove-scroll-bar/constants": "https://ga.jspm.io/npm:react-remove-scroll-bar@2.3.4/dist/es2015/constants.js", diff --git a/packages/figma-to-react-native/src/interface/utils/previewer/index.ts b/packages/figma-to-react-native/src/interface/utils/previewer/index.ts new file mode 100644 index 00000000..24380a82 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/previewer/index.ts @@ -0,0 +1,102 @@ +import * as $ from 'interface/store'; +import {bundle} from 'interface/utils/bundler'; +import {notify} from 'interface/telemetry'; +import {UNISTYLES_LIB} from 'config/env'; + +import importMap from './importMap.json'; +import iframe from './templates/iframe.html.tpl'; +import loader from './templates/loader.tsx.tpl'; +import app from './templates/app.tsx.tpl'; + +import type {Settings} from 'types/settings'; +import type {ComponentBuild} from 'types/component'; + +const ENTRY_POINT = '/index.tsx'; + +interface PreviewOptions { + tag: string, + name: string, + props: string, + theme: string, + settings: Settings, + build: ComponentBuild, +} + +export async function preview(options: PreviewOptions) { + const {tag, name, props, theme, settings, build} = options; + + // Virtual filesystem + const files: Map = new Map(); + + // Add components to filesystem + for (const [key, component] of Object.entries(build.roster)) { + try { + const contents = $.getComponentCode(key); + const path = `/components/${component.name}`; + const code = contents.toString(); + files.set(path, code); + if (name === component.name) { + console.debug('[preview]', tag); + } + } catch (e) { + notify(e, `Failed to build preview component: ${component}`); + console.error('[preview]', e.toString()); + } + } + + // Add assets to filesystem + for (const asset of Object.values(build.assets)) { + try { + const ext = asset.isVector ? 'svg' : 'png'; + const folder = asset.isVector ? 'vectors' : 'images'; + const path = `/assets/${folder}/${asset.name}.${ext}`; + files.set(path, asset.bytes); + } catch (e) { + notify(e, `Failed to build preview asset: ${asset.name}`); + console.error('[preview]', e.toString()); + } + } + + // Build preview app + const previewApp = atob(app.toString()); + try { + files.set('/styles', UNISTYLES_LIB); + files.set('/theme', $.getProjectTheme().toString()); + files.set(ENTRY_POINT, previewApp + .replace('__CURRENT_THEME__', theme) + .replace('__COMPONENT_DEF__', getImports(name, props)) + .replace('__COMPONENT_REF__', tag)); + return await bundle(ENTRY_POINT, files, settings.esbuild, importMap); + } catch (e) { + notify(e, 'Failed to build preview app'); + console.error('[preview/app]', e.toString()); + } +} + +export async function init(settings: Settings) { + // Build filesystem + const files = new Map(); + files.set(ENTRY_POINT, atob(loader.toString())); + + // Build preview loader + try { + const output = await bundle(ENTRY_POINT, files, settings.esbuild, importMap); + return atob(iframe) + .replace('__IMPORT_MAP__', JSON.stringify(importMap, undefined, 2)) + .replace('__LOADER__', output); + } catch(e) { + notify(e, 'Failed to build preview loader'); + } +} + +function getImports(name: string, props: string) { + const regex = /<\s*([a-zA-Z][^\s>\/]*)[^>]*>/g; + const swaps = Array + .from(props.matchAll(regex), match => match[1]) + .filter(swap => swap !== 'Icon'); + const imports = [ + `import {${name}} from 'components/${name}';`, + ...swaps?.map(swap => `import {${swap}} from 'components/${swap}';`), + ]; + return imports.join('\n'); +} diff --git a/packages/figma-to-react-native/src/interface/utils/previewer/templates/app.tsx.tpl b/packages/figma-to-react-native/src/interface/utils/previewer/templates/app.tsx.tpl new file mode 100644 index 00000000..84934262 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/utils/previewer/templates/app.tsx.tpl @@ -0,0 +1,70 @@ +// @ts-nocheck + +import {UnistylesTheme} from 'react-native-unistyles'; +import {AppRegistry} from 'react-native'; +import {Logtail} from '@logtail/browser'; +import {Icon} from 'react-native-exo'; +import defaultTheme, * as themes from 'theme'; + +__COMPONENT_DEF__ + +const logtail = new Logtail('3hRzjtVJTBk6BDFt3pSjjKam'); + +export function App() { + const [theme, setTheme] = React.useState('__CURRENT_THEME__'); + const [variant, setVariant] = React.useState(__COMPONENT_REF__); + + React.useEffect(() => { + const updateProps = (e: JSON) => { + switch (e.data?.type) { + case 'theme': + return setTheme(e.data.theme); + case 'variant': + const newRoot = React.cloneElement(variant, e.data.variant.props); + return setVariant(newRoot); + } + }; + addEventListener('message', updateProps); + return () => removeEventListener('message', updateProps); + }, []); + + return ( + + Component error. Check devtools console. + + }> + + {variant} + + + ) +} + +AppRegistry.registerComponent('app', () => App); +AppRegistry.runApplication('app', { + rootTag: document.getElementById('component'), +}); + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = {hasError: false}; + } + + static getDerivedStateFromError(error) { + return {hasError: true}; + } + + componentDidCatch(error, info) { + const payload = {componentStack: info.componentStack}; + logtail.error(error, payload); + logtail.flush(); + } + + render() { + if (this.state.hasError) + return this.props.fallback; + return this.props.children; + } +} diff --git a/src/interface/utils/preview/template/iframe.tpl.html b/packages/figma-to-react-native/src/interface/utils/previewer/templates/iframe.html.tpl similarity index 52% rename from src/interface/utils/preview/template/iframe.tpl.html rename to packages/figma-to-react-native/src/interface/utils/previewer/templates/iframe.html.tpl index ee5d4575..8276cecf 100644 --- a/src/interface/utils/preview/template/iframe.tpl.html +++ b/packages/figma-to-react-native/src/interface/utils/previewer/templates/iframe.html.tpl @@ -20,54 +20,47 @@ } diff --git a/src/interface/utils/preview/template/_loader.tpl.tsx b/packages/figma-to-react-native/src/interface/utils/previewer/templates/loader.tsx.tpl similarity index 53% rename from src/interface/utils/preview/template/_loader.tpl.tsx rename to packages/figma-to-react-native/src/interface/utils/previewer/templates/loader.tsx.tpl index c0e4e901..836bb27a 100644 --- a/src/interface/utils/preview/template/_loader.tpl.tsx +++ b/packages/figma-to-react-native/src/interface/utils/previewer/templates/loader.tsx.tpl @@ -1,42 +1,67 @@ // @ts-nocheck -import React from 'react'; import {createRoot} from 'react-dom/client'; import {useEffect, useState} from 'react'; import {useControls, TransformWrapper, TransformComponent} from 'react-zoom-pan-pinch'; import {Inspector} from 'react-dev-inspector'; // import {Console, Hook, Unhook} from 'console-feed'; +export default function Loader() { + return ( + + + + ); +} + export function Preview() { const [name, setName] = useState(); const {zoomToElement} = useControls(); const [hasInspect, setInspect] = useState(false); + const [isMouseInComponent, setMouseInComponent] = useState(false); useEffect(() => { const load = (e: JSON) => { - if (e.data?.type === 'inspect') { - setInspect(e.data.enabled); - } - if (e.data?.type === 'preview') { - const component = document.getElementById('component'); - const prev = document.getElementById('target'); - const next = document.createElement('script'); - next.type = 'module'; - next.id = 'target'; - next.innerHTML = e.data.preview; - prev && document.body.removeChild(prev); - next && document.body.appendChild(next); - if (name !== e.data.name) { - const isInitLoad = !name; - setName(e.data.name); - setTimeout(() => - requestIdleCallback(() => - requestAnimationFrame(() => - zoomToElement(component, 1, isInitLoad ? 0 : 100) + const component = document.getElementById('component'); + switch (e.data?.type) { + case 'inspect': + setInspect(e.data.enabled); + break; + case 'resize': + zoomToElement(component, 1, 0); + break; + case 'preview': + // Update frame + component.style.display = 'flex'; + component.style.width = e.data.width ? e.data.width + 'px' : 'auto'; + component.style.height = e.data.height ? e.data.height + 'px' : 'auto'; + component.onmouseenter = () => setMouseInComponent(true); + component.onmouseleave = () => setMouseInComponent(false); + // Update script + const prev = document.getElementById('target'); + const next = document.createElement('script'); + next.id = 'target'; + next.type = 'module'; + next.innerHTML = e.data.bundle; + prev && document.body.removeChild(prev); + next && document.body.appendChild(next); + // New component + if (name !== e.data.name) { + const isInitLoad = !name; + setName(e.data.name); + setTimeout(() => + requestIdleCallback(() => + requestAnimationFrame(() => + zoomToElement(component, 1, isInitLoad ? 0 : 150) + ) ) - ) - , isInitLoad ? 500 : 0); - } + , isInitLoad ? 500 : 0); + } + break; } }; addEventListener('message', load); @@ -47,7 +72,7 @@ export function Preview() {
console.debug('[inspect]', e)} onInspectElement={(e) => { const id = e?.fiber?.memoizedProps?.testID; @@ -62,17 +87,6 @@ export function Preview() { ); } -export default function Loader() { - return ( - - - - ); -} - /*function LogsContainer() { const [logs, setLogs] = useState([]) diff --git a/packages/figma-to-react-native/src/interface/views/ComponentCode.tsx b/packages/figma-to-react-native/src/interface/views/ComponentCode.tsx new file mode 100644 index 00000000..8b74c041 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/views/ComponentCode.tsx @@ -0,0 +1,116 @@ +import {h, Fragment} from 'preact'; +import {useRef, useState, useEffect, useCallback} from 'preact/hooks'; +import MonacoReact, {DiffEditor} from '@monaco-editor/react'; +import {LoadingIndicator} from '@create-figma-plugin/ui'; +import {ScreenWarning} from 'interface/base/ScreenWarning'; +import {initComponentEditor} from 'interface/utils/editor'; +import {MonacoBinding} from 'interface/utils/editor/lib/yjs'; +import {F2RN_EDITOR_NS} from 'config/env'; +import * as $ from 'interface/store'; + +import type {Monaco, Editor} from 'interface/utils/editor'; +import type {ComponentBuild} from 'types/component'; +import type {Settings} from 'types/settings'; + +interface ComponentCodeProps { + componentKey: string, + build: ComponentBuild, + options: Settings['monaco']['general'], + monaco: Monaco, +} + +export function ComponentCode(props: ComponentCodeProps) { + const [patch, setPatch] = useState(''); + const constraint = useRef(null); + const editor = useRef(null); + + const $componentInfo = $.components.get(props.componentKey); + const $componentCode = $.getComponentCode(props.componentKey); + + // GPT triggered by user + const handleGPT = useCallback(async () => { + const response = await fetch('http://localhost:8000', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + code: $componentCode.toString(), + image: props.build.roster[props.componentKey].preview, + }), + }); + const output = await response.text(); + setPatch(output); + }, [$componentCode, props.build]); + + // Update component dependencies on new build + useEffect(() => { + if (props.build) { + Object.entries(props.build.roster).forEach(([key, component]) => { + const code = $.getComponentCode(key); + const uri = `${F2RN_EDITOR_NS}${component.name}.tsx`; + const path = props.monaco.Uri.parse(uri); + const model = props.monaco.editor.getModel(path); + if (!model) { + props.monaco.editor.createModel(code.toString(), 'typescript', path); + } else { + model.setValue(code.toString()); + } + }); + } + }, [props.build]); + + // Update editor constraints on target change + /*useEffect(() => { + if (constraint.current) { + const model = editor.current?.getModel(); + constraint.current?.removeRestrictionsIn(model); + constraint.current?.addRestrictionsTo(model, [ + { + label: 'start', + range: [1, 1, 1, 1], + allowMultiline: true, + }, + ]); + } + }, [props.target]);*/ + + return ( + + {!$componentInfo && + + } + {/* @ts-ignore Preact issue */} + {!patch && as JSX.Element} + path={`${F2RN_EDITOR_NS}${$componentInfo?.name}.tsx`} + onMount={(e, m) => { + editor.current = e; + constraint.current = initComponentEditor(e, m, handleGPT); + new MonacoBinding( + $componentCode, + e.getModel(), + new Set([e]), + $.provider.awareness, + ); + }} + />} + {/* @ts-ignore Preact issue */} + {patch && as JSX.Element} + original={$componentCode.toString()} + modified={patch} + originalModelPath={`${F2RN_EDITOR_NS}${$componentInfo?.name}.tsx`} + modifiedModelPath={`${F2RN_EDITOR_NS}patch/${$componentInfo?.name}.tsx`} + keepCurrentOriginalModel={true} + keepCurrentModifiedModel={false} + />} + + ); +} diff --git a/packages/figma-to-react-native/src/interface/views/ComponentPreview.tsx b/packages/figma-to-react-native/src/interface/views/ComponentPreview.tsx new file mode 100644 index 00000000..c3836197 --- /dev/null +++ b/packages/figma-to-react-native/src/interface/views/ComponentPreview.tsx @@ -0,0 +1,136 @@ +import {h, Fragment} from 'preact'; +import {emit} from '@create-figma-plugin/utilities'; +import {useWindowSize} from '@uidotdev/usehooks'; +import {useState, useCallback, useEffect, useRef} from 'preact/hooks'; +import {useSelectedVariant} from 'interface/hooks/useSelectedVariant'; +import {init, preview} from 'interface/utils/previewer'; +import {ScreenWarning} from 'interface/base/ScreenWarning'; +import * as $ from 'interface/store'; + +import type {ComponentBuild} from 'types/component'; +import type {EventFocusNode} from 'types/events'; +import type {Settings} from 'types/settings'; + +interface ComponentPreviewProps { + componentKey: string, + theme: string, + build: ComponentBuild, + settings: Settings, +} + +export function ComponentPreview(props: ComponentPreviewProps) { + const {componentKey, theme, build, settings} = props; + const [src, setSrc] = useState(''); + const iframe = useRef(null); + const loaded = useRef(false); + const screen = useWindowSize(); + const variant = useSelectedVariant(); + const component = $.components.get(componentKey); + + // Inits the loader that renders component apps + const initLoader = useCallback(() => { + init(settings).then(code => { + loaded.current = true; + setSrc(code); + if (component) { + initApp(); + } + }); + }, [iframe, component, settings]); + + // Inits a component app in the loader + const initApp = useCallback(() => { + if (!component) return; + if (!loaded.current) return + const {name, props, width, height} = component; + const tag = '<' + component.name + component.props + '/>'; + preview({tag, name, props, theme, settings, build}).then(bundle => { + const ctx = iframe.current?.contentWindow; + const name = component?.name; + ctx?.postMessage({type: 'preview', bundle, name, width, height}) + }); + }, [iframe, component, settings, props.build]); + + // Enable inspect mode in the app + const inspectApp = useCallback((enabled: boolean) => { + const ctx = iframe.current?.contentWindow; + ctx?.postMessage({type: 'inspect', enabled}); + }, [iframe]); + + // Render the loader when the settings change + useEffect(initLoader, [settings]); + + // Render the app when the component or settings change + useEffect(initApp, [component, settings]); + + // Update the preview dimensions when screen or component change + useEffect(() => { + const ctx = iframe.current?.contentWindow; + ctx?.postMessage({type: 'resize', width: screen.width, height: screen.height}); + }, [iframe, screen]); + + // Update the preview theme when it changes + useEffect(() => { + const ctx = iframe.current?.contentWindow; + ctx?.postMessage({type: 'theme', theme}); + }, [iframe, theme]); + + // Update the preview variant when it changes + useEffect(() => { + const ctx = iframe.current?.contentWindow; + ctx?.postMessage({type: 'variant', variant}); + }, [variant]); + + // Handle focus events from inspect mode + useEffect(() => { + const onFocus = (e) => { + if (e.data?.type === 'focus' && e.data.id) { + emit('FOCUS', e.data.id); + } + }; + addEventListener('message', onFocus); + return () => removeEventListener('message', onFocus); + }, []); + + // Enable inspect mode when the user holds down the control/meta key + useEffect(() => { + if (!src) return; + const onKeydown = (e: KeyboardEvent) => { + if (e.ctrlKey || e.key === 'Meta') + inspectApp(true); + }; + const onKeyup = (e: KeyboardEvent) => { + if (e.ctrlKey || e.key === 'Meta') + inspectApp(false); + }; + addEventListener('keydown', onKeydown); + addEventListener('keyup', onKeyup); + return () => { + removeEventListener('keydown', onKeydown); + removeEventListener('keyup', onKeyup); + }; + }, [src]); + + return ( + + {!component && + + } +